Subject: Re: [MMUSIC] WGLC: draft-ietf-mmusic-ice-15.txt

From: Colin Perkins <[email-masked]>
Date: Sun, 1 Apr 2007 14:00:03 +0100

[Not as chair]

On 29 Mar 2007, at 16:06, Jean-Francois Mule wrote:
> This is to announce a Working Group Last Call on ICE
> draft-ietf-mmusic-ice-15.txt.
>
> A URL for this Internet-Draft is:
> http://www.ietf.org/internet-drafts/draft-ietf-mmusic-ice-15.txt
>
> This WGLC will end on Friday April 20.
>
> Please mail all your final comments to the author and the mmusic  
> mailing
> list.

I notice that there are a number of IPR claims against ICE:

https://datatracker.ietf.org/public/ipr_detail_show.cgi?ipr_id=799  
(Cisco)
https://datatracker.ietf.org/public/ipr_detail_show.cgi?ipr_id=727  
(Tandberg)
https://datatracker.ietf.org/public/ipr_detail_show.cgi?ipr_id=728  
(Tandberg)
https://datatracker.ietf.org/public/ipr_detail_show.cgi?ipr_id=729  
(Tandberg)

The license terms offered for the Cisco IPR are reasonable, and not  
problematic.

The license terms offered by Tandberg are more of a concern. While  
the intent to grant a royalty free license is greatly appreciated,  
the requirement to negotiate the license, rather than explicitly  
granting a royalty free license to anyone to implement the standard,  
is a barrier for open-source implementers. I would hope Tandberg will  
revise these terms, before ICE is considered for publication.

-- 
Colin Perkins
http://csperkins.org/

_______________________________________________
mmusic mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/mmusic

---

From: "Geir Arne Sandbakken" <[email-masked]>
Date: Tue, 3 Apr 2007 11:05:39 +0200

Colin,

The part of the IPR concerning negotiation of a license is adopted from
the standard ITU patent policy statement.  We understand you concern,
and it is now under revision.

Cheers,
Geir Arne

> -----Original Message-----
> From: Colin Perkins [mailto:[email-masked]]
> Sent: 01 April 2007 15:00
> To: Jean-Francois Mule
> Cc: [email-masked]; Joerg Ott
> Subject: Re: [MMUSIC] WGLC: draft-ietf-mmusic-ice-15.txt
> 
> [Not as chair]
>

---

From: Jonathan Lennox <[email-masked]>
Date: Wed, 4 Apr 2007 17:54:33 -0400

Hi, all --

ICE-15 (section 8.2, bullet 3, sub-bullet 2) says that even after a media
stream enters the Completed state, an agent MUST still respond to any checks
it receives, and perform the corresponding triggered checks.

The question is, when can it *stop* doing this?  In particular, when is it
safe to stop listening on unselected ports, release unused TURN relays,
stop STUN keepalives, and the like?  Clearly it's not desirable to keep
using all these resources for the entire duration of a multimedia session.

For a controlling endpoint doing regular nomination, as soon as you send a
request containing USE-CANDIDATE, it's safe to close your other local
candidates.  However, for a controlled endpoint, or a controlling endpoint
doing aggressive nomination, this won't work.

One option might be to close unused ports after you receive the updated
offer or answer.  However, the updated offer/answer is only used if when the
default candidates weren't selected, so you can't necessarily always count
on that, unless we want to make an updated offer/answer mandatory for
aggressive nominators; and even then things are unclear for the controlled
endpoint.

Thoughts?

-- 
Jonathan Lennox
[email-masked]

---

From: Jonathan Lennox <[email-masked]>
Date: Wed, 4 Apr 2007 18:15:28 -0400

The ICE pair-priority formula (defined in section 5.7.2) takes as its
parameters the priority of the offerer's candidate and that of the
answerer's candidate.

However, in 3PCC scenarios, the two endpoints can disagree about which of
them is the offerer.  This was the reason for the introduction of the
ICE-CONTROLLING and ICE-CONTROLLED attributes in ICE-15.  In this case, the
two endpoints would calculate different pair priorities, and thus start
their periodic checks in a different order.

As I understand it, the order of the periodic checks is important to the
protocol, so that "suicide packets" hit firewalls at roughly the same time;
this is why the prioritization algorithm is normative.  As such, a
disagreement about which party is the offerer would cause a problem.

My suggestion would be to change the formula of 5.7.2.  Rather than having
its parameters be the offerer's priority and the answerer's priority, the
parameters would instead be the controlling endpoint's priority and the
controlled endpoint's priority.

Thus, if an endpoint switches its role after "losing" a role conflict,
following the procedures of 7.2.1.1, it needs to re-calculate its pair
priorities and re-sort its check lists.

This change to the formula won't cause a compatibility problems with ICE-14
or earlier, or with ICE-15 if there hasn't been a role conflict, because the
only case in which the offerer is not the controller is if the offerer is
using ICE-lite.  Since an ICE-lite endpoint can list only a single
candidate, the order of the check list will be the same either way, and
anyway doesn't matter since the lite endpoint isn't sending any checks.

Thoughts?

-- 
Jonathan Lennox
[email-masked]

---

From: Jonathan Rosenberg <[email-masked]>
Date: Thu, 05 Apr 2007 09:21:33 -0400

I think this is a good suggestion and I've made the change in my working 
-16.

Thanks,
Jonathan R.

-- 
Jonathan D. Rosenberg, Ph.D.                   600 Lanidex Plaza
Cisco Fellow                                   Parsippany, NJ 07054-2711
Cisco Systems
[email-masked]                              FAX:   (973) 952-5050
http://www.jdrosen.net                         PHONE: (973) 952-5000
http://www.cisco.com

---

From: Jonathan Rosenberg <[email-masked]>
Date: Thu, 05 Apr 2007 09:31:37 -0400

inline.

> doing aggressive nomination, this won't work.

Right. If the controlled endpoint knew that the controller was using 
regular nomination, it could also free things up upon completed. The 
main issue is the agressive mode.

> aggressive nominators; and even then things are unclear for the controlled

Well, much as a hate timers, its probably the only option here. With 
agressive nomination, if you wair one STUN transaction lifetime after 
you've entered completed, you can free up resources since there 
shouldn't be any further changes after that.

Signaling whether agreessive or regular nomination is in use doesn't 
really help, since you'll still need the timer for agressive mode. Other 
choice is to eliminate agressive mode and I don't want to do that.

-Jonathan R.

---

From: Benny Prijono <[email-masked]>
Date: Thu, 05 Apr 2007 15:17:58 +0100

> shouldn't be any further changes after that.

Can't we use the arrival of RTP packets for this purpose? We know 
that once we receive an RTP packet, each component in peer for this 
stream has a valid pair.

This wouldn't work perfectly when peer is using aggressive mode 
though, since some checks may still be running in peer even if it 
has begun sending RTP packets, so if we close the unused ports now 
those checks will fail. But on the other hand, by closing these 
unused ports now, it ensures that there will be no change in the 
selected candidate in peer.

  -benny

---

From: Jonathan Lennox <[email-masked]>
Date: Thu, 5 Apr 2007 23:04:25 -0400

How should an ICE endpoint handle receiving a 300 Try Alternate STUN error
response to a connectivity check request?

Should it actually send a connectivity check to the ALTERNATE-SERVER address
listed in the 300, and if so should it treat the alternate server as a new
remote peer-reflexive candidate?  Or should it just consider the
connectivity check to have failed, as with other error responses to the
check request?

Other than 300, I think the rest of the STUN error response codes defined by
3489bis (i.e., other than 487 Role Conflict) should indeed cause a
connectivity check to fail.  (The only other potential case in which
different behavior might be useful would be 500 Server Error, but I don't
think retrying a failing connectivity check is a good idea.)

-- 
Jonathan Lennox
[email-masked]

---

From: Jonathan Rosenberg <[email-masked]>
Date: Mon, 09 Apr 2007 09:17:24 -0400

Benny Prijono wrote:

> Can't we use the arrival of RTP packets for this purpose? We know that 
> once we receive an RTP packet, each component in peer for this stream 
> has a valid pair.

No, that doesn't work. With agressive mode, you are allowed to send 
media to what you THINK is the selected pair, but then a higher priority 
check completes and there is a new selected pair. So you then begin 
using that.

> 
> This wouldn't work perfectly when peer is using aggressive mode though, 
> since some checks may still be running in peer even if it has begun 
> sending RTP packets, so if we close the unused ports now those checks 
> will fail. But on the other hand, by closing these unused ports now, it 
> ensures that there will be no change in the selected candidate in peer.

The whole issue here is what to do with agressive mode. Closing ports 
early is likely to lead to ambiguity in the selected pairs, since checks 
might be completing just as the allocations are freed; there are 
definitely race conditions here.

I think its just easier to use a timer for this. We are talking about 
'clean-up' kind of operations, so I don't see the drawback. Setting this 
to a few seconds is a safe number.

-Jonathan R.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Mon, 09 Apr 2007 09:18:26 -0400

I don't think 300 is meaningful for the connectivity usage. Its easier 
to just disallow this case. I'll add a note that says a server MUST NOT 
send it.

-Jonathan R.

---

From: Benny Prijono <[email-masked]>
Date: Mon, 09 Apr 2007 20:12:14 +0100

> check completes and there is a new selected pair. So you then begin 

Sure, I understand that.

>> though, since some checks may still be running in peer even if it has 
>> begun sending RTP packets, so if we close the unused ports now those 
>> checks will fail. But on the other hand, by closing these unused ports 
>> now, it ensures that there will be no change in the selected candidate 
>> in peer.
> 

I can't see the race condition here. If a socket is closed, then 
that's it, you can't send response. Although, thinking about it 
again, that's not exactly true for relay candidate. Okay, I can see 
what you mean.

But yeah, there is another drawback for RTP approach, as it relies 
on peer sending RTP as soon as ICE completes, which may not be the 
case when VAD/DTX is used (or when media is sendonly).

> to a few seconds is a safe number.

Timer looks like the only solution indeed.

Although there is another problem.

Suppose agent A has one media stream, one component, and two 
candidates, relay and srflx. The relay candidate has lower priority 
than the srflx candidate.

Agent A is doing aggressive nomination, and sends check using srflx 
candidate to agent B. Agent B receives the check fine, sends 
response, and set the nominated pair. But for some strange reason, 
the response never gets to agent A (perhaps the NAT in agent A's 
premises messes up with the Binding response).

Next agent A sends the second check using the relayed candidate, and 
this time it gets the response fine.

So at this time, both agents have different nominated pair to use. 
Agent A uses the relay candidate, since it's the only one that's 
successful, while agent B uses the srflx candidate, since it has 
higher priority, and as far as it concerns, it has sent response 
successfully.

Is this possible at all?

thanks,
  -benny

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 10 Apr 2007 09:33:00 -0400

inline.

Benny Prijono wrote:

>> early is likely to lead to ambiguity in the selected pairs, since 
>> checks might be completing just as the allocations are freed; there 
>> are definitely race conditions here.
> 
> 
> I can't see the race condition here. If a socket is closed, then that's 
> it, you can't send response. Although, thinking about it again, that's 
> not exactly true for relay candidate. Okay, I can see what you mean.

Yes, relayed was exactly the case. If the relayed candidate is freed 
while the connectivity check is in flight between the relay and the 
client, this will fail.

> 
> But yeah, there is another drawback for RTP approach, as it relies on 
> peer sending RTP as soon as ICE completes, which may not be the case 
> when VAD/DTX is used (or when media is sendonly).

Right, another good point.

>> 'clean-up' kind of operations, so I don't see the drawback. Setting 
>> this to a few seconds is a safe number.
> 
> 

Yup. I will add that to ICE-16.

> Suppose agent A has one media stream, one component, and two candidates, 
> relay and srflx. The relay candidate has lower priority than the srflx 
> candidate.
> 
> candidate to agent B. Agent B receives the check fine, sends response, 
> and set the nominated pair. But for some strange reason, the response 
> never gets to agent A (perhaps the NAT in agent A's premises messes up 
> with the Binding response).

A relies on a reverse check to succeed before it sets the nominated 
flag. Read carefully section 7.2.1.5. It talks about the state of the 
pair generated as a result of the processing in 7.2.1.4 - that is the 
pair generated from the triggered check.

So if the response from B to A is never received due to firewall, a 
reverse check won't succeed either and so B will not set the nominated flag.

> So at this time, both agents have different nominated pair to use. Agent 
> A uses the relay candidate, since it's the only one that's successful, 
> while agent B uses the srflx candidate, since it has higher priority, 
> and as far as it concerns, it has sent response successfully.
> 
> Is this possible at all?

Inconsistent view on the selected pair is possible, but it is very 
unlikely. It would require a transaction to succeed in one direction, 
but to fail completely (timeout) in the reverse direction. This would 
not occur as a consequence of any firewalling or NATting, but rather, 
some really bad packet loss that persists for many seconds. This error 
would be detected from the a=remote-candidates in the re-invite (see 
section 9.2.2.3) and will cause an ICE restart for that media stream.

-Jonathan R.

---

From: Benny Prijono <[email-masked]>
Date: Tue, 10 Apr 2007 16:00:25 +0100

> Yup. I will add that to ICE-16.

Sounds good. Just to be sure, we don't need to make the procedure 
normative as not all implementations have this problem.

In my case, for example, I use one socket for one component (that's 
one socket and one STUN "session" for all candidates, including 
multiple host candidates, srflx, and potentially relay), and I 
recycle media transports between calls. So if for one particular 
call some of the resources are not used, I just keep them alive, 
because anyway they may still need to send keep-alives to their 
STUN/TURN server.

> pair generated from the triggered check.

I'm a bit confused here. Section 7.2.1.5 is about controlled agent 
(that is agent B). Agent A is in controlling role (implied by it 
doing aggressive nomination), so it doesn't have to wait for a 
reverse check before it sets the nominated flag.

But anyway, I was trying to describe the very unlikely scenario that 
you explained below, where STUN transactions only succeed in one 
direction. Glad to hear that this has been covered in Chapter 9 
(which I haven't implemented, so I haven't read it very closely :) 
). So you may close this "ticket" now. Sorry for the false alarm.

thanks,
  -benny

-- 
Benny Prijono
http://www.pjsip.org

---

From: "Guylain Lavoie" <[email-masked]>
Date: Tue, 10 Apr 2007 12:12:25 -0400

Hi Benny,

