SIP (Session Initiation Protocol) - Recursos VoIP University Electrical Engineering EE384B -...

32
Stanford University Electrical Engineering EE384B - Mutimedia Networking and Communications Group #25 SIP (Session Initiation Protocol) Venkatesh Venkataramanan <[email protected]> Matthew Densing <[email protected]> Nathan Ashelman <[email protected]> Source code and demonstration of our implementation are available at: /afs/ir/users/a/s/ashelman/sipdemo/

Transcript of SIP (Session Initiation Protocol) - Recursos VoIP University Electrical Engineering EE384B -...

Stanford University Electrical Engineering EE384B - Mutimedia Networking and Communications

Group #25

SIP (Session Initiation

Protocol)

Venkatesh Venkataramanan <[email protected]> Matthew Densing <[email protected]>

Nathan Ashelman <[email protected]>

Source code and demonstration of our implementation are available at: /afs/ir/users/a/s/ashelman/sipdemo/

SIP (Session Initiation Protocol) EE384B - Group 25

Page 2

Abstract SIP, specified in RFC2543, is an elegant protocol designed to initiate calls

made over IP networks. It permits rapid call setup and provides a rich set of features, including user mobility. It achieves a simple, flexible, and extensible architecture by leveraging existing internet standards. Though primarily used for internet telephony at the moment, it is general enough to be used to set up any kind of connection, from multicast voice broadcasts to multiplayer game sessions to video conferences.

Our team's goal was to implement a basic User Agent (UA), which are the endpoints of a SIP session. The UA integrates a user agent client, which initiates a SIP session, and a user agent server which responds. Much of the richness of SIP comes from using servers to direct call flow, so we desired to make our UA interoperable with standard SIP servers. Our goal was to demonstrate successful call initiation: the establishment of an end-to-end SIP connection and communication of the information necessary to subsequently establish an RTP connection.

We developed a C implementation of the SIP user agent which runs on the Stanford Leland machines. We used our code to successfully demonstrate direct host-to-host calls, registration with a SIP registrar, calls negotiated through a SIP proxy server, calls through a gateway to the PSTN, session media negotiation, and call termination. In this paper we present a summary of SIP's advantages and features, a description of how SIP works, and the results of our tests.

SIP (Session Initiation Protocol) EE384B - Group 25

Page 3

Table of Contents Introduction .....................................................................................................................4 The Basics of SIP..............................................................................................................5 Examples of Supported Call Flows..............................................................................7

1. Direct Peer-to-Peer Two-Party Call with SDP Negotiation.............................7 2. Registration of a client with a SIP server.............................................................7 3. Two-Party Call and Negotiation using a Proxy SIP Server.............................8 4. PSTN Call through a Proxy Server......................................................................8

Session Description Protocol (SDP) Overview...........................................................9 Overview of the Implementation ...............................................................................10

Primary Data Structures (described in sip.h) ........................................................11 The “sipparams” file..............................................................................................11

Main Routine (main in module sip.c).....................................................................11 Registration (SipRegister in sip.c)...........................................................................12 Making Calls (SipCall in sip.c) ................................................................................13 Listening for Calls (SipAccept in sip.c) ..................................................................13 Building SIP Messages (in build.c) .........................................................................14 NegotiateMedia (in build.c).....................................................................................15 Parsing SIP Messages (in parseMsg.c)....................................................................15

Test Results....................................................................................................................16 Scenario 1 – UAC directly to UAS, failure to negotiate common protocol .......16 Scenario 2 – UAC directly to UAS, successful protocol negotiation..................19 Scenario 3 – Registration with a Proxy Server.......................................................23 Scenario 4 – Calling Through a Proxy Server........................................................24 Scenario 5 – PSTN Call..............................................................................................28 Lessons Learned in Testing......................................................................................31

References and Resources ...........................................................................................32 References: ..................................................................................................................32 Other Useful Resources: ...........................................................................................32

SIP (Session Initiation Protocol) EE384B - Group 25

Page 4

Introduction Traditionally, telephony protocols have been following the dumb-terminal

approach, where most of the intelligence lies in switches that drive the endpoints. This is very different from the traditional data networking protocols, where more intelligence is concentrated at the end nodes. This intelligence is used to manage an extremely error-prone network, and handle negotiations between complex devices which support a combination of voice, video, and data protocols. With the advent of IP telephony, signaling protocols were needed to support call set-up and tear-down mechanisms in the IP world. H.323 and SIP are two such signaling protocols in use today.

H.323 is widely used today (for example, in Microsoft Netmeeting), but has significant drawbacks. First, today’s networks are not as reliable as H.323 supposes. Also, H.323 is not especially robust- the numerous messages required to set up calls mean plenty of targets for call setup failures due to packet loss. In the H.323 protocol, a caller obtains an address for the end party, and then establishes a session with that user using one of the H.323 protocols (H.225). Another protocol (H.245) is then used to negotiate the different media types that the caller will send and the end party will support. The extra step used by the H.323 suite in negotiating media after the establishment of the session introduces significant delays in making a call. Some have estimated delays of up to eight seconds, with even larger delays for international calls. Finally, H.323 is very complex to implement. It spans six documents and defines every component of a voice, video, and data conferencing network. Thus, a need existed for a simple, effective protocol to replace H.323 and to handle telephony signaling on the Internet.

SIP, which stands for Session Initiation Protocol, has been a recent development in the areas of multimedia conferencing and IP telephony. An application layer protocol that initiates sessions between two or more participants, SIP addresses the problems with the existing H.323 protocol.

SIP solves this problem by including the negotiation step in its first contact with the end user. A caller sends out an INVITE request, with the supported media types included in the message body. This significantly reduces the delays which were prevalent in H.323. Another attractive feature of SIP is its support for personal mobility. A user can generate or receive calls on any terminal in any location. Also, SIP works with other protocols such as RSVP and RTP for reserving resources and delivering media content. However, SIP is appropriately limited in scope in that it only sets up the session between the caller and end parties. Thus, it is independent of the different media control protocols.

SIP (Session Initiation Protocol) EE384B - Group 25

Page 5

In the magazine named Computer Telephony, Bill Michael best describes some of the aspects of SIP, including the choice to make it a text-based protocol.

