<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:"Times New Roman \(Body CS\)";
panose-1:2 11 6 4 2 2 2 2 2 4;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0in;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:"Courier New";}
span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:"Consolas",serif;}
span.EmailStyle20
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Lorenzo, are you saying that one can do these things with libnice by doing some of the work externally (e.g. determine external address, determine interfaces) and then passing them to the right libnice methods? Does this entail calling
libnice methods that are normally considered internal and not intended for external use?<br>
<br>
<o:p></o:p></p>
<p class="MsoNormal">Stuart<br>
<br>
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:12.0pt;color:black">From: </span></b><span style="font-size:12.0pt;color:black">Lorenzo Miniero <lminiero@gmail.com><br>
<b>Date: </b>Tuesday, October 20, 2020 at 11:24 PM<br>
<b>To: </b>Stuart Marshall <stuart@seelye.net><br>
<b>Cc: </b>Olivier Crête <olivier.crete@collabora.com>, Fabrice Bellet <fabrice@bellet.info>, Juan Navarro <juan.navarro@gmx.es>, nice <nice@lists.freedesktop.org>, "I'm@gmail.com" <I'm@gmail.com><br>
<b>Subject: </b>Re: [libnice] Force an external address (srflx) candidate?<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Hi all,<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I'm not sure any change is needed in libnice, actually, as it can already take care of those scenarios quite nicely.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">If the main aim is avoiding using STUN on cloud services like AWS, where the instance runs with on a private address but it's also uniquely associated with a public one, then all you need to do is advertise the public address in the candidate
you trickle or put in the SDP. In fact, those cloud providers use what we call a 1-to-1 NAT mapping: the public port used in the NAT is always the same as the private one, and if the port is open in the firewall it will also automatically forward packets addresses
to a public port to the private one. This means that you don't need STUN to open a port and/or find it out: you just need to tell your peer about the public address, and everything will still work (connectivity checks will work just fine).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">In Janus we let people configure which public address to use in that case, with the option of keeping the private ones as advertised candidates: which means we either always replace the private IP with the public one, or duplication the
candidates we advertise where in one the private address is replaced and in another one it isn't (it's sometimes useful to have the private address advertised too). Some cloud providers expose the public IP of the instance as environment variables, which would
make it easier to configure. You can also use libnice to do a STUN request at startup, which we do but for other reasons. At any rate, this means that libnice as it is is perfectly capable of handling these weird use cases. Of course, if this 1-1 NAT behaviour
is not happening, and you can expect different ports being used privately and publicly then a STUN request will always be needed for each agent, or checks will just fail if you try to just replace the private address with the public one (exactly because of
the different public and private ports, and then being closed in the NAT until opened by a previous STUN request).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Only binding to some interfaces or skipping some (eg, programmatically disable ipv6) is also relatively easy, taking advantage of the libnice feature that allows you to manually choose which interfaces to use for gathering. You simply iterate
on available interfaces yourself, prune the ones you don't want, and pass the others to libnice, which will then stick to those. A bit of a manual (and, for interface iteration, system specific) process, but not complex at all and quite flexible: you can check
how we do it in Janus for an example.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Hope this helps with the discussion,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Lorenzo<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Wed, 21 Oct 2020, 06:06 Stuart Marshall, <<a href="mailto:stuart@seelye.net">stuart@seelye.net</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">That’s a good point: that the port can be remapped.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I’ve observed NAT routers commonly use the same external port as the internal host computer. Router manufacturers certainly should randomize the external port, but I wonder what
the actual numbers are. If libnice guessed that the router would use the same port, and if it remembered its external address, it might be work a good amount of the time. If libnice had some degree of memory, it could even keep track of whether it seems to
be behind a router that uses the same port externally as internally.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Another option would be to provide an API so that the host process could ask libnice to do the STUN request ahead of time. For example, as soon as a client app is launched it could
ask libnice to allocate a port and make a stun request, knowing that the user is probably going to make a call soon. This is rather app dependent, but in many cases the app could correctly anticipate that port allocation and a stun request will not be wasted.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I like the idea of using UPnP if that can streamline port discovery too.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">Olivier Crête <<a href="mailto:olivier.crete@collabora.com" target="_blank">olivier.crete@collabora.com</a>><br>
<b>Date: </b>Tuesday, October 20, 2020 at 12:29 PM<br>
<b>To: </b>Stuart Marshall <<a href="mailto:stuart@seelye.net" target="_blank">stuart@seelye.net</a>>, Fabrice Bellet <<a href="mailto:fabrice@bellet.info" target="_blank">fabrice@bellet.info</a>>, Juan Navarro <<a href="mailto:juan.navarro@gmx.es" target="_blank">juan.navarro@gmx.es</a>>,
<a href="mailto:nice@lists.freedesktop.org" target="_blank">nice@lists.freedesktop.org</a> <<a href="mailto:nice@lists.freedesktop.org" target="_blank">nice@lists.freedesktop.org</a>><br>
<b>Subject: </b>Re: [libnice] Force an external address (srflx) candidate?</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Hi,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The thing is that the external address might be the same. But on very new connection, the port will be different. And we have no way what kind of mapping from internal to external
port the router will chose. From what I understand, it is even recommended to router manufacturer that they randomize the external port to try to make it harder for attackers to guess the next port.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">So even if we remebered the external address, it wouldn't help so much.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">What can help, is to build libnice with UPnP support. This way, the external address can be retrieved over the LAN and this is very quick. We could also implement NAT-PMP, which
is what Apple routers use. But I don't know if this is common anymore.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Olivier<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">On Tue, 2020-10-20 at 17:42 +0000, Stuart Marshall wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #729FCF 1.5pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I like the idea of doing just one STUN request to avoid the many semi-duplicate candidates.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Another interesting thing to think about is that in most cases (99.9% ish) the STUN query is going to return the same result as last time. In most cases the host computer has not
moved networks and the external address has not changed.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">What if libnice could remember the previous external address and lead with that as a candidate. Libnice could still do one (or more) STUN queries to check if the external address
has changed. But starting with the previously known external address could speed up connection a lot.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The challenge is “how to remember the previous external address”. Libnice lives in somebody’s process and on some random host computer. Libnice might be completely shut down in-between
uses, even if the process keeps running.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">What if libnice remembered the previous external address somewhere in process space. If the process shuts down the knowledge is lost. But if the process keeps running (e.g. a server
or a long running browser) then the external address is remembered. Is there a cross-platform place to stash data? Environment variables might work. A persistent background thread might work.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The reason I suggest optimizations like this is customer experience. I see chrome to gstreamer establish connections in less than a second. Gstreamer to gstreamer often takes much
more time – easily five seconds plus.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Stuart<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">nice <<a href="mailto:nice-bounces@lists.freedesktop.org" target="_blank">nice-bounces@lists.freedesktop.org</a>><br>
<b>Date: </b>Monday, October 19, 2020 at 11:00 AM<br>
<b>To: </b>Stuart Marshall <<a href="mailto:stuart@seelye.net" target="_blank">stuart@seelye.net</a>><br>
<b>Cc: </b>Juan Navarro <<a href="mailto:juan.navarro@gmx.es" target="_blank">juan.navarro@gmx.es</a>>,
<a href="mailto:nice@lists.freedesktop.org" target="_blank">nice@lists.freedesktop.org</a> <<a href="mailto:nice@lists.freedesktop.org" target="_blank">nice@lists.freedesktop.org</a>><br>
<b>Subject: </b>Re: [libnice] Force an external address (srflx) candidate?</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Hi Stuart,<br>
<br>
On 10/14/20 at 09:22pm, Stuart Marshall wrote:<br>
> In contrast, the ICE candidates emitted by Chrome are stunningly few and precise. I understand that the ICE protocols and the libnice implementation were/are meant to be general case. But they miss obvious efficiencies that can be provided by additional external
information. STUN servers facilitate some of that additional information, but introduce a dependency and more latency.<br>
> <br>
> My knowledge of libnice internals is not great, but I kind of wish we could<br>
> <br>
> 1. Feed some particular IP candidate addresses to it,<br>
> 2. Tell it to skip a bunch of other candidate generation and testing<br>
<br>
I think of some optimisations, that could help to limit the number of<br>
candidates, without weakening the versatility of the ice method overall<br>
(except in *rare* cases where the server running libnice uses source<br>
routing, ie chooses the default route based on the source IP address):<br>
<br>
We could use a single server reflexive candidate and relay local<br>
candidate, per stream/component.<br>
<br>
Generally, there's no gain to send a stun request from each local<br>
interface, because all packets will reach the same stun server by the<br>
same default route. <br>
<br>
The consequence is that we obtain <N> distinct server-reflexive<br>
candidates from <N> distinct source IP addresses. These<br>
server-reflexives candidates are distinct because their IP address will<br>
be the same (this is our public IP address), but the port mapping will<br>
be different. The same applies to turn relay candidates too (including<br>
unnecessary resources reservations on the turn servers BTW).<br>
<br>
To avoid that, we could for example:<br>
1. discard these redundant candidates when we discover them (when<br>
processing the discovery stun response).<br>
2. or more radically, just send a single stun and turn discovery request.<br>
<br>
In case of 2. the choice of the local interface used as the base address<br>
to send this unique stun/turn discoevry request is normally not<br>
relevant, because the routing table will hopefully make these packets go<br>
out by the same default route again, whatever source interface they come<br>
from.<br>
<br>
To summarize, I think that sending a single stun request from a single<br>
network interface during gathering phase to obtain our server-reflexive<br>
address is normally a cheap operation (one RTT when the thr stun server<br>
is available), but what is expensive from libnice point of view is to<br>
deal with many identical reflexive/relay candidates during the<br>
connecting phase, because it creates many possibilities to be tested.<br>
And the more possibilities we have to test, the more time it takes to<br>
complete.<br>
<br>
Best wishes,<o:p></o:p></p>
<pre>_______________________________________________<o:p></o:p></pre>
<pre>nice mailing list<o:p></o:p></pre>
<pre><u><span style="color:blue"><a href="mailto:nice@lists.freedesktop.org" target="_blank">nice@lists.freedesktop.org</a></span></u><o:p></o:p></pre>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<pre> <o:p></o:p></pre>
<pre><u><span style="color:blue"><a href="https://lists.freedesktop.org/mailman/listinfo/nice" target="_blank">https://lists.freedesktop.org/mailman/listinfo/nice</a></span></u><o:p></o:p></pre>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<pre> <o:p></o:p></pre>
</div>
</blockquote>
<div>
<pre>-- <o:p></o:p></pre>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Olivier Crête<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><a href="mailto:olivier.crete@collabora.com" target="_blank">olivier.crete@collabora.com</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
</div>
</div>
</div>
<p class="MsoNormal">_______________________________________________<br>
nice mailing list<br>
<a href="mailto:nice@lists.freedesktop.org" target="_blank">nice@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/nice" target="_blank">https://lists.freedesktop.org/mailman/listinfo/nice</a><o:p></o:p></p>
</blockquote>
</div>
</div>
</div>
</body>
</html>