Subject: [MMUSIC] review of ICE-13

From: "Dan Wing" <[email-masked]>
Date: Fri, 19 Jan 2007 16:29:56 -0800

An impressive document, Jonathan.

Primary comment:

* After doing a binding discovery, the agent needs to keep those
  bindings open until it's sure they're no longer used.  Consider the
  case of a little old lady from Pasadena who takes 35 seconds to type
  in a phone number; if you obtained the binding as soon as she went
  offhook, the binding will have timed out by the time the Invite is
  sent.  Similarly, SIP retransmissions could cause a healthy delay in
  the Invite reaching the called party or all of the called parties
  (when forking) or the final target (if retargeting).

  I suggest this keepalive should be a STUN Binding Request, so that 
  if an implementation keeps this binding open for a long time it 
  is aware of a reassignment of public transport address by the NAT
  (due to NAT crashing, new DHCP lease for the NAT, whatever).

General comments:  

* As Eric said, more headings and lists would be useful; some of these
  sections run two pages and the text is dense.

* I noticed both "lite" and "passive" are used almost interchangably
  in the document, with the intention they mean the same thing.  It
  would be useful to eliminate one of those terms.

* I found using "L" and "R" to refer to the agents a bit confusing
  because it's difficult to say a sentence like "R takes its local
  candidate and sends it its remote peer, L".  I did notice some of
  the examples use A and B, and others use L and R.  It would be
  useful to stick with one unless there is a reason to switch between
  A/B and L/R.

* Run http://tools.ietf.org/tools/idnits/ against the document;
  boilerplate is wrong, a few lines exceed the maximum.

* In several places different terminology was used which appears to
  mean the same thing:
  - Triggered / tentative
  - Ignore duplicates / prune / eliminate redundant candidates
  - Intermediary / media relay / (and "gateway", when talking about
    the SIP option tag in 12.2).
  - Active / in-use
  - Lite / passive / passive-only
  - Callee / answerer (in section 12)

* Is the plan for TURN, or for ICE, to explain that TURN is only
  needed if the two agents are behind NATs that perform Address and
  Port Dependent Mapping (previously called "symmetric NAT")?  Right
  now there isn't a discussion of this in ICE, but it might be useful
  to provide guidance on when the 'provider variance' is permissable.

* There isn't a discussion of what happens when a lite implementation
  encounters a lite implementation.  I assume there aren't any
  connectivity checks sent by either side.  (Should be added to 5.2)

Detailed nits and suggestions:

> Abstract
>
>   This document describes a protocol for Network Address Translator
>   (NAT) traversal for multimedia session signaling protocols based on
>   the offer/answer model, such as the Session Initiation Protocol
>   (SIP).  This protocol is called Interactive Connectivity
>   Establishment (ICE).  ICE makes use of the Session Traversal
>   Utilities for NAT (STUN) protocol, applying its binding discovery and
>   relay usages, 

add "and keepalive usage,"

> in addition to defining a new usage for checking
>   connectivity between peers.

...
> 2.  Overview of ICE

>   Figure Figure 1 shows a typical environment for ICE deployment.  The
    ^^^^^^^^^^^^^^^
    duplicated

>   two endpoints are labelled L and R (for left and right, which helps
>   visualize call flows). 

It does help visualizing the flow, but it's also difficult to think
of phrases like "R takes its local candidate and sends it its
remote peer, L" in your head.  A nit, but I would be more comfortable 
with A and B instead of L and R.

> Both L and R are behind NATs -- though as

"behind NATs" -> "behind their own respective NATs"

...
> 2.1.  Gathering Candidate Addresses
...
> Note

Does this "Note" apply to just the next paragraph, or to the rest of section
2.1?  Indenting would help clarify.  I think it is intended to only apply to
the next paragraph.

>   "Base" refers to the address you'd send from for a particular
>   candidate.  Thus, as a degenerate case host candidates also have a
>   base, but it's the same as the host candidate.
>
>   When there are multiple NATs between the agent and the STUN server,
>   the STUN request will create a binding on each NAT, but only the
>   outermost server reflexive candidate will be discovered by the agent.
>   If the agent is not behind a NAT, then the base candidate will be the
>   same as the server reflexive candidate and the server reflexive
>   candidate can be ignored.

In section 4.1.1, "Gatering Candidates", the text reads:

  >   Next, the agent eliminates redundant candidates.  A candidate is
  >   redundant if its transport address equals another candidate, and its
  >   base equals the base of that other candidate.  Note that two
  >   candidates can have the same transport address yet have different
  >   bases, and these would not be considered redundant.

Is this what you mean by "ignore"?  If so, using consistent terminology
would help; it seems it isn't really ignored.

Question:  does learning you're not behind a NAT mean that you MAY, MAY NOT,
SHOULD, or MUST go into 'lite' mode?  

>   The final type of candidate is a RELAYED candidate.  The STUN Relay
>   Usage [12] allows a STUN server to act as a media relay, forwarding
>   traffic between L and R. In order to send traffic to L, R sends
>   traffic to the media relay which forwards it to L and vice versa.
>   The same thing happens in the other direction.

That last sentence gave me deja vu with vice versa.

...
> 2.3.  Sorting Candidates
>
>   Because the algorithm above searches all candidate pairs, if a
>   working pair exists it will eventually find it no matter what order
>   the candidates are tried in.  In order to produce faster (and better)
>   results, the candidates are sorted in a specified order.  The
>   algorithm is described in Section 4.1.2 but follows two general
>   principles:
>
>   o  Each agent gives its candidates a numeric priority which is sent
>      along with the candidate to the peer
>
>   o  The local and remote priorities are combined so that each agent
>      has the same ordering for the candidate pairs.
>
>   The second property is important for getting ICE to work when there
>   are NATs in front of A and B.

"A and B" -> "L and R".

>   Frequently, NATs will not allow packets
>   in from a host until the agent behind the NAT has sent a packet
>   towards that host.  Consequently, ICE checks in each direction will
>   not succeed until both sides have sent a check through their
>   respective NATs.
>
>   In general the priority algorithm is designed so that candidates of
>   similar type get similar priorities and so that more direct routes

add:  "(that is, through fewer media relays and through fewer NATs)"

>   are preferred over indirect ones.  Within those guidelines, however,
>   agents have a fair amount of discretion about how to tune their
>   algorithms.
>
> 2.4.  Frozen Candidates
>
>   The previous description only addresses the case where the agents
>   wish to establish a single media component--i.e., a single flow with
>   a single host-port quartet.  However, in many cases (in particular
>   RTP and RTCP) the agents actually need to establish connectivity for
>   more than one flow.
>
>   The naive way to attack this problem would be to simply do
>   independent ICE exchanges for each media component.  This is
>   obviously inefficient because the network properties are likely to be
>   very similar for each component (especially because RTP and RTCP are
>   typically run on adjacent ports

The port adjacency isn't really why RTP and RTCP are going to take the same
path; rather, it's because they're used on the same interface and use the
same protocol (UDP).  Besides, later in the document you clearly indicate
RFC3605 (a=rtcp) is needed, so this port adjacency is moot.  I suggest,
instead:

  "(especially because RTP and RTCP are sent and received 
   from the same IP address)"

>).  Thus, it should be possible to
>   leverage information from one media component in order to determine
>   the best candidates for another.  ICE does this with a mechanism
>   called "frozen candidates."
...
> 2.5.  Security for Checks
>
>   Because ICE is used to discover which addresses can be used to send
>   media between two agents, it is important to ensure that the process
>   cannot be hijacked to send media to the wrong location.  Each STUN
>   connectivity check is covered by a message authentication code (MAC)
>   computed using a key exchanged in the signalling channel.  This MAC
>   provides message integrity and data origin authentication, thus
>   stopping an attacker from forging or modifying connectivity check
>   messages.  The MAC also aids in disambiguating ICE exchanges from
>   forked calls.

Need a reference to forked calls for readers unfamiliar with this 
aspect of SIP.  It's important for ICE implementations to expect
calls to fork and to expect, as a normal event, STUN Connectivity
Checks arriving from many different source transport addresses.

> 2.6.  Concluding ICE
>
>   ICE checks are performed in a specific sequence, so that high
>   priority pairs 

"of candidates"

> are checked first, followed by lower priority ones.
>   One way to conclude ICE is to declare victory as soon as a check for
>   each component of each media stream completes successfully.  Indeed,
>   this is a reasonable algorithm, and details for it are provided
>   below.  However, it is possible that packet losses will cause a
>   higher priority check to take longer to complete, and allowing ICE to

change to:
  "... check to take longer to complete.  In that case, allowing ICE ..."

...
>   Once ICE is concluded, it can be restarted at any time for one or all
>   of the media streams by each agent.  This is done by sending an
                         ^^^^^^^^^^^^^
I think you want "by either agent".  I believe this aspect is only
really mentioned here in the overview.  If you want "either agent" to
be able to send a new offer, it should also be clearly stated in 
section 9 ("Subsequent Offer/Answer Exchanges" that either agent can 
generate a new offer and restart ICE.

>   updated offer indicating a restart.
>
> 2.7.  Lite Implementations
>
>   In order for ICE to be used in a call, both agents need to support
>   it.  However, certain agents, such as those in gateways to the PSTN,
>   media servers, conferencing servers, and voicemail servers, are known
>   to not be behind a NAT or firewall. 

Citing specific examples of equipment is frightening.  Consider that
most voicemail servers deployed by most enterprises are, in fact,
behind the Enterprise's NAT box.  Vendors will point to this sentence
and explain they are "compliant" with their lite implementation.  This
is bad.  

How about, instead, saying that devices which are only ever deployed
on the public Internet only need a lite implementation?

You had good text in Appendix A that needs to be moved here to section 2.7.
It is:

   Consequently, a lite implementation is only appropriate for devices
   that will always be connected to the public Internet and have a
   public IP address at which it can receive packets from any
   correspondent.  ICE will not function when a lite implementation is
   placed behind a NAT.

Consider moving all of Appendix A up here to introduce the difference
between a Full and Lite implementation, as it seems too important to hide in
the Appendix.

...
>   Foundation: Each candidate has a foundation, which is an identifier
>      that is distinct for two candidates that have different types,
>      different interface IP addresses for their base, and different IP
>      addresses for their STUN servers.  Two candidates have the same
>      foundation when they are of the same type, their bases have the
>      same IP address, and, for server reflexive or relayed candidates,
>      they come from the same STUN server.  Foundations are used to
>      correlate candidates, so that when one candidate is found to be
>      valid, candidates sharing the same foundation can be tested next,
>      as they are likely to also be valid.

(Wow, that is a complicated definition.)

It isn't clear, reading this, if a foundation is something that is
communicated in SDP, communicated in the STUN messages between peers,
or derived from information in the SDP or STUN messages.

> 3.  Terminology
...
>   Server Reflexive Candidate: A candidate obtained by sending a STUN
>      request from a host candidate to a STUN server, distinct from the
>      peer, whose address is configured or learned by the client prior
           ^^^^^^^^^^^^^^^
           .  The STUN server's address

>      to an offer/answer exchange.

...
> 4.  Sending the Initial Offer
>
>   In order to send the initial offer in an offer/answer exchange, an
>   agent must gather candidates, priorize them, choose ones for
>   inclusion in the m/c-line,

"line" -> "lines"

> and then formulate and send the SDP.  The
>   first of these three steps differ for full and lite implementations.

I counted 4 or 5 steps, depending on how I count.

I agree with Eric -- separate headings would really help, especially for the
candidate gathering which you said differs from Lite and Full
implementations, but I have to read all 10 paragraphs to see what is
different.

> 4.1.  Full Implementation Requirements
>
> 4.1.1.  Gathering Candidates

At about the middle of this section you mention you're describing STUN's
Binding Discovery usage.  This should be done earlier.

...
>   Agents SHOULD obtain relayed candidates and MUST obtain server
>   reflexive candidates.  The requirement to obtain relayed candidates
>   is at SHOULD strength to allow for provider variation.  
                                       ^^^^^^^^^^^^^^^^^^

The real reason is if you somehow know you aren't behind a Address and Port
Dependent Mapping NAT, or if you cannot get a media relay for some reason
(costs too much, nobody is your friend, whatever).   

...
>   The agent next pairs each host candidate with the STUN server with
>   which it is configured or has discovered by some means.  This
>   specification only considers usage of a single STUN server.  Every Ta
>   seconds, the agent chooses another such pair (the order is

"seconds" -> "milliseconds"

>   inconsequential), and sends a STUN request to the server from that
>   host candidate. 

"host candidate" -> "base" ??

> If the agent is using both relayed and server
>   reflexive candidates

add "with that STUN server"

>, this request MUST be a STUN Allocate request
>   from the relay usage [12].  If the agent is using only server
>   reflexive candidates, the request MUST be a STUN Binding request
>   using the binding discovery usage [11].

Nit:  In the two sentences above, they end with 

  "... from the relay usage."
and
  "... using the binding discovery usage."

I don't have a preference, but using "from" or "using" would read easier.

>   The value of Ta SHOULD be configurable, and SHOULD have a default of
>   20ms.  

Provide forward reference to section B.1, "Timing of STUN Transactions".

> Note that this pacing applies only to starting STUN
>   transactions with source and destination transport addresses (i.e.,
>   the host candidate and STUN server respectively) for which a STUN
>   transaction has not previously been sent.  Consequently,
>   retransmissions of a STUN request are governed entirely by the
>   retransmission rules defined in [11].  Similarly, retries of a
>   request due to recoverable errors (such as an authentication
>   challenge) happen immediately and are not paced by timer Ta.  Because
>   of this pacing, it will take a certain amount of time to obtain all
>   of the server reflexive and relayed candidates.  Implementations
>   should be aware of the time required to do this, and if the
>   application requires a time budget, limit the amount of candidates
>   which are gathered.
>
>   An Allocate Response will provide the agent with a server reflexive

Insert at the beginning of this paragraph:

  "The agent will receive a STUN Binding or Allocate response."

>   candidate (obtained from the mapped address) and a relayed candidate
>   in the RELAY-ADDRESS attribute.  A Binding Response will provide the
>   agent with only a server reflexive candidate (also obtained from the
>   mapped address).  The base of the server reflexive candidate is the
>   host candidate from which the Allocate or Binding request was sent.
>   The base of a relayed candidate is that candidate itself.  A server
>   reflexive candidate obtained from an Allocate response is the called
>   the "translation" of the relayed candidate obtained from the same
>   response.

The word "translation" only occurs one other place in the document.  Can we
nuke it?

...
> 4.1.2.  Prioritizing Candidates
>
>   The prioritization process results in the assignment of a priority to
>   each candidate.  Each candidate for a media stream MUST have a unique
>   priority.  An agent SHOULD compute the priority by determining a
>   preference for each type of candidate (server reflexive, peer
>   reflexive, relayed and host), and, when the agent is multihomed,
>   choosing a preference for its interfaces.  These two preferences are
>   then combined to compute the priority for a candidate.  That priority
>   SHOULD be computed using the following formula:
    ^^^^^^
In the overview (section 2), it was said there was leeway in using
different schemes.  The SHOULD implies that interoperability will
break if this formula isn't used.  Can you provide additional guidance
on the importance of following this formula, or a forward reference
to an appendix section that discusses how to use a different priority
scheme?

>   priority = (2^24)*(type preference) +
>              (2^8)*(local preference) +
>              (2^0)*(256 - component ID)
>
>
>   The type preference MUST be an integer from 0 to 126 inclusive, and
>   represents the preference for the type of the candidate (where the
>   types are local, server reflexive, peer reflexive and relayed).  A
>   126 is the highest preference, and a 0 is the lowest.  Setting the
>   value to a 0 means that candidates of this type will only be used as
>   a last resort.  The type preference MUST be identical for all
>   candidates of the same type and MUST be different for candidates of
>   different types.  The type preference for peer reflexive candidates
>   MUST be higher than that of server reflexive candidates.  Note that
>   candidates gathered based on the procedures of Section 4.1.1 will
>   never be peer reflexive candidates; candidates of these type are
>   learned from the STUN connectivity checks performed by ICE.  The
>   component ID is the component ID for the candidate, and MUST be
>   between 1 and 256 inclusive.  The local preference MUST be an integer
>   from 0 to 65535 inclusive.  It represents a preference for the
>   particular interface from which the candidate was obtained, in cases
>   where an agent is multihomed. 65535 represents the highest
>   preference, and a zero, the lowest.  When there is only a single
>   interface, this value SHOULD be set to 65535.  Generally speaking, if
>   there are multiple candidates for a particular component for a
>   particular media stream which have the same type, the local
>   preference MUST be unique for each one.  

That last sentence reads:

  "Generally speaking, ... MUST be unique"

Should that be a SHOULD, or can you better qualify the "Generally speaking"
into an if/then clause?

...
>   additional router hops that may be taken.  It may increase the cost
>   of providing service, since media will be routed in and right back
>   out of an intermediary run by the provider. 
           ^^^^^^^^^^^^^^^
a media relay

...
>   Another criteria for selection of preferences is IP address family.
>   ICE works with both IPv4 and IPv6.  It therefore provides a
>   transition mechanism that allows dual-stack hosts to prefer
>   connectivity over IPv6, but to fall back to IPv4 in case the v6
>   networks are disconnected (due, for example, to a failure in a 6to4
>   relay) [23].  It can also help with hosts that have both a native
>   IPv6 address and a 6to4 address.  In such a case, lower local
                                                      ^^^^^
  "higher" ?

>   preferences could be assigned to the v6 interface, followed by the
>   6to4 interfaces, followed by the v4 interfaces.  This allows a site
>   to obtain and begin using native v6 addresses immediately, yet still
>   fallback to 6to4 addresses when communicating with agents in other
>   sites that do not yet have native v6 connectivity.

...
> 4.1.3.  Choosing In-Use Candidates
...
>   An agent MUST choose a set of candidates, one for each component of
>   each active media stream, to be in-use.  A media stream is active if
>   it does not contain the a=inactive SDP attribute.

active = in-use?

The paragraph and section 5.7 appear to both be defining in-use, but
their definition is different.  5.7 says port 0, bandwidth of 0 
mean it's still in-use from ICE's perspective.  Section 9.1 prohibits
an ICE endpoint from using 0.0.0.0 in a subsequent O/A, and says
port=0 means a=candidate can't be used.  I expect a=candidate with
port=0 is also prohibited in an initial offer, but nothing seems
to jump out and say that like 9.1 says it.

It would be useful to have an appendix section, which is forward
referenced in 4.1.3 and in 9.1, that explains why bandwidth=0, 
0.0.0.0, port=0 are all considered 'active' from ICE's perspective.  
(I believe the reason is so that when the stream becomes active 
for the endpoint with another O/A, we don't need to restart ICE 
and wait for ICE's delay).

...
>   Indeed, the difficulty in picking just one transport address that
>   will work is the whole problem that motivated the development of this
>   specification in the first place.  As such, it is RECOMMENDED that
>   agents select relayed candidates to be in-use.

insert:

  " (if relayed candidates are available), server 
   reflexive candidates (if server reflexive candidates 
   are available), and finally host candidates."

> 4.2.  Lite Implementation
>
>   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 is multi-homed, it MUST choose one of its interfaces for a
>   particular media stream;

insert "because with the Lite implementation, "

> 4.3.  Encoding the SDP
>
>   The process of encoding the SDP is identical between full and lite
>   implementations.
>
>   The agent includes a single a=candidate media level attribute in the
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>   SDP for each candidate for that media stream. 

The use of 'single' was confusing; it reads as if only one a=candidate can
be included.  How about:

  "The agent includes an a=candidate media leval attribute for 
   each candidate for each media stream in the SDP".

> The a=candidate
>   attribute contains the IP address, port and transport protocol for
>   that candidate.  A Fully Qualified Domain Name (FQDN) for a host MAY
>   be used in place of a unicast address.  
                          ^^^^^^^^^^^^^^^
This is the only place where "unicast" appears in the document.  Can
we nuke it?  It implies ICE is only useable for unicast (which is 
probably true).

> In that case, when receiving
>   an offer or answer containing an FQDN in an a=candidate attribute,
>   the FQDN is looked up in the DNS using an A or AAAA record, and the
>   resulting IP address is used for the remainder of ICE processing.
>   The candidate attribute also includes the component ID for that
>   candidate.  For media streams based on RTP, candidates for the actual
>   RTP media MUST have a component ID of 1, and candidates for RTCP MUST
>   have a component ID of 2.  Other types of media streams which require
>   multiple components MUST develop specifications which define the
>   mapping of components to component IDs, and these component IDs MUST
>   be between 1 and 256.

A forward reference to the section 14 ("extensibility considerations") would
be useful.  There, you should provide guidance on the meaning of the
component ID values (the lowest numbered one is attempted first; except ...)
... I noticed that section 9.3.1 has a special meaning for the value 1:

  >   Next, the agent goes through each check list, starting with the
  >   highest priority check.  If a check has a state of Succeeded, and it
  >   has a component ID of 1, then all Frozen checks in the same check
  >   list with the same foundation whose component IDs are not one, have
  >   their state set to Waiting.  If, for a particular check list, there
  >   are checks for each component of that media stream in the Succeeded
  >   state, the agent moves the state of all Frozen checks for the first
  >   component of all other media streams (and thus in different check
  >   lists) with the same foundation to Waiting.

The extensibility section needs to explain if "1" has a special meaning
(which it does per 9.3.1).

>   The candidate attribute also includes the priority and the
>   foundation.  The agent SHOULD include a type for each candidate by
>   populating the candidate-types production with the appropriate value
                                   ^^^^^^^^^^

Nit: I stumbled over the word "production"; RFC4234 (ABNF) doesn't use the
term "production".  I do see that several RFCs in the 4000's use it with the
same meaning you have.  RFC4234 recommends enclosing the term in "<>" when
used in prose, which seems to help legibility, like this:

  ... populating <candidate-types> with the appropriate value

>   - "host" for host candidates, "srflx" for server reflexive
>   candidates, "prflx" for peer reflexive candidates (though these never
                                                       ^^^^^^^^^^^^^^^^^^
>   appear in an initial offer/answer exchange), 
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A lite implementation would use its "host" candidate in its initial 
o/a exchange.

But even for a full implementation, I don't understand why it wouldn't
include a=candidate for its server reflexive candidate -- that's the address
on the public side of its NAT.

>   and "relay" for relayed candidates. 

As Eric said, and I'd like to re-iterate:  what is the reason for
doing this?  Nothing seems to take advantage of this information.  

...
>   There MUST be a candidate attribute for each component of the media
                    ^^^^^^^^^^^^^^^^^^^          ^^^^^^^^^
>   stream in the m/c-line.

Does this mean that a "component" is a "candidate", or does it mean
there is a 1:1 relationship between "component" and "candidate"?

>   Once an offer or answer are sent, an agent MUST be prepared to
>   receive both STUN and media packets on each candidate. 

Vague; does this mean once both an offer and an answer have been sent,
or does this mean that from the perspective of each agent, when it sent
its offer or it sent its answer?  I suggest:

  Once an agent has sent its offer or sent its answer, that agent
  MUST be prepared ...

> As discussed
>   in Section 11.1, media packets can be sent to a candidate prior to
>   its appearence in the m/c-line.

  add, at the end, "of the original offer/answer or a subsequent
offer/answer".

> 5.  Receiving the Initial Offer
>
>   When an agent receives an initial offer, it will check if the offeror
>   supports ICE, determine its role, 

"determints its role" -> "determins the offerer's role"

...
> 5.2.  Determining Role
...
>   If one of the agents is a lite implementation, it MUST assume the
>   controlled role, and its peer (which will be full) MUST assume the
>   controlling role. 

We won't ever have a "lite" calling a "lite"?

>   If the agent and its peer are both full
>   implementations, the agent which generated the offer which started
>   the ICE processing takes on the controlling role, and the other takes
>   the controlled role.
>
>   Based on this definition, once roles are determined for a session,
>   they persist unless ICE is restarted, as discussed below.  A restart
>   causes a new selection of roles.

  "An ICE restart [section 9] causes a new selection of roles."

> 5.3.  Gathering Candidates
>
>   The process for gathering candidates at the answerer is identical to
>   the process for the offerer as described in Section 4.1.1 for full
>   implementations and Section 4.2 for lite implementations.  It is
>   RECOMMENDED that this process begin immediately on receipt of the
>   offer, prior to user acceptance of a session. 
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

"Alerting" is used in RFC3261 and in section 12.1 of this document; would
"alerting the user" be better than "acceptance of a session"?

...
> 5.7.  Forming the Check Lists
>
>   Forming check lists is done only by full implementations.  Lite
>   implementations MUST skip the steps defined in this section.
>
>   There is one check list per in-use media stream resulting from the
>   offer/answer exchange.  A media stream is in-use as long as its port
>   is non-zero (which is used in RFC 3264 to reject a media stream).
>   Consequently, a media stream is in-use even if it is marked as
>   a=inactive or has a bandwidth value of zero.  Each check list is a
>   sequence of STUN connectivity checks that are performed by the agent.
>   To form the check list for a media stream, the agent forms candidate
>   pairs, computes a candidate pair priority, orders the pairs by
>   priority, prunes them, and sets their states.  These steps are
              ^^^^^^^^^^^
"pruning" is eliminating duplicates, or something else?  ("Prune" and
"pruning" appear only twice in the document, and neither normatively
explain dried plums (prunes).)

>   described in this section.

Separate headings or bullets would really help this section.  This one
section has two paragraphs that start with "First, ".

...
>   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.  This formula ensures a unique priority
>   for each pair in most cases.  One the priority is assigned, the agent
                                  ^^^
                                  Once

>   sorts the candidate pairs in decreasing order of priority.  If two
>   pairs have identical priority, the ordering amongst them is
>   arbitrary.

>   This sorted list of candidate pairs is used to determine a sequence
>   of connectivity checks that will be performed.  Each check involves
>   sending a request from a local candidate to a remote candidate.
>   Since an agent cannot send requests directly from a reflexive
>   candidate, but only from its base, the agent next goes through the
>   sorted list of candidate pairs.  For each pair where the local
>   candidate is server reflexive, the server reflexive candidate MUST be
>   replaced by its base.  Once this has been done, the agent MUST remove
>   redundant pairs.  A pair is redundant if its local and remote
>   candidates are identical to the local and remote candidates of a pair
>   higher up on the priority list. 

I believe the last 3 sentences, which are embedded in this paragraph,
are describing the "pruning" step (a.k.a. "elimination of duplicates",
yes), yes?  If so, those sentences need to be pulled into its own 
header or section or bullet.

> The result is called the check list
>   for that media stream, and each candidate pair on it is called a
>   check.
>
>   Each check is also said to have a foundation, which is merely the
>   combination of the foundations of the local and remote candidates in
>   the check.
>
>   Each check in the check list is associated with a state.  This state
>   is assigned once the check list for each media stream has been
>   computed.  There are five potential values that the state can have:

Previous two paragraphs can be simplified and combined, thusly:

  Each check has a foundation and a state.  The foundation is the
  combination of the local and remote candidates in the check.
  The state is assigned once the check list for each media stream
  has been computed.  There are five states:

...
>   First, the agent sets all of the checks in each check list to the
>   Frozen state.  Then, it takes the first check in the check list for
>   the first media stream (a media stream is the first media stream when
>   it is described by the first m-line in the SDP offer and answer),

This parenthetical comment was important for the offerer to know when
it was formings its SDP.  It would be useful to place it there 
(section 4.3), to encourage the offerer to put the media lines it 
wants ICE to complete first in the front (for example, audio 
before video before whiteboarding, so we can all say "hello, do 
you see me yet" or whatever).

...

> 5.8.  Performing Periodic Checks

"Performing Initial Periodic Checks"?  

>   Checks are generated only by full implementations.  Lite
>   implementations MUST skip the steps described in this section.
>
>   An agent performs two types of checks.  The first type are periodic
>   checks.  These checks occur periodically for each media stream, and
>   involve choosing the highest priority check in the Waiting state from
>   each check list, and performing it.  The other type of check is
>   called a triggered check.  This is a check that is performed on
>   receipt of a connectivity check from the peer.  This section
>   describes how periodic checks are performed.

I noticed there is no section called "Performing Triggered Checks".  There
should be.  The text appears to be in section 7.2.1, "Additional Procedures
for Full Implementations".

>   Once the agent has computed the check lists as described in
>   Section 5.7, it sets a timer for each active check list.  The timer
>   fires every Ta/N seconds, where N is the number of active check lists
>   (initially, there is only one active check list). 

Need a discussion of how Ta/N milliseconds was derived, perhaps in an
Appendix, with a forward reference.

> Implementations
>   MAY set the timer to fire less frequently than this.  Ta is the same
>   value used to pace the gathering of candidates, as described in
>   Section 4.1.1.  The first timer for each active check list fires
>   immediately, so that the agent performs a connectivity check the
    ^^^^^^^^^^^
>   moment the offer/answer exchange has been done, followed by the next
>   periodic check Ta seconds later.

This 'immediate' seems to conflict with the 'immediate' in section 5.3,
"Gathering Candidates".  Is it best to gather candidates first, or send
connectivity checks?  The end of section 7.2.1 requires the offerer to wait
until it sees the SDP (containing the answerer's ICE password), so nothing
can really happen until the offerer receives the answer, I guess.  Maybe the
order isn't important.

Question:  is the answerer's first binding discovery packet (to its STUN
server) paced Ta milliseconds from its first connectivity check to its peer?

>   When the timer fires, the agent MUST find the highest priority check
>   in that check list that is in the Waiting state.  The agent then
>   sends a STUN check from the local candidate of that check to the
>   remote candidate of that check.  The procedures for forming the STUN
>   request for this purpose are described in Section 7.1.1.  If none of
>   the checks in that check list are in the Waiting state, but there are
>   checks in the Frozen state, the highest priority check in the Frozen
>   state is moved into the Waiting state, and that check is performed.
>   When a check is performed, its state is set to In-Progress.  If there
>   are no checks in either the Waiting or Frozen state, then the timer
>   for that check list is stopped.

It's awkward how RFC3489bis's connectivity check retries work with 
ICE's timer.  Not sure how to resolve that, though.

>   Performing the connectivity check requires the agent to know the
>   username fragment for the local and remote candidates, and the
>   password for the remote candidate.  For periodic checks, the remote
>   username fragment and password are learned directly from the SDP
>   received from the peer, and the local username fragment is known by
>   the agent.
>
> 6.  Receipt of the Initial Answer
>
>   This section describes the procedures that an agent follows when it
>   receives the answer from the peer.  It verifies that its peer
>   supports ICE, determines its role, 
                  ^^^^^^^^^^^^^^^^^^^
              "determines its peer's role,"

> and for full implementations,
>   forms the check list and begins performing periodic checks.
>
> 6.1.  Verifying ICE Support
>
>   The answerer will proceed with the ICE procedures defined in this
>   specification if there is at least one a=candidate attribute for each
>   media stream in the answer it just received.  If this condition is
>   not met, the agent MUST process the SDP based on normal RFC 3264
>   procedures, without using any of the ICE mechanisms described in the
>   remainder of this specification, with the exception of Section 10,
>   which describes keepalive procedures.

I noticed section 5.1 ("Verifying ICE Support") requires an a=candidate that
matches its m/c line, but 6.1 doesn't have that requirement.  I assume
that's on purpose.

> 7.  Connectivity Checks
>
>   This section describes how connectivity checks are performed.  All
>   ICE implementations are required to be compliant to [11], as opposed
>   to the older [14].  However, whereas a full implementation will both
>   generate checks (acting as a STUN client) and receive them (acting as
>   a STUN server), a lite implementation will only ever receive checks,
>   and thus will only act as a STUN server.

Should there be a forward reference, from section 5.8, "Performing Periodic
Checks", to this section?

> 7.1.  Client Procedures
>
>   These procedures define how an agent sends a connectivity check,
>   whether it is a periodic or a triggered check.  These procedures are
>   only applicable to full implementations.
>
> 7.1.1.  Sending the Request
>
>   The agent acting as the client generates a connectivity check either
                        ^^^^^^^^^^
                      the STUN client?

>   periodically, or triggered. 
                     ^^^^^^^^^

If an agent was triggered, it was acting as a STUN server just a split
second ago (it received a connectivity check).

Maybe delete that first sentence entirely?

> In either case, the check is generated
>   by sending a Binding Request from a local candidate, to a remote
>   candidate.  The agent must know the username fragment for both
                              ^^^^^^^^^^^^^^^^^
                              transport address

>   candidates and the password for the remote candidate.
  ^^^^^^^^^^^^
  local and remote candidates

(Knowing the transport address is sortof obvious, but it allows
us to explain two ways to "know" it:  SDP or a receipt of a 
connectivity check (which causes us to initiate a triggered 
check)).

...
> 7.1.2.  Processing the Response
>
>   If the STUN transaction generates an unrecoverable failure response

What is a failure response?  I expect it includes ICMP hard errors.
Maybe ICMP soft errors?  I expect it includes STUN errors.  Would be
good to enumerate them.

>   or times out, the agent sets the state of the check to Failed.  The
>   remainder of this section applies to processing of successful
>   responses (any response from 200 to 299).
               ^^^^^^^^^^^^
             any STUN response

...
> 7.2.  Server Procedures
>
>   An agent MUST be prepared to receive a Binding Request on the base of
>   each candidate it included in its most recent offer or answer.
>   Receipt of a Binding Request on a transport address that the agent
>   had included in a candidate attribute is an indication that the

"a transport address that the agent had included in a candidate attribute"
is going to be received by the "base", right?  Can we just say "base"?

>   connectivity check usage applies to the request.

The meaning is the same in 17.3, but the wording is different.  Here is
17.3:

  > The server is aware of this usage because it signaled this port
  > through the offer/answer exchange.  Any STUN packets received on this
  > port will be for the connectivity check usage.

It'd be good to have identical wording, or just forward reference 17.3.

>   The agent MUST use a short term credential to authenticate the
>   request and perform a message integrity check.  The agent MUST accept
>   a credential if the username consists of two values separated by a
>   colon, where the first value is equal to the username fragment
>   generated by the agent in an offer or answer for a session in-
>   progress, and the password is equal to the password for that username
>   fragment.  

The password isn't sent in the STUN packet; rather, the MESSAGE-INTEGRITY is
the output of a hash of the password and the STUN packet's contents.

>   It is possible (and in fact very likely) that an offeror
>   will receive a Binding Request prior to receiving the answer from its
>   peer.  However, the request can be processed without receiving this
>   answer, and a response generated.

Add:  "By doing this, ICE processing completes faster."

...
> 7.2.1.  Additional Procedures for Full Implementations
...
>   Assuming a success response, if the source transport address of the
>   request does not match any existing remote candidates, it represents
>   a new peer reflexive remote candidate.  The full-mode agent gives the
>   candidate a priority equal to the PRIORITY attribute from the
>   request.  The type of the candidate is equal to peer reflexive.  Its
>   foundation is set to an arbitrary value, different from the
>   foundation for all other remote candidates.  Note that any subsequent
>   offer/answer exchanges will contain this new peer reflexive candidate
>   in the SDP, and will signal the actual foundation for the candidate.
>   This candidate is then added to the list of remote candidates.
>   However, the agent does not pair this candidate with any local
>   candidates.

Add header, "Triggered Check"

>   Next, the agent constructs a tentative check in the reverse
                                 ^^^^^^^^^^^^^^^
Tentative check = triggered check?

>   direction, called a triggered check.  The triggered check has a local
>   candidate equal to the candidate on which the STUN request was
>   received, and a remote candidate equal to the source transport
>   address where the request came from (which may be a new peer-
>   reflexive remote candidate).  Since both candidates are known to the
>   agent, it can obtain their priorities and compute the candidate pair
>   priority.  This tentative check is then looked up in the check list.
>   There can be one of several outcomes:
>
>   o  If there is already a check on the check list with this same local
>      and remote candidates, and the state of that check is Waiting or
>      Frozen, its state is changed to In-Progress and the tentative
>      check is performed.
>
>   o  If there is already a check on the check list with this same local
>      and remote candidates, and its state was In-Progress, the agent
>      SHOULD abandon the new tentative check and instead generate an
                              ^^^^^^^^^
                              triggered?

>      immediate retransmit of the Binding Request for the check in
>      progress.  This is to facilitate rapid completion of ICE when both
>      agents are behind NAT.
...
>   If the tentative check is to be performed, it is constructed and
>   processed as described in Section 7.1.1.  These procedures require
>   the agent to know the username fragment and password for the peer.
                         ^
                transport address,

>   They are readily determined from the SDP and from the check that was
    ^^^^^^^^                                              ^^^^^
 The username is             source transport address of the STUN request

>   just received.  The username fragment for the remote candidate is
>   equal to the bottom half (the part after the colon) of the USERNAME
                 ^^^^^^
                 second

I don't like "half", as it implies/requires that both ICE agents
have the same length for their usernames.  How about just saying:

  is equal to the part after the colon of the USERNAME

>   in the Binding Request that was just received.  Using that username
>   fragment, the agent can check the SDP messages received from its peer
>   (there may be more than one in cases of forking), and find this
>   username fragment.  The corresponding password is then selected.  If
>   agent has not yet received this SDP (a likely case for the offerer in
                                   ^
                               username in 

>   the initial offer/answer exchange), it MUST wait for the SDP to be
>   received, and then proceed with the triggered check.

Add:  It must wait because it won't have its peer's ICE password until it
has the SDP.

...
> 8.  Concluding ICE
...
>   An alternative is called "proactive selection".  In this approach,
>   the controlling agent includes the USE-CANDIDATE attribute in every
>   check it sends.  Once the first check for a component succeeds, it is
>   used by ICE. 
    ^^^^^^^^^^^

"Used by ICE" means ICE declares itself finished, media starts flowing?
(the term is only used a few times in the document, but never with this
meaning.)

...
>   If an agent is controlling and its peer has a lite implementation, an
>   agent MUST use an introspective selection algorithm.  Of course, it
>   MAY select a favored pair based on ICE's prioritization.  The key
>   requirement is that the agent must complete a successful check before
                                  ^^^^
                                  MUST

>   redoing it with the USE-CANDIDATE attribute.

(Is this because a Lite implementation will immediately start sending
data when it sees a USE-CANDIDATE?  What's the reason for this key
requirement?)

...
> 9.  Subsequent Offer/Answer Exchanges
>
>   An agent MAY generate a subsequent offer at any time. 
    ^^^^^^^^                                 ^^^^^^^^^^^
"Either agent" ?                            not while there is an
                                            outstanding offer, though;
                                            perhaps cite O/A as the
                                            canonical rulemaker so that
                                            ICE isn't excused from 
                                            changing O/A rules?

> However, the

Delete "However,"

...
> 9.1.2.  Additional Procedures for Lite Implementations
>
>   A passive-only agent includes its one and only candidate for each
      ^^^^^^^^^^^^^^^^^^
      Lite implementation

>   component of each media stream in an a=candidate attribute in any
>   subsequent offer.  This candidate is formed identically to the
>   procedures for initial offers, as described in Section 4.2.
>
> 9.2.  Receiving the Offer and Generating an Answer
>
>   When receiving a subsequent offer within an existing session, an
>   agent MUST re-apply the verification procedures in Section 5.1
>   without regard to the results of verification from any previous
>   offer/answer exchanges.  Indeed, it is possible that a previous
>   offer/answer exchange resulted in ICE not being used, but it is used
>   as a consequence of a subsequent exchange.
>
>   If the offer contained a change in the a=ice-ufrag or a=ice-pwd
>   attributes compared to the previous SDP from the peer, it is a signal
>   that ICE is restarting for this media stream.  If all media streams
>   are restarting, than ICE is restarting overall.  Procedures for ICE
>   restarts are discussed below.  Unless ICE is restarting for that
>   media stream, an agent MUST NOT change the a=ice-ufrag or a=ice-pwd
>   attributes in an answer relative to the last SDP it provided.  Such a
>   change can only take place in an offer.  If ICE is restarting, the
>   a=ice-ufrag and a=ice-pwd attributes MUST be changed.
>
>   An agent MUST NOT change its implementation level from its previous
>   SDP unless, based on the offer, ICE procedures are being restarted
>   for all media streams in the offer.  In that case, it MAY change its
>   level.

The two paragraphs above would be easier to parse if the allowed and
prohibited actions were on bulleted or enumerated lists.

>   An agent MUST NOT include the a=remote-candidates attribute in an
>   answer.

Is this prohibited only in Subsequent O/A?  I would think it's also
prohibited in initial O/A, too?

>   When the answerer generates its answer, it must decide what
>   candidates to include in the answer, how to populate the m/c-line,
>   and how to adjust the states of ICE processing.  The rules for
>   inclusion of candidate attributes in an answer are identical to the
>   rules followed by the offerer as described in Section 9.1 for both
>   full and lite implementations.  For lite implementations, those rules
>   also apply for setting the m/c-line.  However, additional
>   considerations apply to full implementations.
>
> 9.2.1.  Additional Procedures for Full Implementations
>
>   The computation of the m/c-line additionally depends on the presence
>   or absence of the a=remote-candidates attribute in a media stream.
>   If present, it means that the offerer (acting as the controlling
>   agent) believed that ICE processing has completed for that media
>   stream.  In this case, the remote-candidates attribute contains the
>   candidates that the answerer is supposed to use.  It is possible that
>   the agent doesn't even know of these candidates yet; they will be
    ^^^^^^^^^
  the answering agent

>   discovered shortly through a response to an in-progress check.  The
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                               a.k.a "triggered check"  ??

>   full-mode agent MUST populate the m/c-line with the candidates from
>   the a=remote-candidates attribute.

...
> 9.3.1.  Additional Procedures for Full Implementations
...
>   Next, the agent goes through each check list, starting with the
>   highest priority check.  If a check has a state of Succeeded, and it
>   has a component ID of 1,

Why "1" instead of "the lowest-numbered component"?

...
> 10.  Keepalives
...
>   If there has been no packet sent on a candidate pair being used for
>   media for Tr seconds (where packets include media and previous
    ^^^^^
RTCP isn't "media", but we want keepalives on RTCP if it hasn't been
used in awhile, too?  (Not usually a problem, as RTCP is sent
often enough to keep NATs happy).  

How about striking "being used for media" and instead say "active
candidate pair"?

>   keepalives), an agent MUST generate a keepalive on that pair.  Tr
>   SHOULD be configurable and SHOULD have a default of 15 seconds.
>
>   If STUN is being used for keepalives, a STUN Binding Indication is
>   used [11].  The Binding Indication SHOULD NOT contain integrity
>   checks; since the messages are simply discarded on receipt regardless
>   of contents.  The Indication SHOULD NOT contain the PRIORITY or USE-
>   CANDIDATE attributes defined here. 
                                 ^^^^
                              in this document.

...
> 11.1.1.  Procedures for Full Implementations
>
>   Agents always send media using a candidate pair.  An agent will send
>   media to the remote candidate in the pair (setting the destination
>   address and port of the packet equal to that remote candidate), and
>   will send it from the local candidate.  When the local candidate is
>   server or peer reflexive, media is originated from the base.  Media
>   sent from a relayed candidate is sent through that relay, using
                                          ^^^^^^^
                                     from the base to 
>   procedures defined in [12].
>
>   If the state of a media stream is Running, there is no old Valid list
>   for that media stream (which would be due to an ICE restart), an
>   agent MUST NOT send media.

The above paragraph is describing the 'check list state' from 5.7?  If so,
might want to be clearer about that.

The previous paragraph needs to justify that MUST; providing a forward
reference to the voice hammer section (16.4.1) should be sufficient for that
justification.

>   When an agent sends media, it MUST send it using the highest priority
>   selected pair for each component in either the old Valid list for a
>   media stream (if it exists), else the new Valid list for that media
>   stream.  In several cases, this will not be the same candidate pairs
>   present in the m/c-line.  When ICE first completes, if the selected
>   pairs aren't a match for the m/c-line, an updated offer/answer
>   exchange will take place to remedy this disparity.  However, until
>   that update offer arrives, there will not be a match.  Furthermore,
         ^^^^^^
         updated

>   in very unusual cases, the m/c-lines in the updated offer/answer will
>   not be a match.
>
>   ICE has interactions with jitter buffer adaptation mechanisms.  An
>   RTP stream can begin using one candidate, and switch to another one,
>   though this happens rarely with ICE.  The newer candidate may result
>   in RTP packets taking a different path through the network - one with
>   different delay characteristics.  As discussed below, agents are
>   encouraged to re-adjust jitter buffers when there are changes in
>   source or destination address. 
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    a.k.a. "in-use candidates"?

> Furthermore, many audio codecs use
>   the marker bit

provide reference to RFC3550.

> to signal the beginning of a talkspurt, for the
>   purposes of jitter buffer adaptation.  For such codecs, it is
>   RECOMMENDED that the sender change the marker bit when an agent
                                ^^^^^^
                                 set

>   switches transmission of media from one candidate pair to another.

Why do both, I wondered.  Then the answer hit:  the other endpoint
might not always realize we switched transport addresses (because
everything is going through a relay, and they're unaware of it).  
Might want to point that out.

The whole previous paragraph, starting with "ICE has interactions with
jitter buffer", should be moved into section 11.2, "Receiving media", which
also talks about jitter buffers and SSRC collisions and whatnot.

> 11.1.2.  Procedures for Lite Implementations
>
>   A lite implementation MUST NOT send media until it has a Valid list
>   that contains a candidate pair for each component of that media
>   stream. 

I believe you should do a forward reference to Voice Hammer (16.4.1).

...
> 11.2.  Receiving Media
>
>   ICE implementations MUST be prepared to receive media on any
                                            ^^^^^^^^^^^^^
"Receive and play it out", or do we not want to open that pandora's box?

>   candidates provided in the most recent offer/answer exchange.

What about non-media, like RTCP?  Should it expect to see RTCP SR or RR
reports?  Do those need to be witheld to prevent voice hammer of RTCP
traffic (probably so; I don't think that's quite clear if one considers
RTP="media", and RTCP="media control").

> 12.1.  Latency Guidelines
...
>   If an offer is received in an INVITE request, the callee SHOULD
                                                      ^^^^^^
                                                      answerer

(several occurances of "callee" appear in this section.)

>   immediately gather its candidates and then generate an answer in a
>   provisional response. 

Does this suggestion override the previous 'immediate' suggestions in 5.3
and 5.8?

>   ICE requires that a provisional response with
>   an SDP be transmitted reliably.  This can be done through the
>   existing PRACK mechanism [9], or through an optimization that is
>   specific to ICE.  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.  To do this, the
>   agent retransmits the provisional response with th exponential
>   backoff timers described in RFC 3262.  Retransmits MUST cease on
>   receipt of a STUN Binding Request for one of the media streams
>   signaled in that SDP or on transmission of a 2xx response. 

Add:  ", because receipt of a binding request indicates the offerer
has received the answer."

...
...
>   However, prior to this point, any media that needs to be sent towards
>   the caller (such as SIP early media [25] cannot be transmitted.  

I believe it's "MUST NOT", rather than "cannot" -- the answerer knows
a transport address, and "can" use it.  I would change this to "MUST
NOT" and provide a forward reference to the voice hammer attack.

...
>   In addition to uses where the offer is in an INVITE, and the answer
>   is in the provisional and/or 200 OK, ICE works with cases where the
>   offer appears in the response.  In such cases, which are common in
>   third party call control,

Need a citation to third party call control.

> ICE agents SHOULD generate their offers in
>   a reliable provisional response (which MUST utilize RFC 3262).  In
>   that case, the answer will arrive in a PRACK.  This allows for ICE
>   processing to take place prior to alerting.  Once ICE completes, the
>   agent can alert the user and then generate a 200 OK. 

200 OK before the user answers?  (Sorry if a silly question; third party 
call control isn't my best subject.)

> The 200 OK
>   would contain no SDP, since the offer/answer exchange has completed.
>   Agents MAY place the offer in a 2xx instead (in which case the answer
>   comes in the ACK).  This flow is simpler but results in a poorer user
>   experience.

The previous paragraph, discussing third party call control, should be moved
out of this latency section and into the third party call control section
(12.5).

>   As discussed in Section 16, offer/answer exchanges SHOULD be secured
>   against eavesdropping and man-in-the-middle attacks.  To do that, the
>   usage of SIPS [3] is RECOMMENDED when used in concert with ICE.

That last pargraph doesn't belong in the Latency Guidelines section.
Perhaps in Security Considerations?

...
> 12.3.  Interactions with Forking
>
>   ICE interacts very well with forking.  Indeed, ICE fixes some of the
>   problems associated with forking.  Without ICE, when a call forks and
>   the caller receives multiple incoming media streams, it cannot
>   determine which media stream corresponds to which callee.
                                                      ^^^^^^
                                                   called party

>
>   With ICE, this problem is resolved.  The connectivity checks which
>   occur prior to transmission of media carry username fragments, which
>   in turn are correlated to a specific callee.  Subsequent media
                                         ^^^^^^
                                       called party

>   packets which arrive on the same 5-tuple as the connectivity check
                                     ^^^^^^^
                  this is a new term.  How about 'transport address'?

>   will be associated with that same callee.  Thus, the caller can
                                      ^^^^^^
                                     called party

>   perform this correlation as long as it has received an answer.

...
> 13.  Grammar
...
>   password              = 22*ice-char
>   ufrag                 = 4*ice-char

To successfully disambiguate forked calls, the username needs to be long
enough so that each called party has a chance to pick a unique value without
the birthday paradox.  I don't think 24 (4*6) bits is sufficient for this.

>   The "ice-pwd" and "ice-ufrag" attributes can appear at either the
>   session-level or media-level.  When present in both, the value in the
>   media-level takes precedence.  Thus, the value at the session level
>   is effectively a default that applies to all media streams, unless
>   overriden by a media-level value.
>
>   The "ice-options" attribute is a session level attribute.  It
>   contains a series of tokens which identify the options supported by
>   the agent.  Its grammar is:
>
>
>   ice-options           = "ice-options" ":" ice-option-tag
>                             0*(SP ice-option-tag)
>   ice-option-tag        = 1*ice-char

This is the first time ice-options has been introduced.

> 15.  Example
>
>   Two agents, L and R, are using ICE.  Both are full-mode ICE
>   implementations.  Both agents have a single IPv4 interface.  For
>   agent L, it is 10.0.1.1, and for agent R, 192.0.2.1.  
                           ^^                          ^^
        in private address space [RFC1918]       on the public Internet

>   Both are
>   configured with a single STUN server each (indeed, the same one for
>   each),

Replace that parenthetical comment with:

  (as shown in this example for simplicity although in practice 
   the agents do not need to use the same STUN server)

> which is listening for STUN requests at an IP address of
>   192.0.2.2 and port 3478.  This STUN server supports only the Binding
>   Discovery usage; relays are not used in this example.  Agent L is
>   behind a NAT, and agent R is on the public Internet.  The NAT has an
>   endpoint independent mapping property and an address dependent
>   filtering property.  The public side of the NAT has an IP address of
>   192.0.2.3.

A figure would help:

              STUN Server
                   |
   L----[NAT]------+---------R

...
>   Agents L and R both pair up the candidates.  They both initially have
>   two.  However, agent L will prune the pair containing its server
                                ^^^^^^^^^^^^^^
                     a.k.a. eliminate redundant candidates

>   reflexive candidate, resulting in just one.  At agent L, this pair
>   (the check) has a local candidate of $L_PRIV_1 and remote candidate
>   of $R_PUB_1, and has a candidate pair priority of 4.57566E+18 (note
>   that an implementation would represent this as a 64 bit integer so as
>   not to lose precision).  At agent R, there are two checks.  The
>   highest priority has a local candidate of $R_PUB_1 and remote
>   candidate of $L_PRIV_1 and has a priority of 4.57566E+18, and the
>   second has a local candidate of $R_PUB_1 and remote candidate of
>   $NAT_PUB_1 and priority 3.63891E+18.
>
>   Agent R begins its connectivity check (message 9) for the first pair
>   (between the two host candidates).  Since R is the passive agent for
>   this session, the check omits the USE-CANDIDATE attribute.  The host
>   candidate from agent L is private and behind a different NAT, and
                                                   ^^^^^^^^^
delete "different" (there is only one NAT)

>   thus this check is discarded.
                       ^^^^^^^^^
"won't be successful, because the packet cannot be routed from R to L."

...
>   Upon receipt of the check from agent L (message 11), agent R will
                        ^^^^^
   STUN binding request

>   generate its triggered check.  This check happens to match the next
>   one on its check list - from its host candidate to agent L's server
>   reflexive candidate.  This check (messages 14-17) will succeed.
>   Consequently, agent R constructs a new candidate pair using the
>   mapped address from the response as the local candidate (R-PUB-1) and
>   the destination of the request (NAT-PUB-1) as the remote candidate.
>   This pair is added to the Valid list for that media stream.  Since
>   the check was generated in the reverse direction of a check that
>   contained the USE-CANDIDATE attribute, the candidate pair is marked
>   as selected.  Consequently, processing for this stream moves into the
>   Completed state, and agent R can also send media.

L now needs to send an updated offer, correct?

>   Of the various techniques for creating faked STUN messages described
>   in [11], many are not applicable for the connectivity checks.
>   Compromises of STUN servers are not much of a concern, since the STUN
>   servers are embedded in endpoints and distributed throughout the
                         ^^^^^^^^^^^^
            in the endpoint's ICE-aware application software

>   network.  Thus, compromising the STUN server is equivalent to
                                 ^^^^^^^^^^^^^^^
                        the peer's embedded STUN server

>   comprimising the endpoint, and if that happens, far more problematic
>   attacks are possible than those against ICE.  Similarly, DNS attacks
>   are usually irrelevant since STUN servers are not typically
>   discovered via DNS, they are signaled via IP addresses embedded in
>   SDP. 

ICE does allow using FQDN, though.  But then, so does SDP.  Perhaps
show how if you're using FQDN with SDP, ICE doesn't make the DNS
vulernerability worse than it already was.

...
>   Forcing the false peer reflexive candidate result with packet replays
>   is different.  The attacker waits until one of the agents sends a
>   check.  It intercepts this request, and replays it towards the other
>   agent with a faked source IP address.  It must also prevent the
>   original request from reaching the remote agent, either by launching
>   a DoS attack to cause the packet to be dropped, or forcing it to be
>   dropped using layer 2 mechanisms.  The replayed packet is received at
>   the other agent, and accepted, since the integrity check passes (the
>   integrity check cannot and does not cover the source IP address and
>   port).  It is then responded to.  This response will contain a XOR-
>   MAPPED-ADDRESS with the false candidate, and will be sent to that
>   false candidate.  The attacker must then intercept it and relay it
                                             ^^^^^^^^^
                                             receive
>   towards the originator.
>
>   The other agent will then initiate a connectivity check towards that
>   false candidate.  This validation needs to succeed.  This requires
>   the attacker to force a false valid on a false candidate.  Injecting
>   of fake requests or responses to achieve this goal is prevented using
>   the integrity mechanisms of STUN and the offer/answer exchange.
>   Thus, this attack can only be launched through replays.  To do that,
>   the attacker must intercept the check towards this false candidate,
>   and replay it towards the other agent.  Then, it must intercept the
>   response and replay that back as well.
>
>   This attack is very hard to launch unless the attacker themself is
>   identified by the fake candidate. 

Considering botnets, I wouldn't say this is a risk or worry to most
attackers.

> This is because it requires the
>   attacker to intercept and replay packets sent by two different hosts.
>   If both agents are on different networks (for example, across the
>   public Internet), this attack can be hard to coordinate, since it
>   needs to occur against two different endpoints on different parts of
>   the network at the same time.

I suggest deleting the above paragraph.  It's overly optimistic that
the attack is difficult.

>   If the attacker themself is identified by the fake candidate the
                    ^^^^^^^^
Delete "themself"

>   attack is easier to coordinate.  However, if SRTP is used [22], the
>   attacker will not be able to play the media packets, they will only
>   be able to discard them, effectively disabling the media stream for
>   the call.  However, this attack requires the agent to disrupt packets
>   in order to block the connectivity check from reaching the target.
>   In that case, if the goal is to disrupt the media stream, its much
>   easier to just disrupt it with the same mechanism, rather than attack
>   ICE.
>
> 16.2.  Attacks on Address Gathering
>
>   ICE endpoints make use of STUN for gathering candidates rom a STUN

"rom" -> "from"

>   server in the network.  This is corresponds to the Binding Discovery
>   usage of STUN described in [11].  As a consequence, the attacks
>   against STUN itself that are described in that specification can
>   still be used against the binding discovery usage when utilized with
>   ICE.
>
>   However, the additional mechanisms provided by ICE actually
>   counteract such attacks, making binding discovery with STUN more
>   secure when combined with ICE than without ICE.
>
>   Consider an attacker which is able to provide an agent with a faked
>   mapped address in a STUN Binding Request that is used for address
>   gathering.  This is the primary attack primitive described in [11].
>   This address will be used as a server reflexive candidate in the ICE
>   exchange.  For this candidate to actually be used for media, the
>   attacker must also attack the connectivity checks, and in particular,
>   force a false valid on a false candidate.  This attack is very hard
>   to launch if the false address identifies a third party,

L and R are the 1st and 2nd parties.  Is the attacker is the 3rd party?  Or
are you talking about a 4th party (someone other than the attacker)?

> and is
>   prevented by SRTP if it identifies the attacker themself.
...

> 16.4.1.  The Voice Hammer Attack
>
>   The voice hammer attack is an amplification attack.  In this attack,
>   the attacker initiates sessions to other agents,

sends an Invite?  (or are you trying to be non-SIP-specific?)

> and includes the IP
     ^
  maliciously

>   address and port of a DoS target in the m/c-line of their SDP.  This
>   causes substantial amplification; a single offer/answer exchange can
>   create a continuing flood of media packets, possibly at high rates
>   (consider video sources).  This attack is not specific to ICE, but
>   ICE can help provide remediation.
>
>   Specifically, if ICE is used, the agent receiving the malicious SDP
>   will first peform connectivity checks to the target of media before
>   sending it there.  If this target is a third party host, the checks
            ^^
           media

>   will not succeed, and media is never sent.
...

> 16.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.  This attack is
>   accomplished by having the offerer send an offer with a large number
>   of candidates, say 50.  

Nit.  Replace last sentence with:

  "The attaker 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.

The last paragraph needs to be discussed earlier, too, somewhere in section
7, with a forward reference to here.

...
> 16.5.  Interactions with Application Layer Gateways and SIP
>
>   If an ALG is SIP aware but not ICE aware, ICE will work through it as
>   long as the ALG correctly modifies the m/c-lines of SDP.  In this
>   case, correctly means that the ALG does not modify m/c-lines with
>   external addresses.  If the m/c-line contains internal addresses, but
>   ones for which a public binding exists, the ALG replaces the internal
>   address in the m/c-line with the public binding. 

That last sentence doesn't parse well.

> Unfortunately, many
>   ALG are known to work poorly in these corner cases.  ICE does not try
>   to work around broken ALGs, as this is outside the scope of its
>   functionality.  ICE can help diagnose these conditions, which often
>   show up as a mismatch between the set of candidates and the m/c-line.
>   The a=ice-mismatch parameter is used for this purpose.
        ^^^^^^^^^^^^^^^^^^^^^^^^
         ice-mismatch attribute
  
...
>   If an SBC is SIP aware but not ICE aware, the result depends on the
>   behavior of the SBC.  If it is acting as a proper Back-to-Back User
>   Agent (B2BUA), the SBC will remove any SDP attributes it doesn't
>   understand, including the ICE attributes.  Consequently, the call
>   will appear to both endpoints as if the other side doesn't support
>   ICE.  This will result in ICE being disabled, and media flowing
>   through the SBC, if they SBC has requested it.  
                        ^^^^
                        the ??

>   If, however, the SBC
>   passes the ICE attributes without modification, yet modifies the m/c-
>   lines, this will be detected as an ICE mismatch, and ICE processing
>   is aborted for the call.  It is outside of the scope of ICE for it to
>   act as a tool for "working around" SBCs.  If one is present, ICE will
>   not be used and the SBC techniques take precedence.
>
>
...
> 17.1.  Applicability
>
>   This STUN usage provides a connectivity check between two peers
>   participating in an offer/answer exchange.  This check serves to
>   validate a pair of candidates for usage of exchange of media.
>   Connectivity checks also allow agents to discover reflexive
>   candidates towards their peers, called peer reflexive candidates.
>   Finally, connectivity checks serve to keep NAT bindings alive.

Delete last sentence (keepalives are now done with Binding Indications).

>   It is fundamental to this STUN usage that the addresses and ports
>   used for media are the same ones used for the Binding Requests and
>   responses.  Consequently, it will be necessary to demultiplex STUN
>   traffic from whatever the media traffic is.  This demultiplexing is
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         other applications on that same port (e.g., RTP or RTCP)

>   done using the techniques described in [11].

That last paragraph seems a pretty important concept, and something that
should be in the Overview section.

> 17.2.  Client Discovery of Server
>
>   The client does not follow the DNS-based procedures defined in [11].
>   Rather, the remote candidate of the check to be performed is used as
>   the transport address of the STUN server.  Note that the STUN server
>   is a logical entity, and is not a physically distinct server in this
>   usage.
>
> 17.3.  Server Determination of Usage
>
>   The server is aware of this usage because it signaled this port
>   through the offer/answer exchange.  Any STUN packets received on this
>   port will be for the connectivity check usage.

Add:

  "Or for the keepalive usage."

> 17.4.  New Requests or Indications
>
>   This usage does not define any new message types.
>
> 17.5.  New Attributes
>
>   This usage defines two new attributes, PRIORITY and USE-CANDIDATE.
>
>   The PRIORITY attribute indicates the priority that is to be
>   associated with a peer reflexive candidate, should one be discovered
>   by this check.  It is a 32 bit unsigned integer, and has an attribute
>   type of 0x0024.
    ^^^^
    value

>
>   The USE-CANDIDATE attribute indicates that the candidate pair
>   resulting from this check should be used for transmission of media.
>   The attribute has no content (the Length field of the attribute is
>   zero); it serves as a flag.  It has an attribute type of 0x0025.
                                                     ^^^^
                                                     value

...
> 19.5.  Issues with Existing NAPT Boxes
>
>   From RFC 3424, any UNSAF proposal must provide:
>
>      Discussion of the impact of the noted practical issues with
>      existing, deployed NA[P]Ts and experience reports.
>
>   A number of NAT boxes are now being deployed into the market which
>   try and provide "generic" ALG functionality.  These generic ALGs hunt
>   for IP addresses, either in text or binary form within a packet, and
>   rewrite them if they match a binding.  This interferes with
>   traditional STUN.  However, the update to STUN [11] uses an encoding
>   which hides these binary addresses from generic ALGs.  Since [11] is
>   required for all ICE implementations, this NAPT problem does not
>   impact ICE.

Delete the last sentence; in this version of ICE, [11] _is_ a 
requirement, and its XOR-MAPPED-ADDRESS resolves this problem.

>   Existing NAPT boxes have non-deterministic and typically short
>   expiration times for UDP-based bindings.  This requires
>   implementations to send periodic keepalives to maintain those
>   bindings.  ICE uses a default of 15s, which is a very conservative
>   estimate.  Eventually, over time, as NAT boxes become compliant to
>   behave [31], this minimum keepalive will become deterministic and
>   well-known, and the ICE timers can be adjusted.  Having a way to
>   discover and control the minimum keepalive interval would be far

Should provide forward reference to B.1, "Pacing of STUN Transactions".

> Appendix A.  Lite and Full Implementations
>
>   ICE allows for two types of implementations.  A full implementation
>   supports the controlling and controlled roles in a session, and can
>   also perform address gathering.  In contrast, a lite implementation
>   is a minimalist implementation that does little but respond to STUN
>   checks.
>
>   Because ICE requires both endpoints to support it in order to bring
>   benefits to either endpoint, incremental deployment of ICE in a
>   network is more complicated.  Many sessions involve an endpoint which
>   is, by itself, not behind a NAT and not one that would worry about
>   NAT traversal.  Examples include gateways to the PSTN, media servers,
>   conference bridges, and application servers. 

Same comment I had previously:  this provides a get-out-of-jail-free
card to vendors building these devices to only built a Lite 
implementation, even when those devices are known to be behind NATs
most of the time.

> A very common case is
>   to have one endpoint that requires NAT traversal (such as a VoIP hard
>   phone or soft phone) make a call through one of these devices.  Even
                                     ^^^^^^^
                                       to

>   if the phone supports a full ICE implementation, ICE won't be used at
>   all if the other device doesn't support it.  The lite implementation
>   allows for a low-cost entry point for these devices.  Once they
>   support the lite implementation, full implementations can connect to
>   them and get the full benefits of ICE.
>
>   Consequently, a lite implementation is only appropriate for devices
>   that will always be connected to the public Internet and have a
>   public IP address at which it can receive packets from any
>   correspondent.  ICE will not function when a lite implementation is
>   placed behind a NAT.
>
>   It is important to note that the lite implementation was added to
>   this specification to provide a stepping stone to full
>   implementation.  Even for devices that are always connected to the
>   public Internet, a full implementation is preferable if achievable.
>   A full implementation will reduce call setup times.  Full
>   implementations also obtain the security benefits of ICE unrelated to
>   NAT traversal; in particular, the voice hammer attack described in
>   Section 16 is prevented only for full implementations, not lite.
>   Finally, it is often the case that a device which finds itself with a
>   public address today will be placed in a network tomorrow where it
>   will be behind a NAT.  It is difficult to definitively know, over the
>   lifetime of a device or product, that it will always be used on the
>   public Internet.  Full implementation provides assurance that
>   communications will always work.

The last two paragraphs ("Consequently, ..." and "It is important") are too
important to put down here.  I would bring them up to the Overview, when
Lite is introduced.  Might be good to just move all of Appendix A up to the
Overview, in fact.

...

> B.1.  Pacing of STUN Transactions
>
>   STUN transactions used to gather candidates and to verify
>   connectivity are paced out at an approximate rate of one new
>   transaction every Ta seconds, where Ta has a default of 20ms.  Why
                         ^^^^^^^
                       milliseconds

>   are these transactions paced, and why was 20ms chosen as default?

...
> B.4.  Importance of the STUN Username
...

>   An unfortunate consequence of the non-uniqueness of IP addresses is
>   that, in the above example, B might not even be an ICE agent.  It
>   could be any host, and the port to which the STUN packet is directed
>   could be any ephemeral port on that host.  If there is an application
>   listening on this socket for packets, and it is not prepared to
>   handle malformed packets for whatever protocol is in use, the
>   operation of that application could be affected.  Fortunately, since
>   the ports exchanged in SDP are ephemeral and usually drawn from the
>   dynamic or registered range, the odds are good that the port is not
>   used to run a server on host B, but rather is the agent side of some
>   protocol.  This decreases the probability of hitting a port in-use,
>   due to the transient nature of port usage in this range.  However,
>   the possibility of a problem does exist, and network deployers should
>   be prepared for it.  Note that this is not a problem specific to ICE;
>   stray packets can arrive at a port at any time for any type of
>   protocol, especially ones on the public Internet.  As such, this
>   requirement is just restating a general design guideline for Internet
>   applications - be prepared for unknown packets on any port.

Should the above paragraph be in IAB considerations?  It's a pretty
damning part of ICE, which we have all long accepted, but it's going
to surprise a goodly number of people.  Perhaps in the "Brittleness
Introduced by ICE" section some mention could be made with a forward
reference to this detailed Design Motivation. 

...
> B.11.  Why are Binding Indications Used for Keepalives?
...
>   Additionally, using a Binding Indication allows integrity to be
>   disabled, allowing for better performance.  This is useful for large
>   scale endpoints, such as PSTN gateways.

and SBCs.

-d

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