I am wondering how you plan on demultiplexing ICMP errors if a single
socket is shared for all candidate of a component?
How will you associate a received ICMP errors with a specific
Connectivity Checks or even a Binding Discovery Request used to keep
server reflexive candidate alive (keepalive)? Normally, at least, on BSD
like stack, you must connect the UDP socket to be able to reliably
receive ICMP errors.

For example, 

from rfc3489bis-06, 7.1, "A STUN transaction over UDP is also considered
failed if there has been a transport failure of some sort, such as a
fatal ICMP error."

from ICE-15, 7.1.2.1, "If the STUN transaction generates an ICMP error,
or..."

Not connecting the socket would not allow you to fully comply with the
specification (your implementation would end up waiting for the full
timeout when such thing happens).

Thanks,
Guylain

-----Original Message-----
From: Benny Prijono [mailto:[email-masked]] 
Sent: April 10, 2007 11:00 AM
To: Jonathan Rosenberg
Cc: Jonathan Lennox; [email-masked]
Subject: Re: [MMUSIC] ICE-15: when do you stop waiting foran aggressive
nomination?

In my case, for example, I use one socket for one component (that's one
socket and one STUN "session" for all candidates, including multiple
host candidates, srflx, and potentially relay), and I recycle media
transports between calls. So if for one particular call some of the
resources are not used, I just keep them alive, because anyway they may
still need to send keep-alives to their STUN/TURN server.

...

---

From: Benny Prijono <[email-masked]>
Date: Tue, 10 Apr 2007 18:25:19 +0100

Hi Guylain,

> like stack, you must connect the UDP socket to be able to reliably

Even if you use one socket for each candidate, I'm not sure if you 
can do UDP connect() on each of them, as ICE requires you to send 
connectivity checks to multiple destinations.

> timeout when such thing happens).

I view ICMP handling as "if you can and want to handle it, then do 
it, if not, then you know the risk" kind of thing, so I would 
disagree that we should call these implementations not fully comply 
just because they don't/can't handle ICMP.

cheers,
  -benny

---

From: "Guylain Lavoie" <[email-masked]>
Date: Tue, 10 Apr 2007 14:30:48 -0400

Hi Benny,

Optional support of ICMP reception is perfectly fine for me because it
is much more easier to implement.

However, if it is mandated, we would basically need to allocate one
socket for each candidate pair plus one for each server reflexive
candidate and relayed candidate. That's a lot of sockets, but that way
you can do a connect on all of them. This solution would work fine on
some operating systems, but on others, it would not because the socket
option SO_REUSEPORT is not available and it is needed so that all socket
may be bound to the same address and port. From what I read, this is not
available on Linux. This might be true for other operating systems as
well. You would also need an non connected socket to be able to support
reception of connectivity checks before the SDP answer arrives. This
would also be required to receive a connectivity check from a peer
reflexive candidate (which is unknown and thus cannot be connected to).

NOTE: The socket option SO_REUSEPORT and SO_REUSEADDR are needed for an
implementation of TCP with ICE because all TCP sockets are inherently
connected and must be bound to the same address and port. Like with UDP,
this would probably no work on all operating systems. This is mentioned
in some NAT hole punching technique papers.

Thanks
Guylain

-----Original Message-----
From: Benny Prijono [mailto:[email-masked]] 
Sent: April 10, 2007 1:25 PM
To: Guylain Lavoie
Cc: [email-masked]
Subject: Re: [MMUSIC] ICE-15: when do you stop waiting foran aggressive
nomination?

Hi Guylain,

Guylain Lavoie wrote:
> server reflexive candidate alive (keepalive)? Normally, at least, on 
> BSD like stack, you must connect the UDP socket to be able to reliably

> receive ICMP errors.

Even if you use one socket for each candidate, I'm not sure if you can
do UDP connect() on each of them, as ICE requires you to send
connectivity checks to multiple destinations.

> timeout when such thing happens).

I view ICMP handling as "if you can and want to handle it, then do it,
if not, then you know the risk" kind of thing, so I would disagree that
we should call these implementations not fully comply just because they
don't/can't handle ICMP.

cheers,
  -benny

---

From: Benny Prijono <[email-masked]>
Date: Tue, 10 Apr 2007 20:42:03 +0100

Hi Guylain,

I can't speak for ICE standards or best practices, having learned it 
only in the past few weeks, but I think creating one socket for each 
candidate *pair* is not the way ICE is supposed to be done, because 
that needs one heck a lot of sockets and it doesn't work on most 
platforms, as you said, especially if this is only needed just to 
get the benefit of ICMP.

So I don't think ICMP would need to be mandated at all by ICE, CMIIW.

I don't think this issue would matter for ICE TCP, since with ICE 
TCP the source address of the connection does not matter, so they 
don't need to be bound to the same address/port.

  -benny

-- 
Benny Prijono
http://www.pjsip.org

---

From: "Dan Wing" <[email-masked]>
Date: Tue, 10 Apr 2007 12:43:22 -0700

> From: Guylain Lavoie [mailto:[email-masked]] 
> Sent: Tuesday, April 10, 2007 11:31 AM
> To: Benny Prijono
> Cc: [email-masked]
> Subject: RE: [MMUSIC] ICE-15: when do you stop waitingforan 
> aggressive nomination?
> 
> Hi Benny,
> 
> However, if it is mandated,

ICMP can't be mandated by ICE.  ICMP is often filtered due to 
incompetence, overzealous administrators, or insufficient 
configuration granularity in firewalls and NATs.

-d

> we would basically need to allocate one

---

From: "Eric Cooper" <[email-masked]>
Date: Tue, 10 Apr 2007 16:05:28 -0400

Hi Geir Arne,

I am not a patent lawyer but I have been discussing Tandberg's ICE-related IPR statements with someone who is.  He has provided the following analysis:

"The Patent Holder is prepared to grant, on the basis of reciprocity in accordance with the above IETF specification, a license to an unrestricted number of applicants. Such licenses shall be on a worldwide, non-discriminatory basis and on reasonable terms and conditions permitting licensee to make, use and sell implementations of the above IETF specification."

This part refers to parties who do not have patent protection on something considered "essential" to practice the standard.  These people will have to pay a royalty to Tandberg for complying with the standard (to the extent a Tandberg patent is essential to compliance).

"The Patent Holder is prepared to grant a "free" license to any prospective licensee if such prospective licensee will commit to license its own essential patent(s) or essential patent claim(s) for implementation of any IETF specification for "free"."

This part says that to the extent a party that has something that is essential to ANY IETF specification, a "free" license can be obtained.  Then they give a definition of free which means only no money will be demanded - they can still demand a royalty free license to an entire product portfolio, restrict the field of use, etc. 

Can you comment on this analysis?  

If the above analysis is correct, I think these terms would hinder ICE's adoption.  Would Tandberg agree to terms similar to these:

http://www1.ietf.org/ietf/IPR/cisco-ipr-draft-ietf-mpls-interas-lspping-00.txt ?

Best Regards,

Eric.

----- Original Message ----- 
From: "Geir Arne Sandbakken" <[email-masked]>
To: "Colin Perkins" <[email-masked]>; "Jean-Francois Mule" <[email-masked]>
Cc: <[email-masked]>; "Joerg Ott" <[email-masked]>
Sent: Tuesday, April 03, 2007 5:05 AM
Subject: RE: [MMUSIC] WGLC: draft-ietf-mmusic-ice-15.txt

Colin,

Cheers,
Geir Arne

---

From: "Guylain Lavoie" <[email-masked]>
Date: Tue, 10 Apr 2007 16:22:26 -0400

Hello Benny,

If someone else does not comment on this ICMP issue, I will assume from
now on that multiple sockets (for a component) are not required since
recevied ICMP can just be discarded.

Concerning the TCP extension of the specification, IMHO, the source
address of the connection DOES matter. At least, for Passive and
Simultaneous Open TCP candidate. This is because the agent must allocate
both an host candidate and its associated server reflexive candidate.
Both candidates must share the same source address and port. So,
effectively, we must be able to bind at least two sockets at the same
location. And as stated before, this does not seems to be possible on
all platforms.

Can you explain why you say that the same source address is not
important?

Regards,
Guylain

-----Original Message-----
From: Benny Prijono [mailto:[email-masked]] 
Sent: April 10, 2007 3:42 PM
To: Guylain Lavoie
Cc: [email-masked]
Subject: Re: [MMUSIC] ICE-15: when do you stop waiting foran aggressive
nomination?

Hi Guylain,

I can't speak for ICE standards or best practices, having learned it
only in the past few weeks, but I think creating one socket for each
candidate *pair* is not the way ICE is supposed to be done, because that
needs one heck a lot of sockets and it doesn't work on most platforms,
as you said, especially if this is only needed just to get the benefit
of ICMP.

I don't think this issue would matter for ICE TCP, since with ICE TCP
the source address of the connection does not matter, so they don't need
to be bound to the same address/port.

  -benny

> option SO_REUSEPORT is not available and it is needed so that all 
> socket may be bound to the same address and port. From what I read, 
> this is not available on Linux. This might be true for other operating

> systems as well. You would also need an non connected socket to be 
> able to support reception of connectivity checks before the SDP answer

> arrives. This would also be required to receive a connectivity check 
> from a peer reflexive candidate (which is unknown and thus cannot be
connected to).
> 
> NOTE: The socket option SO_REUSEPORT and SO_REUSEADDR are needed for 
> an implementation of TCP with ICE because all TCP sockets are 
> inherently connected and must be bound to the same address and port. 
> Like with UDP, this would probably no work on all operating systems. 
> This is mentioned in some NAT hole punching technique papers.
> 
> Thanks
> Guylain
> 
> Subject: Re: [MMUSIC] ICE-15: when do you stop waiting foran 
> aggressive nomination?
> 
> Hi Guylain,
> 
> Guylain Lavoie wrote:
>> Hi Benny,
>>

> if not, then you know the risk" kind of thing, so I would disagree 
> that we should call these implementations not fully comply just 
> because they don't/can't handle ICMP.
> 
> cheers,
>   -benny

--
Benny Prijono
http://www.pjsip.org

---

From: "Geir Arne Sandbakken" <[email-masked]>
Date: Wed, 11 Apr 2007 14:53:28 +0200

Eric,

Not being a lawyer myself I can not verify the analysis, but I will
forward this mail to someone who can.  It is still under revision as
more comments have been presented on the latest version of the IPR.

Geir Arne

> From: Eric Cooper [mailto:[email-masked]]
> Sent: 10 April 2007 22:05
> To: Geir Arne Sandbakken
> Cc: [email-masked]; Joerg Ott; Jean-Francois Mule; Colin Perkins
> I am not a patent lawyer but I have been discussing Tandberg's
ICE-related
> IPR statements with someone who is.  He has provided the following
> analysis:
> 
> "The Patent Holder is prepared to grant, on the basis of reciprocity
in
> accordance with the above IETF specification, a license to an
unrestricted
> number of applicants. Such licenses shall be on a worldwide, non-
> discriminatory basis and on reasonable terms and conditions permitting
> licensee to make, use and sell implementations of the above IETF
> specification."
> 
> This part refers to parties who do not have patent protection on
something
> considered "essential" to practice the standard.  These people will
have
> to pay a royalty to Tandberg for complying with the standard (to the
> extent a Tandberg patent is essential to compliance).
> 
> "The Patent Holder is prepared to grant a "free" license to any
> prospective licensee if such prospective licensee will commit to
license
> its own essential patent(s) or essential patent claim(s) for
> implementation of any IETF specification for "free"."
> 
> This part says that to the extent a party that has something that is
> essential to ANY IETF specification, a "free" license can be obtained.
> Then they give a definition of free which means only no money will be
> demanded - they can still demand a royalty free license to an entire
> product portfolio, restrict the field of use, etc.
> 
> If the above analysis is correct, I think these terms would hinder
ICE's
> adoption.  Would Tandberg agree to terms similar to these:
> 
>
http://www1.ietf.org/ietf/IPR/cisco-ipr-draft-ietf-mpls-interas-lspping-
> 00.txt ?

---

From: Philip Matthews <[email-masked]>
Date: Wed, 11 Apr 2007 13:48:40 -0400

If I understand this comment correctly, then the only question is  
which end is
the offerer and which end is the answerer.

Given that the formula is:
       pair priority = 2^32*MIN(O,A) + 2*MAX(O,A) + (O>A?1:0)
the value of the priority differs by at most one if the roles of the  
offerer and answerer
are reversed.

So how important is this really?

- Philip

On 5-Apr-07, at 09:21 , Jonathan Rosenberg wrote:

> I think this is a good suggestion and I've made the change in my  
> working -16.
>
> Thanks,
> Jonathan R.
>
>
> Jonathan Lennox wrote:
>

---

From: "Alfred E. Heggestad" <[email-masked]>
Date: Thu, 12 Apr 2007 01:32:36 +0200

> location. And as stated before, this does not seems to be possible on

Guylain, can you explain why you need 2 sockets for host+srflx candidate?

my understanding is that first you open one socket for a particular
network interface, which is used as a host candidate, and then send
a STUN Binding Request from the *same* socket to obtain a server
reflexive candidate, with the corresponding host socket as base..
i.e. you would only need 1 socket.

/alfred

<snip>

---

From: Rémi Denis-Courmont <[email-masked]>
Date: Thu, 12 Apr 2007 10:06:23 +0300

> like stack, you must connect the UDP socket to be able to reliably

This is a common issue with UDP applications. FYI, if you really want to 
handle ICMP errors on an unconnected UDP socket, you can usually dequeue 
error messages separately through recvmsg(). Most people simply ignore the 
errors, which should be OK for ICE, since it has fairly low packets sending 
rate until a pair is confirmed. Another possibility consists of creating as 
many connected UDP sockets as you may need, possibly bound to the same port 
(with SO_REUSEADDR, SO_REUSEPORT or whatever, most BSD stacks allow this 
somehow).
 
> timeout when such thing happens).

Good point.

-- 
Rémi Denis-Courmont

---

From: "Guylain Lavoie" <[email-masked]>
Date: Thu, 12 Apr 2007 10:47:17 -0400

Alfred,

In don't really understand what you mean. How can you send Binding
Request to a STUN server without ever connecting the socket? Remember,
it is TCP that we are talking about, not UDP.

For a passive candidate, you really need to allocate at least two TCP
sockets and bind them at the same address and port. One will be a TCP
server socket and will be used to receive TCP connection requests
associated with peer initialited connectivity checks from its Active
candidates (Reception of a connection request will effectively create a
entirely new socket, also bound at the same address and port). The other
will be a TCP client socket connected to the STUN server to gather a
server reflexive candidate and periodically, it will also send Binding
Request to keep alive the NAT binding.

For SO, it is a bit different. You need to allocate at least two TCP
client sockets and also bind them at the same address and port. One will
be connected to the STUN server to gather a server reflexive candidate
and periodically send Binding Request to keep alive the NAT binding. The
other, or others, are used to send connectivity checks to the peer SO
candidates. Each one of them must be connected to peer SO candidate
before sending its connecitivity checks.

The situation becomes even more complex if you think that you may have
more than one STUN server. Note however, that the specification does not
encourage this.

Regards,
Guylain

-----Original Message-----
From: Alfred E. Heggestad [mailto:[email-masked]] 
Sent: April 11, 2007 7:33 PM
To: Guylain Lavoie
Cc: Benny Prijono; [email-masked]
Subject: Re: [MMUSIC] ICE-15: when do you stop waiting foran aggressive
nomination?

Guylain Lavoie wrote:
> Simultaneous Open TCP candidate. This is because the agent must 
> allocate both an host candidate and its associated server reflexive
candidate.
> location. And as stated before, this does not seems to be possible on 

Guylain, can you explain why you need 2 sockets for host+srflx
candidate?

my understanding is that first you open one socket for a particular
network interface, which is used as a host candidate, and then send a
STUN Binding Request from the *same* socket to obtain a server reflexive
candidate, with the corresponding host socket as base..
i.e. you would only need 1 socket.

/alfred

<snip>

---

From: "Guylain Lavoie" <[email-masked]>
Date: Thu, 12 Apr 2007 11:11:17 -0400

Hi Dan,

Although ICMP may be lost in transit for multiple reasons like the one
you stated I would really like to know, from an ICE implementer
perspective, what exactly are we required to implement. Must an
implementation be able to receive these ICMP errors and correctly
associate them, without ambiguity, to the correct STUN usage which
triggered them in the first place? Or, is an implementation allowed to
ignore them with the consequence of having to wait until the full
timeout. Having the correctly manage ICMP adds a lot of complexity to
the implementation. Do we have to resort to this added complexity (lot
of connected UDP sockets) or can we just ignore ICMP and use only a non
connected UDP socket for all operations.

Benny has indicated that he would ignore ICMP reception. Should we all
do that?

Thanks,
Guylain 

-----Original Message-----
From: Dan Wing [mailto:[email-masked]] 
Sent: April 10, 2007 3:43 PM
To: Guylain Lavoie; 'Benny Prijono'
Cc: [email-masked]
Subject: RE: [MMUSIC] ICE-15: when do you stop waitingforan aggressive
nomination?

> Subject: RE: [MMUSIC] ICE-15: when do you stop waitingforan aggressive

ICMP can't be mandated by ICE.  ICMP is often filtered due to
incompetence, overzealous administrators, or insufficient configuration
granularity in firewalls and NATs.

-d

> we would basically need to allocate one socket for each candidate pair

> plus one for each server reflexive candidate and relayed candidate. 
> That's a lot of sockets, but that way you can do a connect on all of 
> them. This solution would work fine on some operating systems, but on 
> others, it would not because the socket option SO_REUSEPORT is not 
> available and it is needed so that all socket may be bound to the same

> address and port. From what I read, this is not available on Linux. 
> This might be true for other operating systems as well. You would also

> need an non connected socket to be able to support reception of 
> connectivity checks before the SDP answer arrives. This would also be 
> required to receive a connectivity check from a peer reflexive 
> candidate (which is unknown and thus cannot be connected to).
> 
> Like with UDP,
> this would probably no work on all operating systems. This is 
> mentioned in some NAT hole punching technique papers.
> 
> Thanks
> Guylain
>

---

From: "Dan Wing" <[email-masked]>
Date: Thu, 12 Apr 2007 10:04:27 -0700

You can ignore them -- it just means you'll hit the timeouts.  It
can't be a MUST requirement in -16, and I recall Jonathan said it
would be a MAY?

-d

> Sent: Thursday, April 12, 2007 8:11 AM
> To: Dan Wing; Benny Prijono
> Cc: [email-masked]
> aggressive

---

From: Magnus Westerlund <[email-masked]>
Date: Fri, 13 Apr 2007 14:14:11 +0200

Hi,

I have reviewed the draft and have some comments. I will start with all 
the real issues. Then I a also have some nits. But let me say that I am 
impressed how good this document has become.

Issues:

I1. Section 7.2.1.1: Why isn't this section applicable for lite 
implementation. If there exist possibilities that the two peer in case 
of full implementations are confused about their roles, why can't a full 
peer be similar confused and think it is talking to a controlling full 
when it in reality talks to a lite. I have a hard time determining if 
that can happen at all or not when you think two full peers can be 
confused about their roles. It seems a simple fix to tell a lite server 
to always do tiebreaking as the loosing side.

I2. Section 7.2.1.1, first bullet:
   "o  If neither ICE-CONTROLLING or ICE-CONTROLLED are present in the
       request, there is no conflict."

When does this happen? To my understanding all ICE peers sending 
connectivity checks will indicate if they are controlling or controlled.

I3. Section 7.2.1.4:

       *  If the state of that pair is Waiting or Frozen, its state is
          changed to In-Progress and a check for that pair is performed
          immediately.  This is called a triggered check.

I am a bit concerned with the immediately part here. I do understand 
that the check should happen as soon as possible. However by stepping 
away from the pacing in these replies you further increases the 
burstiness of the connectivity checks. To be slightly more conservative. 
Why not simply bump the triggered checks to the top of the queue. The 
alternative I see if you like to keep the quick response (and potential 
bunching together of response and the triggered check request) is to 
delay the next scheduled check an extra Ta interval. That way the 
triggered check does not increase the consumed bit-rate.

I4. Section 10.
"Examples of formats which readily meet this
    goal are RTP No-Op [31] and RTP comfort noise [25]."

I would argue that RTP comfort noise does not readily meet it. It works 
in some cases, like for an audio stream where the peers both support it. 
Two solutions, a) remove comfort noise as an example. b) clarify the 
main limitations.

I5. Section 15.1:

There are a number of cases where one uses 1* in the ABNF. Can these 
please be changed to a upper limit on the number of characters. With the 
current definition I could use a 5000 digit long priority number from 
parsing perspective. This is likely to lead to overflow. In the case of 
priority as this is limited to 2^32-1 as largest number then using 
1*10DIGIT seems to be without risk. I guess that also component-ID and 
foundation can be limited to a reasonable upper limit. Making it easier 
to separate the cases of potentially valid numbers and plain errors. 
This comment also applies to section 15.4 and the password and ufrag 
definitions.

I6. Pacing of connectivity checks. I need to think a bit more about this 
and how ICE relates to the UDP usage guidelines 
(http://www.ietf.org/internet-drafts/draft-eggert-tsvwg-udp-guidelines-02.txt) 
we are working on getting accepted in the transport area. Ice with the 
current parameters are rather aggressive in its bandwidth usage in worst 
case. I understand in most cases it would not consume close to as much.

The biggest problem with this bloody protocol is its purpose resulting 
in that basically all STUN request packets could be dropped by NAT 
filtering rather than congestion. Or it could be the other way around. 
We have no way of knowing. This also causes the connectivity checks 
themselves some problem. As all checks easily can congest themselves 
thus causing worse performance then the correct rate limited sending 
would have. I think we need to at least consider putting some further 
limitation or adaptation of the pacing timers in some cases. At least 
when you have knowledge about link speeds.

I know we have had quite some discussion on this topic earlier and the 
algorithm has clearly been made to try as few checks as possible thanks 
to the freezing of some checklist etc. But in my current role I need to 
take this even more serious than before.

NITS:

N1. Section 2.6, third paragraph: Last sentence starts with what appears 
with an stray "A".

N2. Figure 4 and 5. Lack of directional arrows for the requests from L.

N3. section 5.7.1, page 30, first paragraph:
"As another example, the
    offerer can multiplex RTP and RTCP on the same port and signals it
    can do that in the SDP through some new attribute."

I think an informative reference to the RTP and RTCP MUXing draft 
(draft-ietf-avt-rtp-and-rtcp-mux-04) is needed in this sentence to make 
it clear what is being talked about.

N4. Section 5.7.2, second paragraph: "Where O-P>A-P?1:0 is an expression 
whose value is 1 if O-P is greater than A-P, and 0 otherwise." As the 
(O-P) part isn't used in the above formula, maybe using the actual 
(O>A?1:0) is better in this context.

N5. Section 7.1: Isn't "STUN Client Procedures" a better section title 
than "Client Procedures"? Similar for 7.2.

N6. Section 8.1.1:
"This check will succeed (since the previous did), causing
    the nominated flag of that and only that pair to be set."

I think this sentence is more correct if you change "will" to "should" 
or "is expected to". There are no guarantees that something else causes 
a failure of the path.

N7. Section 12.1.1:
   "With this optimization, provisional responses containing an SDP
    answer that begins ICE processing for one or more media streams can
    be sent reliably without RFC 3264."

Isn't the reference to RFC 3264 wrong? Shouldn't it be to RFC 3262?

N8. Section 16. The line breaks in the SDP example are bad and looks 
strange.

N9. The following references needs update:

   == Outdated reference: A later version (-03) exists of
      draft-ietf-behave-turn-02

   == Outdated reference: A later version (-01) exists of
      draft-ietf-sip-ice-option-tag-00

   == Outdated reference: A later version (-01) exists of
      draft-ietf-avt-rtp-no-op-00

   == Outdated reference: A later version (-08) exists of
      draft-ietf-sip-outbound-07

N10. Section B.2
Use of 192.168.1.1 and 10.0.1.1 as end-host addresses. As these 
addresses usually will be assigned the gateway/NAT in respective network 
isn't using them for end-host a bad choice.

N11. Section B.8:
"That section
    requires that the type preference for peer reflexive candidates
    always be lower than server reflexive. "

I think "lower" is supposed to be "higher".

Cheers

Magnus Westerlund

IETF Transport Area Director & TSVWG Chair
----------------------------------------------------------------------
Multimedia Technologies, Ericsson Research EAB/TVM/M
----------------------------------------------------------------------
Ericsson AB                | Phone +46 8 4048287
Torshamsgatan 23           | Fax   +46 8 7575550
S-164 80 Stockholm, Sweden | mailto: [email-masked]
----------------------------------------------------------------------

---

From: "Dan Wing" <[email-masked]>
Date: Fri, 13 Apr 2007 16:29:27 -0700

> From: Magnus Westerlund [mailto:[email-masked]] 
> Sent: Friday, April 13, 2007 5:14 AM
> To: Jonathan Rosenberg
> Cc: [email-masked]; Lars Eggert
...
> I would argue that RTP comfort noise does not readily meet 
> it. It works in some cases, like for an audio stream where 
> the peers both support it.  Two solutions, a) remove comfort 
> noise as an example. b) clarify the main limitations.

Describing other, non-STUN techniques for performing keepalives seems out of
scope for ICE.  It is interesting information.

There is another technique, too (RTP/RTCP muxing), which Colin pointed out:

http://www1.ietf.org/mail-archive/web/avt/current/msg08248.html

I suggested in a followup to Colin's post that perhaps
draft-marjou-behave-app-rtp-keepalive-01.txt should become an AVT working
group document.  This might well be the best way to discuss all of the
various keepalive techniques in one place and compare/contrast the benefits
and drawbacks of each technique.

-d

---

From: "Dan Wing" <[email-masked]>
Date: Fri, 13 Apr 2007 16:41:34 -0700

...
> I6. Pacing of connectivity checks.  I need to think a bit more about
> this and how ICE relates to the UDP usage guidelines
> (http://www.ietf.org/internet-drafts/draft-eggert-tsvwg-udp-gu
> idelines-02.txt)  we are working on getting accepted in the
> transport area.  Ice with the current parameters are rather
> aggressive in its bandwidth usage in worst case.  I understand
> in most cases it would not consume close to as much.
>
> The biggest problem with this bloody protocol is its purpose
> resulting in that basically all STUN request packets could be
> dropped by NAT filtering rather than congestion.  Or it could be the
> other way around.  We have no way of knowing.  This also causes the
> connectivity checks themselves some problem.  As all checks easily
> can congest themselves thus causing worse performance then the
> correct rate limited sending would have.  I think we need to at
> least consider putting some further limitation or adaptation of the
> pacing timers in some cases.  At least when you have knowledge about
> link speeds.
>
> I know we have had quite some discussion on this topic earlier and
> the algorithm has clearly been made to try as few checks as possible
> thanks to the freezing of some checklist etc. But in my current role
> I need to take this even more serious than before.

Right now, the "Ta" timer in ICE is suggested to be 20ms.  Would it
be reasonable to make "Ta" be the greater of 20ms or the "ptime" for
the associated media line?  That is, if the ptime is 50ms, then 
ICE's "Ta" would also be 50ms.  In this way, ICE is no worse than 
the RTP flow itself.

Using the link speed, if you know it, could be helpful, too, but
you seldom know it.  For example I have a DSL uplink at home but 
my local network is all 100mb Ethernet.

-d

---

From: Magnus Westerlund <[email-masked]>
Date: Mon, 16 Apr 2007 10:21:48 +0200

> ICE's "Ta" would also be 50ms.  In this way, ICE is no worse than

Actually ICE is much worse. Because you have no way of determining if 
the lost connectivity checks are being filtered by a NAT or are 
congestion losses. When running RTP you know that losses are most likely 
to be congestion losses. And you have RTCP to tell you as a sender that 
something is happening. At least on a medium time scale. That way an RTP 
+ RTCP implementation can at least avoid persistent congestion.

Maybe what I am looking for is better guidance on how to tune the 
parameters when you know something. And in addition maybe some more 
conservative default values.

But what is needed is discussion on this.

> my local network is all 100mb Ethernet.

Yes, that is the big problem.

-- 

Magnus Westerlund

---

From: "Dan Wing" <[email-masked]>
Date: Mon, 16 Apr 2007 08:55:08 -0700

> congestion losses. When running RTP you know that losses are 
> most likely to be congestion losses.

I don't understand.

With RTP, you're going to transmit a packet every 10ms (or 20ms) into
the network, with no built-in backoff (no initial RTT estimate, and no
requirement that RTCP indicates successful packet reception until the
first RTCP receiver report is sent, which is approximately every 5
seconds).  In the meantime, the sender is sending a packet every 10ms
(or 20ms or so) into the network.

ICE is going to transmit a packet every 20ms (per its current 
recommendation in ice-16), wait for a response, and has built-in 
exponential backoff for its retransmits.  

