<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hi All,</p>
    <p>Following up on some work I've been busy with
      (<a class="moz-txt-link-freetext" href="https://gerrit.asterisk.org/c/asterisk/+/13362">https://gerrit.asterisk.org/c/asterisk/+/13362</a>) a few potential
      issues came to the fore on which I need some input on what the
      "correct" behaviour should be.</p>
    <p>Note that none of this affect me directly (currently).</p>
    <p>For the purposes of this discussion, let's assume a host with two
      IPv4 addresses, and two IPv6 addresses (globals, ignore link-local
      and scope-restricted for now):<br>
      <br>
      eth0:  192.168.0.1/24 and dead::beaf/64<br>
      eth1:  192.168.1.1/24 and foo::ba/64<br>
      <br>
      v4 routing has default pointing out on eth0 via 192.168.0.2, and a
      rule-based from 192.168.1.1 via 192.168.1.2.</p>
    <p>v6 has "high pref" route out via eth0 on LL%eth0, and "medium
      pref" out via eth1 on LL%eth1.  This may well require things like
      rp_filter to be switched off, so I'm going to assume you're
      networking is fine.<br>
    </p>
    <p>When calculating ICE candidates, it's generally for a specific
      socket, which can be bound to a specific address (IPv4, or IPv6,
      or ANY - as far as I understand).</p>
    <p>1.  In the case where the socket is NOT bound to any, does it
      make sense to include ANY OTHER addresses as ICE candidates? 
      Specifically, let's say socket is bound to 192.168.0.1:10000 -
      does it really make sense to advertise 192.168.1.1:10000 as ICE
      candidate?  Not to mention the v6 addresses?</p>
    <p>2.  In the case of STUN (srflx) requests being included, as I
      understand the raddr should be the address FROM where the STUN
      request was sent.</p>
    <p>3.  raddr should be one of the candidates presented.</p>
    <p>So currently the code has two ACLs, one for ICE addressess
      candidates.  I actually require this.  And one for the STUN
      *source* address, which is the address to which the rtp socket is
      bound (ANY in the case of PJSIP).</p>
    <p>So we will send STUN in the case that:</p>
    <p>1.  STUN is configured;<br>
      2.  The RTP bound socket is NOT blacklisted for STUN purposes;<br>
      3.  We haven't got PJ_ICE_MAX_CAND candidates yet (default value
      is 32, so unlikely).<br>
      4.  The socket is bound to IPv4 or then ANY ([::] or 0.0).</p>
    <p><b>First issue:  include non-bound addresses as candidates</b>:</p>
    <p>If socket is bound to 192.168.0.1:10000 then the kernel will drop
      all frames to 192.168.1.1:10000, unless there is a DNAT rule in
      place to forward these packets, or a SNAT rule created a matching
      CONNTRACK entry on egress of our first RTP frame.  If you're using
      these kind of stunts on an asterisk host I officially declare you
      braver than me.</p>
    <p>I'm arguing in a case where the RTP socket is NOT bound to ANY we
      should only advertise the bound address on ICE (v4 or v6).</p>
    <p>If the RTP socket is bound to v4 ANY (0.0.0.0) we should only
      advertise v4 addresses.  This is current behaviour.</p>
    <p>If the RTP socket is bound to v6 ANY ([::]) we should advertise
      all addresses.</p>
    <p><b>Second+Third issue:</b></p>
    <p>This gets really tricky.  Assuming the above four conditions (it
      should be noted we won't sent STUN for a v6 socket bound anywhere
      other than ANY ([::]), so we've already decided we need to send
      STUN.<br>
    </p>
    <p>My opinion, based on a potentially wrong understanding of the
      reading I've done:<br>
      <br>
      1.  If RTP is bound to ANY (v4 or v6), we should:<br>
      1.1 Force-include the v4 address from which ast_ouraddrfor as an
      ICE candidate (even if it's ICE blacklisted); and<br>
      1.2 Use same for base address (raddr).</p>
    <p>2.  If RTP is bound to a specific v4 address, we should:<br>
      2.1 Force-include the address as an ICE candidate (even if it's
      ICE blacklisted); and<br>
      2.2 Use same for base address (raddr).</p>
    <p>I need to check if it's possible to include the srflx (STUN)
      address before the "forced" address or not, but I can investigate
      that if need be.<br>
    </p>
    <p>Current behaviour is to iterate the list of selected candidate
      addresses and use the first IPv4 address found for base address
      (raddr).</p>
    <p>This unfortunately is a behavioural change.  One option would be
      to bind this to a configuration option.  Or two, one for the
      change in base address (raddr) selection, and one for forcing
      selected raddr as a candidate.  But then, what should the defaults
      be?<br>
    </p>
    <p>I would greatly appreciate any input on these thoughts as to what
      the correct thing to do is.</p>
    <p>Kind Regards,<br>
      Jaco<br>
    </p>
  </body>
</html>