
For more information: http://code.google.com/p/boghe/
Many other features are supported by the underlying framework but not exposed to the user interface (in progress). For more information please refer to doubango website.
These features include: IPv6, OMA Large IM Message (MSRP), File Transfer (MSRP), Image Sharing (IR.79), Video Sharing (IR.74), TLS and IPSec Security Agreement (RFC 3329), Proxy-CSCF discovery using DHCPv4/v6, TURN, ...
SDP stands for Session Description Protocol and has been specified by the IETF in RFC 4566. It was previously defined in RFC 2327, which is now obsolete.
In order to understand this post, the reader MUST have a basic knowledge of how SIP (Session Initiation Protocol) works and how sessions are setted up and teared down.
The goal of this post is to explain (Highlights) how to implement a robust SOA (SDP Offer/Answer) machine. This can apply to both basic SIP equipment and 3GPP NGN/IMS nodes with MMTel extensions.
Related RFCs (Highlights): 3261, 3262 (100rel; PRACK), 3264 (Offer/Answer model), 3311 (UPDATE), 3312 (Preconditions/QoS), 3960 (Early Media and Ringing Tone Generation) and draft-ietf-sipping-sip-offeranswer-12.
| Alice | Bob |
|
|
|
| SDP Offer | SDP Answer | RFC | Callflow | Note |
|
|
|
|
|
|
1- Basic Call [[Alice ==> Bob]] | INVITE | 2xx INVITE | 3261 |
|
|
2- Bodiless INVITE (without 100rel extension) [[Bob ==> Alice]] | ACK | 2xx INVITE | 3261 |
|
|
3- Provisional response [[Alice ==> Bob]] | INVITE | 1xx-rel INVITE | 3262 |
|
|
4- Bodiless INVITE (with 100rel extension) [[Bob ==> ALice]] | PRACK
| 1xx-rel INVITE | 3262 |
|
|
5- Two rounds [[Alice ==> Bob]] | PRACK | 200 PRACK | 3262 |
|
|
6 – UPDATE [[Alice ==> Bob]] | UPDATE | 2xx UPDATE | 3311 |
|
|
== SDP offer can be in:
Any reliable non-failure response (1xx-rel or 2xx),
== In a SDP pmessage, some lines in each description are REQUIRED and some are OPTIONAL, but all MUST appear in exactly the order given in RFC 4566 subclause 5.
Generating an Answer
== SDP message in the unreliable responses to the INVITE request must be identical to the answer which is included in the reliable response. A session description in an unreliable response that precedes a reliable response can be considered a "preview" of the answer that will be coming, and hence may be treated like an answer until the actual one arrives (draft-ietf-sipping-sip-offeranswer-12 subclause 3.1).
== An offered stream MAY be rejected in the answer, for any reason. If a stream is rejected, the offerer and answerer MUST NOT generate media (or RTCP packets) for that stream. To reject an offered stream, the port number in the corresponding stream in the answer MUST be set to zero (RFC 3264 subclause 6).
== For each "m=" line in the offer, there MUST be a corresponding "m=" line in the answer. The answer MUST contain exactly the same number of "m=" lines as the offer. This allows for streams to be matched up based on their order. This implies that if the offer contained zero "m=" lines, the answer MUST contain zero "m=" lines (RFC 3264 subclause 6).
== UAS should send an SDP answer reliably (if possible) before it starts sending media. And, if neither the UAC nor the UAS support 100rel, the UAS should send a preview of the answer before it starts sending media (draft-ietf-sipping-sip-offeranswer-12 subclause 3.1).
== When a UAS has received an initial INVITE without an offer, it must include an offer in the first reliable response to the INVITE (draft-ietf-sipping-sip-offeranswer-12 subclause 5.2.2).
== The answer to an offered session description is based on the offered session description. If the answer is different from the offer in any way (different IP addresses, ports, etc.), the origin line MUST be different in the answer, since the answer is generated by a different entity. In that case, the version number in the "o=" line of the answer is unrelated to the version number in the o line of the offer (RFC 3264 subclause 6).
== The "t=" line in the answer MUST be equal that of the offer. The time of the session cannot be negotiated (RFC 3264 subcaluse 6).
== When a UAC does not include an SDP body in the INVITE request, it expects the offer to be received with the first reliable response.
== The UAC will send the answer in the request to acknowledge the response, i.e. PRACK or ACK request of the reliable response (draft-ietf-sipping-sip-offeranswer-12 subclause 3.1.2)
Modifying the Session
== Both the re-INVITE and UPDATE methods can be used in an established dialog to update the session (draft-ietf-sipping-sip-offeranswer-12 subclause 3.3).
== When both UAs support the 100rel extension, they can UPDATE the session in the early dialog once the first offer/answer exchange has been completed (draft-ietf-sipping-sip-offeranswer-12 subclause 3.2).
== When issuing an offer that modifies the session, the "o=" line of the new SDP MUST be identical to that in the previous SDP, except that the version in the origin field MUST increment by one from the previous SDP. If the version in the origin line does not increment, the SDP MUST be identical to the SDP with that version number. The answerer MUST be prepared to receive an offer that contains SDP with a version that has not changed; this is effectively a no-op. If the previous SDP had N "m=" lines, the new SDP (in the UPDATE or reINVITE) MUST have at least N "m=" lines. The i-th media stream in the previous SDP, counting from the top, matches the i-th media stream in the new SDP, counting from the top. (RFC 3264 subcaluse 8).
== New media streams are created by new additional media descriptions below the existing ones, or by reusing the "slot" used by an old media stream which had been disabled by setting its port to zero. Reusing its slot means that the new media description replaces the old one, but retains its positioning relative to other media descriptions in the SDP. New media descriptions MUST appear below any existing media sections (RFC 3264 subcaluse 8.1).
== Existing media streams are removed by creating a new SDP with the port number for that stream set to zero. The stream description MAY omit all attributes present previously, and MAY list just a single media format (RFC 3264 subclause 8.2).
== The list of media formats used in the session MAY be changed (RFC 3264 subcaluse 8.3.2).
== The Address, Port or Transport for a stream MAY be changed (RFC 3264 subclause 8.3.1).
== The media type (audio, video, etc.) for a stream MAY be changed (RFC 3264 subclause 8.3.3).
== Any other attributes in a media description MAY be updated in an offer or answer (RFC 3264 subclause 8.3.4).
== If a reINVITE fails, the session parameters in effect prior to the reINVITE MUST remain unchanged, as if no re-INVITE had been issued (draft-ietf-sipping-sip-offeranswer-12 subclause 3.4 which reference RFC 3261 section 14.1).
== At any time, either agent MAY generate a new offer that updates the session. However, it MUST NOT generate a new offer if it has received an offer which it has not yet answered or rejected. It MUST NOT generate a new offer if it has generated a prior offer for which it has not yet received an answer or a rejection (draft-ietf-sipping-sip-offeranswer-12 subclause 4).
Holding media
== "HOLD" should be indicated in an established session by sending a new offer containing "a=sendonly" for each media stream to be held. An answerer is then to respond with "a=recvonly" to acknowledge that the hold request has been understood (RFC 3264 subclause 5.1). That is, the directionality of the media stream has no impact on the RTCP usage.
If UA2 has previously been "placed on hold" by UA1, via receipt of "a=sendonly", then it may initiate its own hold by sending a new offer containing "a=sendonly" to UA1. Upon receipt of that, UA1 will answer with "a=inactive" because that is the only valid answer that reflects its desire not to receive media (draft-ietf-sipping-sip-offeranswer-12 subclause 5.3).
== An agent MUST be capable of receiving SDP with a connection address of 0.0.0.0, in which case it means that neither RTP nor RTCP should be sent to the peer (RFC 3264 subclause 8.4).
Indicating Capabilities
== An SDP constructed to indicate media capabilities is structured as follows (RFC 3264 subclause 9):
rport
This is the simplest way to deal with NATs problem at signalling (SIP only) plan for connectionless protocols (e.g. UDP). rport has been defined in RFC 3581 and apply to both connectionless (e.g. UDP) and connection-oriented (e.g. TCP, TLS, SCTP) protocols.
Because connection-oriented protocols such as TCP are bidirectional it is easier to deal with NAT traversal (all responses will be sent back using the same connection from which the request has been received from).
The philosophy (of rport) is that when you add this attribute (rport) in your requests (Via: SIP/2.0/UDP 192.168.16.108:27208;branch=z9hG4bK1234;rport) then all responses will be sent back to the ip:port from which the request has been received from. This parameter MUST be added in the top most Via header.
The response will contain a new parameter (« received ») containing the IP address from which the request has been received and the rport value will be filled with the mapped (public?) source port. In this way the client/caller (the sender of the request) can learn it's public/reflexive IP address and port (Via: SIP/2.0/UDP 192.168.16.108:27208;branch=z9hG4bK1234;rport=1234;received=10.1.1.1).
By examining the response the client can know if it's behind a NAT or not.
The problem with this solution is that it only deals with SIP messages and cannot be used for RTP/RTCP packets as the SDP will contain wrong IP addresses and ports. A solution to this issue could be using Symmetric RTP/RTCP (see above).
Symmetric RTP / RTP Control Protocol (RTCP)
As we have seen above (rport), we cannot use « rport » to deal with RTP/RTCP packets which are almost always transported using UDP. A solution to this problem could be using « Symetric RTP/RTCP » as per RFC 4961. This solution is a bit like using « rport ».
In this case the caller (INVITE originator) will create the request as per RFC 3261 as usual. When the 2xx (with SDP) or 1xx (with SDP) is received, the caller will ignore the IP addresses and ports defined in the response and send RTP/RTCP packets to IPs/Ports from which the RTP/RTCP packets have been sent (like rport).
To summarize:
As you can imagine this solution only work for only some NATs.
Session border controller
As its name says, it controls (both media and SIP packets) sessions (SIP calls) and is in the border (between two networks) of the networks.
In our case (NAT traversal) the role of SBC will be to inspect/control all outgoing and incoming SIP/RTP/RTCP packets. All SIP packets will be inspected and IP addresses and ports within the packet will be rewritten (e.g from private IP to public IP).
This solution has several problems:
As the SBC operates on the SIP packets then it MUST be aware of all headers (or functions) in order to know what should be changed and what should not be changed. This mean that the SBC MUST always be up to date in order to efficiently handle SIP packets
Most SBCs can only handle well-know protocols such as SIP, RTP or RTCP and will drop all unknown protocols
There is also many problems when End-to-End encryption (e.g. TLS, SRTP or IPSec) is used unless the SBC has the key (which is a bad idea)
As the SBC will be used to relay all RTP/RTCP packets then this will introduce additional delay (dad sound quality)
When unreliable transport is used this (relaying packets) could also increase packet loss (QoS problem)
In the 3GPP IMS context the SBC is in most case bundled with the Proxy-CSCF (P-CSCF plus IMS-ALG) and this could resolve the security issue (SIP-IPSec).
STUN
STUN was previously defined in RFC 3489 and updated by RFC 5389. STUN stands for « Session Traversal Utilities for NAT » and is a client-server protocol (request <-> response) as SIP.
There is also « indication requests » that don't generate responses like « binding requests ».
Both reliable (e.g. UDP) and unreliable (e.g TCP, TLS or SCTP) are supported.
Like SIP, when unreliable transoport is used there is the notion of transctions and retransmissions.
When STUN is used the client learn its public IP address and port (a.k.a reflexive transport address) by sending a binding request to the STUN server (default UDP/TCP port:3478 and default TLS port: 5349). The server will in some case challenge (401) the client which should resend its request with all credentials (HTTP digest authentication).
If the request is suceessfuly autheticated by the server, then a success binding response is sent back to the client. This response contains a STUN attribute (XOR-MAPPED-ADDRESS)
with the client's public IP address, family and port. This is also called the « reflexive transport address ».
Once this reflexive transport address is know then the client can for example begin REGISTERing using this address and port as AOR.
====== Step 1: Sending binding request ======
In this request I send my STUN request from "192.168.16.108:1115" to the server in order to get the public IP address and port associated to this local socket/Private address (file descriptor).
The major problem with STUN is that it could not be used behind bi-directional NATs. In the next parts I will explain how to overcome this problem by using TURN and ICE.