This is more gentle to the network than the RTP flow that needs
to start soon.  In fact, if the network is dropping so many 
packets that a connectivity check can't complete (even with its
retransmits), the RTP flow won't be started; without ICE, the 
new RTP flow would start and further contribute to network 
congestion.

> And you have RTCP to tell you as a sender that something is 
> happening. At least on a medium time scale. That 
> way an RTP + RTCP implementation can at least avoid 
> persistent congestion.

As can ICE, with ICE's exponential backoff of the STUN 
transaction retransmission timers.

> But what is needed is discussion on this.

Ok.  What is the best venue for such discussion?  Would the TSVWG
or perhaps the e2e-interest mailing list be better?  I expect 
MMUSIC isn't usually read by folks interested in network 
congestion.

-d

---

From: "Henry Sinnreich" <[email-masked]>
Date: Mon, 16 Apr 2007 09:06:54 -0700

Magnus Westerlund writes:

> Actually ICE is much worse.
---snip---
>That way an RTP + RTCP implementation can at least avoid persistent
>congestion.

I don't understand this. The only way to avoid persistent congestion is
to change to another ISP that is not oversubscribed. 

Since when can an application level protocol avoid oversubscription :-)

Thanks, Henry

-----Original Message-----
From: Magnus Westerlund [mailto:[email-masked]] 
Sent: Monday, April 16, 2007 1:22 AM
To: Dan Wing
Cc: Lars Eggert; [email-masked]
Subject: Re: ICE pacing connectivity checks (was RE: [MMUSIC]
WGLC:draft-ietf-mmusic-ice-15.txt)

-- 

Magnus Westerlund

---

From: Magnus Westerlund <[email-masked]>
Date: Tue, 17 Apr 2007 17:05:53 +0200

> (or 20ms or so) into the network.

Yes, if you are the common congestion problem ignoring implementation 
then there are no difference. However for RTP you can do a number of 
things to make it much more responsive. First you can reconfigure your 
RTCP reporting using AVPF to be sending at least every 0.5 second or 
even faster depending on your general bit-rate. But the main point is 
that you do have a feedback mechanism. Which you really should take into 
account.

> exponential backoff for its retransmits.  

Yes, but the problem is that it is starting new transmissions every Ta 
seconds. And you have no idea when the sum of these transmissions on any 
of your local interfaces are reaching the capacity of that path. It is 
far from obvious that your paths can handle the 180 kbps max rate the 
draft talks about. What if your outgoing link is 30 kbps.

> new RTP flow would start and further contribute to network 

If that RTP flow is at least having some adaptation which it really 
should have then it will react to the congestion. More for the sake of 
the application then anything else. And I do not consider ICE being 
gentle. It is still spewing out packets in the worst case after 2 seconds.

> MMUSIC isn't usually read by folks interested in network 

I think TSV-Area is a good list to discuss this.

Cheers

Magnus Westerlund

---

From: Magnus Westerlund <[email-masked]>
Date: Tue, 17 Apr 2007 17:07:36 +0200

Roy, Radhika R. skrev:
> 
> Probably, Magnus is saying about the time-scale that RTP + RTCP provides 
> to measure the persistent congestion in the network.

Exactly, if you are seeing congestion that continue to be present during 
a few seconds you better react to it if you are a sending application. 
We do prefer that transmitters are reacting within an RTT. But reacting 
on time scale of seconds are still better than not reacting at all.

Cheers

Magnus Westerlund

---

From: "Roy, Radhika R." <[email-masked]>
Date: Mon, 16 Apr 2007 13:23:04 -0400

Probably, Magnus is saying about the time-scale that RTP + RTCP provides to measure the persistent congestion in the network.
 
Best regards,
Radhika
 
PS: Of course, people have to change ISP, but it take some time to decide it is due to oversubscriptions of the ISP.

________________________________

From: [email-masked] on behalf of Henry Sinnreich
Sent: Mon 4/16/2007 12:06 PM
To: Magnus Westerlund; Dan Wing
Cc: [email-masked]; Lars Eggert
Subject: RE: ICE pacing connectivity checks (was RE: [MMUSIC]WGLC:draft-ietf-mmusic-ice-15.txt)

---snip---

Thanks, Henry

---

From: Alan Johnston <[email-masked]>
Date: Wed, 18 Apr 2007 12:59:57 -0500

Do we have any running code and actual deployment experience here?

If not, I'd suggest adding further congestion avoidance in ICE would 
likely only have the effect of increasing the time taken to complete 
connectivity checks.  This could be a significant problem for ICE in the 
real world.

Thanks,
Alan

Magnus Westerlund wrote:
>>> Actually ICE is much worse. Because you have no way of determining 
>>> if the lost connectivity checks are being filtered by a NAT or are 
>>> congestion losses. When running RTP you know that losses are most 
>>> likely to be congestion losses.
>>
>> I don't understand.
>>
> that you do have a feedback mechanism. Which you really should take 
> into account.
>
>>
> seconds. And you have no idea when the sum of these transmissions on 
> any of your local interfaces are reaching the capacity of that path. 
> It is far from obvious that your paths can handle the 180 kbps max 
> rate the draft talks about. What if your outgoing link is 30 kbps.
>
>>
>> to start soon.  In fact, if the network is dropping so many packets 
>> that a connectivity check can't complete (even with its
>> retransmits), the RTP flow won't be started; without ICE, the new RTP 
>> flow would start and further contribute to network congestion.
>
>>> happening. At least on a medium time scale. That way an RTP + RTCP 
>>> implementation can at least avoid persistent congestion.
>>
>> As can ICE, with ICE's exponential backoff of the STUN transaction 
>> retransmission timers.
>>
>> or perhaps the e2e-interest mailing list be better?  I expect MMUSIC 
>> isn't usually read by folks interested in network congestion.
>

---

From: "Francois Audet" <[email-masked]>
Date: Wed, 18 Apr 2007 17:03:25 -0500

My comments for WGLC are included below:

In order to be able to use ICE as the mechanism for supporting a
dual-stack
IPv4/IPv6 implementation, some minor changes need to be made to ICE-15.
Specifically, 
for the case where BOTH sides are using ICE-lite.

The procedures when one or both sides are NOT using ICE-lite are OK as
is in ICE-15.

Using section 5 of ICE-15 as a basis.

A sends offer to B. A uses ICE-lite, but it is dual stack, so the offer
looks like 
this:

Offer:

	m=IPv4              <- Assumption is that IPv4 is morelikely to
succeed than IPv6
	candidate 1=IPv6
	candidate 2=IPv4
	a=ice-lite

B receives the offer, it is also using ice-lite and is also dual stack.

It sends an answer:

	m=IPv4
	candidate 1=IPv6
	candidate 2=IPv4
	a=ice-lite

According to section 5 today it would result in having "NO CONNECTIVITY
CHECK".

The current wording says "ICE cannot proceed", which I think is
innacurate since the 
candidates have already been sent, so ICE has already proceeded to a
certain point. I think it 
needs to be clarified is that it "ICE does not proceed with the
connectivity check".

According to section 5 again, it would result in having the IPv4
selected instead of the 
IPv6 (i.e., the m line).

That's NOT the behavior we want. What we want is in this case to have
both sides use the candidates 
and the RFC 3484 procedures. I would like to see some guidance around
using RFC 3484 procedures.

One easy way for B to ensure that it's choice is selected, is to respond
with this answer
instead:

	m=IPv6                <- i.e., forcing the other side to use the
IPv6 address
	candidate 1=IPv6      <- I'm not sure we actually need this
line?
	a=ice-lite            <- This is to tell A that it understood
ICE

It might also be useful in this case, for the second offer answer
(normal in ICE) to
proceed to "lock" on the IPv6 address and help middleboxes. Therefore,
the second offer
answer would look like:

Offer:
	m=IPv6              

Answer: 
	m=IPV6

I believe that if we do this, we will have addressed the requirements
for dual-stack.

> From: Jean-Francois Mule [mailto:[email-masked]] 
> Sent: Thursday, March 29, 2007 08:07
> To: [email-masked]
> Cc: Colin Perkins; Joerg Ott
> Subject: [MMUSIC] WGLC: draft-ietf-mmusic-ice-15.txt
> 
> 
> Please mail all your final comments to the author and the 
> mmusic mailing list.
> 
> Jean-Francois -- As WG co-chair
> [email-masked] 
> 
> 
>

---

From: "Kevin Johns" <[email-masked]>
Date: Wed, 18 Apr 2007 23:04:08 -0600

Francois email prompted me to pay special attention to section 4.2 while
doing a detailed read of ice-15 as I was under the impression that
ICE-lite only allowed for a single candidate. Reading section 4.2 a few
times seems to provide mixed direction. The section starts off
indicating that "for each media stream, the agent allocates a single
candidate for each component of the media stream from one of its
interfaces. If an agent has multiple interfaces it MUST choose one for
each component of a particular media stream." I read this text to
indicate a lite implementation can only have a single candidate per
component?

Further on in section 4.2 (the 3rd paragraph) it states "if an agent has
included two candidates for a component, the v4 candidate SHOULD be
selected as the default. Since a lite implementation has a single
candidate for a component, each of these candidates is considered to be
default." I find these two sentence a bit contradictory?

Can someone clarify the intent of the text in section 4.2 and whether an
ice-lite implementation can include multiple candidates for a single
component? If multiple candidates are allowed then what Francois is
proposing seems reasonable (along with some text clean up in section 4.2
of ICE).

Thanks
Kevin

-----Original Message-----
From: Francois Audet [mailto:[email-masked]] 
Sent: Wednesday, April 18, 2007 4:03 PM
To: Jean-Francois Mule; [email-masked]; Jonathan Rosenberg
Cc: Colin Perkins; Joerg Ott
Subject: RE: [MMUSIC] WGLC: draft-ietf-mmusic-ice-15.txt
Importance: High

Offer:

It sends an answer:

	m=IPv4
	candidate 1=IPv6
	candidate 2=IPv4
	a=ice-lite

Offer:
	m=IPv6              

Answer: 
	m=IPV6

---

From: "Xavier Marjou" <[email-masked]>
Date: Thu, 19 Apr 2007 08:29:00 +0200

Here are some comments:

Title:
- Replace "Methodology" by "Protocol", since "protocol" is used in introduction.

Section 5.7.3 "Pruning the Pairs"
- Why is a local relayed candidate not also replaced by its base, as
well as for a local reflexive candidate?

Section 7.2 "Server Procedures"
- What happens if the credential is unknown? Is the request silently discarded?

Section 12.1.1 "Offer in INVITE":
- My opinion is to keep a single one with RFC3262 and not to add a 2nd
mechanism for doing it.
- Typo: replace "3264" by "3262", "th exponential" by "the
exponential", and "transmission of a 2XX response" by "transmission of
the answer in a 2XX response".

Other:
- Replace 3 instances of "offeror" by "offerer"

---

From: Magnus Westerlund <[email-masked]>
Date: Thu, 19 Apr 2007 13:11:10 +0200

> Do we have any running code and actual deployment experience here?

A very good question. And I am also interested in real-world experience. 
But stating that it works is not sufficient as I am convinced that ICE 
will end up finding the cases that works eventually. However in a number 
of cases it might be after having first induced congestion and the 
checks that gets through are the ones that are in later when the 
exponential retransmission back-off has reduced the load below the 
congestion threshold.

> connectivity checks.  This could be a significant problem for ICE in the 

I have no doubts that this is a difficult problem with very 
contradicting requirements. 1. One wants the checks to complete as 
quickly as possible. 2. While doing that do not congest the network.

However I think you might be a bit short sighted if you at least do not 
acknowledge that in cases where the connectivity checks do result in 
congestion loss you are actually delaying the completion of the checks.

Cheers

Magnus Westerlund

---

From: Benny Prijono <[email-masked]>
Date: Thu, 19 Apr 2007 13:44:04 +0100

> A very good question. And I am also interested in real-world experience. 

In my experience, live testing results have been good, ICE does work 
as it says in the tin and the process completes quickly (thanks to 
triggered check). But what has it got to do with the topic here?

IMO congestion would depend on the number of connectivity checks to 
be performed, and therefore the number of candidates that agents put 
in SDP. If we keep the number of candidates low, I believe should be 
fine.

Lets consider an example. Suppose two agents are running similar 
configuration. Each agent only has one component (RTP only), and 
each component has three candidates (two multihomed interface and 
one server mapped). This is a fair example, IMO.

Each agent will end up having six connectivity checks to perform, 
and they will be performed according to these schedule (using Ta=20 ms):

    Time period    Number of STUN packets
    ---------------------------------------------------
    0.000 - 0.200  12  (avg= 1 packet every ~20 ms)
    0.300 - 0.400   6  (avg= 1 packet every 20 ms)
    0.700 - 0.800   6
    1.500 - 1.600   6
    3.100 - 3.200   6
     etc.. (according to STUN retransmission rule)

I think that's acceptable.

Now add RTCP, and the number of checks is doubled (twelve), and the 
checks will be scheduled like these:

    Time period    Number of STUN packets
    --------------------------------------
    0.000 - 0.520  36
    0.700 - 0.920  12
    1.500 - 1.720  12
    3.100 - 3.320  12
    etc..  (according to STUN retransmission rule)

Drilling down what's happening in t=0 - t=0.520, we'll see that 
packets are transmitted like this:

  Time   Nb of packet transmitted at this time and total number
         of packets transmitted so far
----------------------------------------------------------------
00.000  1 (total=1)
00.020  1 (total=2)
00.040  1 (total=3)
00.060  1 (total=4)
00.080  1 (total=5)
00.100  2 (total=7)
00.120  2 (total=9)
00.140  2 (total=11)
00.160  2 (total=13)
00.180  2 (total=15)
00.200  2 (total=17)
00.220  2 (total=19)
00.240  1 (total=20)
00.260  1 (total=21)
00.280  1 (total=22)
00.300  2 (total=24)
00.320  2 (total=26)
00.340  1 (total=27)
00.360  1 (total=28)
00.380  1 (total=29)
00.400  1 (total=30)
00.420  1 (total=31)
00.440  1 (total=32)
00.460  1 (total=33)
00.480  1 (total=34)
00.500  1 (total=35)
00.520  1 (total=36)

Granted that the numbers look less amusing now, and this probably 
qualifies as congestion situation, but looking at the brighter side, 
at least it's only happening for the first 520 msec; subsequent 
burst of 12 packets (paced at Ta=20ms) will happen at STUN 
retransmit time (t=700, t=1500, t=3100, etc).

I wouldn't like putting any congestion avoidance mechanism in ICE 
(and btw, how?). ICE as now is complicated already; adding more 
rules will just make it more difficult to implement and make it less 
attractive.

