Wireshark RST against TCP Zero Window - sockets

During application sharing with Microsoft Lync Client (Mac OS X), TCP ACK with RST flag is sent from my application end to Lync end against TCP Zero Window packets and call gets dropped.
FYI:
My Application End: 172.16.6.106:55848
Lync End (Remote): 172.16.14.58:18627
Environment:
My Application End: Centos/Linux
Lync End: Mac OSX
Shared Over Wifi.
EDIT
Wireshark TCP Dump
Lync BYE message to my Application:
BYE sip:172.16.6.106:48038;transport=tls;ms-opaque=28c9d310c1;ms-received-cid=BEED00;grid SIP/2.0
ms-user-logon-data: RemoteUser
Via: SIP/2.0/TLS 172.16.6.252:5061;branch=z9hG4bKB5634D63.2E095CFF28141DF6;branched=FALSE;ms-internal-info="agIDti2ZsTK4cWfhAGG1qbj2usseveww7YKemPpN3Jvhv_XAkuuCofIQAA"
Max-Forwards: 67
Via: SIP/2.0/TLS 192.168.2.3:51217;branch=z9hG4bK77E14D58.4A2E43E7B13911D2;branched=FALSE;ms-received-port=51217;ms-received-cid=BEE600
Authentication-Info: NTLM qop="auth", opaque="4207B105", srand="D2C8703A", snum="21", rspauth="010000008bc2daa4dc3b08b864000000", targetname="Lync-FE.LTN2013-Dev.local", realm="SIP Communications Service", version=4
Via: SIP/2.0/TLS 192.168.2.4:50740;branch=z9hG4bKFF62C04C.B8AD61CF28131DF6;branched=FALSE;ms-received-port=50740;ms-received-cid=1117700
Via: SIP/2.0/TLS 172.16.14.58:30689;received=172.16.14.58;ms-received-port=57719;ms-received-cid=BEE400
From: "" <sip:test1#ltn2013-dev.net>;epid=48777ee2e9;tag=dd8ced12ab
To: <sip:ilanaroom#ltn2013-dev.net>;tag=1442263920;epid=14422639
Call-ID: RkdVRZrTUlhKLke0Et9MiVaJTOJd5UMJKljncCC1
CSeq: 1 BYE
User-Agent: UCCAPI/4.0.7323.0 MC/14.0.5093.11 (Microsoft Lync for Mac 2011)
ms-client-diagnostics: 34; reason="Call terminated on a mid-call media failure where both endpoints are remote";MediaDebug="Diag:LastError:time out,time:3651253182890;LastRTP Seq:30662,SeqDelta:1,time:3651253152751;LastRTCP time:3651253151390;Last transport receive error:0x0,time:0;Last transport send error:0x0,time:0;"
Content-Length: 0

The capture excerpt shown indicates that Lync is sending data to your Ap Ok but, for whatever reason, is unwilling to accept any data from your Ap (since the advertised window from 172.16.14.58 is 0).
One possibilityfor the RST from your Ap: your Ap has data to send to Lync but can't (since the win = 0) and eventually gives up.
Obviously, this doesn't help much other than to suggest that there's a problem with the Lync end. It's possible that examining a complete capture would provide more information.
For example: was the Ap previously able to send data ? What was the history of the window advertised by Lync ? and so on.
Update:
*Examining the capture you've posted a link to:
It looks quite normal (other than the zero-window stuff at the end).
Starting at about the 91 sec point, the Lync server stops accepting data (win=0), sends some short messages back to your client and then your client sends an RST to the server 30 secs after the server stops accepting data.
So: there's not really any info in the capture which indicates anything much about what's going on with the Lync server.
I do note that just before the win=0 from the server, the windows advertised by the server are smaller than the range advertised previously. (Note: I expect that the actual window size is larger than that seemingly advertised because there's a "window size scale factor" greater than 1 involved. Wireshark doesn't know the scale factor since the original TCP connection establishment handshake is not part of the capture).

Related

Pjsua (pjsip client) does not want use TCP

