-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdraft-ietf-ice-trickle.xml
1896 lines (1887 loc) · 82.4 KB
/
draft-ietf-ice-trickle.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<rfc category='std' ipr='trust200902'
docName='draft-ietf-ice-trickle-21'>
<?rfc toc='yes' ?>
<?rfc symrefs='yes' ?>
<?rfc sortrefs='yes'?>
<?rfc iprnotified='no' ?>
<?rfc strict='yes' ?>
<?rfc compact='yes' ?>
<front>
<title abbrev='Trickle ICE'>
Trickle ICE: Incremental Provisioning of Candidates for the Interactive
Connectivity Establishment (ICE) Protocol
</title>
<author initials='E.' surname='Ivov'
fullname='Emil Ivov'>
<organization abbrev='Atlassian'>Atlassian</organization>
<address>
<postal>
<street>303 Colorado Street, #1600</street>
<city>Austin</city>
<region>TX</region>
<code>78701</code>
<country>USA</country>
</postal>
<phone>+1-512-640-3000</phone>
<email>eivov@atlassian.com</email>
</address>
</author>
<author fullname="Eric Rescorla" initials="E.K." surname="Rescorla">
<organization>RTFM, Inc.</organization>
<address>
<postal>
<street>2064 Edgewood Drive</street>
<city>Palo Alto</city>
<region>CA</region>
<code>94303</code>
<country>USA</country>
</postal>
<phone>+1 650 678 2350</phone>
<email>ekr@rtfm.com</email>
</address>
</author>
<author fullname="Justin Uberti" initials="J." surname="Uberti">
<organization>Google</organization>
<address>
<postal>
<street>747 6th St S</street>
<city>Kirkland</city>
<region>WA</region>
<code>98033</code>
<country>USA</country>
</postal>
<phone>+1 857 288 8888</phone>
<email>justin@uberti.name</email>
</address>
</author>
<author initials="P." surname="Saint-Andre" fullname="Peter Saint-Andre">
<organization>Mozilla</organization>
<address>
<postal>
<street>P.O. Box 787</street>
<city>Parker</city>
<region>CO</region>
<code>80134</code>
<country>USA</country>
</postal>
<phone>+1 720 256 6756</phone>
<email>stpeter@mozilla.com</email>
<uri>https://www.mozilla.com/</uri>
</address>
</author>
<date />
<abstract>
<t>
This document describes "Trickle ICE", an extension to the Interactive
Connectivity Establishment (ICE) protocol that enables ICE agents
to begin connectivity checks while they are still gathering
candidates, by incrementally exchanging candidates over time instead
of all at once. This method can considerably accelerate the process
of establishing a communication session.
</t>
</abstract>
</front>
<middle>
<section title='Introduction'>
<t>
The Interactive Connectivity Establishment (ICE) protocol
<xref target="rfc5245bis"/> describes how an ICE agent
gathers candidates, exchanges candidates with a peer ICE
agent, and creates candidate pairs. Once the pairs have been
gathered, the ICE agent will perform connectivity checks, and
eventually nominate and select pairs that will be used for
sending and receiving data within a communication session.
</t>
<t>
Following the procedures in <xref target="rfc5245bis"/> can
lead to somewhat lengthy establishment times for communication sessions,
because candidate gathering often involves querying STUN servers
<xref target="RFC5389"/> and allocating relayed candidates using
TURN servers <xref target="RFC5766"/>. Although many ICE procedures
can be completed in parallel, the pacing requirements from
<xref target="rfc5245bis"/> still need to be followed.
</t>
<t>
This document defines "Trickle ICE", a supplementary mode of ICE
operation in which candidates can be exchanged
incrementally as soon as they become available (and simultaneously
with the gathering of other candidates). Connectivity checks can
also start as soon as candidate pairs have been created. Because
Trickle ICE enables candidate gathering and connectivity checks
to be done in parallel, the method can considerably accelerate
the process of establishing a communication session.
</t>
<t>
This document also defines how to discover support for
Trickle ICE, how the procedures in <xref target="rfc5245bis"/> are
modified or supplemented when using Trickle ICE, and how a Trickle
ICE agent can interoperate with an ICE agent compliant to
<xref target="rfc5245bis"/>.
</t>
<t>
This document does not define any protocol-specific usage of Trickle
ICE. Instead, protocol-specific details for Trickle ICE are defined
in separate usage documents. Examples of such documents are
<xref target="I-D.ietf-mmusic-trickle-ice-sip"/> (which defines usage
with the Session Initiation Protocol (SIP) <xref target='RFC3261'/>
and the Session Description Protocol <xref target='RFC3261'/>) and
<xref target='XEP-0176'/> (which defines usage with XMPP
<xref target='RFC6120'/>). However, some of the examples in the
document use SDP and the offer/answer model <xref target='RFC3264'/>
to explain the underlying concepts.
</t>
<t>
The following diagram illustrates a successful Trickle ICE exchange with a
using protocol that follows the offer/answer model:
</t>
<figure title="Flow" anchor="fig-flow">
<artwork>
<![CDATA[
Alice Bob
| Offer |
|---------------------------------------------->|
| Additional Candidates |
|---------------------------------------------->|
| Answer |
|<----------------------------------------------|
| Additional Candidates |
|<----------------------------------------------|
| Additional Candidates and Connectivity Checks |
|<--------------------------------------------->|
|<========== CONNECTION ESTABLISHED ===========>|
]]>
</artwork>
</figure>
<t>
The main body of this document is structured to describe the behavior
of Trickle ICE agents in roughly the order of operations and interactions
during an ICE session:
<list style='numbers'>
<t>Determining support for trickle ICE</t>
<t>Generating the initial ICE description</t>
<t>Handling the initial ICE description and generating the initial ICE response</t>
<t>Handling the initial ICE response</t>
<t>Forming check lists, pruning candidates, performing connectivity checks, etc.</t>
<t>Gathering and conveying candidates after the initial ICE description and response</t>
<t>Handling inbound trickled candidates</t>
<t>Generating and handling the end-of-candidates indication</t>
<t>Handling ICE restarts</t>
</list>
</t>
<t>
There is quite a bit of operational experience with the technique behind
Trickle ICE, going back as far as 2005 (when the XMPP Jingle extension
defined a "dribble mode" as specified in <xref target='XEP-0176'/>); this
document incorporates feedback from those who have implemented and
deployed the technique over the years.
</t>
</section>
<section title="Terminology">
<t>
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described
in <xref target="RFC2119"/>.
</t>
<t>
This specification makes use of all terminology defined
for Interactive Connectivity Establishment in
<xref target="rfc5245bis"/>. In addition, it defines the following terms:
</t>
<t>
<list style="hanging">
<t hangText="Full Trickle:">
The typical mode of operation for Trickle ICE agents, in which
the initial ICE description can include any number of candidates (even
zero candidates) and does not need to include a full generation
of candidates as in half trickle.
</t>
<t hangText="Generation:">
All of the candidates conveyed within an ICE session (correlated
with a particular Username Fragment and Password combination).
</t>
<t hangText="Half Trickle:">
A Trickle ICE mode of operation in which the initiator gathers
a full generation of candidates strictly before creating
and conveying the initial ICE description. Once conveyed,
this candidate information can be
processed by regular ICE agents, which do not require support
for Trickle ICE. It also allows Trickle ICE capable
responders to still gather candidates and perform
connectivity checks in a non-blocking way, thus providing roughly
"half" the advantages of Trickle ICE. The half trickle mechanism
is mostly meant for use when the responder's support for Trickle
ICE cannot be confirmed prior to conveying the initial ICE description.
</t>
<t hangText="ICE Description:">
Any attributes related to the ICE session (not candidates)
required to configure an ICE agent. These include but are not
limited to the username fragment, password, and other attributes.
</t>
<t hangText="Trickled Candidates:">
Candidates that a Trickle ICE agent conveys after conveying the initial
ICE description or responding to the initial ICE description, but within
the same ICE session. Trickled candidates can be conveyed in
parallel with candidate gathering and connectivity checks.
</t>
<t hangText="Trickling:">
The act of incrementally conveying trickled candidates.
</t>
<t hangText="Empty Check List:">
A check list that initially does not contain any candidate pairs
because they will be incrementally added as they are trickled.
(This scenario does not arise with a regular ICE agent, because all
candidate pairs are known when the agent creates the check list set).
</t>
</list>
</t>
</section>
<section title='Determining Support for Trickle ICE' anchor="support">
<t>
To fully support Trickle ICE, using protocols
SHOULD incorporate one of the following mechanisms so that implementations
can determine whether Trickle ICE is supported:
</t>
<t>
<list style='numbers'>
<t>
Provide a capabilities discovery method so that agents can verify
support of Trickle ICE prior to initiating a session (XMPP's
<xref target="XEP-0030">Service Discovery</xref> is
one such mechanism).
</t>
<t>
Make support for Trickle ICE mandatory so that user agents
can assume support.
</t>
</list>
</t>
<t>
If a using protocol does not provide a method of determining
ahead of time whether Trickle ICE is supported, agents can make use of
the half trickle procedure described in <xref target="half-trickle"/>.
</t>
<t>
Prior to conveying the initial ICE description, agents that implement using protocols
that support capabilities discovery can attempt to verify whether or
not the remote party supports Trickle ICE. If an agent determines
that the remote party does not support Trickle ICE, it MUST fall back
to using regular ICE or abandon the entire session.
</t>
<t>
Even if a using protocol does not include a capabilities discovery
method, a user agent can provide an indication within the ICE description
that it supports Trickle ICE by communicating an ICE option of 'trickle'.
This token MUST be provided either at the session level or, if at the data
stream level, for every data stream (an agent MUST NOT specify Trickle ICE
support for some data streams but not others).
Note: The encoding of the 'trickle' ICE option, and the message(s) used to
carry it to the peer, are protocol specific; for instance, the encoding for
the Session Description Protocol (SDP) <xref target='RFC4566'/> is defined in
<xref target='I-D.ietf-mmusic-trickle-ice-sip'/>.
</t>
<t>
Dedicated discovery semantics and half trickle are needed only prior
to initiation of an ICE session. After an ICE session is established
and Trickle ICE support is confirmed for both parties, either
agent can use full trickle for subsequent exchanges (see also
<xref target='subsequent'/>).
</t>
</section>
<section title='Generating the Initial ICE Description' anchor="initial">
<t>
An ICE agent can start gathering candidates as soon as it has an
indication that communication is imminent (e.g., a user interface
cue or an explicit request to initiate a communication session). Unlike in
regular ICE, in Trickle ICE implementations do not need to
gather candidates in a blocking manner. Therefore, unless half
trickle is being used, the user experience is improved if the
initiating agent generates and transmits its initial ICE description
as early as possible (thus enabling the remote party to start
gathering and trickling candidates).
</t>
<t>
An initiator MAY include any mix of candidates when conveying
the initial ICE description. This includes the possibility of conveying
all the candidates the initiator plans to use
(as in half trickle), conveying only a
publicly-reachable IP address (e.g., a candidate at a data
relay that is known to not be behind a firewall), or conveying
no candidates at all (in which case the initiator can obtain the
responder's initial candidate list sooner and the responder can begin
candidate gathering more quickly).
</t>
<t>
For candidates included in the initial ICE description, the methods
for calculating priorities and foundations, determining redundancy
of candidates, and the like work just as in regular ICE
<xref target="rfc5245bis"/>.
</t>
</section>
<section title='Handling the Initial ICE Description and Generating the Initial ICE Response' >
<t>
When a responder receives the initial ICE description, it will first check if
the ICE description or initiator indicates support for Trickle ICE as explained
in <xref target="support"/>. If not, the responder MUST
process the initial ICE description according to regular ICE procedures
<xref target="rfc5245bis"/> (or, if no ICE support is detected at all,
according to relevant processing rules for the using
protocol, such as offer/answer processing rules <xref target="RFC3264"/>).
However, if support for Trickle ICE is confirmed, a responder will
automatically assume support for regular ICE as well.
</t>
<t>
If the initial ICE description indicates support for Trickle ICE, the
responder will determine its role and start gathering and prioritizing
candidates; while doing so, it will also respond by conveying an
initial ICE response, so that both the initiator
and the responder can form check lists and begin connectivity checks.
</t>
<t>
A responder can respond to the initial ICE description at any point while
gathering candidates. The initial ICE response MAY contain any set of
candidates, including all candidates or no candidates. (The benefit of
including no candidates is to convey the initial ICE response as
quickly as possible, so that both parties can consider the
ICE session to be under active negotiation as soon as
possible.)
</t>
<t>
As noted in <xref target="support"/>, in using protocols that use
SDP the initial ICE response can indicate support for Trickle ICE
by including a token of "trickle" in the ice-options attribute.
</t>
</section>
<section title="Handling the Initial ICE Response">
<t>
When processing the initial ICE response, the initiator follows regular ICE
procedures to determine its role, after which it
forms check lists (<xref target="checklists"/>)
and performs connectivity checks (<xref target='checks'/>).
</t>
</section>
<section title='Forming Check Lists' anchor='checklists'>
<t>
According to regular ICE procedures <xref target="rfc5245bis"/>,
in order for candidate pairing
to be possible and for redundant candidates to be pruned, the
candidates would need to be provided in the initial ICE description
and initial ICE response.
By contrast, under Trickle ICE check lists can be empty until
candidates are conveyed or received. Therefore a Trickle ICE agent
handles check list formation and candidate pairing in a slightly different
way than a regular ICE agent: the agent still forms the check lists, but
it populates a given check list only after it actually has candidate
pairs for that check list. Every check list is initially placed in the
Running state, even if the check list is empty (this is consistent
with Section 6.1.2.1 of <xref target='rfc5245bis'/>).
</t>
</section>
<section title='Performing Connectivity Checks' anchor='checks'>
<t>
As specified in <xref target='rfc5245bis'/>, whenever timer
Ta fires, only check lists in the Running state will be picked
when scheduling connectivity checks for candidate pairs.
Therefore, a Trickle ICE agent MUST keep each check list in
the Running state as long as it expects candidate pairs to be
incrementally added to the check list. After that, the check
list state is set according to the procedures in
<xref target='rfc5245bis'/>.
</t>
<t>
Whenever timer Ta fires and an empty check list is picked, no action
is performed for the list. Without waiting for timer Ta to expire
again, the agent selects the next check list in the Running state,
in accordance with Section 6.1.4.2 of <xref target='rfc5245bis'/>.
</t>
<t>
Section 7.2.5.3.3 of <xref target='rfc5245bis'/>
requires that agents update check lists and timer states upon
completing a connectivity check transaction. During such an
update, regular ICE agents would set the state of a check list
to Failed if both of the following two conditions are satisfied:
</t>
<t>
<list style="symbols">
<t>
all of the pairs in the check list are either in the
Failed state or Succeeded state; and
</t>
<t>
there is not a pair in the valid list for each component
of the data stream.
</t>
</list>
</t>
<t>
With Trickle ICE, the above situation would often occur when
candidate gathering and trickling are still in progress, even
though it is quite possible that future checks will succeed. For
this reason, Trickle ICE agents add the following conditions to
the above list:
</t>
<t>
<list style="symbols">
<t>
all candidate gathering has completed and the agent
is not expecting to discover any new local candidates; and
</t>
<t>
the remote agent has conveyed an end-of-candidates indication
for that check list as described in
<xref target="end-of-candidates.send"/>.
</t>
</list>
</t>
</section>
<section title='Gathering and Conveying Newly Gathered Local Candidates'
anchor="trickle-send">
<t>
After Trickle ICE agents have conveyed initial ICE descriptions
and initial ICE responses, they will most
likely continue gathering new local candidates as STUN, TURN,
and other non-host candidate gathering mechanisms begin to
yield results. Whenever an agent discovers such a new candidate
it will compute its priority, type, foundation, and component ID
according to regular ICE procedures.
</t>
<t>
The new candidate is then checked for redundancy against the
existing list of local candidates. If its transport address and
base match those of an existing candidate, it will be considered
redundant and will be ignored. This would often happen for
server reflexive candidates that match the host addresses they
were obtained from (e.g., when the latter are public IPv4
addresses). Contrary to regular ICE, Trickle ICE agents will
consider the new candidate redundant regardless of its priority.
</t>
<t>
Next the agent "trickles" the newly discovered
candidate(s) to the remote agent. The actual delivery of the new
candidates is handled by a using protocol such as SIP or XMPP.
Trickle ICE imposes no restrictions on the way this is done
(e.g., some using protocols might
choose not to trickle updates for server reflexive
candidates and instead rely on the discovery of peer reflexive ones).
</t>
<t>
When candidates are trickled, the using protocol MUST deliver each
candidate (and any end-of-candidates indication as described in
<xref target='end-of-candidates.send'/>) to the receiving Trickle ICE implementation
exactly once
and in the same order it was conveyed. If the using protocol
provides any candidate retransmissions, they need to be hidden
from the ICE implementation.
</t>
<t>
Also, candidate trickling needs to be correlated to a specific
ICE session, so that if there is an ICE restart, any
delayed updates for a previous session can be recognized as such
and ignored by the receiving party. For example, using protocols
that signal candidates via SDP might include a Username
Fragment value in the corresponding a=candidate line, such as:
<figure>
<artwork>
<![CDATA[
a=candidate:1 1 UDP 2130706431 2001:db8::1 5000 typ host ufrag 8hhY
]]>
</artwork>
</figure>
Or, as another example, WebRTC implementations might include a Username
Fragment in the JavaScript objects that represent candidates.
</t>
<t>
Note: The using protocol needs to provide a mechanism for both
parties to indicate and agree on the ICE session in force
(as identified by the Username Fragment and Password combination)
so that they have a consistent view of which candidates are
to be paired. This is especially important in the case of ICE
restarts (see <xref target='subsequent'/>).
</t>
<t>
Note: A using protocol might prefer not to
trickle server reflexive candidates to entities that are known
to be publicly accessible and where sending a direct STUN
binding request is likely to reach the destination faster than
the trickle update that travels through the signaling path.
</t>
</section>
<section title='Pairing Newly Gathered Local Candidates' anchor="local-pairing">
<t>
As a Trickle ICE agent gathers local candidates, it needs
to form candidate pairs; this works as described in
the ICE specification <xref target='rfc5245bis'/>, with the
following provisos:
<list style='numbers'>
<t>
A Trickle ICE agent MUST NOT pair a local candidate until it
has been trickled to the remote party.
</t>
<t>
Once the agent has conveyed the local candidate to the remote
party, the agent checks if any remote candidates are currently
known for this same stream and component. If not, the agent
merely adds the new candidate to the list of local candidates
(without pairing it).
</t>
<t>
Otherwise, if the agent has already learned of one or more
remote candidates for this stream and component, it attempts
to pair the new local candidate as described in the ICE
specification <xref target='rfc5245bis'/>.
</t>
<t>
If a newly formed pair has a local candidate whose type is server
reflexive, the agent MUST replace the local candidate with its
base before completing the relevant redundancy tests.
</t>
<t>
The agent prunes redundant pairs by following the rules
in Section 6.1.2.4 of <xref target='rfc5245bis'/>, but checks
existing pairs only if they have a state of Waiting or Frozen;
this avoids removal of pairs for which connectivity checks are
in flight (a state of In-Progress) or for which connectivity
checks have already yielded a definitive result (a state of
Succeeded or Failed).
</t>
<t>
If after the relevant redundancy tests the check list where the
pair is to be added already contains the maximum number of candidate
pairs (100 by default as per <xref target="rfc5245bis"/>), the agent
SHOULD discard any pairs in the Failed state to make room for the
new pair. If there are no such pairs, the agent SHOULD discard a
pair with a lower priority than the new pair in order to make room
for the new pair, until the number of pairs is equal to the maximum
number of pairs. This processing is consistent with Section 6.1.2.5
of <xref target='rfc5245bis'/>.
</t>
</list>
</t>
</section>
<section title='Receiving Trickled Candidates' anchor="trickle-recv">
<t>
At any time during an ICE session, a Trickle ICE agent might receive
new candidates from the remote agent, from which it will attempt to
form a candidate pair; this works as described in the ICE specification
<xref target='rfc5245bis'/>, with the following provisos:
<list style='numbers'>
<t>
The agent checks if any local candidates are currently known for
this same stream and component. If not, the agent merely adds the
new candidate to the list of remote candidates (without pairing it).
</t>
<t>
Otherwise, if the agent has already gathered one or more
local candidates for this stream and component, it attempts
to pair the new remote candidate as described in the ICE
specification <xref target='rfc5245bis'/>.
</t>
<t>
If a newly formed pair has a local candidate whose type is server
reflexive, the agent MUST replace the local candidate with its
base before completing the redundancy check in the next step.
</t>
<t>
The agent prunes redundant pairs as described below, but checks
existing pairs only if they have a state of Waiting or Frozen;
this avoids removal of pairs for which connectivity checks are
in flight (a state of In-Progress) or for which connectivity
checks have already yielded a definitive result (a state of
Succeeded or Failed).
<list style='letters'>
<t>
If the agent finds a redundancy between two pairs and one of
those pairs contains a newly received remote candidate whose
type is peer reflexive, the agent SHOULD discard the
pair containing that candidate, set the priority of the
existing pair to the priority of the discarded pair, and
re-sort the check list. (This policy helps to eliminate
problems with remote peer reflexive candidates for which
a STUN binding request is received before signaling of the
candidate is trickled to the receiving agent, such as a
different view of pair priorities between the local agent
and the remote agent, because the same candidate could be
perceived as peer reflexive by one agent and as server
reflexive by the other agent.)
</t>
<t>
The agent then applies the rules defined in
Section 6.1.2.4 of <xref target='rfc5245bis'/>.
</t>
</list>
</t>
<t>
If after the relevant redundancy tests the check list where the
pair is to be added already contains the maximum number of candidate
pairs (100 by default as per <xref target="rfc5245bis"/>), the agent
SHOULD discard any pairs in the Failed state to make room for the
new pair. If there are no such pairs, the agent SHOULD discard a
pair with a lower priority than the new pair in order to make room
for the new pair, until the number of pairs is equal to the maximum
number of pairs. This processing is consistent with Section 6.1.2.5
of <xref target='rfc5245bis'/>.
</t>
</list>
</t>
</section>
<section title='Inserting Trickled Candidate Pairs into a Check List'
anchor="trickle-insert">
<t>
After a local agent has trickled a candidate and formed a candidate
pair from that local candidate (<xref target='trickle-send'/>), or after
a remote agent has received a trickled candidate and formed a candidate
pair from that remote candidate (<xref target='trickle-recv'/>), a Trickle
ICE agent adds the new candidate pair to a check list as defined in
this section.
</t>
<t>
As an aid to understanding the procedures defined in this section,
consider the following tabular representation of all check lists in
an agent (note that initially for one of the foundations, i.e., f5,
there are no candidate pairs):
</t>
<t>
<figure title="Example of Check List State" anchor="fig-checklist-0">
<artwork>
<![CDATA[
+-----------------+------+------+------+------+------+
| | f1 | f2 | f3 | f4 | f5 |
+-----------------+------+------+------+------+------+
| s1 (Audio.RTP) | F | F | F | | |
+-----------------+------+------+------+------+------+
| s2 (Audio.RTCP) | F | F | F | F | |
+-----------------+------+------+------+------+------+
| s3 (Video.RTP) | F | | | | |
+-----------------+------+------+------+------+------+
| s4 (Video.RTCP) | F | | | | |
+-----------------+------+------+------+------+------+
]]>
</artwork>
</figure>
</t>
<t>
Each row in the table represents a component for a given data
stream (e.g., s1 and s2 might be the RTP and RTCP components
for audio) and thus a single check list in the check list set.
Each column represents one foundation. Each cell represents one
candidate pair. In the tables shown in this section, "F" stands
for "frozen", "W" stands for "waiting", and "S" stands for
"succeeded"; in addition, "^^" is used to notate newly-added
candidate pairs.
</t>
<t>
When an agent commences ICE processing, in accordance with
Section 6.1.2.6 of <xref target="rfc5245bis"/>, for each
foundation it will unfreeze the pair with the lowest component
ID and, if the component IDs are equal, with the highest priority
(this is the topmost candidate pair in every column).
This initial state is shown in the following table.
</t>
<t>
<figure title="Initial Check List State" anchor="fig-checklist-initial">
<artwork>
<![CDATA[
+-----------------+------+------+------+------+------+
| | f1 | f2 | f3 | f4 | f5 |
+-----------------+------+------+------+------+------+
| s1 (Audio.RTP) | W | W | W | | |
+-----------------+------+------+------+------+------+
| s2 (Audio.RTCP) | F | F | F | W | |
+-----------------+------+------+------+------+------+
| s3 (Video.RTP) | F | | | | |
+-----------------+------+------+------+------+------+
| s4 (Video.RTCP) | F | | | | |
+-----------------+------+------+------+------+------+
]]>
</artwork>
</figure>
</t>
<t>
Then, as the checks proceed (see Section 7.2.5.4 of
<xref target="rfc5245bis"/>), for each pair
that enters the Succeeded state (denoted here by "S"),
the agent will unfreeze all pairs for all data streams with the same
foundation (e.g., if the pair in column 1, row 1 succeeds then
the agent will unfreeze the pair in column 1, rows 2, 3, and 4).
</t>
<t>
<figure title="Check List State with Succeeded Candidate Pair" anchor="fig-checklist-succeeded">
<artwork>
<![CDATA[
+-----------------+------+------+------+------+------+
| | f1 | f2 | f3 | f4 | f5 |
+-----------------+------+------+------+------+------+
| s1 (Audio.RTP) | S | W | W | | |
+-----------------+------+------+------+------+------+
| s2 (Audio.RTCP) | W | F | F | W | |
+-----------------+------+------+------+------+------+
| s3 (Video.RTP) | W | | | | |
+-----------------+------+------+------+------+------+
| s4 (Video.RTCP) | W | | | | |
+-----------------+------+------+------+------+------+
]]>
</artwork>
</figure>
</t>
<t>
Trickle ICE preserves all of these rules as they apply to
"static" check list sets. This implies that if
a Trickle ICE agent were to begin connectivity checks with all
of its pairs already present, the way that pair states change
is indistinguishable from that of a regular ICE agent.
</t>
<t>
Of course, the major difference with Trickle ICE is that check list
sets can be dynamically updated because candidates can
arrive after connectivity checks have started. When this happens, an
agent sets the state of the newly formed pair as described below.
</t>
<t>
Rule 1: If the newly formed pair has the lowest component ID and,
if the component IDs are equal, the highest priority of any candidate
pair for this foundation (i.e., if it is the topmost pair in the
column), set the state to Waiting. For example, this would be the
case if the newly formed pair were placed in column 5, row 1. This
rule is consistent with Section 6.1.2.6 of <xref target="rfc5245bis"/>.
</t>
<t>
<figure title="Check List State with Newly Formed Pair, Rule 1" anchor="fig-checklist-rule1">
<artwork>
<![CDATA[
+-----------------+------+------+------+------+------+
| | f1 | f2 | f3 | f4 | f5 |
+-----------------+------+------+------+------+------+
| s1 (Audio.RTP) | S | W | W | | ^W^ |
+-----------------+------+------+------+------+------+
| s2 (Audio.RTCP) | W | F | F | W | |
+-----------------+------+------+------+------+------+
| s3 (Video.RTP) | W | | | | |
+-----------------+------+------+------+------+------+
| s4 (Video.RTCP) | W | | | | |
+-----------------+------+------+------+------+------+
]]>
</artwork>
</figure>
</t>
<t>
Rule 2: If there is at least one pair in the Succeeded state for
this foundation, set the state to Waiting. For example, this would be
the case if the pair in column 5, row 1 succeeded and the newly formed
pair were placed in column 5, row 2. This rule is consistent with
Section 7.2.5.3.3 of <xref target="rfc5245bis"/>.
</t>
<t>
<figure title="Check List State with Newly Formed Pair, Rule 2" anchor="fig-checklist-rule2">
<artwork>
<![CDATA[
+-----------------+------+------+------+------+------+
| | f1 | f2 | f3 | f4 | f5 |
+-----------------+------+------+------+------+------+
| s1 (Audio.RTP) | S | W | W | | S |
+-----------------+------+------+------+------+------+
| s2 (Audio.RTCP) | W | F | F | W | ^W^ |
+-----------------+------+------+------+------+------+
| s3 (Video.RTP) | W | | | | |
+-----------------+------+------+------+------+------+
| s4 (Video.RTCP) | W | | | | |
+-----------------+------+------+------+------+------+
]]>
</artwork>
</figure>
</t>
<t>
Rule 3: In all other cases, set the state to Frozen. For example,
this would be the case if the newly formed pair were placed in
column 3, row 3.
</t>
<t>
<figure title="Check List State with Newly Formed Pair, Rule 3" anchor="fig-checklist-rule3">
<artwork>
<![CDATA[
+-----------------+------+------+------+------+------+
| | f1 | f2 | f3 | f4 | f5 |
+-----------------+------+------+------+------+------+
| s1 (Audio.RTP) | S | W | W | | S |
+-----------------+------+------+------+------+------+
| s2 (Audio.RTCP) | W | F | F | W | W |
+-----------------+------+------+------+------+------+
| s3 (Video.RTP) | W | | ^F^ | | |
+-----------------+------+------+------+------+------+
| s4 (Video.RTCP) | W | | | | |
+-----------------+------+------+------+------+------+
]]>
</artwork>
</figure>
</t>
</section>
<section title='Generating an End-of-Candidates Indication'
anchor="end-of-candidates.send">
<t>
Once all candidate gathering is completed or expires for an
ICE session associated with a specific data stream, the agent will generate an
"end-of-candidates" indication for that session and convey it to
the remote agent via the signaling channel. Although the exact form of
the indication depends on the using protocol, the indication
MUST specify the generation (Username Fragment and Password combination) so that an agent
can correlate the end-of-candidates indication with a particular ICE
session. The indication can be conveyed in the following ways:
<list style='symbols'>
<t>As part of an initiation request (which would typically be the case with
the initial ICE description for half trickle)</t>
<t>Along with the last candidate an agent can send for a stream</t>
<t>As a standalone notification (e.g., after STUN Binding requests
or TURN Allocate requests to a server time out and the agent
is no longer actively gathering candidates)</t>
</list>
</t>
<t>
Conveying an end-of-candidates indication in a timely manner is important
in order to avoid ambiguities and speed up the conclusion of ICE processing.
In particular:
<list style='symbols'>
<t>
A controlled Trickle ICE agent SHOULD convey an end-of-candidates
indication after it has completed gathering for a data stream,
unless ICE processing terminates before the agent has had a chance
to complete gathering.
</t>
<t>
A controlling agent MAY conclude ICE processing prior to conveying
end-of-candidates indications for all streams. However, it is
RECOMMENDED for a controlling agent to convey end-of-candidates
indications whenever possible for the sake of consistency and to
keep middleboxes and controlled agents up-to-date on the state of
ICE processing.
</t>
</list>
</t>
<t>
When conveying an end-of-candidates indication during trickling
(rather than as a part of the initial ICE description or a response thereto),
it is the responsibility of the
using protocol to define methods for associating the
indication with one or more specific data streams.
</t>
<t>
An agent MAY also choose to generate an end-of-candidates
indication before candidate gathering has actually completed, if the
agent determines that gathering has continued for more than an
acceptable period of time. However, an agent MUST NOT convey any
more candidates after it has conveyed an end-of-candidates
indication.
</t>
<t>
When performing half trickle, an agent SHOULD convey an
end-of-candidates indication together with its initial ICE description unless
it is planning to potentially trickle additional candidates (e.g., in
case the remote party turns out to support Trickle ICE).
</t>
<t>
After an agent conveys the end-of-candidates indication, it will
update the state of the corresponding check list as explained
in <xref target="checks"/>. Past that point, an
agent MUST NOT trickle any new candidates within this ICE session.
Therefore, adding new candidates to the
negotiation is possible only through an ICE restart (see
<xref target='subsequent'/>).
</t>
<t>
This specification does not
override regular ICE semantics for concluding ICE processing.
Therefore, even if end-of-candidates indications are conveyed,
an agent will still need to go through pair nomination. Also, if
pairs have been nominated for components and data streams, ICE
processing MAY still conclude even if end-of-candidates
indications have not been received for all streams. In all cases,
an agent MUST NOT trickle any new candidates within an ICE session
after nomination of a candidate pair as described in Section 8.1.1
of <xref target='rfc5245bis'/>.
</t>
</section>
<section title='Receiving an End-of-Candidates Indication'
anchor="end-of-candidates.recv">
<t>
Receiving an end-of-candidates indication enables an agent to
update check list states and, in case valid pairs do not exist
for every component in every data stream, determine that ICE
processing has failed. It also enables an agent to speed up the
conclusion of ICE processing when a candidate pair has been validated
but it involves the use of lower-preference transports such as
TURN. In such situations, an implementation MAY choose to wait
and see if higher-priority candidates are received; in this case
the end-of-candidates indication provides a notification that such
candidates are not forthcoming.
</t>
<t>
When an agent receives an end-of-candidates indication for a
specific data stream, it will update the state of the relevant
check list as per <xref target="checks"/> (which might lead to
some check lists being marked as Failed). If the check list is
still in the Running state after the update, the agent will persist
the fact that an end-of-candidates indication has been
received and take it into account in future updates
to the check list.
</t>
<t>
After an agent has received an end-of-candidates indication, it
MUST ignore any newly received candidates for that data
stream or data session.
</t>
</section>
<section title='Subsequent Exchanges and ICE Restarts'
anchor="subsequent">
<t>
Before conveying an end-of-candidates indication,
either agent MAY convey subsequent candidate information at any time allowed
by the using protocol. When this happens, agents will use
<xref target="rfc5245bis"/> semantics (e.g., checking of the
Username Fragment and Password combination) to determine whether or not
the new candidate information requires an ICE restart.
</t>
<t>
If an ICE restart
occurs, the agents can assume that Trickle ICE is still supported
if support was determined previously, and thus can engage in Trickle ICE
behavior as they would in an initial exchange of ICE descriptions where
support was determined through a capabilities discovery method.
</t>
</section>
<section title='Half Trickle' anchor="half-trickle">
<t>
In half trickle, the initiator conveys the initial ICE description
with a usable but not necessarily full generation of candidates. This
ensures that the ICE description can be processed by a regular ICE
responder and is mostly meant for use in cases where support for
Trickle ICE cannot be confirmed prior to conveying the initial ICE
description. The initial ICE description indicates support for
Trickle ICE, so that the responder can respond with something less
than a full generation of candidates and then trickle the rest.
The initial ICE description for half trickle can contain
an end-of-candidates indication, although this is not mandatory
because if trickle support is confirmed then the initiator can
choose to trickle additional candidates before it conveys an
end-of-candidates indication.
</t>
<t>
The half trickle mechanism can be used in cases where there is
no way for an agent to verify in advance whether a remote
party supports Trickle ICE. Because the initial ICE description contain
a full generation of candidates, it can thus be handled by a regular
ICE agent, while still allowing a Trickle ICE agent to use
the optimization defined in this specification. This prevents
negotiation from failing in the former case while still giving
roughly half the Trickle ICE benefits in the latter.
</t>
<t>
Use of half trickle is only necessary during an initial
exchange of ICE descriptions. After both parties have received
an ICE description from their peer, they can each reliably
determine Trickle ICE support and use it for all subsequent
exchanges (see <xref target='subsequent'/>).
</t>
<t>
In some instances, using half trickle might bring more than
just half the improvement in terms of user experience. This
can happen when an agent starts gathering candidates upon user
interface cues that the user will soon be initiating an interaction,
such as activity on a keypad or the phone going off hook. This
would mean that some or all of the candidate
gathering could be completed before the agent actually
needs to convey the candidate information. Because the responder will be able
to trickle candidates, both agents will be able to start