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>
This commit is contained in:
Craig Rodrigues 2011-06-24 02:56:24 +00:00
parent f1a16106b6
commit 14de21443e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=223487

View File

@ -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)
}
int
synchnet(int peer __unused)
{
/* 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).
*/
return 0;
int
synchnet(int peer) /* socket to flush */
{
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);
}
}
}