strange TCP handling in opensips 2.4

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

strange TCP handling in opensips 2.4

Чалков Артём
Hi all.
Today i encountered some strange behavior in TCP handling. Case:
A - caller, proto=tcp, behind NAT
B - callee, proto=udp, not behind NAT
Nathelper is active, so A is pinged by OPTIONS from opensips.
A registering and then calling to B, B answers, A sends ACK for 200 and in some moment after that - disappears from network (for example - unplug network cable).
After that B send BYE request.
 
Parameters of proto_tcp:
modparam("proto_tcp", "tcp_port", 5060)
modparam("proto_tcp", "tcp_send_timeout", 5000)
modparam("proto_tcp", "tcp_async", 1)
modparam("proto_tcp", "tcp_crlf_pingpong", 0)
 
 
Expected behavior:
1. if TCP session is still active: opensips will try to send BYE to A via TCP and close TCP-connection after 5000ms (tcp_send_timeout interval), send 477 Send Failed to himself and 408 to B, as result of BYE transaction.
2. if TCP session is no active (after some TCP-FIN): opensips will try to re-establish TCP session, and if it will be not successfull - send 477 Send Failed to himself and 408 to B, as result of BYE transaction.
 
Real behavior:
TCP session is active (there was no TCP-FIN), next OPTIONS-ping from opensips is not answered by A (because he disappeared from network) on TCP-level (no TCP-ACK for request with options), opensips starts to send TCP-retransminnions of last OPTIONS request (and continue to send this retransmissions in a next few minutes), not trying to send BYE request at all, not trying to close TCP session. After fr_timeout number of  seconds opensips sends 408 to B as result of BYE transaction and not sends 477 to himself.
 
There is screenshot of my example:
 
So - it looks like opensips totally ignore tcp_send_timeout value and it leads to some misbehavior in handling TCP requests. Am i right or i missed something?
 
 

_______________________________________________
Users mailing list
[hidden email]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users
Reply | Threaded
Open this post in threaded view
|

Re: strange TCP handling in opensips 2.4

Bogdan-Andrei Iancu-2
Hi Artem,

On the "real-behavior" - OpenSIPS generates and sends an OPTIONS request (a NAT ping) via the stale connection to A. You say :

1) the TCP write operation in OpenSIPS  blocks ? (you mentioned the tcp_send_timeout)

2) the retransmission you mentioned, are at TCP level or SIP level ? If at TCP level, these are done by the TCP/IP stack in the Operating System, they are not done by OpenSIPS.

The received BYE is not sent out as the outgoing connection (to A) is locked by the process trying to send the OPTIONS to A (assuming that the write operation blocks).

Best regards,
Bogdan-Andrei Iancu

OpenSIPS Founder and Developer
  https://www.opensips-solutions.com
OpenSIPS Summit 2019
  https://www.opensips.org/events/Summit-2019Amsterdam/
On 03/25/2019 04:40 PM, Artem Chalkov wrote:
Hi all.
Today i encountered some strange behavior in TCP handling. Case:
A - caller, proto=tcp, behind NAT
B - callee, proto=udp, not behind NAT
Nathelper is active, so A is pinged by OPTIONS from opensips.
A registering and then calling to B, B answers, A sends ACK for 200 and in some moment after that - disappears from network (for example - unplug network cable).
After that B send BYE request.
 
Parameters of proto_tcp:
modparam("proto_tcp", "tcp_port", 5060)
modparam("proto_tcp", "tcp_send_timeout", 5000)
modparam("proto_tcp", "tcp_async", 1)
modparam("proto_tcp", "tcp_crlf_pingpong", 0)
 
 
Expected behavior:
1. if TCP session is still active: opensips will try to send BYE to A via TCP and close TCP-connection after 5000ms (tcp_send_timeout interval), send 477 Send Failed to himself and 408 to B, as result of BYE transaction.
2. if TCP session is no active (after some TCP-FIN): opensips will try to re-establish TCP session, and if it will be not successfull - send 477 Send Failed to himself and 408 to B, as result of BYE transaction.
 
Real behavior:
TCP session is active (there was no TCP-FIN), next OPTIONS-ping from opensips is not answered by A (because he disappeared from network) on TCP-level (no TCP-ACK for request with options), opensips starts to send TCP-retransminnions of last OPTIONS request (and continue to send this retransmissions in a next few minutes), not trying to send BYE request at all, not trying to close TCP session. After fr_timeout number of  seconds opensips sends 408 to B as result of BYE transaction and not sends 477 to himself.
 
There is screenshot of my example:
 
So - it looks like opensips totally ignore tcp_send_timeout value and it leads to some misbehavior in handling TCP requests. Am i right or i missed something?
 
 


_______________________________________________
Users mailing list
[hidden email]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users


_______________________________________________
Users mailing list
[hidden email]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users
Reply | Threaded
Open this post in threaded view
|

Re: strange TCP handling in opensips 2.4

Vitalii Aleksandrov
In reply to this post by Чалков Артём
"tcp_send_timeout" configures the time TCP worker process can stay
blocked in "write()" syscall. In your case opensips successfuly wrote
data into socket and OS accepted it and put into tcp socket's outgoing
queue. Since OPTIONS wasn't delivered (no TCP level ACK from A), kernel
doesn't try to send BYE and continues retransmits. You should see you
OPTIONS and BYE in "Send-Q" field of the netstat output.

You can also play with tcp_keepalive, tcp_keepcount, tcp_keepidle,
tcp_keepinterval options to close stale TCP connections faster.

> Hi all.
> Today i encountered some strange behavior in TCP handling. Case:
> A - caller, proto=tcp, behind NAT
> B - callee, proto=udp, not behind NAT
> Nathelper is active, so A is pinged by OPTIONS from opensips.
> A registering and then calling to B, B answers, A sends ACK for 200
> and in some moment after that - disappears from network (for example -
> unplug network cable).
> After that B send BYE request.
> Parameters of proto_tcp:
> modparam("proto_tcp", "tcp_port", 5060)
> modparam("proto_tcp", "tcp_send_timeout", 5000)
> modparam("proto_tcp", "tcp_async", 1)
> modparam("proto_tcp", "tcp_crlf_pingpong", 0)
> Expected behavior:
> 1. if TCP session is still active: opensips will try to send BYE to A
> via TCP and close TCP-connection after 5000ms (tcp_send_timeout
> interval), send 477 Send Failed to himself and 408 to B, as result of
> BYE transaction.
> 2. if TCP session is no active (after some TCP-FIN): opensips will try
> to re-establish TCP session, and if it will be not successfull - send
> 477 Send Failed to himself and 408 to B, as result of BYE transaction.
> Real behavior:
> TCP session is active (there was no TCP-FIN), next OPTIONS-ping from
> opensips is not answered by A (because he disappeared from network) on
> TCP-level (no TCP-ACK for request with options), opensips starts to
> send TCP-retransminnions of last OPTIONS request (and continue to send
> this retransmissions in a next few minutes), not trying to send BYE
> request at all, not trying to close TCP session. After fr_timeout
> number of  seconds opensips sends 408 to B as result of BYE
> transaction and not sends 477 to himself.
> There is screenshot of my example:
> https://imgur.com/HNxwxPo
> So - it looks like opensips totally ignore tcp_send_timeout value and
> it leads to some misbehavior in handling TCP requests. Am i right or i
> missed something?
>

_______________________________________________
Users mailing list
[hidden email]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users