diff options
author | rodrigc <rodrigc@FreeBSD.org> | 2011-07-31 03:12:20 +0000 |
---|---|---|
committer | rodrigc <rodrigc@FreeBSD.org> | 2011-07-31 03:12:20 +0000 |
commit | 0336e0c56d8e745763e6de53639f4d8f9e50c96b (patch) | |
tree | bb7156c57fea13636703162ba89821b77aca93c2 | |
parent | 48395f1e9158c619dfe304bd64c27055851055a6 (diff) | |
download | FreeBSD-src-0336e0c56d8e745763e6de53639f4d8f9e50c96b.zip FreeBSD-src-0336e0c56d8e745763e6de53639f4d8f9e50c96b.tar.gz |
In the old TFTP server, there was an undocumented behavior where
the block counter would rollover to 0 if a file larger
than 65535 blocks was transferred. With the default block size
of 512 octets per block, this is a file size of approximately 32 megabytes.
The new TFTP server code would report an error and stop transferring
the file if a file was larger than 65535 blocks.
This patch restores the old TFTP server's behavior to the new
TFTP server code. If a TFTP client transfers a file larger
than 65535 blocks, and does *not* specify the "rollover" option,
then automatically rollover the block counter to 0 every time
we reach 65535 blocks.
This restores interoperability with the FreeBSD 6 TFTP client.
Without this change, if a FreeBSD 6 TFTP client tried to
retrieve a file larger than 65535 blocks from a FreeBSD 9 TFTP server
, the transfer would fail.
The same file could be retrieved successfully if the same FreeBSD 6
TFTP client was used against a FreeBSD 6 TFTP server.
Approved by: re (kib)
Tested by: Pawan Gupta <pawang at juniper dot net>,
Obtained from: Juniper Networks
-rw-r--r-- | libexec/tftpd/tftp-transfer.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/libexec/tftpd/tftp-transfer.c b/libexec/tftpd/tftp-transfer.c index fd0e00d..d0c8a95 100644 --- a/libexec/tftpd/tftp-transfer.c +++ b/libexec/tftpd/tftp-transfer.c @@ -129,14 +129,16 @@ tftp_send(int peer, uint16_t *block, struct tftp_stats *ts) (*block)++; if (oldblock > *block) { if (options[OPT_ROLLOVER].o_request == NULL) { - tftp_log(LOG_ERR, - "Block rollover but not allowed."); - send_error(peer, EBADOP); - gettimeofday(&(ts->tstop), NULL); - return; + /* + * "rollover" option not specified in + * tftp client. Default to rolling block + * counter to 0. + */ + *block = 0; + } else { + *block = atoi(options[OPT_ROLLOVER].o_request); } - *block = atoi(options[OPT_ROLLOVER].o_request); ts->rollovers++; } gettimeofday(&(ts->tstop), NULL); @@ -196,14 +198,16 @@ tftp_receive(int peer, uint16_t *block, struct tftp_stats *ts, (*block)++; if (oldblock > *block) { if (options[OPT_ROLLOVER].o_request == NULL) { - tftp_log(LOG_ERR, - "Block rollover but not allowed."); - send_error(peer, EBADOP); - gettimeofday(&(ts->tstop), NULL); - return; + /* + * "rollover" option not specified in + * tftp client. Default to rolling block + * counter to 0. + */ + *block = 0; + } else { + *block = atoi(options[OPT_ROLLOVER].o_request); } - *block = atoi(options[OPT_ROLLOVER].o_request); ts->rollovers++; } |