Is there a way to prevent sending multiple SIP messages in a single TCP packet? - sockets

I am testing the integration of a SIP Server(just a PBX) with another PBX.
The incoming call comes into the PBX and is sent to my SIP Server.
Once the call arrives on my SIP Server, it is then again sent back to a user who is registered to my PBX. Here we have 2 call legs – one from the caller to PBX and another from Sip Server to called party.
The call is set up correctly and there is no issue with audio as well.
When the called party releases the call, my SIP Server sends a BYE message to called party and caller in the same TCP packet.
Upon running a Wireshark trace I found that BYE message from my SIP Server reaches the called party but never reaches the caller.
I know there is a firewall between my SIP Server and PBX.
Question:
Is there an option for how to prevent multiple SIP messages in a single TCP packet? Other than using UDP or fight against FW?
>> BYE from SIP Server to called party and it gets a 200 OK:
11:39:03.163: Sending [31,TCP] 462 bytes to 10.cc.dd.ddf:5060 >>>>>
BYE sip:+xxxxxxxxx#10.xx.cc.vv:1122;transport=tcp SIP/2.0
Call-ID: 003BA5CE-58A9-1D9C-ACEB-886231C0AA77-57379#1xx.vv.vv.vvv
<................>
>> BYE from SIP Server to the caller and it never makes it to the PBX:
11:39:03.163: Sending [31,TCP] 448 bytes to 10.cc.dd.ddf:5060 >>>>>
BYE sip:+420702252645#10.cc.cc.bb:5060;transport=tcp SIP/2.0
Call-ID: acda8080-da917a0e-5a26b-8a61610a#10.xx.cc.vvb

Is there an option for how to prevent multiple SIP messages in a single TCP packet?
While the setup your describe is confusing (images with setup and message flow might make it more clear) and the question by itself is likely off-topic (unrelated to programming), this specific part of the question can be answered:
There is no option like this in SIP. While your specific but unknown endpoint or PBX might have such an option it is unlikely. The sender is fully within the specification if it packs multiple SIP messages to the same hop (i.e. SIP endpoint or SIP proxy) into the same TCP connection where they also can end up in the same packet because this is how TCP works. If the recipient has problems with this then it is a bug in the recipient and should be fixed there instead of working around it in every possible peer.

Related

SIP dialog established via UDP - what is the transport AFTER a large SIP request has been sent via TCP?

Given a SIP dialog (INVITE, 200 OK, ACK) has been established via UDP; And a large message gets sent that requires TCP as transport.
What is the applied transport protocol after the large message has been sent for all other following (and normal sized) messages?
Does the protocol switch to TCP for all further request/responses or does it keep using the initially negotiated transport - UDP - for standard sized (NOT large) messages?
What I found (based on RFC 3261):
All SIP elements MUST implement UDP and TCP. SIP elements MAY
implement other protocols.
- from rfc3261#18
The ACK MUST be sent to the same address,
port, and transport to which the original request was sent.
- from rfc3261#18
Okay that says NOT all requests (especially ACK) are able to choose the transport independently.
Making TCP mandatory for the UA is a substantial change from RFC
2543. It has arisen out of the need to handle larger messages,
which MUST use TCP, as discussed below. Thus, even if an element
never sends large messages, it may receive one and needs to be
able to handle them.
- from rfc3261#18
During an established dialog a UAS/UAC never knows if the need for a large message arises - switching from UDP to TCP is just fine (without any RE-INVITE that changes the transport in advance to the actual request).
A 301 (Moved Permanently) or 302 (Moved Temporarily) response may
also give the same location and username that was targeted by the
initial request but specify additional transport parameters such as
a different server or multicast address to try, or a change of SIP
transport from UDP to TCP or vice versa.
- from rfc3261#8.3
not really relevant - the UAS may want to change the transport suggested by the UAC; but that is based on the reaction onto some INVITE (or RE-INVITE) only
The destination address,
port, and transport for the CANCEL MUST be identical to those used to
send the original request.
- from rfc3261#9.1
Okay CANCEL (like ACK) also must NOT independently choose the transport.
If a request is within 200 bytes of the path MTU, or if it is larger
than 1300 bytes and the path MTU is unknown, the request MUST be sent
using an RFC 2914 [43] congestion controlled transport protocol, such
as TCP. If this causes a change in the transport protocol from the one
indicated in the top Via, the value in the top Via MUST be changed.
That says if the SIP dialog was established via UDP, it has to be able to receive TCP requests also.
For any port and interface
that a server listens on for UDP, it MUST listen on that same port and
interface for TCP. This is because a message may need to be sent
using TCP, rather than UDP, if it is too large. As a result, the
converse is not true. A server need not listen for UDP on a
particular address and port just because it is listening on that same
address and port for TCP. There may, of course, be other reasons why
a server needs to listen for UDP on a particular address and port.
Okay that explains how switching from UDP to TCP works seamless. - And for the other direction it is just not required, but (I understand like: it still MAY work).
Both TCP and UDP are usable at that point and the transport layer is responsible for the choice.
SIP is transport independent, both are active at the same time.

Sofia SIP not sending REGISTER refresh when using TCP transport

I have noticed that when I changed transport from UDP to TCP in Sofia SIP stack for some reason the SIP registration refreshes are not sent. Only the first REGISTER is sent properly and then nothing.
On the other hand, with the exact same setup if I use UDP as transport I properly get the REGISTER refreshes without issues.
Any ideas what might be the issue?
Best regards,
Antonis Tsakiridis

ICE solution on RFC 6314

