« Previous - Version 23/61 (diff) - Next » - Current version
Adrian Georgescu, 07/28/2009 01:07 pm


= ICE negotiation through OpenSIPS/Mediaproxy =

Background

ICE negotiation is used to solve the NAT traversal issue of RTP media as much as possible in the SIP end-points. Where the topology does not allow, a TURN server has been standardized to provide end-points with a visible public presence that can be used to relay traffic to SIP end-points behind an unfriendly NAT type (e.g. symmetric). TURN servers are not widely deployed today whereas solutions like SIP Proxies in tandem with RTP relays are.

RTP relays that work in tandem with SIP Proxies perform similar function to the TURN protocol except that the reservation is done by the SIP Proxy rather than by the user agent. The SIP User Agent does not need to support TURN protocol in order to use the relay, which makes it compatible with any SIP User Agent available today. Such solution used widely today is the tandem OpenSIPS/MediaProxy.

MediaProxy module rewrites the SDP in order to present to the destination SIP User Agent a reachable IP:port number for sending RTP/RTCP. This has the dis-advantage that is always using a relay and is mutually exclusive with the use of ICE. The rewriting of the SDP and the missing candiate correspondent to the c= line of the SDP causes the target SIP end-point to reply with ICE missmatch and the ICE negotiation fails in its tracks.

Requirements

To circumvent the failure of ICE negotiation, mediaproxy module must:

  • Create a proper candidate based on the media relay IP:port allocation
  • Append the candidate to the offer/answer of the SDP
  • Allow an administrator to set a policy about when to use of the relay candidate
  • Solve the accounting issues and BYE sending depending on the use of ICE
Implementation

Add a new setting to mediaproxy module:

{{{
mediaproxy_ice_candidate=none|low|high
}}}

For the initial INVITE and its reply append an ICE candidate to the SDP as follows:

{{{
if mediaproxy_ice_candidate != none and SDP offer contains ice-offer (has a=candidate line(s)) then
append to the SDP the following line:
a=candidate:ID 1 UDP PRIORITY MP_IP MP_PORT typ relay raddr UA_IP rport UA_PORT
}}}

where

  • ID = is the highest candidate ID found in SDP + 1
  • PRIORITY = 2!^24 * POLICY + 2!^8 * 65535 + 2!^0 * 256 - ID * POLICY = 0 if mediaproxy_ice_candidate = low and POLICY = 126 if mediaproxy_ice_candidate = high
  • UA_IP the IP used by the end-point
  • UA_port the port used by the end-point

Once the ICE negotiation is completed and the IP selected for media differs from what it has been indicated in the c= line of the original INVITE, a re-INVITE initiated by the controlling (in the sense of ICE) agent indicates this fact. The re-INVITE contains the selected candidate in the c= line. Mediaproxy module should analyze this re-INVITE (or the lack thereof) and figure out whether the relay IP:port has been chosen for the RTP media. If the answer is negative than MediaProxy should deallocate its ports and cancel subsequent actions related to the accounting and dialog terminating purposes.

ICE standard mandates that the re-INVITE is required only if the IP in the c= line differs from the IP selected by ICE negotiation. This means that if two hosts decide to use the local IP in c= line and they can use those IPs to communicate with each other then no re-invite will be sent out. In this case the SIP Proxy does not have an indication if ICE has been successful or not. MediaProxy can in this case decide on its own that the end-points selected another candidate than the relay based on the fact that after the initial exchange of STUN packets via the mediaproxy, not further RTP packets followed.

SIP trace

