diff options
author | ambrisko <ambrisko@FreeBSD.org> | 2002-04-09 19:13:43 +0000 |
---|---|---|
committer | ambrisko <ambrisko@FreeBSD.org> | 2002-04-09 19:13:43 +0000 |
commit | 0b5427f93222d7a5251fc9abac47d442bfc11af1 (patch) | |
tree | 482d06c360ce87ad7d7bf200f2c85d773c555655 | |
parent | f7565e52d7c3cd6a1efc21ae3ed4a818e8e4498e (diff) | |
download | FreeBSD-src-0b5427f93222d7a5251fc9abac47d442bfc11af1.zip FreeBSD-src-0b5427f93222d7a5251fc9abac47d442bfc11af1.tar.gz |
Better handle the case with a network that drops packets by retrying
with a back off. This was discovered when Luigi sent me code to
handle this for Etherboot. The Etherboot patch worked okay but
FreeBSD's tftpd had trouble handling it and would fail to transfer
the file since it would abort on send and not retry.
Submitted by: luigi
MFC after: 1 week
-rw-r--r-- | libexec/tftpd/tftpd.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c index 7192866..057a3bd 100644 --- a/libexec/tftpd/tftpd.c +++ b/libexec/tftpd/tftpd.c @@ -576,9 +576,19 @@ xmitfile(struct formats *pf) (void)setjmp(timeoutbuf); send_data: - if (send(peer, dp, size + 4, 0) != size + 4) { - syslog(LOG_ERR, "write: %m"); - goto abort; + { + int i, t = 1; + for (i = 0; ; i++){ + if (send(peer, dp, size + 4, 0) != size + 4) { + sleep(t); + t = (t < 32) ? t<< 1 : t; + if (i >= 12) { + syslog(LOG_ERR, "write: %m"); + goto abort; + } + } + break; + } } read_ahead(file, pf->f_convert); for ( ; ; ) { |