in RFC6314, section 5.2.1.2, it mentions that after Client_L collected its candidate list, it sends INVITE to Client_R with the list, and then both ends can start connectivity check.
I have a question is that why Client_L can send INVITE to Client_R? or why Client_R can receive those data (candidate list)? I think in this time Client_L should have no address info of Client_R. Thanks your answer in advanced.
https://www.rfc-editor.org/rfc/rfc6314#section-5.2.1
In order for clients to establish a P2P ICE session, they have to rendezvous through a reliable signaling server. The signaling server exists for clients to exchange address candidates in order for ICE negotiation to actually begin. This is typically a SIP server. Although ICE allows for almost anything to be used for exchanging addresses.
When the INVITE is sent out, it gets sent to a server that knows how to forward that message to the other client. When the remote client gets the INVITE, it responds back with a series of SIP messages - one of which is the "180 RINGING" or "200 OK" message that contains the address candidates from the client that received the INVITE.

making SIP calls over TCP using PJSIP

I'm using a PJSIP's pjsua dialer (based on pjsua_app.c, PJSIP 2.0.1) with TCP transport and a SIP trunk to make calls to a mobile phone. The dialer registers with a SIP Server over TCP and also sends out INVITES over TCP. UDP transport is not being used.
The environment is something like this -
PJSIP (behind NAT)<--- SIP over TCP ---> SIP Server <--- SIP trunk --> SIP trunk Provider <-- PSTN/Mobile Gateway-->Mobile phone
All calls are made from PJSIP over TCP to the mobile. To disable UDP transport creation I inserted a line "cfg->no_udp = true;" at the end of the function
"static void default_config(struct app_config *cfg)" in pjsua_app.c
I followed the instructions given here to make calls over TCP.
The problem is that we don't receive audio sent from the mobile end into the PJSIP dialer.
But RTP packets from the PJSIP dialer reach the mobile side just fine. We can hear audio in the mobile when the call is established.
We found from packet traces that the reason we dont receive media in the PJSIP dialer is that the SIP server is sending RTP packets received over the SIP trunk to a private IP address.
But when we switch to UDP for registration and send INVITES over TCP the call works fine (audio at both ends).
The wireshark packet capture shows the following -
1. PJSIP registers with server over TCP.
2. Server sends 401 with PJ's public IP and port in VIA
3. PJ registers again but inserts its public ip and port in the
contact header in the next REGISTER message sequence.
So far so good. Same sequence of messages seen when UDP is used to REGISTER.
4. INVITE sent over TCP. Dialog establishment works fine.
But in the record-route header nat=yes is missing.
5. Server sends media to private IP. No media received at PJSIP.
Is this a bug in PJSIP? If so how can this be fixed. Wireshark packet traces are available on request.
Your help and inputs are much appreciated.
Your question doesn't actually make sense as the transport of the signalling between the sip endpoint and the sip server (either UDP or TCP) has no bearing on the media transport between the two sip endpoints (most likely UDP). So there must be something else going on.
Since your talking about private IP addresses, I'm assuming you are coming from a behind a NAT over the internet to a "public" sip server.
In these types of environments I would recommend you setup STUN, TURN and ICE on the sip endpoint.
I would guess the UDP setup you where talking about has the STUN server setup and the TCP setup you where talking about doesn't.
Without further information I can't help much more.
Try to use port other than 5060 in both client and server, and/or reducing the SIP message size.
It seams this is a know issue for sending INVITE request over TCP in PJSIP.
Also you can find here some advices for reducing the SIP message size.
Please make sure that allow_contact_rewrite is set to true so that the media will be received to your end.
I think my answer is too late but this may help some other folks

SIP: Wait for ACK packet on Callee site to start RTP session

The Situation:
I have a question concerning the ACK message (yellow) which is send from the Asterisk to the Callee (Tel B) after the Callee has send its 200 OK + SDP message (purple). The Asterisk call flow which I am talking about looks like:
My network for testing porposes:
Laptop+Softphone ---- Asterisk ---- Laptop+Softphone
The Question:
All of my tested Linux softphones (Twinkle, SFLPhone, Ekiga-Softon, Linphone and QuteCom) are not waiting for the ACK to start the RTP session. I filtered the ACK message with iptables on the Asterisk Server and the RTP session started anyways. However due to my project intention I would like to wait for the ACK message and then start the RTP session. Is there a way, switch, command or preference to let the softphone wait with the RTP stream until the ACK message is received?
Additional:
I googled a lot and found some device e.g. the iiNet Branded Belkin VoIP Router which has the option: Start RTP session before receiving ACK [default: off] Thus I guess there must be a way to let the RTP session start after the ACK is received.
As well I found that it is best practice that the session starts directly after the 200 OK + SDP is send. However as aforementioned this is not sufficient for my project.
Source of Figure:
http://www.panoramisk.com/101/asterisk-and-voice-transport/en/
The short answer is no; there isn't going to be a widely supported setting that allows you to force RTP to be started after the ACK. At best you'll find some devices/softphones, such as the one you mention, that have a setting that allows it. I have seen this query come up before on the SIP implementers mailing list and if I recall correctly the RFC isn't actually definitive on whether the RTP should start after the 2xx response or the ACK but the generally excepted premise is that it's the 2xx response.
Another angle you could explore is looking for a setting, or maybe even getting tricky with your firewall rules, to send the initial INVITE without SDP. INVITEs without SDP are supported by RFC 3261 and when they are received it indicates the 2xx response should contain the initial SDP offer and the subsequent ACK will then have the SDP response. With that mechanism the RTP will have nowhere to go until after the ACK is sent.