]> git.dujemihanovic.xyz Git - u-boot.git/commit
net/tftp: make tftpput working with servers that do not use OACK
authorMikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Fri, 12 Jul 2024 09:47:54 +0000 (13:47 +0400)
committerTom Rini <trini@konsulko.com>
Thu, 1 Aug 2024 14:10:00 +0000 (08:10 -0600)
commit1dd034ec001152b37ba3d9a60bf892b445886e8b
treec355a2bf1221e1e67257045dae8df44bc90388d2
parentfb2f2a38b6c52d8f80d7b0a0589fd0fb93c3973c
net/tftp: make tftpput working with servers that do not use OACK

Option Acknowledgment (OACK) is an extension of TFTP protocol (see rfc2347).
Not all tftp servers implements it. For example it does not supported by
tftpd server from debian-11 (https://packages.debian.org/bullseye/tftpd).

Starting the "tftpput $loadaddr $size out_file" command with such server
will results in the following packets flow:

192.168.27.3   192.168.27.1   TFTP   Write Request, ...
192.168.27.1   192.168.27.3   TFTP   Acknowledgement, Block: 0
192.168.27.3   192.168.27.1   TFTP   Write Request, ...
192.168.27.1   192.168.27.3   TFTP   Acknowledgement, Block: 0
192.168.27.3   192.168.27.1   TFTP   Write Request, ...
192.168.27.1   192.168.27.3   TFTP   Acknowledgement, Block: 0
192.168.27.1   192.168.27.3   TFTP   Acknowledgement, Block: 0
192.168.27.1   192.168.27.3   TFTP   Acknowledgement, Block: 0
...

so, no data transfer happening.

Here is a packets flow for tftp-server with OACK support
(tftpd-hpa: https://packages.debian.org/stable/tftpd-hpa)

192.168.27.3   192.168.27.1   TFTP   Write Request, ...
192.168.27.1   192.168.27.3   TFTP   Option Acknowledgement, ...
192.168.27.3   192.168.27.1   TFTP   Data Packet, Block: 1
192.168.27.1   192.168.27.3   TFTP   Acknowledgement, Block: 1
192.168.27.3   192.168.27.1   TFTP   Data Packet, Block: 2
192.168.27.1   192.168.27.3   TFTP   Acknowledgement, Block: 2

and this time data transfer starts normally.

As we can see there is no OACK packet in the first case. Investigating
an issue we'll find out:

1) tftp_start() sets

      tftp_state = STATE_SEND_WRQ;

2) on OACK tftp_handler() sets

      tftp_state = STATE_DATA;

   and send a first DATA packet.

3) on ACK tftp_handler() will call a tftp_send() function.
   tftp_send() will

   * tftpd with OACK support:

       Current state is STATE_DATA, so transmittion of data packet will
       happen.

   * tftpd without OACK support

      Current state is STATE_SEND_WRQ, so retransmission of WRQ packet
      will happen. Thus tftpd-server will retransmit an ACK.

      This will repeats until timeout happens.

      According to RFC1350 this is wrong. We should start data transfer
      instead of WRQ retransmission.

This patch fix an issue, so tftpput works fine with both types of servers.

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
net/tftp.c