Reference11r1:Concept ICE
Applies To
This information applies to
- all innovaphone devices from V11
Overview
ICE is a protocol for finding and selecting a working network path between two media endpoints. The basic idea is that each endpoint discovers all its addresses that could be used to receive media. Those candidates are sent to the other endpoint. Then all combinations of local and remote candidates are tested. The best working combination is used for the actual media stream. If there is no working combination, the call can be disconnected.
ICE is designed to solve the following problems:
- NAT traversal
- If an endpoint is behind NAT, ICE creates a NAT mapping using STUN. Even if both sides are behind NAT, ICE can successfully establish a connection.
- Avoid no media / one-way media
- Only network paths are chosen for media that work in both directions. So there is no risk of one-way media. If there is no appropriate path, the call can be disconnected automatically.
- IPv4 and IPv6
- ICE also selects the IP version that is supported by both endpoints. This is good news for migrating from IPv4 to IPv6 because there is no extra configuration change to be done if more and more endpoints support IPv6.
Candidate types
ICE supports different types of candidates:
- Host
- The local address of a network interface.
- Server reflexive
- The address as seen by the STUN server. If the endpoint is behind NAT this candidate reflects a NAT mapping.
- Peer reflexive
- The address as seen by the remote endpoint. If the endpoint is behind NAT this candidate reflects a NAT mapping.
- Relay
- The address of an allocated channel on a public TURN server. (not supported in v11)
Each SRFLX, PRFLX or RELAY candidate is related to a single HOST candidate.
Protocol flow
Gathering
When a call is started the local endpoint needs to discover all the IP addresses and ports it can use for receiving media. This process is called gathering. It is done for all components of the call (RTP, RTCP, T.38). Endpoints that are behind NAT create NAT mappings using requests to a STUN server that are sent from the same port that will be used for the media stream.
innovaphone endpoints return the following candidates for each network interface, if given:
- HOST candidates (addresses of local network interfaces)
- IPv4
- IPv6 SiteLocal
- IPv6 Global
- SRVFLX candidates (NAT mappings)
- IPv4
Transmission of the candidates
The local candidates are sent to the other endpoint using the signalling protocol as part of the offer or answer. If an endpoint has got both the local and remote candidates it starts the connectivity checks.
Connectivity checks
Each endpoint pairs up the local and remote candidates with the same IP version. Then it starts checking all the candidate pairs by sending special STUN requests to the remote party. If it receives the corresponding STUN response it knows that the network path works.
During the connectivity checks the endpoint might learn additional peer reflexive candidates of the remote endpoints. Checks for that candidates are added dynamically.
Nomination
ICE defines roles for the two endpoints of a connection: controlling and controlled. The controlling endpoint nominates one of the working candidate pairs that should be used for media. This is done by another STUN request that contains a special attribute.
Media establishment
After nominating a working candidate pair the media stream is started. If no working path was discovered after a timeout the call is terminated.
Configuration
From v11 ICE is the default call establishment mechanism, so it does not have to be enabled.
However some SIP providers can't handle the ICE parameters correctly. In that case you can deactivate ICE for specific SIP interfaces using the "No ICE" checkmark.
STUN
The STUN server is used for gathering server reflexive candidates. The server configuration is a string in one of the following formats:
- a single DNS name and an optional port (e.g.
stun.example.com:1234
). - a comma separated list of one or two IP addresses and optional ports (e.g.
172.16.13.1:1234,172.16.13.2
).
The STUN server string can be configured at the following places:
- For many boxes using the DHCP Server (on page IP4/ETHx/DHCP-Server)
- For an individual box (on page IP4/General/STUN)
- For an individual registration (as part of the configuration of the registration)
If it is configured in more than one place, the more specific one is used. For example the configuration at the registration overwrites the DHCP config.
Tracing
Activation
Traces for debugging ICE can be activated at the signalling module. The trace flags are also available on the debug.xml page.
config add H323 /ice-trace on config add SIP /ice-trace on config add TSIP /ice-trace on config add SIPS /ice-trace on
Reading traces
When a new call is started the local candidates are gathered. In the trace this process starts with the Initialize
line and ends with Initialized
followed by the gathered candidates.
ICE.1: Initialize STUN(145.253.157.4:3478, :::0) ICE.1: STUN :::16400 -> 145.253.157.4:3478 Request ICE.1: STUN :::16401 -> 145.253.157.4:3478 Request ICE.1: STUN 192.168.0.103:16401 <- 145.253.157.4:3478 Response ICE.1: Gathered RTCP server reflexive address 145.253.157.4:50689 ICE.1: STUN 192.168.0.103:16400 <- 145.253.157.4:3478 Response ICE.1: Gathered RTP server reflexive address 145.253.157.4:50690 ICE.1: Initialized RTP(172.16.147.1:16400) RTCP(172.16.147.1:16401) T38(172.16.147.1:0) CANDIDATES:AUDIO,count(4),fingerprint(),usr(ICC8),pwd(4CPSnC3MJDfQ4Dt4oDHqJD) :HOST addr([192.168.0.103]:16400/16401) prio(2129289471/2129289470) :SRFLX addr([145.253.157.4]:50690/50689) related([192.168.0.103]:16400/16401) prio(1693081855/1693081854) :HOST addr([2002:95ac:69a:e472:290:33ff:fe2f:1d5]:16400/16401) prio(2119049471/2119049470) :HOST addr([172.16.147.1]:16400/16401) prio(2130569471/2130569470)
In this example the STUN server 145.253.157.4:3478
is used. In the end ICE gathered candidates for 4 different IP addresses. One of them is the server reflexive address returned by the stun server.
In some cases the signaling protocol has to change the STUN username and password to avoid confusion after renegotiation. This is shown in the trace with the Update
line followed by the updated candidates. The candidates are the same as the candidates from Initialized
but with changed usr and pwd.
ICE.1: Update CANDIDATES:AUDIO,count(4),fingerprint(),usr(6SsK),pwd(qUm/LVgK7XatqY7mMZ2p71) :HOST addr([192.168.0.103]:16400/16401) prio(2129289471/2129289470) :SRFLX addr([145.253.157.4]:50690/50689) related([192.168.0.103]:16400/16401) prio(1693081855/1693081854) :HOST addr([2002:95ac:69a:e472:290:33ff:fe2f:1d5]:16400/16401) prio(2119049471/2119049470) :HOST addr([172.16.147.1]:16400/16401) prio(2130569471/2130569470)
When the call is answered, both sides start doing their connectivity checks. The controlling endpoint also nominates the candidate pair that should actually be used for sending media. This process starts with Connect
line and ends with a Connected
line that also contains the nominated addresses and ports. Additional obsolete checks may follow the Connected
.
ICE.1: Connect media=audio role=controlling CANDIDATES:AUDIO,count(4),fingerprint(c573d6ef2f009002b5dec807d316dc9092ac950f),usr(5r5y),pwd(pAoYKIKw6R6eq0q8M8M+8f) :HOST addr([172.16.4.62]:16408/16409) prio(2129289471/2129289470) :SRFLX addr([145.253.157.4]:50694/50695) related([172.16.4.62]:16408/16409) prio(1693081855/1693081854) :HOST addr([fec0:9033::290:33ff:fe2f:3da]:16408/16409) prio(2121609471/2121609470) :HOST addr([2002:91fd:9d04:0:290:33ff:fe2f:3da]:16408/16409) prio(2119049471/2119049470) ICE.1: RTP check RTP(172.16.147.1:16400 -> 172.16.4.62:16408 in-progress), RTCP(172.16.147.1:16401 -> 172.16.4.62:16409 frozen) ICE.1: STUN 172.16.147.1:16400 -> 172.16.4.62:16408 Request ICE.1: RTP check RTP(2002:95ac:69a:e472:290:33ff:fe2f:1d5:16400 -> fec0:9033::290:33ff:fe2f:3da:16408 in-progress), RTCP(2002:95ac:69a:e472:290:33ff:fe2f:1d5:16401 -> fec0:9033::290:33ff:fe2f:3da:16409 frozen) ICE.1: STUN 2002:95ac:69a:e472:290:33ff:fe2f:1d5:16400 -> fec0:9033::290:33ff:fe2f:3da:16408 Request ICE.1: RTP check RTP(2002:95ac:69a:e472:290:33ff:fe2f:1d5:16400 -> 2002:91fd:9d04:0:290:33ff:fe2f:3da:16408 in-progress), RTCP(2002:95ac:69a:e472:290:33ff:fe2f:1d5:16401 -> 2002:91fd:9d04:0:290:33ff:fe2f:3da:16409 frozen) ICE.1: STUN 2002:95ac:69a:e472:290:33ff:fe2f:1d5:16400 -> 2002:91fd:9d04:0:290:33ff:fe2f:3da:16408 Request ICE.1: STUN 172.16.147.1:16400 <- 172.16.4.62:16408 Response ICE.1: RTP checked RTP(172.16.147.1:16400 -> 172.16.4.62:16408 succeeded), RTCP(172.16.147.1:16401 -> 172.16.4.62:16409 frozen) ICE.1: STUN 172.16.147.1:16400 -> 172.16.4.62:16408 Request ICE.1: STUN 192.168.0.103:16400 <- 145.253.157.4:50694 Request ICE.1: STUN 192.168.0.103:16400 -> 145.253.157.4:50694 Response ICE.1: RTP check RTP(172.16.147.1:16400 -> 145.253.157.4:50694 in-progress), RTCP(172.16.147.1:16401 -> 145.253.157.4:50695 frozen) ICE.1: STUN 172.16.147.1:16400 -> 145.253.157.4:50694 Request ICE.1: STUN 172.16.147.1:16400 <- 172.16.4.62:16408 Response ICE.1: RTP nominated RTP(172.16.147.1:16400 -> 172.16.4.62:16408 succeeded), RTCP(172.16.147.1:16401 -> 172.16.4.62:16409 frozen) ICE.1: STUN 172.16.147.1:16401 -> 172.16.4.62:16409 Request ICE.1: STUN 172.16.147.1:16400 <- 172.16.4.62:16408 Request ICE.1: STUN 172.16.147.1:16400 -> 172.16.4.62:16408 Response ICE.1: STUN 172.16.147.1:16401 <- 172.16.4.62:16409 Request ICE.1: STUN 172.16.147.1:16401 -> 172.16.4.62:16409 Response ICE.1: STUN 192.168.0.103:16401 <- 145.253.157.4:50695 Request ICE.1: STUN 192.168.0.103:16401 -> 145.253.157.4:50695 Response ICE.1: STUN 172.16.147.1:16400 <- 172.16.4.62:16408 Request ICE.1: STUN 172.16.147.1:16400 -> 172.16.4.62:16408 Response ICE.1: STUN 172.16.147.1:16401 <- 172.16.4.62:16409 Response ICE.1: RTCP nominated RTP(172.16.147.1:16400 -> 172.16.4.62:16408 nominated), RTCP(172.16.147.1:16401 -> 172.16.4.62:16409 nominated) ICE.1: Connected rtp(172.16.147.1:16400 -> 172.16.4.62:16408, 0 retries) rtcp(172.16.147.1:16401 -> 172.16.4.62:16409, 0 retries) ICE.1: STUN 172.16.147.1:16400 <- 172.16.4.62:16408 Request ICE.1: STUN 172.16.147.1:16400 -> 172.16.4.62:16408 Response ICE.1: STUN 172.16.147.1:16401 <- 172.16.4.62:16409 Request ICE.1: STUN 172.16.147.1:16401 -> 172.16.4.62:16409 Response
If ICE fails the Connect
line does not contain addresses or ports.
ICE.1: Connected rtp(:::0 -> :::0, 0 retries) rtcp(:::0 -> :::0, 0 retries)
The Abort connect
line can be ignored. It is an implementation detail and only interesting for the developer.
ICE.1: Abort connect
Incoming STUN requests before the Connect
are answered with an error message. This is normal behaviour and can be ignored. It happens because both endpoints do not start ICE excactly at the same time.
ICE.0: STUN 172.16.4.62:16390 <- 172.16.0.11:16922 Request ICE.0: STUN 172.16.4.62:16390 -> 172.16.0.11:16922 Error ICE.0: Connect media=audio role=controlling
Known limitations
- ICE trickling is not supported. This is by design of the underlying H.323 and SIP signalling.
- TURN is currently not implemented, so ICE doesn't support both endpoints being behind symmetric NAT. Also one endpoint behind symmetric NAT and the other one behind port restricted cone NAT doesn't work.
References
- Reference11r1:Concept Using PBX services from public internet
- RFC5245 - Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal for Offer/Answer Protocols
- RFC5389 - Session Traversal Utilities for NAT (STUN)