Initially, SIP was intended to create a mechanism for inviting people to large scale, multipoint conferences. The emphasis of SIP has always been to remain as independent as possible of the media it underlies. This abstractive approach is one of the keys to SIP’s simplicity and elegance. The protocol makes a total separation between what it means to be a session and what it means to establish one. SIP talks about establishing or modifying or terminating a session, but that session could be anything from a multiplayer game to a voice channel or a video conference. So too, the decision to format SIP messages as text was a profound one. Text is human-readable. Text is flexible: Interpreting text demands some amount of parsing intelligence - this renders applications more robust and lends itself to innovation. Above all, text processing lies at the heart of most of the applications on the Internet today. Consequently, extensible tagging systems, data-type declaration, document identification, parsing methods, and software for the same - all these have been worked over, normalized and shared out by most of the Internet applications. This would allow vendors to rapidly develop such a protocol given that they already posses a vast amount of experience and knowledge in this area. Hence SIP decided to use text messages composed of ISO UTF-8 characters, using HTTP 1.1 syntax. (p. 61)

The Basics of SIP SIP is a text-based protocol that uses the DNS system for locating end users.

A SIP message looks like the first five or six lines of source behind a well-formed web page. It uses variations of the URL for identification, and supports both TCP and UDP connections. SIP also adopts the conventional URL format of addressing server entities and people. The SIP “phone number” looks very much similar to the email address, though many variations of this basic plan are supported, including ways to embed a standard phone number in an URL. The implication of using such a simple addressing scheme is huge. For example, with SIP it’s just as easy to transfer someone to another phone as it is to transfer someone to a web page or any other application that accepts URL’s. Such simplicities arise out of the decision to use standard URL’s to manage a telephone.

A caller using SIP can either send the first initial session request to a local SIP server or to the end user directly. SIP servers are a key element of the protocol, in that they can redirect calls (as a redirect server) and even initiate requests on behalf of the caller (as a proxy server). A basic example of a call (taken from RFC 2543) is illustrated in Figure 1.

SIP (Session Initiation Protocol) EE384B - Group 25

Page 6

A basic call to setup a session begins with an INVITE request, sent by the initiating party. Each message in the SIP protocol is distinguished by various text fields. Some of these are shown in Figure 1. The first line describes the type of the message, whether an actual INVITE request, an ACK (acknowledgement) request, or a response message denoted by its three-digit response code (as in 200 OK). In the example, a user ([email protected]) sends an INVITE request to a local SIP proxy server, asking for [email protected] to join a session. The proxy server then uses a location server to get a more precise location. It then sends its own INVITE request, which is received by hgs@play. The end party wishes to join the session, so it sends a 200 OK response back to the proxy server, which forwards the response to the caller. By sending an ACK request, the caller acknowledges the 200 OK response of the end party. The proxy server receives the ACK and modifies it to reach hgs@play. After this series of exchanges, the session is set up, and the caller can begin transmitting media using RTP or whatever protocol he had earlier specified in his INVITE request.

As seen in the above example, SIP uses response codes that are similar to

HTTP/FTP. This provides a sense of ease and familiarity to those developers who have been working in the data networking protocol area. If IP end point addresses are known, a single message suffices to establish a point-to-point call,

SIP (Session Initiation Protocol) EE384B - Group 25

Page 7

including RTP and codec determination and dynamic port allocation on each side. To support mobility and higher order applications, SIP defines several useful entities that help manage calls in different ways: registrars, which maintain a map of what IP address a given user is currently using; proxies, which can act as transcoders, auto-responders, and forwarding agents; and redirect servers, which perform a subset of forwarding functions. These helpers can be set up to work around problems of dynamic IP addressing, such as PC terminals that can get turned off, and workers that move from place to place.

Examples of Supported Call Flows The following is a general description of each call flow – for a more in-depth

look at each call flow, please see the call flow examples and their actual logs later in this paper.

1. Direct Peer-to-Peer Two-Party Call with SDP Negotiation

For this example, a caller sends an invitation directly to the address of the end user, bypassing the SIP server. Once the caller determines the port number that end user is listening on (from a higher layer), he/she sends the INVITE request. The callee parses the incoming message (received on its TCP listening port), and calls the NegotiateMedia function to compare the SDP media types with its own supported media types. If the caller has indicated that he/she will support a media type also supported by the end user, then a 200 OK response message is sent back to the caller. In the 200 OK response are the various media types supported by the callee. On reception of the 200 OK response, the initiator of the call calls the NegotiateMedia function again, and decides which Audio and Video media type to send. The caller then sends an ACK request to the end user, acknowledging the 200 OK response. If the callee does not find a matching media type after receiving an INVITE, it sends a 606 Not Acceptable response back to the caller, and the session is not set up.

2. Registration of a client with a SIP server In this example, our User Agent Client (UAC) registers with a SIP server

(sipfx.com). The REGISTER message sent by the user contains an additional address in the Contact field, which is used by the SIP server in directing future messages to the client. The user’s name and the server’s URL are located in both the To and From fields. When the REGISTER message reaches the server, it adds the addresses in the To field and the Contact field to its database. Since the Contact field that we specify is usually in the format

SIP (Session Initiation Protocol) EE384B - Group 25

Page 8

[email protected], (or a similar machine domain name), the server will redirect all future messages to that address. If no expiration time is indicated (which in our case, is not), then a one-hour lifetime for each registration is assumed. In case the user wants to cancel all of its SIP registrations with a particular server, another REGISTER request is sent, with the Expires field set to zero, and a wildcard “*” symbol in the Contact field.

If a user is registered with a SIP server under multiple addresses, the SIP server will send a request to each of the listed addresses when it receives a message destined for that user. This feature of SIP can be used to provide ACD (Automatic Call Distribution) capabilities in an IP network.

3. Two-Party Call and Negotiation using a Proxy SIP Server

This two-party call is similar to the example above, except the INVITE message is sent to a local proxy SIP server (sipfx.com). Before the call takes place, the receiving party registers with the SIP server, leaving an appropriate address for future redirection of messages. The caller sends the INVITE message to the server, which directs the message to the address previously specified. The rest of the call proceeds as in the example above, except that all messages are passed through the proxy server, which adds the necessary fields to keep track of the call and the status of the end users.

The proxy is one of the most powerful aspects of SIP. A complete proxy can act as a redirect server, operate as a firewall, and originate new calls on behalf of a SIP client. SIP proxy servers can also support two SIP User Agents with disparate media capabilities through transcoding.

4. PSTN Call through a Proxy Server In this example, a caller sends an INVITE request to another user, who has

registered his or her phone number with a SIP server (sipfx.com). When the proxy SIP server receives the INVITE request, it attempts to contact the end user at the telephone number specified. If the phone does not ring right away, the server sends back informational messages, such as 100 Trying and 180 Ringing, which update the caller on the situation. Such a call can be initiated using our code and the sipfx server, although we have not implemented voice coding to permit actual conversation.

