summaryrefslogtreecommitdiffstats
path: root/libexec/tftpd
diff options
context:
space:
mode:
authorrodrigc <rodrigc@FreeBSD.org>2011-06-24 02:56:24 +0000
committerrodrigc <rodrigc@FreeBSD.org>2011-06-24 02:56:24 +0000
commit5d88d5d7feadac7d9ef3004a0506e1fc0f8b4bde (patch)
tree00db30ea57e9609a8b4a10a5d93394ca5446fbd3 /libexec/tftpd
parentdc0788739aaaf15b40f6d2fded382c167e26133d (diff)
downloadFreeBSD-src-5d88d5d7feadac7d9ef3004a0506e1fc0f8b4bde.zip
FreeBSD-src-5d88d5d7feadac7d9ef3004a0506e1fc0f8b4bde.tar.gz
Bring back synchnet() implementation from older
tftp implementation. The synchnet() function was converted to a no-op when the new TFTP implementation was committed to FreeBSD. However, this function, as it was in the older code, is needed in order to synchronize between the tftpd server and tftp clients, which may be buggy. Specifically, we had a buggy TFTP client which would send TFTP ACK packets for non-TFTP packets, which would cause the count of packets to get out of whack, causing transfers to fail with the new TFTPD implementation. Obtained from: Juniper Networks Submitted by: Santhanakrishnan Balraj <sbalraj at juniper dot net>
Diffstat (limited to 'libexec/tftpd')
-rw-r--r--libexec/tftpd/tftp-file.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/libexec/tftpd/tftp-file.c b/libexec/tftpd/tftp-file.c
index 1ef8820..6b8fb6e 100644
--- a/libexec/tftpd/tftp-file.c
+++ b/libexec/tftpd/tftp-file.c
@@ -27,6 +27,8 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
@@ -249,9 +251,34 @@ read_close(void)
}
+/* When an error has occurred, it is possible that the two sides
+ * are out of synch. Ie: that what I think is the other side's
+ * response to packet N is really their response to packet N-1.
+ *
+ * So, to try to prevent that, we flush all the input queued up
+ * for us on the network connection on our host.
+ *
+ * We return the number of packets we flushed (mostly for reporting
+ * when trace is active).
+ */
+
int
-synchnet(int peer __unused)
+synchnet(int peer) /* socket to flush */
{
-
- return 0;
+ int i, j = 0;
+ char rbuf[MAXPKTSIZE];
+ struct sockaddr_storage from;
+ socklen_t fromlen;
+
+ while (1) {
+ (void) ioctl(peer, FIONREAD, &i);
+ if (i) {
+ j++;
+ fromlen = sizeof from;
+ (void) recvfrom(peer, rbuf, sizeof (rbuf), 0,
+ (struct sockaddr *)&from, &fromlen);
+ } else {
+ return(j);
+ }
+ }
}
OpenPOWER on IntegriCloud