1

I have a somewhat simple, but specific, question about implementing the transport layer for a SIP UAC.

Do I expect the response to a request on the same socket that I sent the request on, or do I let the UDP or TCP listener pick up the response and then route it to the correct transaction from there? The RFC does not seem to say anything on the matter.

It seems that especially using UDP, which is connection-less, that I should just let the listeners pick up the response, but that seems sort of counter intuitive. Particularly, I have seen plenty of UAC implementations which do not depend on having a Listener in the transport layer.

Also, most implementations I have looked at do not have the UAS receiving loop responding on the socket at all. This would tend to indicate that the client should not be expecting a reply on the socket that it sent the request on.

For clarification:

Suppose my transport layer consists of the following elements:

TCPClient (Sends Requests for a UAC via TCP)
UDPClient (Sends Requests for a UAC vid UDP)
TCPSever (Loop receiving Requests and dispatching to transaction layer via TCP)
UDPServer (Loop receiving Requests and dispatching to transaction layer via UDP)

Obviously, the *Client sends my Requests. The question is, what receives the Response? The *Client waiting on a recv or recvfrom call on the socket it used to send the request, or the *Server?

Conversely, the *Server receives my requests, What sends the Response? The *Client? doesn't this break the roles of each member a bit?

Update I did a packet capture on an SIP Invite transaction between Ekiga and a PolyCom server. Ekiga was the client, and the polycom was the server. In the invite request Ekiga used port 5060 in the via header. 5060 is the port that its UAS is listening on, so that would seem to indicate that the UDPServer is receiving the responses to all requests and not the UDPClient that sent the request. Is this valid reasoning?

8
  • Since this is specific to implementation and doesn't really fit in to the "All programmers" layer of the onion diagram, I've voted to move to StackOverflow.
    – StuperUser
    Commented Nov 15, 2012 at 21:14
  • Which RFC? Wikipedia suggests that it's similar to HTTP in terms of responses. It's also not clear what you mean by "implementing the transport layer" --- surely you're not implementing a TCP or UDP stack?
    – Peter K.
    Commented Nov 15, 2012 at 21:15
  • 1
    @StuperUser, I didn't put it on StackOverflow, because it didn't seem specific enough, since I was talking about a general design question and not a question like: "How do I receive an SIP request on a Linux socket in C." or something like that. Commented Nov 15, 2012 at 21:17
  • 1
    @PeterK. No, I am not implementing TCP or UDP, just using it. By transport I mean creating the Client and Server Sockets, and sending and receiving the data, and then passing the data to the transaction layer. Commented Nov 15, 2012 at 21:18
  • 1
    Mea culpa, it does make sense here.
    – StuperUser
    Commented Nov 15, 2012 at 21:23

2 Answers 2

2

On reading section 18 of RFC3261 about the transport layer, it quite clearly states that the transport layer must be able to receive responses for a transaction on each of

  • The TCP socket used for sending the request (TCPClient)
  • A new TCP connection to the address that the request was sent from and the port number as advertised in the 'sent-by' field of the 'Via' header (TCPServer on sending IP address)
  • A new TCP connection to where the UA is normally listening for new transactions (TCPServer)
  • An UDP datagram on the address that the request was sent from and the port number as advertised in the 'sent-by' field of the 'Via' header (UDPServer on sending IP address)
  • An UDP datagram where the UA is normally listening for new transactions (UDPServer)

So, basically only the UDPClient can't receive responses.


As for sending responses, when the request came in on a reliable transport (TCP), try to use the same socket for the response. If that is not possible, open a new connection as if you are sending an entirely new message. That should give the least surprises.

Regarding the *Server and *Client roles: Usually, the Client sends requests and receives responses, while the server receives requests and sends responses. However, for UDP this model does not really work. There you might go for the model that the Client sends datagrams, while the server receives datagrams (independent of whether they are requests or responses).

3
  • Thank you so much for this. This is EXACTLY the answer to my question. Commented Jan 22, 2013 at 3:34
  • Should I send to the port in the via header in tcp, even when I have an open connection? In other words, should I trust that criteria 1 is always fulfilled. i.e. MUST Commented Jan 22, 2013 at 3:36
  • @JonathanHenson: You must fill in the 'sent-by' field of the top Via header, but you are not required to use the (often ephemeral) port number of your sending socket. I would just send the port number where I would normally accept connections. For replying on the same TCP connection, you don't need any information from the message, the information provided by the sockets implementation is sufficient. Commented Jan 22, 2013 at 8:19
0

When I did my sip stack I build all the messages in the transport layer and than passed them up to the next layer which had to identify the correct transactions.

Doing so also makes everything easier to test.

8
  • thanks for answering. However, I know that much, I want to know the specifics about the Client/Server model as to how which elements are responsible for sending requests / receiving responses. The UAS portion is easy, it is just the UAC that is confusing me. Commented Nov 15, 2012 at 21:20
  • what about it is confusing? Each time you receive a response you are the UAC. Each time you receive a request you are the UAS
    – jgauffin
    Commented Nov 15, 2012 at 21:22
  • Not that part. Here is the problem. I create a socket to send the request on and send it. Now here is the question. Do I wait for a response on THAT socket (like in TCP communications) (i.e. a call to ::read(SOCKET...), or do I close the socket and forget about it trusting that the TCP or UDP Listeners will receive the response? Commented Nov 15, 2012 at 21:26
  • TCP should be kept open. UDP is connection less
    – jgauffin
    Commented Nov 15, 2012 at 21:29
  • But that would cause the Client to block waiting on a response, and doesn't that break the "STATELESS" rules? Commented Nov 15, 2012 at 21:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.