A proxy server also can queue calls to a SIP User Agent if the UA is currently busy. This is achieved by sending a 182 response message to the calling party. This would be useful in implementing PBX features like call waiting, and

SIP (Session Initiation Protocol) EE384B - Group 25

Page 9

automatic call distribution functions provided by traditional PSTN switches today.

Session Description Protocol (SDP) Overview

As a part of the initial request to connect to a caller, SIP provides a mechanism by means of which a caller can describe his/her media capabilities. Although, SIP by itself does not lay any restriction as to how this information may be sent to the called party, SDP is an overwhelmingly popular protocol that describes media capabilities as a part of a SIP message. The purpose of SDP in a SIP message is to convey information about media streams in the multimedia sessions to allow the recipients of a session description to participate in the session. Thus the SDP includes:

The session name and purpose. Time the session is active. The media comprising the session. Information to receive those media (addresses, ports, formats etc).

As resources necessary to participate in a session may be limited, some additional information may also be desirable:

Information about the bandwidth to be used by the session. Contact information of the person responsible for the session.

In general, SDP must convey sufficient information to be able to join a session and to announce the resources to be used to non-participants that need to know. The media information includes the following:

The type of media (audio, video, etc.) The transport protocol (TCP/UDP/IP/H.320 etc.) The format of the media (H.261, G.711, G.723, MPEG, JPEG, etc.) Remote address for the media. Transport port for contact address.

Furthermore, as sessions may either be bounded or unbounded in time, the session description (SDP) can contain the start times and end times of a particular session. The timing information is globally consistent. This is achieved by using the Network Time Protocol (NTP) to specify the timing values.

Like SIP, SDP recommends the use of ISO 10646 character sets in the UTF-8 (ASCII) encoding to provide all the above information, although, to assist in compact representations, SDP also allows other character sets such as ISO8859-1. The rationale behind using textual representation as against XDR (Extended Data Representation) or other binary forms is to enhance portability, enable a

SIP (Session Initiation Protocol) EE384B - Group 25

Page 10

variety of transports to be fixed and to allow flexible, text based tool kits to be used to generate and to process the session descriptions.

The SPD session description consists of a number of lines of text of the form, <type>=<value>. The <type> field is always exactly one character long and is case-significant. <value> is structured text string whose format depends on <type>. The <value> field is case significant as well.

A session description consists of a session-level description that applies to the session as a whole and several media-level sessions. The media-level session information is optional and depends upon the type of media that the sender is going to be transmitting. However, the order that the fields are transmitted is critical! The following fields define the “session as a whole”:

The protocol version (denoted by “v” for the type field). The Owner or creator of the session (denoted by the “o” for the type

field). The Session Name (denoted by the “s” field).

The following define the media capabilities of the several media-level sessions. The media name and transport address (denoted by “m”). The media title (denoted by “i” and is optional). The connection information (denoted by “c” and is optional. This defines

the port address on which this media will be received). Bandwidth information (optional and denoted by “b”). Media Attributes (denoted by “a” and is optional. When present, this

describes the attributes of the media session, like receive only, or send only, send/receive, etc).

Overview of the Implementation Structure of Code Modules Common data types & definitions sip.h Main program & subroutines sip.c Initialization from params file readSipParams.c Building SIP messages build.c Parsing SIP messages

parseMsg.c parseSipUrl.c parseStr.c

In the following, we describe the overall structure of the implementation and the major subroutines used. There are additional supporting subroutines which can be examined by looking at the code.

SIP (Session Initiation Protocol) EE384B - Group 25

Page 11

Primary Data Structures (described in sip.h) The CallerProfile structure stores data that remains constant for the duration

of the program execution. This includes items such as the user’s name, the host, and the supported media types to be advertised in SDP messages. Much of CallerProfile is initialized from a configuration file, which is described below.

The CallData structure stores data for each ongoing call. This is basically the contents of the various header fields needed to identify the call, and to generate and parse messages. To send messages, the necessary fields in CallData are set, and we call a routine from build.c to generate a message. The parseMsg.c routines return a CallData filled from the received message.

The “sipparams” file Our implementation of SIP uses a flat file that describes the caller profile

using our SIP stack to make a SIP call. The following are the details of the various parameters and how or what they are used for.

Server port number: This information is used by the SIP stack to determine the port to which a connect request is to be sent while sending any SIP messages to the SIP server. Typically, this would be set to port 5060, as specified in the SIP specification, but flexibility is provided to use alternate port numbers if needed.

Server URL: This information is used by the SIP stack to decide where to register with SIP messages. This would allow users of the stack to use different SIP server implementations of various vendors and perform inter-operability tests of our stack with others.

Host Port Number: This specifies to the stack which port to receive incoming SIP calls on. If not specified or set to zero, the stack will choose an arbitrary free port.

Media Capabilities: This information decides what types of media are supported by the SIP UA. This information will be used while making an outbound call. When an incoming INVITE is received, the media capabilities are compared to determine which ones are supported by our user agent. Keeping this parameter tunable allows us to perform testing to verify the proper exchange of media capabilities between the SIP UA’s. It also determines whether to proceed with a call using our implementation.

Main Routine (main in module sip.c) On startup, the User Agent (UA) first initializes the CallerProfile structure

from the sipparams file. It thus knows who to register with and what audio/video media are supported by this client. It gets the machine’s host name

SIP (Session Initiation Protocol) EE384B - Group 25

Page 12

and sets the user name to be whoever is logged in and running the program. Next it opens a port to receive incoming SIP messages on. If the port number is specified in sipparams (typically 5060) then that number is used, otherwise an arbitrary free port is chosen. In either case, this port number is recorded in the CallerProfile. Initialization is now complete, and the program is ready to accept user commands.

Valid user commands are:

r - Register yourself with sipfx

c - Initiate a SIP call. You will be prompted for the URL to call

Examples: [email protected], [email protected]:33167

l - Listen for incoming SIP messages

? – Query the server for all of your current registrations: they will be listed in the Contact field of the response

x - Clear all your registrations with the server

h - Hide SIP messages (and just display status information)

s - Show SIP messages

q - Quit the program

The user has three options, to register with the SIP server specified by sipparams, to initiate a call, or to listen for incoming calls. Thus the functionality of the user agent client (UAC) is accomplished by the registration and call routines, and of the user agent server (UAS) by the listen routine.

