Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with TCP ZeroWindow #17

Open
adaszek opened this issue Dec 18, 2016 · 0 comments
Open

Problem with TCP ZeroWindow #17

adaszek opened this issue Dec 18, 2016 · 0 comments

Comments

@adaszek
Copy link

adaszek commented Dec 18, 2016

Hi,

I have a strange problem with ... actually I am not sure. I use PubSub library to access MQTT broker with RF24Ethernet bellow. From time to time publish() returns false, but actually data is published. I went through PubSub implementation and i noticed that on "failed" cases ethernet client write() returns different size than size of data prepared to transfer over that client (line 462 of PubSubClient.cpp):
rc = _client->write(buf+(4-llen),length+1+llen);
I printed out the returned values and the size of buffer to write and it looks like in error cases rc is equal to size of currently sending buffer + size of previously sent buffer. An example:

Publish attempt 1 		raw/sensor/ardClient1/temperature
rc=41
bufsize=41
Success				connected
----
Publish attempt 1 		raw/sensor/ardClient1/humidity
rc=79
bufsize=38
Failed to publish		connected
Publish attempt 2 		raw/sensor/ardClient1/humidity
rc=38
bufsize=38
Success				connected
----
Publish attempt 1 		raw/sensor/ardClient1/voltage
rc=75
bufsize=37
Failed to publish		connected
Publish attempt 2 		raw/sensor/ardClient1/voltage
rc=37
bufsize=37
Success				connected
----
Publish attempt 1 		raw/sensor/ardClient1/temperature
rc=41
bufsize=41
Success				connected
----

As a next step I did a TCP dump from tun interface where my Arduino is connected to (I use RF24Gateway) and there is a correlation between failed publish() and TCP ACK for MQTT PING RESPONSE sent from broker:

...
"15","17.495376","10.10.3.30","10.10.3.13","MQTT","71","Ping Request, Publish Message"
"16","17.496005","10.10.3.13","10.10.3.30","TCP","40","1883 → 1025 [ACK] Seq=1 Ack=244 Win=28859 Len=0"
"17","17.496099","10.10.3.13","10.10.3.30","MQTT","42","Ping Response"
"18","17.519380","10.10.3.30","10.10.3.13","TCP","40","[TCP ZeroWindow] 1025 → 1883 [ACK] Seq=244 Ack=3 Win=0 Len=0"
"19","17.815883","10.10.3.30","10.10.3.13","MQTT","69","[TCP ZeroWindow] , Publish Message"
"20","17.856177","10.10.3.13","10.10.3.30","TCP","40","1883 → 1025 [ACK] Seq=3 Ack=273 Win=28830 Len=0"
...

10.10.3.30 is my Arduino. TCP Zero Window means "give me a break" so for some reason Arduino is overloaded. From wireshark wiki:

This means that a client is not able to receive further information at the moment, and the TCP transmission is halted until it can process the information in its receive buffer.

Similar situation happens when broker sends Publish to my Arduino:

...
"75","63.738718","10.10.3.13","10.10.3.30","MQTT","73","Publish Message"
"76","63.957258","10.10.3.13","10.10.3.30","TCP","73","[TCP Retransmission] 1883 → 1025 [PSH, ACK] Seq=7 Ack=1026 Win=28077 Len=33"
"77","64.396158","10.10.3.13","10.10.3.30","TCP","73","[TCP Retransmission] 1883 → 1025 [PSH, ACK] Seq=7 Ack=1026 Win=28077 Len=33"
"78","65.274099","10.10.3.13","10.10.3.30","TCP","73","[TCP Retransmission] 1883 → 1025 [PSH, ACK] Seq=7 Ack=1026 Win=28077 Len=33"
"79","66.741943","10.10.3.30","10.10.3.13","MQTT","69","Publish Message"
"80","66.742495","10.10.3.13","10.10.3.30","TCP","40","1883 → 1025 [ACK] Seq=40 Ack=1055 Win=28048 Len=0"
"81","67.031025","10.10.3.13","10.10.3.30","TCP","73","[TCP Retransmission] 1883 → 1025 [PSH, ACK] Seq=7 Ack=1055 Win=28048 Len=33"
"82","67.090560","10.10.3.30","10.10.3.13","MQTT","69","Publish Message"
"83","67.091067","10.10.3.13","10.10.3.30","TCP","40","1883 → 1025 [ACK] Seq=40 Ack=1084 Win=28019 Len=0"
"84","67.125260","10.10.3.30","10.10.3.13","TCP","40","[TCP ZeroWindow] 1025 → 1883 [ACK] Seq=1055 Ack=40 Win=0 Len=0"
"85","67.125746","10.10.3.13","10.10.3.30","TCP","40","[TCP Dup ACK 83#1] 1883 → 1025 [ACK] Seq=40 Ack=1084 Win=28019 Len=0"
"86","67.371144","10.10.3.30","10.10.3.13","MQTT","76","Publish Ack, Publish Message"
..

Ok, I understand that some retransmissions may occur due to a sleep/delay in my code. But when frame 75 is ACK in frame 84 again it seems that Arduino TCP window == 0.

Any idea what's going on here and what can be the reason? How to debug it further?

Here is a link to the implementation:
https://bitbucket.org/elvisPA/radiosensornet/raw/9a888cb7845406e0efd82b561870cebe471ca9ff/arduinoSensorFirmware/client.ino

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant