svn commit: r223487 - head/libexec/tftpd

Craig Rodrigues rodrigc at FreeBSD.org
Fri Jun 24 02:56:25 UTC 2011


Author: rodrigc
Date: Fri Jun 24 02:56:24 2011
New Revision: 223487
URL: http://svn.freebsd.org/changeset/base/223487

Log:
  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>

Modified:
  head/libexec/tftpd/tftp-file.c

Modified: head/libexec/tftpd/tftp-file.c
==============================================================================
--- head/libexec/tftpd/tftp-file.c	Fri Jun 24 02:30:02 2011	(r223486)
+++ head/libexec/tftpd/tftp-file.c	Fri Jun 24 02:56:24 2011	(r223487)
@@ -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);
+		}
+	}
 }


More information about the svn-src-head mailing list