-
Notifications
You must be signed in to change notification settings - Fork 119
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
Dallying after tftpy sends last ACK #137
Comments
Not sure. Maybe we could add a unit test to simulate that and see if it happens? |
Thanks for the quick response.
I've tried running the tests ( I'll come back to it tomorrow. |
OK, I think I'm making a bit more progress on this ...
The test (without the dropped ACK) previous ran on my machine in about 2 to 2.6 seconds, whereas with the dropped ACK the test took 17 to 17.6 seconds. The corresponding section of the debug log output is:
So the Download does "drop" the connection immediately after it sent the last ACK, and the Server does attempt to resend the DAT, but eventually reaches a retry limit and then drops the connection. |
If I drop any other than the last ACK, then the packet trace shows a rapid recovery...
|
I've repeated the test, but changed it to an upload.
What I hadn't expected was that the Upload failed raising an TftpTimeout exception. The extract from the debug log follows:
I think that the server, having sent the last ACK is dropping the connection, then ignores the Client resends until the client gives up and throws an exception. Of course, it is always possible that the connection between the Client and Server is lost at the end of communication, so the Client must be ready to handle a lost connection. |
(I hope you don't see the above as "spam" comments, but only as an honest attempt to understand how tftpy works.) A "dally" state after the last ACK packet can probably only be terminated by a timeout since the other-end of the connection is not expecting to send anything more after receiving the last ACK packet. In the case of a Client Download from a Server, dallying will cause a delay to the client that will effect every download for the sake of some wasted resends on the Server in an error corner-case. I tend to assume that the Server is likely to be around for as long as it is needed, so a few wasted resends do not seem to be a problem, and the Server will clean-up by simply dropping the connection. Therefore, in this case a dally would not be justified. However, in the Upload case, there may be an argument for the Server dallying after sending its last ACK packet. This could remove superfluous resends for the Upload client (and maybe even a complete upload reattempt or passing up a false failure to the Uploads own client), while causing only a minor delay in closing a connection on the Server. The tftpy Server can accept many connections, so such a delay will not cause a delay to any other transfer requests. |
(Thanks to tftpy.)
I'm working on a problem where a tftpy has successfully downloaded a file, but the other end seems to think that the connection is still open. I don't know that the following is the cause, but I have noticed an oddity that might be relevant...
RFC 1350 §6 states: "The end of a transfer is marked by a DATA packet that contains between 0 and 511 bytes of data (i.e., Datagram length < 516). This packet is acknowledged by an ACK packet like all other DATA packets. The host acknowledging the final DATA packet may terminate its side of the connection on sending the final ACK. On the other hand, dallying is encouraged. This means that the host sending the final ACK will wait for a while before terminating in order to retransmit the final ACK if it has been lost. The acknowledger will know that the ACK has been lost if it receives the final DATA packet again. The host sending the last DATA must retransmit it until the packet is acknowledged or the sending host times out."
If I've read the TftpState.handleDat function correctly, then after sending the ACK, it immediately terminates the tftpy connection by returning a None state. Perhaps there could be one more TftpyState that "Dallys" for a while, in case the sender missed the ACK? (Again, I could have missed something, but it looks like the tftpy upload process would hang on an endless resendLast if it did not receive the last ACK.)
The text was updated successfully, but these errors were encountered: