Original text:
3.4. <del> When a new ICE candidate is available, the ICE Agent will notify the application via a callback; these candidates will automatically be added to the local session description.  When all candidates have been gathered, the callback will also be invoked to signal that the gathering process is complete. </del> 3.4.1.  Candidate trickling is a technique through which a caller may incrementally provide candidates to the callee after the initial offer has been dispatched; the semantics of "Trickle ICE" are defined in cases where gathering is not performed prior to initiating the call. <del> JSEP supports optional candidate trickling by providing APIs that provide control and feedback on the ICE candidate gathering process. Applications that support candidate trickling can send the initial offer immediately and send individual candidates when they get the notified of a new candidate; applications that do not support this feature can simply wait for the indication that gathering is complete, and then create and send their offer, with all the candidates, at this time. </del>  Upon receipt of trickled candidates, the receiving application will supply them to its ICE Agent.  This triggers the ICE Agent to start using the new remote candidates for connectivity checks. <del> 3.4.1.1. </del>  As with session descriptions, the syntax of the IceCandidate object provides some abstraction, but can be easily converted to and from Implementations receiving an ICE Candidate object SHOULD use the MID if they implement that functionality, or the m-line index, if not. <del> 3.4.2. </del>  JSEP applications typically inform the browser to begin ICE gathering via the information supplied to setLocalDescription, as this is where <del> the app specifies the number of media streams for which to gather candidates.  However, to accelerate cases where the application knows the number of media streams to use ahead of time, it MAY ask the browser to gather a pool of potential ICE candidates to help ensure rapid media setup.  When setLocalDescription is eventually called, and the browser goes to gather the needed ICE candidates, it SHOULD start by checking if any candidates are available in the pool.  If there are candidates in the pool, they SHOULD be handed to the application immediately via the ICE candidate callback.  If the pool becomes depleted, either because a larger-than-expected number of media streams is used, or because the pool has not had enough time to gather candidates, the remaining candidates are gathered as usual. </del>  3.5. The PeerConnection constructor allows the application to specify global parameters for the media session, such as the STUN/TURN <del> servers and credentials to use when gathering candidates.  The size of the ICE candidate pool can also be set, if desired; this indicates the number of ICE components to pre-gather candidates for.  If the application does not indicate a candidate pool size, the browser may select any default candidate pool size. In addition, the application can specify its preferred policy regarding use of BUNDLE, the multiplexing mechanism defined in I- D.ietf-mmusic-sdp-bundle-negotiation.  By specifying a policy from the list below, the application can control how aggressively it will try to BUNDLE media streams together.  The set of available policies is as follows: </del>  The application will BUNDLE all media streams of the same type together.  That is, if there are multiple audio and multiple video non-BUNDLE-aware endpoints, but require separate candidates to be gathered for each media stream.  4.1.2. The createOffer method generates a blob of SDP that contains a 4.1.9. <del> The updateIce method allows the configuration of the ICE Agent to be changed during the session, primarily for changing which types of local candidates are provided to the application and used for connectivity checks.  A callee may initially configure the ICE Agent to use only relay candidates, to avoid leaking location information, but update this configuration to use all candidates once the call is accepted. </del>  <del> Regardless of the configuration, the gathering process collects all available candidates, but excluded candidates will not be surfaced in onicecandidate callback or used for connectivity checks. </del>  This call may result in a change to the state of the ICE Agent, and may result in a change to media state if it results in connectivity Each "a=mid" line MUST stay the same. <del> Each "a=ice-ufrag" and "a=ice-pwd" line MUST stay the same unless the "IceRestart" option (sec.options-handling was specified.  Note that it's not clear why you would actually want to do this, since at this point ICE has not yet started and is thus unlikely to need a restart. </del>  For MediaStreamTracks that are still present, the "a=msid", "a=ssrc", and "a=ssrc-group" lines MUST stay the same. this option is specified in the case where at least N audio MediaStreamTracks have already been added to the PeerConnection, or N non-rejected m= sections with media type "audio" would otherwise be <del> generated, it has no effect.  For backwards compatibility, a value of "true" is interpreted as equivalent to N=1. </del>  5.2.3.2. this option is specified in the case where at least N video MediaStreamTracks have already been added to the PeerConnection, or N non-rejected m= sections with media type "video" would otherwise be <del> generated, it has no effect.  For backwards compatibility, a value of "true" is interpreted as equivalent to N=1. </del>  5.2.3.3. offer MUST indicate an ICE restart by generating new ICE ufrag and pwd attributes, as specified in RFC5245, Section 9.1.1.1.  If this option is specified on an initial offer, it has no effect (since a <del> new ICE ufrag and pwd are already generated).  This option is useful for reestablishing connectivity in cases where failures are detected. </del>  5.3.

Reviewer comments:
Tony: Explain, give example for ICE candidate pool () Magnus: ICE policy should be overridable by local policy () Explain ICE gathering phase () Replace updateIce with setConfiguration Define behavior of setConfiguration, explain how changing ICE policy works () Default candidate pool size to zero ()
OK, I rewrote a bunch of stuff here to make it clear that changes to the candidate policy require ICE restart, and ICE restart happens automatically in createOffer if the ICE configuration has changed.
PTAL
Note to self: fix the Travis failure on a bad "URL" xref
PTAL
This all LGTM.
Does it happen on PC construction, or on receiving a remote offer? Justin and Cullen thought the former, with unlimited binding keepalive time; Eric thought the latter.
Cullen and I talked about this. I think I mostly hadn't thought through the implications of unlimited keepalive. Based on that, I think we adopt the J/C interpretation but strongly advise a 0-sized default pool.
worksforme
On Jul 4, 2014, at 4:31 PM, ekr EMAIL wrote: I’m fine with default size of zero as long as when the JS explicitly sets it to something else they get that
Fixed by
Section 4.1.9: Should this section discuss that it might be browser that has overriding controls regarding if other candidates then relay ones may be provided, i.e. privacy mode? JU: Probably. The use of host candidates is something that might be forbidden by local policy. I think the right thing to do would be to introduce the concept of iceTransports in section 3.4 (ICE), and then refer to it here in updateIce (now called setConfiguration), as well as the ctor section, where the initial policy can be set. Section 5.2.1: Structure in relation between RTP media and DATA channel. Maybe you should try to find a structure that makes the difference between the two types of transport more clear, and what applies to the perspective. JU: Agree this could be improved. 5.2.3.3. VoiceActivityDetection If the "VoiceActivityDetection" constraint is specified, with a value of "true", the offer MUST indicate support for silence suppression by including comfort noise ("CN") codecs for each supported clock rate, as specified in [RFC3389], Section 5.1. As currently specified this text requires the usage of a comfort noise codec, currently there is no such on required. I think the "MUST" needs to be rewritten. JU: I think this needs to be specified as a MUST in RTP usage then. Otherwise, this setting won't work in some browsers, leading to nondeterministic behavior. This should also be updated to set usedtx=1 for Opus. Section 5.3.1: Note that for simplicity, the answerer MAY use different payload types for codecs than the offerer, as it is not prohibited by Section 6.1. I react to the word simplicity here. I never consider usage of different PTs per direction anything simple. But, yes it is allowed by RFC 3264. But I kind of protest to encourage the usage. JU: Clearly this needs more explanation. The basic issue is the fact that using the same payload types gets really hairy when using RTX and when bundling. We can add an example of the problem.
Proposed resolution is update RTP Usage updated to say 3389 is MTI
Re: 5.2.3.3 - resolution today to suggest 3389 be MTI in rtp-usage.
Proposed resolution for 5.3.1 is to remove "simplicity" and provide an example
Local policy override part addressed in .
I believe this is fixed in the current version. There has been a lot of rewriting here. I'm going to declare this closed and let Magnus re-raise if he is still sad. I believe this is addressed in PR.
I filed a new issue for this last point,
The proposed scenario is where .iceTransports is set to 'relay', and so relay gathering occurs first; non-relay gathering only occurs after .iceTransports is changed to 'all'. The flow is something like: new PC({iceTransports: 'relay'}) setRD(offer) createAnswer setLD(answer) onicegatheringstatechange(gathering) onicecandidate(relay1) onicecandidate(relay2) A: setConfiguration({iceTransports: 'all'}) onicecandidate(null) onicegatheringstatechange(complete) B: setConfiguration({iceTransports: 'all'}) In case A, we could definitely release the gathered ICE candidates immediately, with no issues. But in case B, does it make sense to emit them, since gathering has completed? Options: 1) Emit them. No state change occurs. You called this API, you deal with it. (My preference.) 2) Transition back to gathering, emit the candidates (which will happen immediately, necessarily), go back to complete. (Changes the meaning of a gathering transition.) 3) No candidates are emitted, no state change occurs. The new type of candidates is gathered on the next ICE restart. (Complicates the use case above. But allows changing type to a more restrictive type.)
You should raise this on the list. I think that the non-relay candidates are effectively in the candidate pool. Not that that helps much.
Agree regarding the pool, i.e. they are immediately available. And that it doesn't help much. Took this to the list.
The consensus seems to be that 3) above is preferred.
Fixed by
Editorial changes: I guess my one comment addressing the document as a whole would be that the examples used in the draft are helpful in explaining certain aspects and therefore even more examples would be even more helpful. J: Which particular examples were most useful - the inline hand-wavy descriptions, the API flows, or the example SDP? Section 1.1, Paragraph 3, Last Sentence I think this can be reworded to be clearer and more powerful, something such as: "JSEP removes the browser almost entirely from the core signaling flow. The Javascript application needs interfaces for only (1) passing in local and remote session descriptions and (2) interacting with the ICE state machine." Perhaps the exact wording I've suggested is not ideal, but something that more clearly shows that JSEP removes the browser from the signaling flow and that the application (and therefore, the application's developer) needs to do only two things for establishing a session. The way it is worded now is unclear at first read and does not adequately persuade me why JSEP is awesome (IMO). J: Agree your wording is more direct. We'll rework this part. Section 3.4.2, Paragraph 1 An example of a situation where the browser might know the number of media streams ahead of time might be useful for context here, if one is easily explained. J: Sure, that makes sense. The typical case here is for an endpoint that wants to be able to quickly set up a received call. The caller has the ability to just start the call and leave it in the local-offer state instead. Section 3.5.1, Paragraph 2 How does the application decide whether to apply as provisional or final? Does JSEP care at all or is this left entirely up to the application to decide? This is expounded on somewhat in the 2 paragraphs that follow, but I still don't feel like these questions are completely answered. J: This is an application decision; in JSEP's opinion, forking should overall be avoided. Section 4.1.2, Paragraph 2 I think this sentence would be clearer if "certain parts that are" was replaced with "functionality that is". J: Agreed. Section 4.1.2, Paragraph 3 This sentence was too hard to compute in my opinion, and I'm still not quite sure what "the document" refers to. I think rewording would be beneficial. J: Agreed - refer to "the RFC" or somesuch Section 5.1.2, bullet R-2 This shouldn't be MAY because it is not referring to an optional implementation specification of JSEP but rather a possible scenario that JSEP needs to support. It should read as just a warning and possibly specify that JSEP MUST be equipped to interface with an endpoint that is using a Lite ICE implementation. J: Agree. We'll adjust accordingly (MAY->may, MUST handle ice-lite) Section 5.2.1, bullet 3 Is there a reason to ignore the following SHOULD from RFC4566? It seems like "-" and " " are both equally meaningless, so why deviate from the standard? (I'm also not sure why we need to match it with the username in the o= line). There may be good reason for both of these, but it is not clear to me from reading the draft so I wanted to bring it up. J: It's entirely arbitrary. Since they are meaningless, I figured using similar meaningless values made this more clear than individual meaningless values. We can add some text to make this clear. Section 5.2.1, Paragraph 3 Consider adding: "URL specified in [RFC4566] Section 5.14..." The draft references specific sections for the other SDP fields and I think it is useful here as well. J: Sounds good. Section 5.2.3, Paragraph 1 I think an example of when this would be useful might be nice for context. J: I assume you are asking for when each of the individual constraints parameters would be useful. That sounds helpful. (also dictionary change) Section 5.2.3.1 AND Section 5.2.3.2, Paragraph 1 The use of "N" is confusing. Is "N" referencing an integer value or a string with value "N". I think removing the quotes around "N" would make it entirely more understandable. J: Agreed. Constraints have been replaced with dictionaries, so we can clearly refer to this as an integer var. Section 5.3.1, Paragraph 5 This sentence is long and hard to parse. I think rewording and/or breaking up would be beneficial. J: OK.
ICE candidate pool part addressed by . I think this is now ready to be closed, but worth a double check.
I think this is now done
The text relies on the phrase "most recent gathering phase" to describe which candidates are present in SDP. Justin enumerated a few cases where the browser gathers a completely new set of candidates for an m= section (or component thereof): when a new m= section is added (which happens for a new RTCPeerConnection obviously) when an m= section did have a port of 0, but is repurposed for new media (basically the same scenario as above) ICE restart This needs a clearer definition, or maybe just a single clear description of what it means to do this. This can probably tie into the whole process of describing when candidate events fire and the interaction between that and setLocalDescription.
Martin, could you give us a PR that would satisfy you

Revised text:
3.4.  3.4.1. <ins> JSEP gathers ICE candidates as needed by the application.  Collection of ICE candidates is referred to as a gathering phase, and this is triggered either by the addition of a new or recycled m= line to the local session description, or new ICE credentials in the description, indicating an ICE restart.  Use of new ICE credentials can be triggered explicitly by the application, or implicitly by the browser in response to changes in the ICE configuration. When a new gathering phase starts, the ICE Agent will notify the application that gathering is occurring through a callback.  Then, when each new ICE candidate becomes available, the ICE Agent will supply it to the application via an additional callback; these candidates will also automatically be added to the local session description.  Finally, when all candidates have been gathered, a callback will be dispatched to signal that the gathering process is complete. Note that gathering phases only gather the candidates needed by new/recycled/restarting m= lines; other m= lines continue to use their existing candidates. 3.4.2. </ins> Candidate trickling is a technique through which a caller may incrementally provide candidates to the callee after the initial offer has been dispatched; the semantics of "Trickle ICE" are defined in cases where gathering is not performed prior to initiating the call.  <ins> JSEP supports optional candidate trickling by providing APIs, as described above, that provide control and feedback on the ICE candidate gathering process.  Applications that support candidate trickling can send the initial offer immediately and send individual candidates when they get the notified of a new candidate; applications that do not support this feature can simply wait for the indication that gathering is complete, and then create and send their offer, with all the candidates, at this time. </ins> Upon receipt of trickled candidates, the receiving application will supply them to its ICE Agent.  This triggers the ICE Agent to start using the new remote candidates for connectivity checks.  <ins> 3.4.2.1. </ins> As with session descriptions, the syntax of the IceCandidate object provides some abstraction, but can be easily converted to and from Implementations receiving an ICE Candidate object SHOULD use the MID if they implement that functionality, or the m-line index, if not.  <ins> 3.4.3. Typically, when gathering ICE candidates, the browser will gather all possible forms of initial candidates - host, server reflexive, and relay.  However, in certain cases, applications may want to have more specific control over the gathering process, due to privacy or related concerns.  For example, one may want to suppress the use of host candidates, to avoid exposing information about the local network, or go as far as only using relay candidates, to leak as little location information as possible (note that these choices come with corresponding operational costs).  To accomplish this, the browser MUST allow the application to restrict which ICE candidates are used in a session.  In addition, administrators may also wish to control the set of ICE candidates, and so the browser SHOULD also allow control via local policy, with the most restrictive policy prevailing. There may also be cases where the application wants to change which types of candidates are used while the session is active.  A prime example is where a callee may initially want to use only relay candidates, to avoid leaking location information to an arbitrary caller, but then change to use all candidates (for lower operational cost) once the user has indicated they want to take the call.  For this scenario, the browser MUST allow the candidate policy to be changed in mid-session, subject to the aforementioned interactions with local policy. To administer the ICE candidate policy, the browser will determine the current setting at the start of each gathering phase.  Then, during the gathering phase, the browser MUST NOT expose candidates disallowed by the current policy to the application, use them as the source of connectivity checks, or indirectly expose them via other fields, such as the raddr/rport attributes for other ICE candidates. Later, if a different policy is specified by the application, the application can apply it by kicking off a new gathering phase via an ICE restart. 3.4.4. </ins> JSEP applications typically inform the browser to begin ICE gathering via the information supplied to setLocalDescription, as this is where  <ins> the app specifies the number of media streams, and thereby ICE components, for which to gather candidates.  However, to accelerate cases where the application knows the number of ICE components to use ahead of time, it may ask the browser to gather a pool of potential ICE candidates to help ensure rapid media setup. When setLocalDescription is eventually called, and the browser goes to gather the needed ICE candidates, it SHOULD start by checking if any candidates are available in the pool.  If there are candidates in the pool, they SHOULD be handed to the application immediately via the ICE candidate callback.  If the pool becomes depleted, either because a larger-than-expected number of ICE components is used, or because the pool has not had enough time to gather candidates, the remaining candidates are gathered as usual. One example of where this concept is useful is an application that expects an incoming call at some point in the future, and wants to minimize the time it takes to establish connectivity, to avoid clipping of initial media.  By pre-gathering candidates into the pool, it can exchange and start sending connectivity checks from these candidates almost immediately upon receipt of a call.  Note though that by holding on to these pre-gathered candidates, which will be kept alive as long as they may be needed, the application will consume resources on the STUN/TURN servers it is using. </ins> 3.5. The PeerConnection constructor allows the application to specify global parameters for the media session, such as the STUN/TURN  <ins> servers and credentials to use when gathering candidates, as well as the initial ICE candidate policy and pool size, and also the BUNDLE policy to use. If an ICE candidate policy is specified, it functions as described in sec.ice-candidate-policy, causing the browser to only surface the permitted candidates to the application, and only use those candidates for connectivity checks.  The set of available policies is as follows: All candidates will be gathered and used. Candidates with private IP addresses [RFC1918] will be filtered out.  This prevents exposure of internal network details, at the cost of requiring relay usage even for intranet calls, if the NAT does not allow hairpinning as described in [RFC4787], section 6. All candidates except relay candidates will be filtered out.  This obfuscates the location information that might be ascertained by the remote peer from the received candidates.  Depending on how the application deploys its relay servers, this could obfuscate location to a metro or possibly even global level. Although it can be overridden by local policy, the default ICE candidate policy MUST be set to allow all candidates, as this minimizes use of application STUN/TURN server resources. If a size is specified for the ICE candidate pool, this indicates the number of ICE components to pre-gather candidates for.  Because pre- gathering results in utilizing STUN/TURN server resources for potentially long periods of time, this must only occur upon application request, and therefore the default candidate pool size MUST be zero. Lastly, the application can specify its preferred policy regarding use of BUNDLE, the multiplexing mechanism defined in I-D.ietf-mmusic- sdp-bundle-negotiation.  By specifying a policy from the list below, the application can control how aggressively it will try to BUNDLE media streams together.  The set of available policies is as follows: </ins> The application will BUNDLE all media streams of the same type together.  That is, if there are multiple audio and multiple video non-BUNDLE-aware endpoints, but require separate candidates to be gathered for each media stream. <ins> As it provides the best tradeoff between performance and compatibility with legacy endpoints, the default BUNDLE policy MUST be set to "balanced". </ins> 4.1.2. The createOffer method generates a blob of SDP that contains a 4.1.9.  <ins> The setConfiguration method allows the global configuration of the PeerConnection, which was initially set by constructor parameters, to be changed during the session.  The effects of this method call depend on when it is invoked, and differ depending on which specific parameters are changed: Any changes to the STUN/TURN servers to use affect the next gathering phase.  If gathering has already occurred, this will cause the next call to createOffer to generate new ICE credentials, for the purpose of forcing an ICE restart and kicking off a new gathering phase, in which the new servers will be used. If the ICE candidate pool has a nonzero size, any existing candidates will be discarded, and new candidates will be gathered from the new servers. Any changes to the ICE candidate policy also affect the next gathering phase, in similar fashion to the server changes described above.  Note though that changes to the policy have no effect on the candidate pool, because pooled candidates are not surfaced to the application until a gathering phase occurs, and so any necessary filtering can still be done on any pooled candidates. Any changes to the ICE candidate pool size take effect immediately; if increased, additional candidates are pre-gathered; if decreased, the now-superfluous candidates are discarded. </ins>  <ins> Any changes to the BUNDLE policy take effect immediately, i.e. any future tracks added to the PeerConnection will have their bundle-only state marked accordingly. </ins> This call may result in a change to the state of the ICE Agent, and may result in a change to media state if it results in connectivity Each "a=mid" line MUST stay the same.  <ins> Each "a=ice-ufrag" and "a=ice-pwd" line MUST stay the same, unless the ICE configuration has changed (either changes to the supported STUN/TURN servers, or the ICE candidate policy), or the "IceRestart" option (sec.icerestart was specified. </ins> For MediaStreamTracks that are still present, the "a=msid", "a=ssrc", and "a=ssrc-group" lines MUST stay the same. this option is specified in the case where at least N audio MediaStreamTracks have already been added to the PeerConnection, or N non-rejected m= sections with media type "audio" would otherwise be  <ins> generated, it has no effect.  For backwards compatibility with pre- standard versions of this specification, a value of "true" is interpreted as equivalent to N=1. </ins> 5.2.3.2. this option is specified in the case where at least N video MediaStreamTracks have already been added to the PeerConnection, or N non-rejected m= sections with media type "video" would otherwise be  <ins> generated, it has no effect.  For backwards compatibility with pre- standard versions of this specification, a value of "true" is interpreted as equivalent to N=1. </ins> 5.2.3.3. offer MUST indicate an ICE restart by generating new ICE ufrag and pwd attributes, as specified in RFC5245, Section 9.1.1.1.  If this option is specified on an initial offer, it has no effect (since a  <ins> new ICE ufrag and pwd are already generated).  Similarly, if the ICE configuration has changed, this option has no effect, since new ufrag and pwd attributes will be generated automatically.  This option is primarily useful for reestablishing connectivity in cases where failures are detected by the application. </ins> 5.3.