Artem Titov | a617867 | 2023-01-30 10:51:01 | [diff] [blame] | 1 | <!-- go/cmark --> |
| 2 | <!--* freshness: {owner: 'jonaso' reviewed: '2021-04-12'} *--> |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 3 | |
Artem Titov | a617867 | 2023-01-30 10:51:01 | [diff] [blame] | 4 | # ICE |
Artem Titov | 0f2ce5c | 2023-01-26 20:18:46 | [diff] [blame] | 5 | |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 6 | ## Overview |
| 7 | |
| 8 | ICE ([link](https://developer.mozilla.org/en-US/docs/Glossary/ICE)) provides |
| 9 | unreliable packet transport between two clients (p2p) or between a client and a |
| 10 | server. |
| 11 | |
| 12 | This documentation provides an overview of how ICE is implemented, i.e how the |
| 13 | following classes interact. |
| 14 | |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 15 | * [`cricket::IceTransportInternal`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/ice_transport_internal.h;l=225;drc=8cb97062880b0e0a78f9d578370a01aced81a13f) - |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 16 | is the interface that does ICE (manage ports, candidates, connections to |
| 17 | send/receive packets). The interface is implemented by |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 18 | [`cricket::P2PTransportChannel`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/p2p_transport_channel.h;l=103;drc=0ccfbd2de7bc3b237a0f8c30f48666c97b9e5523). |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 19 | |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 20 | * [`cricket::PortInterface`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/port_interface.h;l=47;drc=c3a486c41e682cce943f2b20fe987c9421d4b631) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 21 | Represents a local communication mechanism that can be used to create |
| 22 | connections to similar mechanisms of the other client. There are 4 |
| 23 | implementations of `cricket::PortInterface` |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 24 | [`cricket::UDPPort`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/stun_port.h;l=33;drc=a4d873786f10eedd72de25ad0d94ad7c53c1f68a), |
| 25 | [`cricket::StunPort`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/stun_port.h;l=265;drc=a4d873786f10eedd72de25ad0d94ad7c53c1f68a), |
| 26 | [`cricket::TcpPort`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/tcp_port.h;l=33;drc=7a284e1614a38286477ed2334ecbdde78e87b79c) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 27 | and |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 28 | [`cricket::TurnPort`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/turn_port.h;l=44;drc=ffb7603b6025fbd6e79f360d293ab49092bded54). |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 29 | The ports share lots of functionality in a base class, |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 30 | [`cricket::Port`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/port.h;l=187;drc=3ba7beba29c4e542c4a9bffcc5a47d5e911865be). |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 31 | |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 32 | * [`cricket::Candidate`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/candidate.h;l=30;drc=10542f21c8e4e2d60b136fab45338f2b1e132dde) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 33 | represents an address discovered by a `cricket::Port`. A candidate can be |
| 34 | local (i.e discovered by a local port) or remote. Remote candidates are |
| 35 | transported using signaling, i.e outside of webrtc. There are 4 types of |
| 36 | candidates: `local`, `stun`, `prflx` or `relay` |
| 37 | ([standard](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidateType)) |
| 38 | |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 39 | * [`cricket::Connection`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/connection.h) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 40 | provides the management of a `cricket::CandidatePair`, i.e for sending data |
| 41 | between two candidates. It sends STUN Binding requests (aka STUN pings) to |
| 42 | verify that packets can traverse back and forth and keep connections alive |
| 43 | (both that NAT binding is kept, and that the remote peer still wants the |
| 44 | connection to remain open). |
| 45 | |
| 46 | * `cricket::P2PTransportChannel` uses an |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 47 | [`cricket::PortAllocator`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/port_allocator.h;l=335;drc=9438fb3fff97c803d1ead34c0e4f223db168526f) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 48 | to create ports and discover local candidates. The `cricket::PortAllocator` |
| 49 | is implemented by |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 50 | [`cricket::BasicPortAllocator`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/client/basic_port_allocator.h;l=29;drc=e27f3dea8293884701283a54f90f8a429ea99505). |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 51 | |
| 52 | * `cricket::P2PTransportChannel` uses an |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 53 | [`cricket::IceControllerInterface`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/ice_controller_interface.h;l=73;drc=9438fb3fff97c803d1ead34c0e4f223db168526f) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 54 | to manage a set of connections. The `cricket::IceControllerInterface` |
| 55 | decides which `cricket::Connection` to send data on. |
| 56 | |
| 57 | ## Connection establishment |
| 58 | |
| 59 | This section describes a normal sequence of interactions to establish ice state |
| 60 | completed |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 61 | [ link ](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/ice_transport_internal.h;l=208;drc=9438fb3fff97c803d1ead34c0e4f223db168526f) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 62 | ([ standard ](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceConnectionState)) |
| 63 | |
| 64 | All of these steps are invoked by interactions with `PeerConnection`. |
| 65 | |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 66 | 1. [`P2PTransportChannel::MaybeStartGathering`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/p2p_transport_channel.cc;l=864;drc=0ccfbd2de7bc3b237a0f8c30f48666c97b9e5523) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 67 | This function is invoked as part of `PeerConnection::SetLocalDescription`. |
| 68 | `P2PTransportChannel` will use the `cricket::PortAllocator` to create a |
| 69 | `cricket::PortAllocatorSession`. The `cricket::PortAllocatorSession` will |
| 70 | create local ports as configured, and the ports will start gathering |
| 71 | candidates. |
| 72 | |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 73 | 2. [`IceTransportInternal::SignalCandidateGathered`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/ice_transport_internal.h;l=293;drc=8cb97062880b0e0a78f9d578370a01aced81a13f) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 74 | When a port finds a local candidate, it will be added to a list on |
| 75 | `cricket::P2PTransportChannel` and signaled to application using |
| 76 | `IceTransportInternal::SignalCandidateGathered`. A p2p application can then |
| 77 | send them to peer using favorite transport mechanism whereas a client-server |
| 78 | application will do nothing. |
| 79 | |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 80 | 3. [`P2PTransportChannel::AddRemoteCandidate`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/p2p_transport_channel.cc;l=1233;drc=0ccfbd2de7bc3b237a0f8c30f48666c97b9e5523) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 81 | When the application get a remote candidate, it can add it using |
| 82 | `PeerConnection::AddRemoteCandidate` (after |
| 83 | `PeerConnection::SetRemoteDescription` has been called!), this will trickle |
| 84 | down to `P2PTransportChannel::AddRemoteCandidate`. `P2PTransportChannel` |
| 85 | will combine the remote candidate with all compatible local candidates to |
| 86 | form new `cricket::Connection`(s). Candidates are compatible if it is |
| 87 | possible to send/receive data (e.g ipv4 can only send to ipv4, tcp can only |
| 88 | connect to tcp etc...) The newly formed `cricket::Connection`(s) will be |
Philipp Hancke | 6c7c495 | 2021-04-15 07:18:38 | [diff] [blame] | 89 | added to the `cricket::IceController` that will decide which |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 90 | `cricket::Connection` to send STUN ping on. |
| 91 | |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 92 | 4. [`P2PTransportChannel::SignalCandidatePairChanged`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/ice_transport_internal.h;l=310;drc=8cb97062880b0e0a78f9d578370a01aced81a13f) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 93 | When a remote connection replies to a STUN ping, `cricket::IceController` |
| 94 | will instruct `P2PTransportChannel` to use the connection. This is signalled |
| 95 | up the stack using `P2PTransportChannel::SignalCandidatePairChanged`. Note |
| 96 | that `cricket::IceController` will continue to send STUN pings on the |
| 97 | selected connection, as well as other connections. |
| 98 | |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 99 | 5. [`P2PTransportChannel::SignalIceTransportStateChanged`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/ice_transport_internal.h;l=323;drc=8cb97062880b0e0a78f9d578370a01aced81a13f) |
Jonas Oreland | 0aa1a19 | 2021-04-12 13:50:24 | [diff] [blame] | 100 | The initial selection of a connection makes `P2PTransportChannel` signal up |
Tony Herre | b0ed120 | 2021-07-22 15:40:44 | [diff] [blame] | 101 | stack that state has changed, which may make [`cricket::DtlsTransportInternal`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/p2p/base/dtls_transport_internal.h;l=63;drc=653bab6790ac92c513b7cf4cd3ad59039c589a95) |
Philipp Hancke | 6c7c495 | 2021-04-15 07:18:38 | [diff] [blame] | 102 | initiate a DTLS handshake (depending on the DTLS role). |