Search code examples
sip

Is there a silent conspiracy to violate sip rfc 3261 18.2.2


My home sip server which is an OpenWRT embedded piece of software called "PBX" or "asterisk18 1.8.32.3-4" sends a response to the UDP REGISTER request to the host and the port from which the request has been originated, while the spec says,

     > Otherwise (for unreliable unicast transports), if the top Via
     has a "received" parameter, the response MUST be sent to the
     address in the "received" parameter, using the port indicated
     in the "sent-by" value, or using port 5060 if none is specified
     explicitly.  If this fails, for example, elicits an ICMP "port
     unreachable" response, the procedures of Section 5 of [4]
     SHOULD be used to determine where to send the response.

https://www.rfc-editor.org/rfc/rfc3261#section-18.2.2

And this ‘received‘ parameter is set by the server itself, as far as I understand eggs previous section 18.2.1.

There's no ‘rport‘ parameter in my Via header, which I understand should actually trigger such a behavior as per https://www.rfc-editor.org/rfc/rfc3581

This breaks my app which is only capable to listen to one, the 5060 port. (It is based on Camel Netty, not on Jain Sip)

Am I missing something, like the newer rfc, or the wording?


Solution

  • Answer:

    My short answer would be: YES (and not only the Via rules, but also the Contact rules)!

    Using "received" parameter, no "rport" and a different socket PORT for sending will not work:

    The reason is related to standard NAT behavior. If a client send a UDP message to a server, the NAT will rewrite both PORT and IP UDP packet. The server can reply by sending a UDP message on the reverse path only: ie, using the IP and PORT from the NAT. In such case, the NAT will relay the UDP message to the socket sender.

    This explain why the IP and PORT in Via can't be used when talking from a LAN to a SIP server on internet.

    The clean solution for receiving SIP replies, without breaking the spec:

    • using the standard "received" parameter
    • using the standard "rport" extension parameter
    • sending request and listening for answers on the SAME port

    Using the standard "received" parameters AND the standard "rport" extension parameter is the only solution to make sure a SIP server can reply to your UDP messages. As a consequence, the only port where you can receive a reply is the port you have used to send the UDP message.

    Of course, the above solution is universal: it also works on a LAN to LAN communication.

    Extension of the solution is required to receive future request from proxy:

    Of course, this is true for SIP answers. However, the same is true for future requests sent by the SIP services which are supposed to be sent to the Contact header. The same limitations exists for the Contact headers and thus, I would adivse to read and implement rfc5626

    The worst solution: a SIP ALG

    SIP specification, as well as some extensions (rfc3581 and rfc5626) are just the best way to have SIP working. A SIP ALG modifying sip content has always been one big point of failure. It worths to speak about that because many people think this was the only solution. (I disagree a lot)

    Your question: why do SIP servers violate the rfc?

    There is only one way to send UDP reply (and forward SIP request). If servers are not re-using the "reverse UDP path":

    • the reply for REGISTER will be dropped by NAT...
    • the incoming call (INVITE) will be dropped by NAT...

    So, there is no reason, from a proxy perspective to not violate the rfc. In most case, on a proxy, violation of Via and Contact will solve lack of extension on SIP clients. It may break some SIP clients behind ALG, but anyway, I dislike much ALG ;)