For all of the above choices, when a call begins a CallData structure is allocated to store call information within the called subroutines. This is to allow for future expansion, where multiple calls could conceivably be going on simultaneously. As a call proceeds the user is given status information, and by default all incoming and outgoing SIP messages are also displayed. Display of the messages can optionally be turned off.

Registration (SipRegister in sip.c) Typically, a user agent would automatically register with its SIP domain

server on start-up, and make sure to re-register before expiry, all without any user intervention. However, to allow greater control in testing, our implementation uses a command to initiate registration.

SIP (Session Initiation Protocol) EE384B - Group 25

Page 13

The host and listening port of the UA are already know, from the initialization of CallerProfile. First, a TCP connection is opened to the SIP server. Then a CallData structure is allocated and initialized. Since re-registrations would typically occur regularly, the routine remembers the contents of CallData to be used the next time it is called. For example, CSeq must be increased on each subsequent registration.

A register message is created using REGrequest and sent to the server. The UA then reads from the port until a final response is returned by the server, which will either indicate success (200 OK) or failure (3xx, 4xx, 5xx, 6xx codes).

Making Calls (SipCall in sip.c) The user is first prompted for who to call, which is in the form

user@host[:port]. Examples are [email protected] or [email protected]:36617. A TCP connection is then opened to the specified host, a CallData structure initialized, an INVITE message generated and sent. The body of the message uses SDP to describe the supported encoding protocols. The UAC then awaits for a reply.

If the call proceeds successfully directly to a UAS or through a proxy server, the UAC will receive a 200 OK message, which is acknowledges with an ACK. If the call is through a redirect server, it will receive a 3xx response, which triggers our UAC to close the existing connection and open a new one to the server specified in the redirect. If the invite does not succeed, the UAC will receive a 4xx or higher response and exit the routine.

Once the call is established and ACKed, the UAC calls NegotiateMedia to choose one of the compatible media types. At this point, media encoding and transmission code (not implemented) would be responsible for transferring the call data. The user terminates the call with a key press, which sends a BYE message. Once the server acknowledges, the TCP connection is closed.

Listening for Calls (SipAccept in sip.c) A TCP port was already opened during initialization to receive incoming

calls (specifically it has already called bind() and listen()). SipAccept calls accept() to return the next connection initiated by a UAC. It then examines the incoming SIP message to determine its type. On receipt of an INVITE, it calls NegotiateMedia to determine if there are common media types supported on both ends. If so it returns a 200 OK, otherwise a 600 level error message. On receipt of a BYE it sends a 200 OK and closes the connection. Since we are using TCP, we do not need to worry about the loss of messages and re-transmission if we do not receive an ACK. On receipt of unsupported methods, or of SIP

SIP (Session Initiation Protocol) EE384B - Group 25

Page 14

messages which are not method requests, it returns an error and closes the connection.

Building SIP Messages (in build.c) The purpose of this part of the code is to pull data from various fields of

the CallData and CallerProfile structures and construct the various SIP messages that will be sent by the main program. Depending on the type of message needed, the appropriate fields are concatenated into a single message buffer (a string). This buffer, which is allocated by the main program and modified by the build module, is sent as a single SIP message. Most of the decision-making processes that deal with building a message are left to the main program. For example, the first-line field after the method type (the Request-URI) is passed into every request message, since this field can change depending on the circumstances. The types of messages implemented in the Build Module include the INVITE, REGISTER, CANCEL, ACK, and BYE requests, as well as most of the response messages.

The following list describes each of the fields which are incorporated in a minimally implemented SIP message. (Not all messages contain each of the fields below).

From: This field is filled with the address of the initiator of the request. It can also contain a “tag” parameter, which is used to identify a user and a call.

To: This field identifies the recipient of the request. Usually, a tag parameter is also included.

Via: The Via field indicates the path that a message has taken up to the current point. The client must add a Via field into a request, which contains its host name or network address. Subsequent proxy servers also add their own Via field, when passing the message along.

Content Length: This field describes the size of the message body, in octets.

Content-Type: In those messages which have a message body (INVITE messages, 200 OK responses, and others), this field is included to indicate the format of the message body. For our implementation, the message body is in the SDP format.

Request URI: The Request URI indicates the user or service to which a request is destined for. It is specified immediately after the method in the first text line of the message.

SIP (Session Initiation Protocol) EE384B - Group 25

Page 15

Call-ID: The Call-ID field uniquely identifies invitations from a particular client.

Contact: The Contact field contains additional addresses where the caller can be reached.

Cseq: This field must be in every request – for each new message sent by a client, the Cseq field is incremented. This way, clients can determine the order of their messages, and the responses they receive.

Message Body: The actual message body is located after the Request or Response header fields, with a new line separating the two. The various media types and pertinent information describing the requested session are included in the message body.

NegotiateMedia (in build.c) Also found in the Build Module is a function which chooses a media type

supportable by both end parties of a particular call. The function parses the different SDP fields stored by the Parse Module, and compares each media type with its own types. If a match is found, the agreed media type is stored in the CallData structure, and the function terminates with a successful indicator. This step is performed by the callee, when an INVITE request is received and the caller’s media types are included in the message body. In the main program, if a common media type is not found by the callee, then an error response is returned (606 Not Acceptable).

Parsing SIP Messages (in parseMsg.c) This module parses an incoming SIP message. It handles receipt of an

incoming new call (like a new INVITE message received) or a response to a message initiated by the SIP UA. The first line in the incoming message distinguishes whether the message was a response received or if it is a new incoming message. A presence of a response code (a three-digit integer) indicates that the incoming message was a RESPONSE received, while the presence of a method name (INVITE, REGISTER, OPTIONS, etc.), indicates that this is an inbound message. The parseMessage module uses this as a key for identification. It then scans through the buffer stream to identify the From, To, Via, and Contact fields and populates the appropriate global variables in the CallData structure. It uses the rules of the SIP-URL guidelines for parsing the From, To and Contact field information.

A presence of a new line by itself indicates the possibility of an SDP message. On encountering a solitary new line, the parse module starts looking for lines

SIP (Session Initiation Protocol) EE384B - Group 25

Page 16

that match the SDP specification. It populates the farEndAudioSupported and farEndVideoSupported linked list as appropriate. It also parses the RTP port on which the far end is willing to accept the various media types it supports and stores them in the global CallData structure.

Based on the type of message received, the parse message module returns appropriate return codes (like INVITE_RECVD, OPTIONS_RECVD, BYE_RECVD, and CONTINUE_READ) to the main module so as to allow the main module to respond as appropriate.