What about "if you're worried about congestion, then keep the number 
of candidates low" kind of approach?

cheers,
  -benny

-- 
Benny Prijono
http://www.pjsip.org

---

From: Magnus Westerlund <[email-masked]>
Date: Thu, 19 Apr 2007 15:40:00 +0200

Lars Eggert skrev:

> Sounds like a good suggestion, but doesn't really help, because an end 
> should always be worried about congestion, it's unclear what "low" 
> means, and what do you do if "1" isn't low enough, since a single 
> connectivity check can eat 180Kb/s?
> 

The figure for 180 kbps was to my understanding the aggregated worst 
case bit-rate for 50 checks all failing to get any response. However 
which time scale that is measured over I don't know. It comes from the 
security consideration section in the ICE draft:

17.4.2.  STUN Amplification Attack

    The STUN amplification attack is similar to the voice hammer.
    However, instead of voice packets being directed to the target, STUN
    connectivity checks are directed to the target.  The attacker sends
    an offer with a large number of candidates, say 50.  The answerer
    receives the offer, and starts its checks, which are directed at the
    target, and consequently, never generate a response.  The answerer
    will start a new connectivity check every 20ms, and each check is a
    STUN transaction consisting of 7 transmissions of a message 65 bytes
    in length (plus 28 bytes for the IP/UDP header) that runs for 7.9
    seconds, for a total of 58 bytes/second per transaction on average.
    In the worst case, there can be 395 transactions in progress at once
    (7.9 seconds divided by 20ms), for a total of 182 kbps, just for STUN
    requests.

    It is impossible to eliminate the amplification, but the volume can
    be reduced through a variety of heuristics.  Agents SHOULD limit the
    total number of connectivity checks they perform to 100.
    Additionally, agents MAY limit the number of candidates they'll
    accept in an offer or answer.

Cheers

Magnus Westerlund

---

From: Benny Prijono <[email-masked]>
Date: Thu, 19 Apr 2007 14:43:13 +0100

Lars Eggert wrote:
> Since you seem to have a simulation setup ready to go, can you pick a 
> suitably interesting bandwidth limit, add some TCP connections to your 
> experiment and see what happens to them when the ICE connectivity checks 
> fire?

Nah, I don't have simulation setup whatsoever. The time schedules 
were generated by this silly program:
http://www.pjsip.org/tmp/icecount.c

It just prints out _when_ STUN Binding requests will be sent 
according to the number of connectivity checks to be performed.

> If ICE ends up significantly ipacting concurrent flows, that'd really 
> make it unattractive. (And I'm not saying it necessarily will, but it is 
> important to investigate this.)

But that won't happen if you keep the candidate number low!

> connectivity check can eat 180Kb/s?

No, that's not true.

A single connectivity check in one agent consists of sending STUN 
Binding request, and retransmitting it according to STUN rule until 
a response is received, or the STUN transaction has timed out.

In my application, a STUN Binding request is approx 108 bytes long, 
and a response is about the same. Since STUN is (re)transmitted at 
t=0, t=100, t=300, t=700, t=1500, t=3100, etc., that gives the 
bandwidth (for each connectivity check):

   for t=0s to t=1s: 4x108 == 432 bytes/s == 3.4 Kbps
   for t=1s to t=2s: 108 bytes/s == 0.8 Kbps
   for t=2s to t=3s: 0 Kbps
   for t=3s to t=4s: 0.8 Kbps again.

It's the first one second that takes the most bandwidth, but then 
again it's not as much as what you quoted, and it will only take 
that amount if connectivity checks failed and the STUN requests get 
retransmitted. In my ADSL to ADSL test, the whole ICE can complete 
in between 100 to 200 ms, so in this case there should be less 
bandwidth taken.

> ICE can be a really powerful tool, but it does need to play nice with 
> other traffic in the Internet.

True.

cheers,
  -benny

> Lars

-- 
Benny Prijono
http://www.pjsip.org

---

From: Magnus Westerlund <[email-masked]>
Date: Thu, 19 Apr 2007 15:48:09 +0200

Many thanks Benny for the good illustration of how things happen.

I think one of the major problems with ICE currently is how the 
relatively short Ta quickly builds up the number of packets sent. If one 
increases Ta to the double you get a longer but less quickly growing 
burst. This is still quite aggressive. It actually sends more packets 
than most speech codecs does during half a second averaged out. And the 
worst part is from 300 ms until 460 ms into the transfer for Ta=40 ms 
where 75 packets per second are sent. The Ta=20 ms has its worst part at 
100 to 200 ms when it runs along at a whooping 100 packets per second.

Compare the left using Ta=40 and the right columns using Ta=20.

00.000  1 (total=1)   00.000  1 (total=1)
00.020  0             00.020  1 (total=2)
00.040  1 (total=2)   00.040  1 (total=3)
00.060  0             00.060  1 (total=4)
00.080  1 (total=3)   00.080  1 (total=5)
00.100  1 (total=4)   00.100  2 (total=7)
00.120  1 (total=5)   00.120  2 (total=9)
00.140  1 (total=6)   00.140  2 (total=11)
00.160  1 (total=7)   00.160  2 (total=13)
00.180  1 (total=8)   00.180  2 (total=15)
00.200  1 (total=9)   00.200  2 (total=17)
00.220  1 (total=10)  00.220  2 (total=19)
00.240  1 (total=11)  00.240  1 (total=20)
00.260  1 (total=12)  00.260  1 (total=21)
00.280  1 (total=13)  00.280  1 (total=22)
00.300  2 (total=15)  00.300  2 (total=24)
00.320  1 (total=16)  00.320  2 (total=26)
00.340  2 (total=18)  00.340  1 (total=27)
00.360  1 (total=19)  00.360  1 (total=28)
00.380  2 (total=21)  00.380  1 (total=29)
00.400  1 (total=22)  00.400  1 (total=30)
00.420  2 (total=24)  00.420  1 (total=31)
00.440  1 (total=25)  00.440  1 (total=32)
00.460  2 (total=27)  00.460  1 (total=33)
00.480  0 (total=27)  00.480  1 (total=34)
00.500  2 (total=29)  00.500  1 (total=35)
00.520  0 (total=29)  00.520  1 (total=36)
00.540  1 (total=30)

What actually is interesting in this situation is if you actually need 
to be this quick at all. The above performs 12 connectivity checks. With 
Ta=40 it takes until 440 ms until all checks has been sent at least 
once. At that point 4 of the checks has been retransmitted twice and 5 
more has been retransmitted once.

So if you have prioritized right and have a reasonable RTT your checks 
may have completed for the most interesting base pairs. Allowing one to 
start unfreeze checks for other components and medias and then actually 
prioritize them over other checks.

What I going for is what we need is to see how the distribution for 
completion times actually varies with different policies and values.

Something that isn't really considered in the above is that some checks 
actually get responded to. And then stops retransmitting, that way 
reducing the number of packets being sent. That is one thing that make 
me want to introduce something like a token bucket rate limiter for 
transmission in general, delaying both new checks and retransmissions if 
need to keep a reasonable rate. I think one token bucket per local 
interface would make sense. The only issue with this would be multihomed 
hosts.

cheers

Magnus Westerlund

---

From: Lars Eggert <[email-masked]>
Date: Thu, 19 Apr 2007 15:03:51 +0300

On 2007-4-19, at 14:11, ext Magnus Westerlund wrote:
>> If not, I'd suggest adding further congestion avoidance in ICE  
>> would likely only have the effect of increasing the time taken to  
>> complete connectivity checks.  This could be a significant problem  
>> for ICE in the real world.
>
> However I think you might be a bit short sighted if you at least do  
> not acknowledge that in cases where the connectivity checks do  
> result in congestion loss you are actually delaying the completion  
> of the checks.

I agree. One issue is that the bandwidth use of ICE could interfere  
with its own efficient operation in bandwidth-limited scenarios.

RFC2914 (the current BCP for congestion control principles)  
identifies two additional concerns: (1) whether a protocol can cause  
congestion collapse and (2) whether it is able to reasonably fairly  
share path capacity with concurrent traffic. For the health of the  
Internet, those are both critical questions to answer for any new  
protocol.

(1) typically involves having a mechanism that causes a reduction in  
bandwidth use when congestion occurs, and does so on reasonable  
timescales. I haven't read the whole ICE draft yet, but a quick look  
tells me that something along those lines is in the specification,  
which is promising.

(2) is usually the harder question to answer. Has there been any  
experimentation with ICE in bandwidth-constrained scenarios and with  
concurrent flows?

 From what Magnus has written, ICE can generate up to 180Kb/s of  
traffic, which far exceeds modem speeds and approaches the typical  
uplink capacity of some "broadband" offers, so I'd like to stress  
that finding out how ICE behaves in such cases (especially if it  
shares capacity with other flows) seems vital.

Lars

---

From: Lars Eggert <[email-masked]>
Date: Thu, 19 Apr 2007 17:12:46 +0300

Hi,

...

Ah. I obviously misunderstood things, and will shut up until I have  
actually read the whole draft - apologies.

Lars

---

From: Benny Prijono <[email-masked]>
Date: Thu, 19 Apr 2007 16:49:54 +0100

> Many thanks Benny for the good illustration of how things happen.

And thanks for providing the analytical comments. I didn't bother 
since I've never been too good with numbers.

..snip..

> interface would make sense. The only issue with this would be multihomed 

That's one solution alright, although we still need to analyze the 
bucket limiter impact to ICE performance (it would slow it down I 
suspect).

I have different solution, and mine is directed towards reducing the 
number of checks. And I believe this one not only help congestion 
problem, but it could also ICE performance significantly.

The idea is to use one socket for all candidates in one component. 
During pruning process, we know that srflx candidate will be pruned 
and be replaced by its base candidate.

But since we use one socket for all candidates, the host candidates 
can be pruned as well, leaving just one host candidate in the check 
list for the component (note: this currently is not in ICE).

If an agent is using this approach (and assuming only host and srflx 
candidates are used), the number of checks that the agent performs 
would be M for each component, where M is the number of candidates 
in that component in the remote agent. Compare this to current ICE 
where the number of checks will be "(N-1) x M"  (the N-1 reflects 
the pruning of srflx candidate).

I think this could work (would be interested to hear Jonathan's 
comment on this). Unfortunately it seems that the use of one socket 
per component has been deprecated long ago and it would be quite a 
big editing work to adapt the text this way. But I've been using one 
socket approach and it seems to work.

cheers,
  -benny

-- 
Benny Prijono
http://www.pjsip.org

---

From: "Dan Wing" <[email-masked]>
Date: Thu, 19 Apr 2007 09:12:59 -0700

I have created an Excel spreadsheet analyzing ICE's behavior compared to
RTP's behavior.  I am tweaking this spreadsheet and expect it to be useful
in helping us tune ICE's algorithms.  I want to make this a more useful
spreadsheet before sharing it; it doesn't quite do everything I like yet.  I
expect it will remain awkward to use, as I'm not an excel wizard.

In my initial analysis using this spreadsheet, I do agree that ICE's default
20ms pacing and STUN's default 100ms retransmit timers are too aggressive if
we assume severely bandwidth-constrained links.  I expect that adjusting
these values based on the ptime, RTP packet size, STUN Request packet size,
and number of candidates will result in ICE behaving as well as RTP (with
RTCP feedback) in all cases, and better than RTP (with RTCP feedback) in
some cases.  The drawback of such tuning, however, is that ICE will take
longer to complete if there are many candidates.

-d

---

From: Philip Matthews <[email-masked]>
Date: Thu, 19 Apr 2007 12:31:28 -0400

[trimming the CC list]