I'm trying to make a SIP request to a SIP server, using pjsua, a SIP client by pjsip (version 2.10, 2020-02-14). Starting the client this way:
pjsua-x86_64-apple-darwin19.4.0 --id sip:addreessee#sever_host_name:5061;transport=tcp --no-udp
Using the "S" command to send an arbitrary REQUEST, typing a SIP method (I tried with MESSAGE and others) to use in the request and than adding as destination URI "sip:sever_host_name:5061"
The result is:
Destination URI: sip:addreessee#sever_host_name:5061
13:48:02.121 pjsua_core.c .TX 342 bytes Request msg MESSAGE/cseq=53264 (tdta0x7f96c501cca8) to UDP sever_host_name:5061:
MESSAGE sip:addresse#sever_host_name:5061 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.15:5060;rport;branch=z9hG4bKPjI-s3KUBrnruOqLAKEtCOLnJ.jJPKmoDe
Max-Forwards: 70
From: <sip:addreessee#server_host_name>;tag=1lsf1PY19Qc4fk-8IhoqTV9plx3kX0yC
To: <sip:addreessee#server_host_name>
Call-ID: -X2iZRlerEaevvVvOZlAX5STQnBaGuN2
CSeq: 53264 MESSAGE
Content-Length: 0
So the request is sent over UDP transport layer, not TCP. Can anyone tell me what am I doing wrong?
You should add ;transport=tcp to your request URI each time.
You can read more here (link)

socket programming for bad network

client:
socket(), connect() and then
for (1 to 1024) {
write(1024 bytes)
}
exit(0);
server:
socket(), bind(), listen()
while (1) {
accept()
while((n = read()) {
if (n == -1) abort(); /* never happended */
total_read += n
}
close()
}
now, client runs on Mac under NAT and server runs on my VPS (abroad)
generally, it works fine (client send all data and exit & server recv all data)
however, when client is running but suddenly the network is broken for couple minutes(and regain), the client won't exit after a long long time... I kill it with control + C and run it again, the server seems not read the data any more (client is still running)
here is what netstat shows:
client:
tcp4 0 130312 192.168.1.254.58573 A.B.C.D.8888 ESTABLISHED
server:
tcp 0 0 A.B.C.D:8888 a.b.c.d:54566 ESTABLISHED 10970/a.out
tcp 102136 0 A.B.C.D:8888 a.b.c.d:60916 ESTABLISHED -
A.B.C.D is my VPS address
a.b.c.d is my public client address
my quesiton is:
1, why ?
2, server will works fine after restarting, how to write code to get rid of it without restarting ?
In TCP, there's no way to tell that a connection has failed unless you try to send something on the connection. TCP doesn't perform active monitoring of the connection (actually, there are optional "keepalive" packets, but these are not normally sent until the connection has been idle for a couple of hours). When you send something, you'll eventually get an error if there's a timeout waiting for the other machine to return an acknowledgement. But if you're just reading data without sending, you can't tell that the connection has failed -- it just looks like the sender doesn't have anything to send.
You can resolve this by designing your application so that the client is required to send something every N seconds. Then set a timer in the server that detects that you haven't received anything for more than N seconds (you should add a little extra time to allow for transient delays).
When the network is broken what happens is that you clients keep sending data and at some point the socket send buffer gets full (I understand from what you show that you are sending 1024 Bytes, 1024 times, 1MB in total). The default for send buffer could be 16KB (surely less than 1MB). Then when the client tries to write, it gets blocked forever.
BTW, now I'm answering your question I don't know whether eventually after a number of TCP timeouts, TCP gives up and closes the socket making the socket interface return with error. I think that's not happening ... :) - So, connect fails if there is a problem in the network but write and read do not fail.
In the server side, the server gets blocked in read because it never receives the EOF.
Solution:
In the client side use non-blocking sockets, if the network is broken, at some point write will return with error EWOULDBLOCK. Then you will realize the send buffer is full for some reason. At that point, you could clouse the connection and try to connect again. If the network is broken, you will receive an error.
In the server side also use non-blocking sockets and select() function with a timeout. After a few timeouts you may decide there is a problem with the new connection and close it.

PostgreSQL frontend unexpectedly closes connection

I'm a little bit confused with the following case.
I've got a Postgres server running on host A, and a java based client running on host B. The client uses org.postgresql.Driver JDBC driver (version 9.1-901.jdbc3).
sometimes while executing long running stored procedure I get exception "java.net.SocketException: Socket closed". I'm using org.apache.commons.dbcp.BasicDataSource for retrieving
connections.
DBCP pool is configured with default options.
I got tcp dump in order to figure out on which side (client or server) socket is being closed;
Here is what I've got:
1. Client B sends a test query message when tries to borrow connection from dbcp pool ("Select 1")
2. Server A sends successful response back (Type: Command completion, Ready for query)
3. Client B sends ACK message in response on server A response (see the item 2).
4. Client B sends query message to the server A.
5. Server A sends ACK message in response on client Query message (see the item 4).
6. Client B sends terminating message (Type : Termination) after some time passed (from 3 to 10 or sometimes even more minutes).
7 Client B sends FIN ACK message to the server.
8. Server A sends back ACK on termination message.
9. Server A sends ACK on (FIN, ACK) message (item 7).
10. Server A sends back a response on the client query (from item 4) Type: Row description Columns: 40.
11. Client B sends RST message (reset).
12. Server A continues sending response on the query Type: Data row Length: 438 Columns 40 and so on.
13 Client B sends RST message (reset) again.
14. Server A continues sending response on the query Type: Data row Length: 438 Columns 40 and so on.
15. Client B sends RST message (reset).
After that communication seems to be finished.
After the item 6, in my client logs I got Exception like the following:
Caused by: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:145)
at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:114)
at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:73)
at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:274)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1661)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
Could you please help me to figure out the reason of such a failure. (This bug happens once per 10 successful cases.)
We had a similar problem, and it was caused by a firewall or connection tracking router between the server and the client.
I am guessing you took the tcpdump on the server side. The query runs for a considerable time with no traffic on the connection. The firewall has a timer on the open connection; it expires and the firewall closes the connection towards the server, and also back towards the client. On the capture at the server side, it looks like the client is closing the connection.
You could verify this by capturing on the client side simultaneously as you capture on the server side - on the client side it will look like the server has closed the connection, while on the server side it looks like the server is closing the connection. In reality the firewall is closing it in both directions.
To prevent this, you can set tcp_keepalives_idle, tcp_keepalives_interval and/or tcp_keepalives_count (if your OS supports TCP Keepalives). Alternatively, you will have to change the settings on the firewall.

Record-route header with lr=on when sent by Kamailio as Outbound proxy

I am using Xlite at one end for sending INVITE.
If i use Kamailio 4.0.1 as outbound proxy,in the call flow it adds lr=on as mentioned below WIRESHARK trace :
Record-Route:
Via: SIP/2.0/UDP 10.44.104.149;branch=z9hG4bK0ecf.1bd4c266.0
Via: SIP/2.0/UDP 10.44.104.160:5998;branch=z9hG4bK-d8754z-829f7d43eed09018-1---d8754z-;rport=5998
and after that the pbx sends 503 response for the INVITE.
but as per RFC 3665 for the call flow ,the lr should be blank as :
Record-Route:
is there any configuration change needed in the Kamailio to meet REcord Route as per RFC 3665 ie lr without On value.
You have to set parameter enable_full_lr for rr module to 0, see:
http://kamailio.org/docs/modules/stable/modules/rr.html#idp21848

FIN,ACK after PSH,ACK

I'm trying to implement a communication between a legacy system and a Linux system but I constantly get one of the following scenarios:
(The legacy system is server, the Linux is client)
Function recv(2) returns 0 (the peer has performed an orderly shutdown.)
> SYN
< SYN, ACK
> ACK
< PSH, ACK (the data)
> FIN, ACK
< ACK
> RST
< FIN, ACK
> RST
> RST
Function connect(2) returns -1 (error)
> SYN
< RST, ACK
When the server have send its data, the client should answer with data, but instead I get a "FIN, ACK"
Why is it like this? How should I interpret this? I'm not that familiar with TCP at this level
When the server have send its data, the client should answer with data, but I instead get a "FIN, ACK" Why is it like this? How should I interpret this?
It could be that once the server has sent the data (line 4) the client closes the socket or terminates prematurely and the operating system closes its socket and sends FIN (line 5). The server replies to FIN with ACK but the client has ceased to exist already and its operating system responds with RST. (I would expect the client OS to silently ignore and discard any TCP segments arriving for a closed connection during the notorious TIME-WAIT state, but that doesn't happen for some reason.)
http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination:
Some host TCP stacks may implement a half-duplex close sequence, as Linux or HP-UX do. If such a host actively closes a connection but still has not read all the incoming data the stack already received from the link, this host sends a RST instead of a FIN (Section 4.2.2.13 in RFC 1122). This allows a TCP application to be sure the remote application has read all the data the former sent—waiting the FIN from the remote side, when it actively closes the connection. However, the remote TCP stack cannot distinguish between a Connection Aborting RST and this Data Loss RST. Both cause the remote stack to throw away all the data it received, but that the application still didn't read
After FIN, PSH, ACK --> One transaction completed
Second request receiving but sending [RST] seq=140 win=0 len=0