Test Results We tested our implementation, and successfully demonstrated direct peer-to-

peer calls, registration with a SIP proxy server, calls through the proxy server, SDP negotiation, and calls to the PSTN through a gateway. Below are descriptions of each test, and logs of the program output and SIP messages.

Scenario 1 – UAC directly to UAS, failure to negotiate common protocol

User ashelman on elaine9 calls somebody on epic10. Note that in somebody’s sipparams file, hostPort was not specified, so the client chooses an arbitrary available port (36617 in this case). ashelman is listening on 5060. Somebody’s client supports PCMU and GSM audio and jpeg video; ashelman’s client supports G723, DVI4, and H.261. Since they share no common protocols, someone responds with a 606 error message and closes the connection.

Note that lines beginning with >> and subsequent indented lines are status messages from our application. -> indicates request for user input. Non-indented lines are printouts of the actual SIP messages. Here is what ashelman on elaine9 sees: elaine9:~/sipdemo> sip >> Reading configuration info from sipparams file... >> Opening socket to listen for incoming SIP messages... success: listening on port 5060 >> Caller Profile Initialization Complete Your user name is: ashelman SIP server to register with: sipfx.com:5060 UAS will listen for SIP messages at: elaine9.Stanford.EDU:5060 Audio Media Supported m=audio 3456 RTP/AVP 4 5 a=rtpmap:4 G723/8000

SIP (Session Initiation Protocol) EE384B - Group 25

Page 17

a=rtpmap:5 DVI4/8000 Video Media Supported m=video 1234 RTP/AVP 7 a=rtpmap:7 h.261/9000 >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> c >> MAKING A SIP CALL >> Please enter address to call (ex [email protected]) -> [email protected]:36617 >> Connected to epic10.stanford.edu:36617 >> Sending INVITE... INVITE sip:[email protected]:36617 SIP/2.0 Via: SIP/2.0/TCP elaine9.Stanford.EDU From: <sip:[email protected]> To: <sip:[email protected]:36617> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Contact: <sip:[email protected]:0; transport=tcp> Content-Length: 143 v=0 c=IN IP4 171.64.15.135/127 m=audio 3456 RTP/AVP 4 5 a=rtpmap:4 G723/8000 a=rtpmap:5 DVI4/8000 m=video 1234 RTP/AVP 7 a=rtpmap:7 h.261/9000 >> Received message (406 bytes): SIP/2.0 606 Not Acceptable Via: SIP/2.0/TCP epic10.Stanford.EDU:36617 From: <sip:[email protected]> To: <sip:[email protected]:36617> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Content-Length: 143 v=0 c=IN IP4 171.64.15.135/127 m=audio 5004 RTP/AVP 0 3 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 m=video 5006 RTP/AVP 11 a=rtpmap:11 jpeg/9000 >> INVITE was unsuccessful >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> q >> Bye bye! elaine9:~/sipdemo>

SIP (Session Initiation Protocol) EE384B - Group 25

Page 18

And somebody on epic10 also runs the sip application, and enters listen mode: >> Reading configuration info from sipparams file... >> Opening socket to listen for incoming SIP messages... success: listening on port 36617 >> Caller Profile Initialization Complete Your user name is: somebody SIP server to register with: sipfx.com:5060 UAS will listen for SIP messages at: epic10.Stanford.EDU:36617 Audio Media Supported m=audio 5004 RTP/AVP 0 3 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 Video Media Supported m=video 5006 RTP/AVP 11 a=rtpmap:11 jpeg/9000 >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> l >> ENTERING LISTEN MODE >> Waiting for incoming connection... >> Received message (490 bytes): INVITE sip:[email protected]:36617 SIP/2.0 Via: SIP/2.0/TCP elaine9.Stanford.EDU From: <sip:[email protected]> To: <sip:[email protected]:36617> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Contact: <sip:[email protected]:0; transport=tcp> Content-Length: 143 v=0 c=IN IP4 171.64.15.135/127 m=audio 3456 RTP/AVP 4 5 a=rtpmap:4 G723/8000 a=rtpmap:5 DVI4/8000 m=video 1234 RTP/AVP 7 a=rtpmap:7 h.261/9000 >> Unsuccessful media negotiation: no common formats. Sending 606 error message. SIP/2.0 606 Not Acceptable Via: SIP/2.0/TCP epic10.Stanford.EDU:36617 From: <sip:[email protected]> To: <sip:[email protected]:36617> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Content-Length: 143

SIP (Session Initiation Protocol) EE384B - Group 25

Page 19

v=0 c=IN IP4 171.64.15.135/127 m=audio 5004 RTP/AVP 0 3 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 m=video 5006 RTP/AVP 11 a=rtpmap:11 jpeg/9000 >> Closing the connection. >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> q >> Bye bye!

Scenario 2 – UAC directly to UAS, successful protocol negotiation

Some hours later, somebody is working on elaine39 and calls mdensing who is on epic24. Being a prepared kind of guy, mdensing can support a wide variety of audio and video formats, including some that somebody also supports. Thus mdensing’s UAS sends a 200 OK message, which somebody’s UAC acknowledges. They both run the same algorithm to select identical audio/video protocols from their common formats, which our program prints out. They agree on PCMU and jpeg. Their call can then proceed, until one of them hangs up. Somebody eventually does so, by sending a BYE, which is acknowledged by mdensing. somebody’s terminal: >> Reading configuration info from sipparams file... >> Opening socket to listen for incoming SIP messages... success: listening on port 59161 >> Caller Profile Initialization Complete Your user name is: somebody SIP server to register with: sipfx.com:5060 UAS will listen for SIP messages at: elaine39.Stanford.EDU:59161 Audio Media Supported m=audio 5004 RTP/AVP 0 3 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 Video Media Supported m=video 5006 RTP/AVP 11 a=rtpmap:11 jpeg/9000 >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> c >> MAKING A SIP CALL >> Please enter address to call (ex [email protected])

SIP (Session Initiation Protocol) EE384B - Group 25

Page 20

