Callisto82 / tftp.net

Implements the TFTP (Trivial File Transfer) protocol (client/server) in an easy-to-use C#/.NET library.
Microsoft Public License
80 stars 38 forks source link

Timeout of Block Acknowledgement is always 5s and not timeout #36

Closed ngerberQuad closed 1 week ago

ngerberQuad commented 1 year ago

I defined the RetryTimeout as 30 seconds for an Upload. This Timeout is correct for the Write Request, but for the Data Packet Block 1 Acknowledgement it times out after 5 seconds.

Callisto82 commented 1 year ago

Hi there! Do you have some way of reproducing that behavior here? I couldn't do so, that's why I'm suspecting that the other party might not honor the TFTP timeout option and just timeout after 5 seconds.

Alternatively, can you please set TftpTrace.Enabled = true and attach the libraries log output?

ngerberQuad commented 1 year ago

Hi, Thank you for the response.

This are the relevant snippets of my code:

//Create the client and set the correct settings
TftpClient tftpClient = new TftpClient(ip);
var transfer = tftpClient.Upload("Firmware.bin");
transfer.TransferMode = TftpTransferMode.octet;
transfer.RetryCount = 0;
transfer.RetryTimeout = TimeSpan.FromSeconds(15);

//Parse the Firmwarefile
byte[] bytes = File.ReadAllBytes(file);
Stream stream = new MemoryStream(bytes);

//Capture the events that may happen during the transfer
transfer.OnProgress += new TftpProgressHandler(transfer_OnProgress);
transfer.OnFinished += new TftpEventHandler(transfer_OnFinshed);
transfer.OnError += new TftpErrorHandler(transfer_OnError);

transfer.Start(stream);

This is the Trace output:

40256670 (Firmware.bin): [StartOutgoingWrite] OnStateEnter
40256670 (Firmware.bin): [StartOutgoingWrite] OnStart
40256670 (Firmware.bin): [SendWriteRequest] OnStateEnter
40256670 (Firmware.bin): [SendWriteRequest] OnCommand: Tftp.Net.Acknowledgement from 192.168.1.164:69
40256670 (Firmware.bin): [Sending] OnStateEnter
40256670 (Firmware.bin): Network timeout.
40256670 (Firmware.bin): [ReceivedError] OnStateEnter
40256670 (Firmware.bin): Received error: Timeout error. RetryTimeout (00:00:05) violated more than 0 times in a row
40256670 (Firmware.bin): [Closed] OnStateEnter
40256670 (Firmware.bin): [Closed] OnCancel: 0 - ITftpTransfer has been disposed.

My TFTP Server runs on a emmbeded lwip stack. The timeout is happening after recieving the block 1 because it takes 7 seconds to send the block acknowlege packet back. But at this time the C# TFTP Client has already timed out.

After opening the issue i modified the variable DEFAULT_TIMEOUT_SECS in the file Tftp.Net/Transfer/TransferOptionSet.cs and that fixed my issue.

Callisto82 commented 1 week ago

Hi - and really sorry for the late reply. I think that's caused by your TFTP server not acknowledging the request to change the timeout. The library falls back to the default in that case. I think that's actually the correct behaviour according to the TFTP spec. RFC 237 states: "An option not acknowledged by the server must be ignored by the client and server as if it were never requested". That's what the library is doing in that case. Do you have any evidence that this would be incorrect behaviour?

ngerberQuad commented 1 week ago

Hi, Thank you for the reply. I think you are right. The server did not acknowledge the timeout. As by RFC2349 this is the correct behavior.