{{{
2009-06-10 19:39:59.172556: 192.168.1.6:56735 (UDP)> 192.168.1.138:51655
INVITE sip::51655 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.6:56735;rport;branch=z9hG4bKPjQ7BB2GHVfNxm65mrFnADJgL5DqDsYM2-
Max-Forwards: 70
From: "Adrian Georgescu" <sip:>;tag=mGpre9UpEro2XQQPOCGpNZqx06vm-rS2
To: sip:
Contact: <sip::56735>;foo
Call-ID: An9PxBh9Impx7Ghu4p0bohL.FN529s4z
CSeq: 10776 INVITE
Route: <sip:192.168.1.138:51655;lr>
Allow: SUBSCRIBE, NOTIFY, PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, MESSAGE
Supported: 100rel
User-Agent: sipsimple 0.9.0
Content-Type: application/sdp
Content-Length: 971

v=0
o=- 3453644399 3453644399 IN IP4 192.168.1.6
s=sipsimple 0.9.0
c=IN IP4 80.101.96.20
t=0 0
m=audio 56738 RTP/AVP 104 103 102 9 0 8 117 3 101
a=rtcp:56739 IN IP4 80.101.96.20
a=rtpmap:104 speex/32000
a=rtpmap:103 speex/16000
a=rtpmap:102 speex/8000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:117 iLBC/8000
a=fmtp:117 mode=20
a=rtpmap:3 GSM/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ice-ufrag:1c62473f
a=ice-pwd:783387a7
a=candidate:S 1 UDP 31 80.101.96.20 56738 typ srflx raddr 192.168.1.6 rport 56738
a=candidate:H 1 UDP 23 192.168.1.6 56738 typ host
a=candidate:H 1 UDP 23 10.211.55.2 56738 typ host
a=candidate:H 1 UDP 23 10.37.129.2 56738 typ host
a=candidate:S 2 UDP 30 80.101.96.20 56739 typ srflx raddr 192.168.1.6 rport 56739
a=candidate:H 2 UDP 22 192.168.1.6 56739 typ host
a=candidate:H 2 UDP 22 10.211.55.2 56739 typ host
a=candidate:H 2 UDP 22 10.37.129.2 56739 typ host
a=sendrecv

--

RECEIVED: Packet 2, +0:00:00.020497
2009-06-10 19:39:59.193053: 192.168.1.138:51655 (UDP)> 192.168.1.6:56735
SIP/2.0 180 Ringing
Via: SIP/2.0/UDP 192.168.1.6:56735;rport=56735;received=192.168.1.6;branch=z9hG4bKPjQ7BB2GHVfNxm65mrFnADJgL5DqDsYM2-
Call-ID: An9PxBh9Impx7Ghu4p0bohL.FN529s4z
From: "Adrian Georgescu" <sip:>;tag=mGpre9UpEro2XQQPOCGpNZqx06vm-rS2
To: <sip:>;tag=2k0Vk26zaHPkQd-BXvkY-TV-.Ax1y4Sy
CSeq: 10776 INVITE
Contact: <sip::51655>
Allow: SUBSCRIBE, NOTIFY, PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, MESSAGE
Server: sipsimple 0.9.0
Content-Length: 0

--

RECEIVED: Packet 3, +0:00:01.627695
2009-06-10 19:40:00.800251: 192.168.1.138:51655 (UDP)> 192.168.1.6:56735
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.6:56735;rport=56735;received=192.168.1.6;branch=z9hG4bKPjQ7BB2GHVfNxm65mrFnADJgL5DqDsYM2-
Call-ID: An9PxBh9Impx7Ghu4p0bohL.FN529s4z
From: "Adrian Georgescu" <sip:>;tag=mGpre9UpEro2XQQPOCGpNZqx06vm-rS2
To: <sip:>;tag=2k0Vk26zaHPkQd-BXvkY-TV-.Ax1y4Sy
CSeq: 10776 INVITE
Allow: SUBSCRIBE, NOTIFY, PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, MESSAGE
Server: sipsimple 0.9.0
Contact: <sip::51655>
Supported: 100rel
Content-Type: application/sdp
Content-Length: 407

v=0
o=- 3453644400 3453644401 IN IP4 192.168.1.138
s=sipsimple 0.9.0
c=IN IP4 192.168.1.138
t=0 0
m=audio 51674 RTP/AVP 104 101
a=rtcp:51675 IN IP4 192.168.1.138
a=rtpmap:104 speex/32000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ice-ufrag:3a4395cd
a=ice-pwd:2b1fe39d
a=candidate:H 1 UDP 39 192.168.1.138 51674 typ host
a=candidate:H 2 UDP 38 192.168.1.138 51675 typ host
a=sendrecv

--

SENDING: Packet 4, +0:00:01.628049
2009-06-10 19:40:00.800605: 192.168.1.6:56735 (UDP)> 192.168.1.138:51655
ACK sip::51655 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.6:56735;rport;branch=z9hG4bKPjR1QyfujYtkkIMGDkR7rlyM4ro1oh6sey
Max-Forwards: 70
From: "Adrian Georgescu" <sip:>;tag=mGpre9UpEro2XQQPOCGpNZqx06vm-rS2
To: sip:;tag=2k0Vk26zaHPkQd-BXvkY-TV-.Ax1y4Sy
Call-ID: An9PxBh9Impx7Ghu4p0bohL.FN529s4z
CSeq: 10776 ACK
User-Agent: sipsimple 0.9.0
Content-Length: 0

--

Session established, using "speex" codec at 32000Hz
Audio RTP endpoints 80.101.96.20:56738 <-> 192.168.1.138:51674
[<SDPAttribute "rtcp: 56739 IN IP4 80.101.96.20">, <SDPAttribute "rtpmap: 104 speex/32000">, <SDPAttribute "rtpmap: 101 telephone-event/8000">, <SDPAttribute "fmtp: 101 0-15">, <SDPAttribute "ice-ufrag: 1c62473f">, <SDPAttribute "ice-pwd: 783387a7">, <SDPAttribute "candidate: S 1 UDP 31 80.101.96.20 56738 typ srflx raddr 192.168.1.6 rport 56738">, <SDPAttribute "candidate: H 1 UDP 23 192.168.1.6 56738 typ host">, <SDPAttribute "candidate: H 1 UDP 23 10.211.55.2 56738 typ host">, <SDPAttribute "candidate: H 1 UDP 23 10.37.129.2 56738 typ host">, <SDPAttribute "candidate: S 2 UDP 30 80.101.96.20 56739 typ srflx raddr 192.168.1.6 rport 56739">, <SDPAttribute "candidate: H 2 UDP 22 192.168.1.6 56739 typ host">, <SDPAttribute "candidate: H 2 UDP 22 10.211.55.2 56739 typ host">, <SDPAttribute "candidate: H 2 UDP 22 10.37.129.2 56739 typ host">, <SDPAttribute "sendrecv: ">]
SENDING: Packet 5, +0:00:01.915510
2009-06-10 19:40:01.088066: 192.168.1.6:56735 (UDP)> 192.168.1.138:51655
INVITE sip::51655 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.6:56735;rport;branch=z9hG4bKPjsvVUtB9EB09AZ.T2eiooJN6JPfbSCbCo
Max-Forwards: 70
From: "Adrian Georgescu" <sip:>;tag=mGpre9UpEro2XQQPOCGpNZqx06vm-rS2
To: sip:;tag=2k0Vk26zaHPkQd-BXvkY-TV-.Ax1y4Sy
Contact: <sip::56735>;foo
Call-ID: An9PxBh9Impx7Ghu4p0bohL.FN529s4z
CSeq: 10777 INVITE
Allow: SUBSCRIBE, NOTIFY, PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, MESSAGE
Supported: 100rel
User-Agent: sipsimple 0.9.0
Content-Type: application/sdp
Content-Length: 768

v=0
o=- 3453644399 3453644400 IN IP4 192.168.1.6
s=sipsimple 0.9.0
c=IN IP4 192.168.1.6
t=0 0
m=audio 56738 RTP/AVP 104 101
a=rtcp:56739 IN IP4 80.101.96.20
a=rtpmap:104 speex/32000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ice-ufrag:1c62473f
a=ice-pwd:783387a7
a=candidate:S 1 UDP 31 80.101.96.20 56738 typ srflx raddr 192.168.1.6 rport 56738
a=candidate:H 1 UDP 23 192.168.1.6 56738 typ host
a=candidate:H 1 UDP 23 10.211.55.2 56738 typ host
a=candidate:H 1 UDP 23 10.37.129.2 56738 typ host
a=candidate:S 2 UDP 30 80.101.96.20 56739 typ srflx raddr 192.168.1.6 rport 56739
a=candidate:H 2 UDP 22 192.168.1.6 56739 typ host
a=candidate:H 2 UDP 22 10.211.55.2 56739 typ host
a=candidate:H 2 UDP 22 10.37.129.2 56739 typ host
a=sendrecv

--

RECEIVED: Packet 6, +0:00:01.921401
2009-06-10 19:40:01.093957: 192.168.1.138:51655 (UDP)> 192.168.1.6:56735
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.6:56735;rport=56735;received=192.168.1.6;branch=z9hG4bKPjsvVUtB9EB09AZ.T2eiooJN6JPfbSCbCo
Call-ID: An9PxBh9Impx7Ghu4p0bohL.FN529s4z
From: "Adrian Georgescu" <sip:>;tag=mGpre9UpEro2XQQPOCGpNZqx06vm-rS2
To: <sip:>;tag=2k0Vk26zaHPkQd-BXvkY-TV-.Ax1y4Sy
CSeq: 10777 INVITE
Contact: <sip::51655>
Allow: SUBSCRIBE, NOTIFY, PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, MESSAGE
Supported: 100rel
Server: sipsimple 0.9.0
Content-Type: application/sdp
Content-Length: 407

v=0
o=- 3453644400 3453644402 IN IP4 192.168.1.138
s=sipsimple 0.9.0
c=IN IP4 192.168.1.138
t=0 0
m=audio 51674 RTP/AVP 104 101
a=rtcp:51675 IN IP4 192.168.1.138
a=rtpmap:104 speex/32000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ice-ufrag:3a4395cd
a=ice-pwd:2b1fe39d
a=candidate:H 1 UDP 39 192.168.1.138 51674 typ host
a=candidate:H 2 UDP 38 192.168.1.138 51675 typ host
a=sendrecv

--

SENDING: Packet 7, +0:00:01.921597
2009-06-10 19:40:01.094153: 192.168.1.6:56735 (UDP)> 192.168.1.138:51655
ACK sip::51655 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.6:56735;rport;branch=z9hG4bKPjSzqtY0z5MlqE1ms3CvVLars70TNGielH
Max-Forwards: 70
From: "Adrian Georgescu" <sip:>;tag=mGpre9UpEro2XQQPOCGpNZqx06vm-rS2
To: sip:;tag=2k0Vk26zaHPkQd-BXvkY-TV-.Ax1y4Sy
Call-ID: An9PxBh9Impx7Ghu4p0bohL.FN529s4z
CSeq: 10777 ACK
User-Agent: sipsimple 0.9.0
Content-Length: 0

--

Detected NAT type: Port Restricted

}}}