> proposing seems reasonable (along with some text clean up in  

I was also confused by this, since it is my understanding that a  
"lite" implementation
can currently advertise only one candidate per media stream.   
However, I don't see
any solid reason for this limitation.

- Philip

---

From: "Kevin Johns" <[email-masked]>
Date: Thu, 19 Apr 2007 12:07:23 -0600

Philip,

Thinking about it some more, the issue with having multiple candidates
in the lite implementation is when you hit two lite implementations, the
non-default candidate is ignored forcing the use of the default
candidate. Jonathan provided some further context to this issue in his
email to the list on 4/9 subject Re: [MMUSIC] Re: ICE micro-lite for
support of IPv6 transition

Kevin

-----Original Message-----
From: Philip Matthews [mailto:[email-masked]] 
Sent: Thursday, April 19, 2007 10:31 AM
To: Kevin Johns
Cc: [email-masked]; Jonathan Rosenberg
Subject: Re: [MMUSIC] WGLC: draft-ietf-mmusic-ice-15.txt

[trimming the CC list]

On 19-Apr-07, at 01:04 , Kevin Johns wrote:

>
> Can someone clarify the intent of the text in section 4.2 and whether 
> an ice-lite implementation can include multiple candidates for a 
> single component? If multiple candidates are allowed then what 
> Francois is proposing seems reasonable (along with some text clean up 
> in section 4.2 of ICE).
>

I was also confused by this, since it is my understanding that a "lite"
implementation
can currently advertise only one candidate per media stream.   
However, I don't see
any solid reason for this limitation.

- Philip

---

From: Philip Matthews <[email-masked]>
Date: Mon, 23 Apr 2007 16:52:35 -0400

On 19-Apr-07, at 11:49 , Benny Prijono wrote:

>
> I have different solution, and mine is directed towards reducing  
> the number of checks. And I believe this one not only help  
> congestion problem, but it could also ICE performance significantly.
>
> If an agent is using this approach (and assuming only host and  
> srflx candidates are used), the number of checks that the agent  
> performs would be M for each component, where M is the number of  
> candidates in that component in the remote agent. Compare this to  
> current ICE where the number of checks will be "(N-1) x M"  (the  
> N-1 reflects the pruning of srflx candidate).
>
> big editing work to adapt the text this way. But I've been using  
> one socket approach and it seems to work.

I don't understand your proposal.

Say I have an application that needs M components, and is running on  
a box with N interfaces. Then for each interface and component, I  
allocate one local port number (socket) -- these are my host  
candidates. Then I use STUN to determine server-reflexive and relay  
candidates that correspond to each of these host candidates.

I don't see how I can reduce anything.  Can you clarify?

- Philip

---

From: Colin Perkins <[email-masked]>
Date: Mon, 23 Apr 2007 23:02:24 +0100

> Please mail all your final comments to the author and the mmusic  

The working group last call period has ended, with approximately 100  
comments received. An updated draft should be submitted, at which  
time we will reissue the working group last call, to ensure the  
comments have been satisfactorily  addressed.

-- 
Colin Perkins
http://csperkins.org/

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 24 Apr 2007 16:07:57 -0400

> still need to send keep-alives to their STUN/TURN server.

The text will say something like, "SHOULD free resources if they are no 
longer in use". THat would cover your case. Also something similar 
happens in forking, where a set of candidates gets used in many sessions.

-Jonathan R.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 24 Apr 2007 16:37:53 -0400

Right now, there is just one sentence on ICMP in ICE:

<t>
If the STUN transaction generates an ICMP error, or generates a STUN
error response that is unrecoverable (as defined in <xref
target="I-D.ietf-behave-rfc3489bis"/>, or times out, the agent sets
the state of the pair to Failed.
</t>

Nothing in here is saying you HAVE to process iCMP, it only says what to 
do when you get one. I'm fine to add a sentence that endpoints MAY 
implement ICMP.

On a related note, there is actually a problem with the current ICE spec 
and ICMP. In the case of clients, both behind a NAT, both agents will 
generate STUN checks to the other. One of these is likely to hit the far 
end NAT first. If that NAT generates ICMP on its public interface since 
no permission exists, the STUN transaction will fail if the agent is 
waiting for ICMP. WIth the current wording, the agent will receive the 
incoming STUN request, and find that its transaction in the reverse 
direction failed, and thats the end. I actually need to fix this, so 
that if the transaction failed due to ICMP, you retry the check.

-Jonathan R.

Dan Wing wrote:

>>>Optional support of ICMP reception is perfectly fine for me 
>>
>>because it
>>
>>
>>>we would basically need to allocate one socket for each 
>>
>>candidate pair
>>
>>
>>>That's a lot of sockets, but that way you can do a connect 
>>
>>on all of 
>>
>>>them. This solution would work fine on some operating 
>>
>>systems, but on 
>>
>>>available and it is needed so that all socket may be bound 
>>
>>to the same
>>
>>
>>>This might be true for other operating systems as well. You 
>>
>>would also
>>
>>
>>>connectivity checks before the SDP answer arrives. This 
>>
>>would also be 
>>
>>>NOTE: The socket option SO_REUSEPORT and SO_REUSEADDR are 
>>
>>needed for 
>>
>>>>I am wondering how you plan on demultiplexing ICMP errors
>>>
>>>if a single
>>>
>>>>Connectivity Checks or even a Binding Discovery Request
>>>
>>>used to keep
>>>
>>>>server reflexive candidate alive (keepalive)? Normally, at
>>>
>>>least, on
>>>
>>>>BSD like stack, you must connect the UDP socket to be able
>>>
>>>to reliably
>>>
>>>
>>>>receive ICMP errors.
>>>
>>>Even if you use one socket for each candidate, I'm not sure 
>>
>>if you can
>>
>>
>>>>Not connecting the socket would not allow you to fully
>>>
>>>comply with the
>>>
>>>
>>>>specification (your implementation would end up waiting for
>>>
>>>the full
>>>
>>>I view ICMP handling as "if you can and want to handle it, 
>>
>>then do it,
>>
>>

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 24 Apr 2007 16:45:36 -0400

inline.

> Request to keep alive the NAT binding.

I had in mind that there would be one socket. You'd first call socket() 
to allocate. THen you'd do a listen() on that socket to bind to a local 
port, and then connect() on the same socket to connect to the STUN 
server. I have not tried to see that BSD sockets will let you both 
listen() and connect() on the same socket. Certainly from a TCP protocol 
perspective this is allowed.

Have you tried it?

> before sending its connecitivity checks.

Again, I think its more like the above.

> more than one STUN server. Note however, that the specification does not

Its not that it doesn't encourage it; it just doesn't specify it. Its 
quite a fine idea as a general rule.

-Jonathan R.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 24 Apr 2007 16:47:18 -0400

Its not hugely important; it'll affect the last component of the formula 
below. I see no reason why not to specify this to work correctly however.

-Jonathan R.

Philip Matthews wrote:

> If I understand this comment correctly, then the only question is  which 
> end is

---

From: Benny Prijono <[email-masked]>
Date: Wed, 25 Apr 2007 15:53:14 +0100

Philip Matthews wrote:
>> would be M for each component, where M is the number of candidates in 
>> that component in the remote agent. Compare this to current ICE where 
>> the number of checks will be "(N-1) x M"  (the N-1 reflects the 
>> pruning of srflx candidate).
>>
>> per component has been deprecated long ago and it would be quite a big 
>> editing work to adapt the text this way. But I've been using one 
> Say I have an application that needs M components, and is running on a 
> box with N interfaces. Then for each interface and component, I allocate 
> one local port number (socket) -- 

No (and that is where the difference is).

We only allocate *one* socket for all host and srflx candidates in 
one component. So even though we have N interfaces (and N host 
candidates), they all share the same port number. The N host 
candidates (of the same component) thus only differ in their IP 
addresses.

The socket is of course bound to INADDR_ANY. So now, for host 
candidates, since it doesn't matter from which interface the 
connectivity check is sent *from*, the host candidates can be 
pruned, leaving only one host candidate to be used for all host 
candidates and server-reflexive checks.

The benefit can be massive with this approach. Say a box has four 
interfaces (I've seen this in real life -- virtual interfaces are 
quite common in Windows), the agent will have 4 host candidates plus 
1 srflx candidate for one component. Add RTCP, we'll have 10 
candidates. If the other agent also has four interfaces, each agent 
will end up with 40 connectivity checks (!) to perform.

Compared to if one agent use one socket, it will only have 10 
connectivity checks to perform.

Assuming of course if my approach works. There will be a problem 
with finding out which candidate to use for triggered check, I can 
explain my solution (if you're still interested).

cheers,
  -benny

> these are my host candidates. Then I 
> use STUN to determine server-reflexive and relay candidates that 
> correspond to each of these host candidates.
> 

-- 
Benny Prijono
http://www.pjsip.org

---

From: Jonathan Rosenberg <[email-masked]>
Date: Wed, 25 Apr 2007 11:02:44 -0400

I don't see how this can possibly work.

The reason why you have a separate candidate for each interface is that 
a check from one might succeed, but not from the other. This is because 
of topological issues that provide connectivity to your peer from one, 
but not the other.

Having a single candidate for all interfaces means that ICE would only 
do the check from one actual interface, and thus you won't even try the 
others.

-Jonathan R.

Benny Prijono wrote:

>> box with N interfaces. Then for each interface and component, I 
>> allocate one local port number (socket) -- 
> 
> 
> We only allocate *one* socket for all host and srflx candidates in one 
> component. So even though we have N interfaces (and N host candidates), 
> they all share the same port number. The N host candidates (of the same 
> component) thus only differ in their IP addresses.
> 
> connectivity check is sent *from*, the host candidates can be pruned, 
> leaving only one host candidate to be used for all host candidates and 
> server-reflexive checks.
> 
> interfaces (I've seen this in real life -- virtual interfaces are quite 
> common in Windows), the agent will have 4 host candidates plus 1 srflx 
> candidate for one component. Add RTCP, we'll have 10 candidates. If the 
> other agent also has four interfaces, each agent will end up with 40 
> connectivity checks (!) to perform.
> 
> Assuming of course if my approach works. There will be a problem with 
> finding out which candidate to use for triggered check, I can explain my 
> solution (if you're still interested).
> 
> cheers,
>  -benny
> 
> 
> 
>> these are my host candidates. Then I use STUN to determine 
>> server-reflexive and relay candidates that correspond to each of these 
>> host candidates.
>>

---

From: Philip Matthews <[email-masked]>
Date: Wed, 25 Apr 2007 11:35:24 -0400

I totally agree with Jonathan.
It matters very much which IP address a connectivity check is sent  
from, and if you have 4 different interface addresses, checks must be  
sent from all four addresses, otherwise you are only checking the  
connectivity from the interfaces you are actually sending from. For  
example, say one interface is a WiFi interface and the other  
interface is an Ethernet interface. If you only send checks from the  
WiFi interface, and the cable connecting the WiFi access point to the  
internet is disconnected, then your checks will fail, but checks via  
the Ethernet interface might actually work.

- Philip

On 25-Apr-07, at 11:02 , Jonathan Rosenberg wrote:

> The reason why you have a separate candidate for each interface is  
> that a check from one might succeed, but not from the other. This  
> is because of topological issues that provide connectivity to your  
> peer from one, but not the other.
>
> Having a single candidate for all interfaces means that ICE would  
> only do the check from one actual interface, and thus you won't  
> even try the others.
>
> -Jonathan R.
>
>
>
> Benny Prijono wrote:
>
>
>>> Say I have an application that needs M components, and is running  
>>> on a box with N interfaces. Then for each interface and  
>>> component, I allocate one local port number (socket) --
>> quite common in Windows), the agent will have 4 host candidates  
>> plus 1 srflx candidate for one component. Add RTCP, we'll have 10  
>> candidates. If the other agent also has four interfaces, each  
>> agent will end up with 40 connectivity checks (!) to perform.
>>> these are my host candidates. Then I use STUN to determine server- 
>>> reflexive and relay candidates that correspond to each of these  
>>> host candidates.
>>>

---

From: Benny Prijono <[email-masked]>
Date: Wed, 25 Apr 2007 17:57:26 +0100

No, I think that's not true (or did I completely miss something?).

But first of all, let me clarify. The candidates don't get removed; 
so if there are N interfaces, there will still be N host candidates 
being advertised in SDP. Only the checks that originates from the 
remaining host candidates are being removed, during pruning process.

So even though there is only one (UDP) socket and with some more 
checks pruned, connectivity checks will be sent from *all* 
interfaces. Let me illustrate with an example.

(please see this table with fixed width font)

          Agent A               |         Agent B
  candidate=1.1.1.1 1 typ host  | candidate 1: 3.3.3.3 3 typ host
  candidate=2.2.2.2 2 typ host  | candidate 2: 4.4.4.4 4 typ host

With usual ICE, these checks will be created on agent A:

   #1)  1.1.1.1:1 --> 3.3.3.3:3
   #2)  1.1.1.1:1 --> 4.4.4.4:4
   #3)  2.2.2.2:2 --> 3.3.3.3:3
   #4)  2.2.2.2:2 --> 4.4.4.4:4

Now, if agent A uses a single socket for all host candidates, AFAIK 
check #3 will produce the same result as check #1, and check #4 will 
produce the same result as check #2.

So we can prune the checks further, leaving the check list in agent 
A to:

   #1)  1.1.1.1:1 --> 3.3.3.3:3
   #2)  1.1.1.1:1 --> 4.4.4.4:4

or

   #1)  2.2.2.2:2 --> 3.3.3.3:3
   #2)  2.2.2.2:2 --> 4.4.4.4:4

(it doesn't really matter which local host candidate to use, they 
will produce the same result using this approach)

It doesn't matter what type of interfaces are for interface 1.1.1.1 
and 2.2.2.2, all that matters is the routing table in the box 
(remember that the socket is bound to INADDR_ANY), and the OS will 
decide for us which interface to use to contact 3.3.3.3 and 4.4.4.4, 
if the routing table says that destination 3.3.3.3 and 4.4.4.4 are 
indeed reachable through one of its interfaces.

AFAIK this will produce *mostly* the same result as normal ICE for 
both successful and failed scenario.

The only situation that I can think of where the result may differ 
is when a remote candidate may be reachable from more than one local 
interfaces (maybe two interfaces are configured in load balance 
mode?). But with ICE it's very hard to predict which interface is 
likely to win anyway (depending on how the implementation sets the 
priorities among host candidates, whether normal/aggressive mode is 
being used, and which response comes earlier), so I don't think it's 
that important. Well at least not for my use case.

  -benny

Philip Matthews wrote:
> It matters very much which IP address a connectivity check is sent from, 
> and if you have 4 different interface addresses, checks must be sent 
> from all four addresses, otherwise you are only checking the 
> example, say one interface is a WiFi interface and the other interface 
> is an Ethernet interface. If you only send checks from the WiFi 
> interface, and the cable connecting the WiFi access point to the 
> internet is disconnected, then your checks will fail, but checks via the 
> Ethernet interface might actually work.
> 
> - Philip
> 
>> that a check from one might succeed, but not from the other. This is 
>> because of topological issues that provide connectivity to your peer 
>> from one, but not the other.
>>
>> do the check from one actual interface, and thus you won't even try 
>> the others.
>>
>> -Jonathan R.
>>
>>
>>
>> Benny Prijono wrote:
>>
>>
>>> leaving only one host candidate to be used for all host candidates 
>>> and server-reflexive checks.
>>> finding out which candidate to use for triggered check, I can explain 
>>> my solution (if you're still interested).
>>> cheers,
>>>  -benny
>>>> server-reflexive and relay candidates that correspond to each of 
>>>> these host candidates.
>>>>
>> --Jonathan D. Rosenberg, Ph.D.                   600 Lanidex Plaza

---

From: Philip Matthews <[email-masked]>
Date: Wed, 25 Apr 2007 15:33:35 -0400

On 25-Apr-07, at 12:57 , Benny Prijono wrote:

> check #3 will produce the same result as check #1, and check #4  
> will produce the same result as check #2.

This is where I disagree. In my opinion, check #1 and check #3 are  
not the same (and nor are checks #2 and #4).
Let me illustrate by elaborating more on my previous example.
On Agent A,
    - say the interface with address 1.1.1.1 is a 802.11 interface  
that connects to an access point which then connects via ethernet to  
a router that connects to the Internet; and
    - say the interface with address 2.2.2.2 is an ethernet interface  
that connects to the same router.
Say static/default routing is used throughout. So if someone unplugs  
the ethernet cable leading to the wireless access point, the box on  
which Agent A runs will not see any routing updates or similar.  
However, packets sent out the wireless interface will just be dropped  
(hopefully with an ICMP Destination Unreachable reply, but even that  
is not certain).
In this case, check #1 and #2 will fail, but check #3 and check #4  
will succeed.

However, your comment does point that you have to force the packets  
out the correct interface. If you just say "send to 3.3.3.3", and let  
the box choose the outgoing interface, then you are not implementing  
ICE properly. You have to tell the box "send to 3.3.3.3 via interface  
1.1.1.1" or "send to 3.3.3.3 via interface 2.2.2.2".

Is this making any sense?

- Philip

---

From: Benny Prijono <[email-masked]>
Date: Thu, 26 Apr 2007 03:16:18 +0100

Philip Matthews wrote:
> This is where I disagree. In my opinion, check #1 and check #3 are not 
> the same (and nor are checks #2 and #4).
>    - say the interface with address 1.1.1.1 is a 802.11 interface that 
> connects to an access point which then connects via ethernet to a router 
> that connects to the Internet; and
> Say static/default routing is used throughout. So if someone unplugs the 
> ethernet cable leading to the wireless access point, the box on which 
> Agent A runs will not see any routing updates or similar. However, 
> packets sent out the wireless interface will just be dropped (hopefully 
> with an ICMP Destination Unreachable reply, but even that is not certain).
> In this case, check #1 and #2 will fail, but check #3 and check #4 will 
> succeed.

Let me come back to this after I explain more about my approach 
below, since there seem to be a misunderstanding.

> However, your comment does point that you have to force the packets out 
> the correct interface. 

No, that is exactly what you MUST NOT do when using my approach!

Using my approach, socket MUST ALWAYS be bound to INADDR_ANY 
(0.0.0.0), to allow the OS to choose the appropriate interface when 
sending the request.

There seems to be a misunderstanding. When I said that the agent 
perform this connectivity check (using my approach):

    1.1.1.1:1 --> 3.3.3.3:3

It doesn't mean that the agent must somehow force the socket to send 
from interface 1.1.1.1:1. No, that's not what I meant.

What I meant is that the agent should choose local host candidate 
1.1.1.1:1 as the local candidate of the check. But as I said, it 
doesn't really matter which local candidate to use as the local part 
of the check, since all candidates shares the same socket.

The socket itself is still bound to INADDR_ANY, to allow the OS to 
choose which interface to send the packet from. We don't need to 
care what interface is chosen for the packet. If the connectivity is 
successful the peer will tell us what it is in XOR-MAPPED-ADDRESS 
attribute in the response.

I hope I'm making myself clear.

Now back to the examples.

Case 1:
=============

Suppose an agent has these connectivity checks as the result of 
pairing process with normal ICE:

And it has this routing table:

   1.1.1.0/24  use interface 1.1.1.1
   2.2.2.0/24  use interface 2.2.2.2
   0.0.0.0/0 (default) use interface 2.2.2.2

Now even if interface 1.1.1.1 is up, check #1 and #2 will always 
fail (immediately with ENETUNREACH/EHOSTUNREACH error, at least on 
Windows and Linux) if you use standard ICE, so the question is why 
bother creating these checks in the first place?

With my approach, these checks will be created instead:

   #1)  0.0.0.0:0 --> 3.3.3.3:3
   #2)  0.0.0.0:0 --> 4.4.4.4:4

(I put 0.0.0.0:0 as the local part to make it clearer that the 
application does not specify which interface to use).

With this approach, the OS will choose for us which interface to use 
for sending the request, and in this case it will choose interface 
2.2.2.2.

So both approaches yield the same result.

Case 2:
===========

Another example, suppose two agents are interconnected like this:

          Agent A                                    Agent B
   +-----------------+                        +-----------------+
   |   wifi: 1.1.1.A | <--------------------->| 1.1.1.B/wifi    |
   |                 |                        |                 |
   |   eth:  2.2.2.A | <--------------------->| 2.2.2.B/eth     |
   +-----------------+                        +-----------------+

Routing table in agent A is like this:

    1.1.1.0/24  use interface 1.1.1.A
    2.2.2.0/24  use interface 2.2.2.A

With normal ICE, agent A will have these checks:

   #1)  1.1.1.A --> 1.1.1.B
   #2)  1.1.1.A --> 2.2.2.B
   #3)  2.2.2.A --> 1.1.1.B
   #4)  2.2.2.A --> 2.2.2.B

Running the checks, check #2 and #3 will fail immediately with 
EHOSTUNREACH/ENETUNREACH error generated by the OS (well at least 
this is true with Windows and Linux). So only check #1 and #4 will 
succeed, and these valid pairs will be generated:

    pair (1.1.1.A, 1.1.1.B)
    pair (2.2.2.A, 2.2.2.B)

Using my approach, agent A will have these checks:

   #1)  0.0.0.0:0 --> 1.1.1.B
   #2)  0.0.0.0:0 --> 2.2.2.B

This will produce the same valid pair as normal ICE, but savings of 
two connectivity checks *not* performed.

Case 3:
=============

Using configuration in case 2 above, suppose the WiFi connection failed.

With normal ICE, checks #1, #2, and #3 will fail, so only one pair 
will be generated in valid list:

    pair (2.2.2.A, 2.2.2.B)

With my approach check #1 will fail too, and it will also produce 
the same, one pair in the valid list.

> If you just say "send to 3.3.3.3", and let the 
> box choose the outgoing interface, then you are not implementing ICE 
> properly. You have to tell the box "send to 3.3.3.3 via interface 

IMO, for all practical purposes, there is absolutely no difference 
between explicitly choosing which interface to use and letting the 
OS choose which interface to use. They will produce the same result, 
but my approach is more optimized! And anyway, we will not use this 
local interface as the local part of our valid list, but rather the 
address in the XOR-MAPPED-ADDRESS.

So I failed to see why we should call this "not a proper ICE 
implementation". The way I see it, it's even cooler than ICE!

    -benny

-- 
Benny Prijono
http://www.pjsip.org

---

From: Benny Prijono <[email-masked]>
Date: Thu, 26 Apr 2007 03:16:18 +0100

1.1.1.1:1 --> 3.3.3.3:3

Case 1:
=============

Case 2:
===========

          Agent A                                    Agent B

   #1)  1.1.1.A --> 1.1.1.B
   #2)  1.1.1.A --> 2.2.2.B
   #3)  2.2.2.A --> 1.1.1.B
   #4)  2.2.2.A --> 2.2.2.B

    pair (1.1.1.A, 1.1.1.B)
    pair (2.2.2.A, 2.2.2.B)

Case 3:
=============

    pair (2.2.2.A, 2.2.2.B)

    -benny

-- 
Benny Prijono
http://www.pjsip.org

---

From: Philip Matthews <[email-masked]>
Date: Thu, 26 Apr 2007 07:14:17 -0400

See inline.
-- Philip
On 25-Apr-07, at 22:16 , Benny Prijono wrote:

>>> Now, if agent A uses a single socket for all host candidates,  
>>> AFAIK check #3 will produce the same result as check #1, and  
>>> check #4 will produce the same result as check #2.
>> that connects to an access point which then connects via ethernet  
>> to a router that connects to the Internet; and
>>    - say the interface with address 2.2.2.2 is an ethernet  
>> interface that connects to the same router.
>> Say static/default routing is used throughout. So if someone  
>> unplugs the ethernet cable leading to the wireless access point,  
>> the box on which Agent A runs will not see any routing updates or  
>> similar. However, packets sent out the wireless interface will  
>> just be dropped (hopefully with an ICMP Destination Unreachable  
>> reply, but even that is not certain).
>> However, your comment does point that you have to force the  
>> packets out the correct interface.
>
> It doesn't mean that the agent must somehow force the socket to  
> send from interface 1.1.1.1:1. No, that's not what I meant.
>
> doesn't really matter which local candidate to use as the local  
> part of the check, since all candidates shares the same socket.
>
> care what interface is chosen for the packet. If the connectivity  
> is successful the peer will tell us what it is in XOR-MAPPED- 
> ADDRESS attribute in the response.
>
> With this approach, the OS will choose for us which interface to  
> use for sending the request, and in this case it will choose  
> interface 2.2.2.2.
>

Let's change your example to have the default route point out  
interface 1.1.1.1 rather than interface 2.2.2.2 (this could easily  
happen, after all). Then let's merge this with my example where  
1.1.1.1 is a 802.11 interface which leads to an Access Point whose  
cable in unplugged (so packets are dropped at the Access Point rather  
than being forwarded),  while 2.2.2.2 is an Ethernet interface and  
has proper Internet connectivity.

Under these conditions, your approach will always send out interface  
1.1.1.1 (in effect, only doing checks #1 and #2), and both of these  
checks will fail. However, assuming other things are OK, a working  
path could be found using interface 2.2.2.2, but your implementation  
will never find this path.

Remember that, in my example, the OS on which Agent A is running is  
only using static routing, so it doesn't have any way to discover  
that packets sent out interface 1.1.1.1 get dropped before they reach  
the Internet.

Does this help?

- Philip

---

From: "Guylain Lavoie" <[email-masked]>
Date: Thu, 26 Apr 2007 10:03:28 -0400

Hi Jonathan,

Yes, I have tried it. It seems that you cannot do a listen and then do a
connect on the same socket. It does not work. At least on the platforms
I tested (Linux and Windows). The only way to achieve this is by binding
two sockets to the exact same address/port and this required special
support from the OS (SO_REUSEPORT and/or SO_REUSEADDR combinason). From
what I read, the needed fonctionality is not available on Linux. You are
right that at the TCP level, nothing should prevent us from doing this.
However, it's the API level that does not follow.

Maybe someone else will bring some light over this.

Best Regards,
Guylain

-----Original Message-----
From: Jonathan Rosenberg [mailto:[email-masked]] 
Sent: April 24, 2007 4:46 PM
To: Guylain Lavoie
Cc: Alfred E. Heggestad; [email-masked]
Subject: Re: [MMUSIC] ICE-15: when do you stop waiting foran aggressive
nomination?

inline.

> candidates (Reception of a connection request will effectively create 
> a entirely new socket, also bound at the same address and port). The 
> other will be a TCP client socket connected to the STUN server to 
> gather a server reflexive candidate and periodically, it will also 
> send Binding Request to keep alive the NAT binding.

Have you tried it?

> client sockets and also bind them at the same address and port. One 
> will be connected to the STUN server to gather a server reflexive 
> candidate and periodically send Binding Request to keep alive the NAT 
> binding. The other, or others, are used to send connectivity checks to

> the peer SO candidates. Each one of them must be connected to peer SO 
> candidate before sending its connecitivity checks.

> more than one STUN server. Note however, that the specification does 
> not encourage this.

-Jonathan R.

---

From: "Dan Wing" <[email-masked]>
Date: Thu, 26 Apr 2007 09:17:36 -0700

(Jonathan had also listed this as ICE issue #11.)

I have moved discussion of ICE pacing to the tsv-area mailing list
<https://www1.ietf.org/mailman/listinfo/tsv-area>, as the tsv-area list is
more appropriate for discussing TCP friendliness.  

My post to tsv-area
<http://www1.ietf.org/mail-archive/web/tsv-area/current/msg00077.html>
proposed new calculations for ICE's Ta and STUN's RTO.  These changes
prevent ICE from exceeding the bandwidth RTP would have consumed.

-d

> Sent: Thursday, April 19, 2007 9:13 AM
> To: 'Lars Eggert'; 'Magnus Westerlund'
> Cc: [email-masked]
> Subject: RE: ICE pacing connectivity checks (wasRE:[MMUSIC] 
> WGLC: draft-ietf-mmusic-ice-15.txt)
>

---

From: Philip Matthews <[email-masked]>
Date: Thu, 26 Apr 2007 13:45:09 -0400

On 26-Apr-07, at 11:35 , [email-masked] wrote:
>
> You're assuming that just because you bind() your socket to a specific
> interface, you can force the OS to spit packets out of that interface,
> bypassing the routing table. It won't work. The OS will return
> ENETUNREACH/EHOSTUNREACH error if you try to do this.
>
> So you can't send packet to 3.3.3.3 or 4.4.4.4 using interface  
> 2.2.2.2, if
> the default route points to interface 1.1.1.1. Your connectivity  
> checks
> will fail.
>
> And so are mine (because 1.1.1.1 is down).
>
> So both approaches produce the same result, again.

Now the discussion is moving from the realm of specification to the
realm of implementation. That is, given that we WANT to force the
packets to be sent out a specific interface, how do we achieve this
under Y, where Y is some specific OS?

Since much of my coding experience at this level has been on a
proprietary embedded operating system that has a
"send packet out interface X" call, I am not the best person to discuss
this with, but perhaps others on the list can provide their insights.
Has anyone else on this list figured out how to force packets out a
specific interface under some popular OS?

- Philip

PS. And BTW, I have downloaded your STUN/TURN/ICE
implementation to take a look at. I haven't had much chance to poke  
around
yet, but I like what I have seen so far. I am glad to see an open-source
implementation of ICE.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Thu, 26 Apr 2007 15:36:15 -0400

thanks for the comments. responses below.

> impressed how good this document has become.

Thanks. It has been a long road. This document has had more effort put 
into it (by me at least) than any document I have done since RFC 3261 
itself.

> to always do tiebreaking as the loosing side.

Based on whats in ICE-15, if one side is lite, they can never be 
controlling. In the use case for the conflict, on which I have just 
posted, if one side were lite and the other full, there would be no 
conflict. It exists only when both are full.

However, based on this lengthy ANAT discussion and the proposed 
enhancement to the lite mode, we can now have a case where two lite 
implementations talk to each other, and there is a conflict. However in 
that mode, there is also no STUN, so supporting the resolution through 
the STUN messages doesn't help.

I hope that clarifies.

> connectivity checks will indicate if they are controlling or controlled.

Correct. THis was an attempt to preserve compatibility with anyone that 
decided to go ahead and implement -13 or onwards, where they weren't 
sending this. We agreed at the ietf meeting IIRC to allow that. I can 
clarify. Text now reads:

<t>If neither ICE-CONTROLLING or ICE-CONTROLLED are present in the
request, the peer agent may have implemented a previous version of
this specification. There may be a conflict, but it cannot be
detected. </t>

> triggered check does not increase the consumed bit-rate.

I'm going to send a separate note on this issue of congestion. Its a big 
issue.

> Two solutions, a) remove comfort noise as an example. b) clarify the 

I'll add, "and in cases where both sides support it, RTP comfort noise".

> This comment also applies to section 15.4 and the password and ufrag 

I havent done this so far in protocol specs, but its not an unreasonable 
request. Here is what I propose:

foundation: 1*32ice-char  (this is a counter, unique for each interface 
and/or stun server/interface combo. 32 chars is way more than enough)

component-ID: 1*3DIGIT (it can't be more than 256)

priority: 1*10DIGIT (this is 32 bits max anyway, so it only needs 10 digits)

password: 22*1024ice-char
ufrag: 4*1024ice-char

these ones, I wanted to make really big. They are for security. I want 
to leave lots of breathing room for huge random numbers, if needed.

> take this even more serious than before.

As above, I'll treat this separately.

> N1. Section 2.6, third paragraph: Last sentence starts with what appears 

fixed.

> N2. Figure 4 and 5. Lack of directional arrows for the requests from L.

fixed.

> it clear what is being talked about.

OK.

> (O>A?1:0) is better in this context.

Yeah, bug. Fixed.

> than "Client Procedures"? Similar for 7.2.

ok.

> or "is expected to". There are no guarantees that something else causes 

ok.

> Isn't the reference to RFC 3264 wrong? Shouldn't it be to RFC 3262?

oops. fixed.

> N8. Section 16. The line breaks in the SDP example are bad and looks 

I have no control over it. rfc-ed will need to fix manually i suspect.

>      draft-ietf-sip-outbound-07

OK. I refresh my local copies of the I-D bibliography prior to each 
submission.

> isn't using them for end-host a bad choice.

OK, will change.

> I think "lower" is supposed to be "higher".

fixed.

THanks for the comments!

-Jonathan R.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Thu, 26 Apr 2007 15:56:55 -0400

This most definitely does not work. Forget about APIs, thats the 
software abstraction layer. Lets talk about networking. See below.

Benny Prijono wrote:

> But first of all, let me clarify. The candidates don't get removed; so 
> if there are N interfaces, there will still be N host candidates being 
> advertised in SDP. Only the checks that originates from the remaining 
> host candidates are being removed, during pruning process.
> 
> So even though there is only one (UDP) socket and with some more checks 
> pruned, connectivity checks will be sent from *all* interfaces. Let me 
> illustrate with an example.
> 
> So we can prune the checks further, leaving the check list in agent A to:
> 
> (it doesn't really matter which local host candidate to use, they will 
> produce the same result using this approach)

Not if the networks are not mutually connected.

If nets 2 and 3 are connected, and nets 1 and 4 are connected, but there 
is no connection between 2 and 1, or 2 and 4, and no connection between 
3 and 1 or 3 and 4, then your approach fails.

And indeed, this is a common problem when you have one interface on a 
totally private network, another on a public one. Or one on a public 
access WiFI, and another on a wired corporate network.

The whole idea with ICE is NOT to make assumptions on topology.

> 
> 
> It doesn't matter what type of interfaces are for interface 1.1.1.1 and 
> 2.2.2.2, all that matters is the routing table in the box (remember that 
> the socket is bound to INADDR_ANY), and the OS will decide for us which 
> interface to use to contact 3.3.3.3 and 4.4.4.4, if the routing table 
> says that destination 3.3.3.3 and 4.4.4.4 are indeed reachable through 
> one of its interfaces.
> 
> AFAIK this will produce *mostly* the same result as normal ICE for both 
> successful and failed scenario.
> 
> The only situation that I can think of where the result may differ is 
> when a remote candidate may be reachable from more than one local 
> interfaces (maybe two interfaces are configured in load balance mode?). 

Its the opposite. It won't work when a particular destination is 
ROUTABLE from both interfaces (meaning your local routing tables assume 
there is a route from each) but it turns out that there is only 
CONNECTIVITY from one. Almost all private networks make use of default 
routes.

This choice about using all interfaces was carefully considered for this 
reason. If you wish to implement this using just one, be my guest, but 
you are taking risks and I think its a bad idea to put this into the spec.

-Jonathan R.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Thu, 26 Apr 2007 16:09:14 -0400

My proposal for ICE is to document Dan's proposal as the RECOMMENDED 
algorithm for computing Ta in a way that makes it as good as RTP. As 
Magnus has indicated, there are many conflicting requirements here. ICE 
completing switfly is important. I think it is unreasonable to ask ICE 
to be more responsive, more cautious, than even RTP itself is.

An additional question/consideration is what about multiple media 
streams. With the frozen algorithm, we only start checks for one stream 
at a time. So if that stream is audio, this means that the checks get 
paced at the audio pace, and once video is unfrozen, we'll speed quickly 
through the video checks. That doesnt make a lot of sense either.

I'm thinking that the Ta and RTO computation would use an aggregate Ta 
that is 1/(SUM_i_from_1_to_N(1/Ta_i)) when there are N streams, each of 
which has a Ta_i computed using Dan's formula. With the existing frozen 
algorithm, this means that the total media bandwidth is utilized for the 
checks when we start, and as more streams get unfrozen, that bandwidth 
is split equally amongst them. I think this works better.

In response to Magnus' question around triggered checks, they are 
excluded from the formula and I think that makes sense. If there is 
congestion then the initial checks themselves get lost and so the 
triggering doesn't happen. Furthermore with agressive mode, you'll only 
see a small number of triggered checks get sent, regardless of the 
number of candidates.

-Jonathan R.

---

From: Magnus Westerlund <[email-masked]>
Date: Fri, 27 Apr 2007 15:31:54 +0200

> to be more responsive, more cautious, than even RTP itself is.

I think Dan's proposal points at at least on important factor. That ICE 
scales to the planned used bit-rate that way not making it worse than a 
planned RTP stream. However, the basic fact is that RTP is no wonder of 
congestion control and network friendly behavior. And the issue is that 
a wrongly configured media bit-rate may create congestion issues. But 
having some binding to session negotiated bit-rate is better than none.

I would also like to consider if there should be some upper limit on 
this, independent of the bit-rate of the media stream. Are there some 
bit-rate where ICE works well enough and making it use more and converge 
quicker isn't wort it. That way at least serious configuration errors 
will not result in extended periods of problems.

> is split equally amongst them. I think this works better.

Yes, sounds reasonable.

> see a small number of triggered checks get sent, regardless of the 

My question is what do you win with that rather than moving the 
triggered checks to the top of the paced list. That way you keep the 
rate and avoid hurting yourself more than what you would by instantly 
initiate the triggered checks.

Cheers

Magnus Westerlund

---

From: Magnus Westerlund <[email-masked]>
Date: Fri, 27 Apr 2007 15:38:17 +0200

Hi,

Issues I1 and I2 are fine with clarification and proposed text. We leave 
the congestion issue to other threads.

>> I would argue that RTP comfort noise does not readily meet it. It 
>> works in some cases, like for an audio stream where the peers both 
>> support it. Two solutions, a) remove comfort noise as an example. b) 
>> clarify the main limitations.
> 

Okay, sounds good.

>> please be changed to a upper limit on the number of characters. With 
>> the current definition I could use a 5000 digit long priority number 
>> from parsing perspective. This is likely to lead to overflow. In the 
>> case of priority as this is limited to 2^32-1 as largest number then 
>> using 1*10DIGIT seems to be without risk. I guess that also 
>> component-ID and foundation can be limited to a reasonable upper 
>> limit. Making it easier to separate the cases of potentially valid 
>> numbers and plain errors. This comment also applies to section 15.4 
>> and the password and ufrag definitions.
> 

I found the numbers reasonable. I don't see a problem with the 1024 
characters. It is simple better to know that if there are more than 1024 
characters then there is an error.

Cheers

Magnus Westerlund

---

From: Benny Prijono <[email-masked]>
Date: Sat, 28 Apr 2007 09:09:42 +0100

Thanks for the reply, Jonathan. I still can't see why it shouldn't 
work, please see below.

Jonathan Rosenberg wrote:
>> checks pruned, connectivity checks will be sent from *all* interfaces. 
>> Let me illustrate with an example.
>>

I can't see why it should fail. If I understood your case correctly, 
then my approach should find two valid pairs too (2 and 3, and 1 and 4).

I pointed out in another mail that when I said to do this 
connectivity check:

   1.1.1.1:3 --> 3.3.3.3:3

It doesn't mean that the agent will send the check from interface 
1.1.1.1, but rather to send the check from any interface (0.0.0.0) 
according to the host's routing table. The 1.1.1.1 represents the 
host candidate instance that is selected in the agent's software to 
represent this check, and it has nothing to do with the source 
address of the actual packet.

> CONNECTIVITY from one. Almost all private networks make use of default 

Okay, that's a valid case not involving API here that my approach 
may not find the connectivity.

Just for clarification and future reference, I think this is what 
you meant, routing table wise:

  net 1 via 1.1.1.1
  net 3 via net 1 metric=X
  net 2 via 2.2.2.2
  net 3 via net 2 metric=Y
  default route via 1.1.1.1

So net 3 is ROUTABLE via both interfaces, but it happens that the 
route via net 1 is down somewhere down the line and the host routing 
table is not updated.

In this case, yeah, ICE will find connectivity, and my approach won't.

> you are taking risks and I think its a bad idea to put this into the spec.

Okay since my approach won't work in all topologies, I'll rest my 
case. Thanks for pointing this out.

    -benny

-- 
Benny Prijono
http://www.pjsip.org

---

From: Benny Prijono <[email-masked]>
Date: Sat, 28 Apr 2007 09:14:22 +0100

Philip Matthews wrote:
>> the default route points to interface 1.1.1.1. Your connectivity checks
>> will fail.
>>

Actually there is another case not involving API where my approach 
fails, so yeah, my approach doesn't work in *all* cases. I'll rest 
my case.

> implementation to take a look at. I haven't had much chance to poke around

Thanks. :)

  -benny

-- 
Benny Prijono
http://www.pjsip.org

---

From: Jonathan Rosenberg <[email-masked]>
Date: Mon, 30 Apr 2007 15:55:12 -0400

inline.

Magnus Westerlund wrote:

>> Magnus has indicated, there are many conflicting requirements here. 
>> ICE completing switfly is important. I think it is unreasonable to ask 
>> ICE to be more responsive, more cautious, than even RTP itself is.
> 
> 

I think its important to mention that ICE doesn't run for the duration 
of the session. We are talking about what happens within the first few 
seconds of what may be a very long overall session. Consequently, I 
think energy is far better spent in dealing with RTP congestion issues 
than ICE.

> will not result in extended periods of problems.

OK, that is fair. I will work out a min Ta.

>> streams. With the frozen algorithm, we only start checks for one 
>> stream at a time. So if that stream is audio, this means that the 
>> checks get paced at the audio pace, and once video is unfrozen, we'll 
>> speed quickly through the video checks. That doesnt make a lot of 
>> sense either.
>>
>> that is 1/(SUM_i_from_1_to_N(1/Ta_i)) when there are N streams, each 
>> of which has a Ta_i computed using Dan's formula. With the existing 
>> frozen algorithm, this means that the total media bandwidth is 
>> utilized for the checks when we start, and as more streams get 
>> unfrozen, that bandwidth is split equally amongst them. I think this 
>> works better.
> 
> 
> Yes, sounds reasonable.
> 
>>
>> triggering doesn't happen. Furthermore with agressive mode, you'll 
>> only see a small number of triggered checks get sent, regardless of 
>> the number of candidates.
>>
>>
> 

Its not just new transactions; in most cases a triggered check is a 
retransmit of a transaction already in progress. Pacing those along with 
periodic checks requires me to mix both of those things into a single 
mechanism, which I don't like. I prefer a cleaner separation of ICE and 
STUN.

-Jonathan R.

---

From: "Dan Wing" <[email-masked]>
Date: Mon, 30 Apr 2007 16:16:22 -0700

> > I would also like to consider if there should be some upper limit
> > on this, independent of the bit-rate of the media stream.  Are
> > there some bit-rate where ICE works well enough and making it use
> > more and converge quicker isn't wort it.  That way at least
> > serious configuration errors will not result in extended periods
> > of problems.
>

The original reason for Ta was to prevent killing some NATs which
couldn't deal with a bunch of new UDP translations close together.
This text justifying Ta's value is still in ICE, as you know.

But Magnus is looking at the overall bit rate, so I think we
need a minimum value for both Ta (initial delay) and for RTO
(STUN retransmit interval).  I played with the spreadsheet a 
bit and Ta=20ms and RTO=100ms cause ICE to converge quickly
and might well be good minimum values (those are the values
in ice-15).  With 10 candidate pairs and those values you
get:

  time    ICE activity
  ----    ------------
    0     STUN Binding Request (C1)
   20     STUN Binding Request (C2)
   40     STUN Binding Request (C3)
   60     STUN Binding Request (C4)
   80     STUN Binding Request (C5)
  100     STUN Binding Request (C6), retransmit of C1
  120     STUN Binding Request (C7), retransmit of C2
  140     STUN Binding Request (C8), retransmit of C3
  160     STUN Binding Request (C9), retransmit of C4
  180     STUN Binding Request (C10), retransmit of C5
  200     retransmit of C6
  220     retransmit of C7
  240     retransmit of C8
  260     retransmit of C9
  280     retransmit of C10

STUN's retransmit timer doubles after that (300ms, 500ms), so you'll get
continual grouping of those retransmits until the client gives up or until
an ICE candidate gets a response.

-d

---

From: Magnus Westerlund <[email-masked]>
Date: Tue, 01 May 2007 02:58:39 +0200

Jonathan Rosenberg skrev:
>>> ICE completing switfly is important. I think it is unreasonable to 
>>> ask ICE to be more responsive, more cautious, than even RTP itself is.
>>
>>
>> I think Dan's proposal points at at least on important factor. That 
>> ICE scales to the planned used bit-rate that way not making it worse 
>> than a planned RTP stream. However, the basic fact is that RTP is no 
>> wonder of congestion control and network friendly behavior. And the 
>> issue is that a wrongly configured media bit-rate may create 
>> congestion issues. But having some binding to session negotiated 
>> bit-rate is better than none.
> 

There are two issues here as I see it. First, that ICE will congest
itself if you run it over low-bandwidth paths. Secondly, that it doesn't
do serious harm to other traffic. It is a very hard problem to
congestion control ICE. That as why I at least like to have some real
numbers on what it does, and put in the right nobs for a max rate and
lower rate when you know you have slow interfaces.

But I agree that having adaptive RTP traffic is actually more important.
  However, ICE is protocol here and now that we can affect and ensure
that we done the most reasonable solution for congestion control. That
means that we actually need some fair understanding for how the dynamics
of ICE is. Which do requires that one do some simulations and studies.

> retransmit of a transaction already in progress.

I had forgotten this. And the reason for doing that is that it is quite
likely that the previous transmission was dropped in the NAT where now a
binding exist?

> Pacing those along with 

I can, understand that. You still have an interface question for the
triggered checks, where ICE needs to tell an ongoing STUN transaction
that the check should be retransmitted. Not complicating that case is fine.

However for all the other cases from the list in section 7.2.1.4 using
pacing to start the triggered checks seems easy to implement. It also
appears there is a good reason for pacing as it prevents multiple
triggered checks to significantly increase the bit-rate consumed. But I
would appreciate more data how this actually play out in a case where
there is multiple medias in a session. Because to me it appears that
when a peer finds the combination of interfaces that works, it will
start unfreezing a lot of candidates that will get through and
triggered checks. I would really appreciate some simulation data for
cases that are a bit more extreme when it comes to the number of
candidates and medias.

Cheers

Magnus Westerlund