-> [email protected] >> Connected to epic24.stanford.edu:5060 >> Sending INVITE... INVITE sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP elaine39.Stanford.EDU From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Contact: <sip:[email protected]:0; transport=tcp> Content-Length: 143 v=0 c=IN IP4 171.64.15.135/127 m=audio 5004 RTP/AVP 0 3 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 m=video 5006 RTP/AVP 11 a=rtpmap:11 jpeg/9000 >> Received message (483 bytes): SIP/2.0 200 OK Via: SIP/2.0/TCP epic24.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Content-Length: 237 v=0 c=IN IP4 171.64.15.135/127 m=audio 3456 RTP/AVP 0 3 4 5 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 a=rtpmap:4 G723/8000 a=rtpmap:5 DVI4/8000 m=video 1234 RTP/AVP 7 9 11 a=rtpmap:7 h.261/9000 a=rtpmap:9 h.262/9000 a=rtpmap:11 jpeg/9000 >> Sending ACK ACK sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP elaine39.Stanford.EDU:59161 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 ACK Content-Length: 0 >> Your call has been set up! >> Agreed Audio = a=rtpmap:0 PCMU/8000 Agreed Video = a=rtpmap:11 jpeg/9000

SIP (Session Initiation Protocol) EE384B - Group 25

Page 21

>> (b) to end call -> b >> Sending BYE BYE sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP elaine39.Stanford.EDU:59161 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 2 BYE Content-Length: 0 >> Received message (211 bytes): SIP/2.0 200 OK Via: SIP/2.0/TCP epic24.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 2 BYE Content-Length: 0 >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> q >> Bye bye! mdensing’s terminal: >> Reading configuration info from sipparams file... >> Opening socket to listen for incoming SIP messages... success: listening on port 5060 >> Caller Profile Initialization Complete Your user name is: mdensing SIP server to register with: sipfx.com:5060 UAS will listen for SIP messages at: epic24.Stanford.EDU:5060 Audio Media Supported m=audio 3456 RTP/AVP 0 3 4 5 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 a=rtpmap:4 G723/8000 a=rtpmap:5 DVI4/8000 Video Media Supported m=video 1234 RTP/AVP 7 9 11 a=rtpmap:7 h.261/9000 a=rtpmap:9 h.262/9000 a=rtpmap:11 jpeg/9000 >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> l >> ENTERING LISTEN MODE >> Waiting for incoming connection... >> Received message (482 bytes): INVITE sip:[email protected] SIP/2.0

SIP (Session Initiation Protocol) EE384B - Group 25

Page 22

Via: SIP/2.0/TCP elaine39.Stanford.EDU From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Contact: <sip:[email protected]:0; transport=tcp> Content-Length: 143 v=0 c=IN IP4 171.64.15.135/127 m=audio 5004 RTP/AVP 0 3 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 m=video 5006 RTP/AVP 11 a=rtpmap:11 jpeg/9000 >> Agreed Audio = a=rtpmap:0 PCMU/8000 Agreed Video = a=rtpmap:11 jpeg/9000 >> Sending 200 OK... SIP/2.0 200 OK Via: SIP/2.0/TCP epic24.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Content-Length: 237 v=0 c=IN IP4 171.64.15.135/127 m=audio 3456 RTP/AVP 0 3 4 5 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 a=rtpmap:4 G723/8000 a=rtpmap:5 DVI4/8000 m=video 1234 RTP/AVP 7 9 11 a=rtpmap:7 h.261/9000 a=rtpmap:9 h.262/9000 a=rtpmap:11 jpeg/9000 >> Waiting for caller to hang up... >> Received message (244 bytes): ACK sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP elaine39.Stanford.EDU:59161 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 ACK Content-Length: 0 >> Received message (244 bytes): BYE sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP elaine39.Stanford.EDU:59161 From: <sip:[email protected]> To: <sip:[email protected]>

SIP (Session Initiation Protocol) EE384B - Group 25

Page 23

Call-ID: [email protected] Cseq: 2 BYE Content-Length: 0 >> Sending 200 OK... SIP/2.0 200 OK Via: SIP/2.0/TCP epic24.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 2 BYE Content-Length: 0 >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> q >> Bye bye!

Scenario 3 – Registration with a Proxy Server In the previous scenarios, the caller had to know the host and even port

number to contact the other party on. To simplify this, and to enable users to move at will between hosts, their client can register with a SIP server, instructing it where to reach them.

We used Nortel’s sipfx server to test our code. TCP connections to port 5060 of sipfx have been down for most of the two weeks prior to turning in this paper. But it came up Saturday evening, and here are our results.

mdensing starts up his SIP user agent on elaine33, and it opens port 5060 to listen for incoming SIP messages on. He then registers with sipfx. Sipfx responds with an immediate 100 Trying message, and then a 200 OK on successful conclusion. The Contact field in its response lists all current registrations for mdensing, which include the newly added one. Sipfx now knows that any incoming calls to mdensing should be forwarded to elaine33.Stanford.edu:5060 (as well as to all other registered destinations). >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> r >> REGISTERING WITH SIP SERVER >> Connected to sipfx.com:5060 >> Registering you as: [email protected] To be contacted at: elaine33.Stanford.EDU:5060 >> Sending: REGISTER sip:sipfx.com SIP/2.0 Via: SIP/2.0/TCP elaine33.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 REGISTER Contact: <sip:[email protected]:5060 ;transport=tcp>

SIP (Session Initiation Protocol) EE384B - Group 25

Page 24

Content-Length: 0 >> Server response message (251 bytes): SIP/2.0 100 Trying Via: SIP/2.0/TCP elaine33.Stanford.EDU:5060 ;received=171.64.15.108 To: <sip:[email protected]> From: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 REGISTER Content-Length: 0 Server: NetFX/1.0 >> Server response message (547 bytes): SIP/2.0 200 Registration Successful Via: SIP/2.0/TCP elaine33.Stanford.EDU:5060 ;received=171.64.15.108 To: <sip:[email protected]> ;tag=80291462 From: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 REGISTER Content-Length: 0 Contact: <sip:[email protected]:5060;transport=tcp> ;q=0.0 ;expires ="Sun, 21 May 2000 19:56:11 GMT", <sip:[email protected]:40916>, <sip: [email protected]:40910>, <sip:[email protected]:62091>, <sip:[email protected]:43588> >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit ->

Scenario 4 – Calling Through a Proxy Server Once Matt (mdensing) has registered with sipfx, then he can be called at the

SIP URL “sip:[email protected],” regardless of which host he is currently logged on to. When anybody wishes to talk to him, they send an INVITE to sipfx, which acts as a proxy server, relaying the messages between the two hosts. After registering, mdensing enters listen mode: >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> l >> ENTERING LISTEN MODE >> Waiting for incoming connection... Venkatesh (vvenkata) connects to sipfx port 5060 and sends an invite to [email protected]: >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> c >> MAKING A SIP CALL >> Please enter address to call (ex [email protected])

SIP (Session Initiation Protocol) EE384B - Group 25

Page 25

-> [email protected] >> Connected to sipfx.com:5060 >> Sending INVITE... INVITE sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP saga3.Stanford.EDU From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Contact: <sip:[email protected]:0; transport=tcp> Content-Length: 143 v=0 c=IN IP4 171.64.15.135/127 m=audio 3456 RTP/AVP 4 5 a=rtpmap:4 G723/8000 a=rtpmap:5 DVI4/8000 m=video 1234 RTP/AVP 7 a=rtpmap:7 h.261/9000 Venkatesh receives some 100 Trying messages as sipfx does the proxying: >> Received message (247 bytes): SIP/2.0 100 Trying Via: SIP/2.0/TCP saga3.Stanford.EDU ;received=171.64.15.133 To: <sip:[email protected]> From: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 INVITE Content-Length: 0 Server: NetFX/1.0 The INVITE is relayed through the proxy. Sipfx connects to elaine33 and sends an INVITE to Matt. Notice the two Via fields showing the path the message traversed. In addition, sipfx has replaced the SIP URL in the INVITE line with Matt’s elaine33 host:port. Matt receives the packet below. >> Received message (576 bytes): INVITE sip:[email protected]:5060;transport=tcp SIP/2.0 Via: SIP/2.0/TCP 204.0.176.18:5060 ;branch=-136459289653826 Via: SIP/2.0/TCP saga3.Stanford.EDU ;received=171.64.15.133 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 INVITE Content-Type: application/sdp Contact: <sip:[email protected]:0; transport=tcp> Content-Length: 143 v=0 c=IN IP4 171.64.15.135/127 m=audio 3456 RTP/AVP 4 5 a=rtpmap:4 G723/8000

SIP (Session Initiation Protocol) EE384B - Group 25

Page 26

a=rtpmap:5 DVI4/8000 m=video 1234 RTP/AVP 7 a=rtpmap:7 h.261/9000 Matt runs NegotiateMedia, and finds compatible types. So he sends a 200 OK message, and waits for an ACK and for the caller to hang up: >> Agreed Audio = a=rtpmap:4 G723/8000 Agreed Video = a=rtpmap:7 h.261/9000 >> Sending 200 OK... SIP/2.0 200 OK Via: SIP/2.0/TCP elaine33.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Content-Length: 143 v=0 c=IN IP4 171.64.15.135/127 m=audio 3456 RTP/AVP 4 5 a=rtpmap:4 G723/8000 a=rtpmap:5 DVI4/8000 m=video 1234 RTP/AVP 7 a=rtpmap:7 h.261/9000 >> Waiting for caller to hang up... Venkatesh receives the 200 OK, and sends an ACK. The call is now set up from his end as well, and media types negotiated. The call proceeds until he hangs up: >> Received message (339 bytes): SIP/2.0 200 OK From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 INVITE Content-Type: application/sdp Content-Length: 143 v=0 c=IN IP4 171.64.15.135/127 m=audio 3456 RTP/AVP 4 5 a=rtpmap:4 G723/8000 a=rtpmap:5 DVI4/8000 m=video 1234 RTP/AVP 7 a=rtpmap:7 h.261/9000 >> Sending ACK ACK sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP saga3.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected]

SIP (Session Initiation Protocol) EE384B - Group 25

Page 27

Cseq: 1 ACK Content-Length: 0 >> Your call has been set up! >> Agreed Audio = a=rtpmap:4 G723/8000 Agreed Video = a=rtpmap:7 h.261/9000 >> (b) to end call Matt receives the ACK: >> Received message (313 bytes): ACK sip:[email protected]:5060;transport=tcp SIP/2.0 Via: SIP/2.0/TCP 204.0.176.18:5060 Via: SIP/2.0/TCP saga3.Stanford.EDU:5060 ;received=171.64.15.133 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 ACK Content-Length: 0 When Venkatesh is done, he sends a BYE: -> b >> Sending BYE BYE sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP saga3.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 2 BYE Content-Length: 0 Matt receives the BYE, and sends a 200 OK, and closes his connection to sipfx: >> Received message (313 bytes): BYE sip:[email protected]:5060;transport=tcp SIP/2.0 Via: SIP/2.0/TCP 204.0.176.18:5060 Via: SIP/2.0/TCP saga3.Stanford.EDU:5060 ;received=171.64.15.133 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] CSeq: 2 BYE Content-Length: 0 >> Sending 200 OK... SIP/2.0 200 OK Via: SIP/2.0/TCP elaine33.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 2 BYE Content-Length: 0 Venkatesh receives the 200 OK and closes his connection to sipfx: >> Received message (245 bytes):

SIP (Session Initiation Protocol) EE384B - Group 25

Page 28

SIP/2.0 200 OK Via: SIP/2.0/TCP saga3.Stanford.EDU:5060 ;received=171.64.15.133 To: <sip:[email protected]> From: <sip:[email protected]> Call-ID: [email protected] CSeq: 2 BYE Content-Length: 0 Server: NetFX/1.0

Scenario 5 – PSTN Call SIP was designed to also support calls to the PSTN through gateways. Sipfx

also supports this, and we have set up an account to allow easy testing. We used sipfx’s web interface to register the public telephone near the elevator in Sweet Hall as [email protected], and to specify that the contact URL is “tel:16508539709”. We then used our client to send an INVITE to [email protected]. This caused the phone to ring. Of course, since our client does not implement audio coding, when picked up the line was silent. But it did demonstrate successful call initiation, and shows how SIP can be used to interface with the PSTN.

Following are the results of the test. ashelman makes the call. sipfx responds with two 100 trying messages, and then two 180 Ringing messages, at which point someone picked up the phone and sipfx sent a 200 OK message. The later three specify SDP parameters for their gateway (which, for example uses standard PCMU encoding). Since ashelman also supports PCMU, the negotiation is successful. The call continues until ashelman sends a BYE. >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit -> c >> MAKING A SIP CALL >> Please enter address to call (ex [email protected]) -> [email protected] >> Connected to sipfx.com:5060 >> Sending INVITE... INVITE sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP myth2.Stanford.EDU From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 INVITE Content-Type: application/sdp Contact: <sip:[email protected]:0; transport=tcp> Content-Length: 237 v=0 c=IN IP4 171.64.15.135/127 m=audio 3456 RTP/AVP 0 3 4 5 a=rtpmap:0 PCMU/8000

SIP (Session Initiation Protocol) EE384B - Group 25

Page 29

