Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question
    
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 Nov 15 '12 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. Nov 15 '12 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. –  Jonathan Henson Nov 15 '12 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. –  Jonathan Henson Nov 15 '12 at 21:18
1  
Mea culpa, it does make sense here. –  StuperUser Nov 15 '12 at 21:23

2 Answers 2

up vote 2 down vote accepted

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).

share|improve this answer
    
Thank you so much for this. This is EXACTLY the answer to my question. –  Jonathan Henson Jan 22 '13 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 –  Jonathan Henson Jan 22 '13 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. –  Bart van Ingen Schenau Jan 22 '13 at 8:19

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.

share|improve this answer
    
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. –  Jonathan Henson Nov 15 '12 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 Nov 15 '12 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? –  Jonathan Henson Nov 15 '12 at 21:26
    
TCP should be kept open. UDP is connection less –  jgauffin Nov 15 '12 at 21:29
    
But that would cause the Client to block waiting on a response, and doesn't that break the "STATELESS" rules? –  Jonathan Henson Nov 15 '12 at 21:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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