tftpd: Flush files as soon as they are fully received

On an RRQ, tftpd doesn't exit as soon as it's finished receiving a file.
Instead, it waits five seconds just in case the client didn't receive the
server's last ACK and decides to resend the final DATA packet.
Unfortunately, this created a 5 second delay from when the client thinks
it's done sending the file, and when the file is available for other
processes.

Fix this bug by closing the file as soon as receipt is finished.

PR:			157700
Reported by:		Barry Mishler <barry_mishler@yahoo.com>
MFC after:		3 weeks
This commit is contained in:
asomers 2018-03-09 23:25:18 +00:00
parent 1c3355767e
commit ccec95ca4c
4 changed files with 3 additions and 10 deletions

View File

@ -694,7 +694,6 @@ TFTPD_TC_DEFINE(w_flag,, w_flag = 1;)
send_data(1, contents, contents_len);
recv_ack(1);
atf_tc_expect_fail("PR 157700 tftpd expects more data after EOF");
fd = open("small.txt", O_RDONLY);
r = read(fd, buffer, sizeof(buffer));
close(fd);
@ -731,7 +730,6 @@ TFTPD_TC_DEFINE(wrq_dropped_ack,)
send_data(2, (const char*)&contents[128], 256);
recv_ack(2);
atf_tc_expect_fail("PR 157700 tftpd expects more data after EOF");
fd = open("medium.txt", O_RDONLY);
r = read(fd, buffer, sizeof(buffer));
close(fd);
@ -764,7 +762,6 @@ TFTPD_TC_DEFINE(wrq_dropped_data,)
send_data(1, contents, contents_len);
recv_ack(1);
atf_tc_expect_fail("PR 157700 tftpd expects more data after EOF");
fd = open("small.txt", O_RDONLY);
r = read(fd, buffer, sizeof(buffer));
close(fd);
@ -798,7 +795,6 @@ TFTPD_TC_DEFINE(wrq_duped_data,)
send_data(2, (const char*)&contents[128], 256);
recv_ack(2);
atf_tc_expect_fail("PR 157700 tftpd expects more data after EOF");
fd = open("medium.txt", O_RDONLY);
r = read(fd, buffer, sizeof(buffer));
close(fd);
@ -865,7 +861,6 @@ TFTPD_TC_DEFINE(wrq_medium,)
send_data(2, (const char*)&contents[128], 256);
recv_ack(2);
atf_tc_expect_fail("PR 157700 tftpd expects more data after EOF");
fd = open("medium.txt", O_RDONLY);
r = read(fd, buffer, sizeof(buffer));
close(fd);
@ -891,14 +886,13 @@ TFTPD_TC_DEFINE(wrq_netascii,)
fd = open("unix.txt", O_RDWR | O_CREAT, 0666);
ATF_REQUIRE(fd >= 0);
close(fd);
contents_len = strlen(contents) + 1;
contents_len = sizeof(contents);
SEND_WRQ("unix.txt", "netascii");
recv_ack(0);
send_data(1, contents, contents_len);
recv_ack(1);
atf_tc_expect_fail("PR 157700 tftpd expects more data after EOF");
fd = open("unix.txt", O_RDONLY);
r = read(fd, buffer, sizeof(buffer));
close(fd);
@ -938,7 +932,6 @@ TFTPD_TC_DEFINE(wrq_small,)
send_data(1, contents, contents_len);
recv_ack(1);
atf_tc_expect_fail("PR 157700 tftpd expects more data after EOF");
fd = open("small.txt", O_RDONLY);
r = read(fd, buffer, sizeof(buffer));
close(fd);

View File

@ -304,6 +304,8 @@ tftp_receive(int peer, uint16_t *block, struct tftp_stats *ts,
gettimeofday(&(ts->tstop), NULL);
} while (n_data == segsize);
write_close();
/* Don't do late packet management for the client implementation */
if (acting_as_client)
return;

View File

@ -823,7 +823,6 @@ tftp_recvfile(int peer, const char *mode)
block = 0;
tftp_receive(peer, &block, &ts, NULL, 0);
write_close();
gettimeofday(&now2, NULL);
if (debug&DEBUG_SIMPLE) {

View File

@ -265,7 +265,6 @@ recvfile(int peer, char *port, int fd, char *name, char *mode)
tftp_receive(peer, &block, &tftp_stats, rp, n);
}
write_close();
if (tftp_stats.amount > 0)
printstats("Received", verbose, &tftp_stats);
return;