mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-27 22:56:49 +08:00
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>
This commit is contained in:
parent
fb2f2a38b6
commit
1dd034ec00
@ -493,8 +493,15 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||
tftp_prev_block = tftp_cur_block;
|
||||
tftp_cur_block = (unsigned short)(block + 1);
|
||||
update_block_number();
|
||||
if (ack_ok)
|
||||
if (ack_ok) {
|
||||
if (block == 0 &&
|
||||
tftp_state == STATE_SEND_WRQ){
|
||||
/* connection's first ACK */
|
||||
tftp_state = STATE_DATA;
|
||||
tftp_remote_port = src;
|
||||
}
|
||||
tftp_send(); /* Send next data block */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user