a=rtpmap:3 GSM/8000 a=rtpmap:4 G723/8000 a=rtpmap:5 DVI4/8000 m=video 1234 RTP/AVP 7 9 11 a=rtpmap:7 h.261/9000 a=rtpmap:9 h.262/9000 a=rtpmap:11 jpeg/9000 >> Received message (247 bytes): SIP/2.0 100 Trying Via: SIP/2.0/TCP myth2.Stanford.EDU ;received=171.64.15.15 To: <sip:[email protected]> From: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 INVITE Content-Length: 0 Server: NetFX/1.0 >> Received message (247 bytes): SIP/2.0 100 Trying Via: SIP/2.0/TCP myth2.Stanford.EDU ;received=171.64.15.15 To: <sip:[email protected]> From: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 INVITE Content-Length: 0 Server: NetFX/1.0 >> Received message (501 bytes): SIP/2.0 180 Ringing Via: SIP/2.0/TCP myth2.Stanford.EDU ;received=171.64.15.15 To: <sip:[email protected]> From: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 INVITE Content-Length: 239 Content-Type: application/sdp v=0 o=NortelNetworksPRIGW 13602780040989342000 13602780040989342000 IN IP4 216.66.26.10 s=nortelnetworks p=+1 972 684 1000 (Nortelnetworks Richardson, Texas) c=IN IP4 216.66.26.10 t=0 0 m=audio 15000 RTP/AVP 0 a=rtpmap:0 PCMU/8000 >> Received message (501 bytes): SIP/2.0 180 Ringing Via: SIP/2.0/TCP myth2.Stanford.EDU ;received=171.64.15.15 To: <sip:[email protected]> From: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 INVITE

SIP (Session Initiation Protocol) EE384B - Group 25

Page 30

Content-Length: 239 Content-Type: application/sdp v=0 o=NortelNetworksPRIGW 13602780049444228000 13602780049444228000 IN IP4 216.66.26.10 s=nortelnetworks p=+1 972 684 1000 (Nortelnetworks Richardson, Texas) c=IN IP4 216.66.26.10 t=0 0 m=audio 15000 RTP/AVP 0 a=rtpmap:0 PCMU/8000 >> Received message (556 bytes): SIP/2.0 200 OK Via: SIP/2.0/TCP myth2.Stanford.EDU ;received=171.64.15.15 To: <sip:[email protected]> ;tag=2134804158 From: <sip:[email protected]> Call-ID: [email protected] CSeq: 1 INVITE Content-Length: 239 Content-Type: application/sdp Contact: <sip:[email protected]:5060> v=0 o=NortelNetworksPRIGW 13602780078162500000 13602780078162500000 IN IP4 216.66.26.10 s=nortelnetworks p=+1 972 684 1000 (Nortelnetworks Richardson, Texas) c=IN IP4 216.66.26.10 t=0 0 m=audio 15000 RTP/AVP 0 a=rtpmap:0 PCMU/8000 >> Sending ACK ACK sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP myth2.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 1 ACK Content-Length: 0 >> Your call has been set up! >> (b) to end call -> b >> Sending BYE BYE sip:[email protected] SIP/2.0 Via: SIP/2.0/TCP myth2.Stanford.EDU:5060 From: <sip:[email protected]> To: <sip:[email protected]> Call-ID: [email protected] Cseq: 2 BYE Content-Length: 0 >> Received message (261 bytes):

SIP (Session Initiation Protocol) EE384B - Group 25

Page 31

SIP/2.0 200 OK Via: SIP/2.0/TCP myth2.Stanford.EDU:5060 ;received=171.64.15.15 To: <sip:[email protected]> ;tag=2134804158 From: <sip:[email protected]> Call-ID: [email protected] CSeq: 2 BYE Content-Length: 0 Server: NetFX/1.0 >> Command: (R)egister (C)all (L)isten - (H)ide SIP msgs - (Q)uit ->

Lessons Learned in Testing Perhaps the most salient lesson is the difficulty in implementing a robust SIP

registration server, as demonstrated by the multiple failures of sipfx which occurred in the two weeks we were testing our code. The Nortel engineers suspected that our messages may have contributed to the crashes. From what we know of the bugs in our early code, we can surmise the following two potential server weaknesses.

First, there were cases where our client did not close the TCP connection to sipfx from its side when exiting the call routine (or when we interrupted program execution with Ctrl-C). We know that the engineers experienced problems with TCP connections on port 5060, but continued to support UDP connections (which unfortunately our code did not support). So it is possible the server kept open connections to us, expecting some response that never came. The conclusion is that a SIP server using TCP connections must be careful to timeout sessions that appear to have died, and actively close connections from its side. This would not be so much of a problem with UDP, though the internal data structures used to track ongoing calls would still have to be timed out.

Secondly, we initially has problems with lines overflowing our string arrays. We corrected this and added overflow detection. But the earlier messages could have potentially crashed the server’s parser. The lines also had some potentially confusing text, such as an incomplete To field at the start of the line, and then the start of a Via field in the second half of the line. So in addition to the authentication and security considerations mentioned in the RFC, server robustness in managing TCP/IP flows and parsing incoming messages is crucial to protect from malicious attacks, as well as unintentional mistakes such as in our early code.

SIP (Session Initiation Protocol) EE384B - Group 25

Page 32

References and Resources

References: “SIP: Session Initiation Protocol,” RFC2543bis draft, March 23, 2000, http://www.cs.columbia.edu/~hgs/sip/drafts/draft-ietf-sip-2543bis-00.pdf “SIP Telephony Call Flow Examples,” draft-ietf-sip-call-flows-00, March 200, http://www.ietf.org/internet-drafts/draft-ietf-sip-call-flows-00.txt “SDP: Session Description Protocol,” RFC2327, April 1998, http://www.ietf.org/rfc/rfc2327.txt “SIP Rules!” Bill Michael, Computer Telephony, May 2000. “Tutorial Lesson 138: Inside the Session Initiation Protocol,” Network Magazine, http://www.networkmagazine.com/magazine/tutorial/internetworking/0001tut.htm “Internetworking with TCP/IP, Volume III, Client-Server Programming and Applications, BSD socket version,” Douglas E. Comer and David L. Stevens, Prentice Hall 1993.

Other Useful Resources: Henning Schulzrinne’s SIP home page:

http://www.cs.columbia.edu/~hgs/sip/ Nortel SIP server http://sipfx.com IETF SIP homepage:

http://www.ietf.org/html.charters/sip-charter.html SIP-Related drafts (search for “SIP”):

http://www.ietf.org/internet-drafts/ 3Com SIP site:

http://www.3com.com/technology/sip/