aboutsummaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorCraig Rodrigues <rodrigc@FreeBSD.org>2011-06-24 02:56:24 +0000
committerCraig Rodrigues <rodrigc@FreeBSD.org>2011-06-24 02:56:24 +0000
commit14de21443e89dacc8aed237e74f5bd21e85d2f84 (patch)
tree00db30ea57e9609a8b4a10a5d93394ca5446fbd3 /libexec
parentf1a16106b6317f4cf5b187daeceda7c1468323c9 (diff)
Notes
Diffstat (limited to 'libexec')
-rw-r--r--libexec/tftpd/tftp-file.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/libexec/tftpd/tftp-file.c b/libexec/tftpd/tftp-file.c
index 1ef882014ea6b..6b8fb6e83c159 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 */
{
+ int i, j = 0;
+ char rbuf[MAXPKTSIZE];
+ struct sockaddr_storage from;
+ socklen_t fromlen;
- return 0;
+ 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);
+ }
+ }
}