Index: stand/libsa/ip.c =================================================================== --- stand/libsa/ip.c +++ stand/libsa/ip.c @@ -416,8 +416,13 @@ while ((getsecs() - t) < tleft) { errno = 0; ret = readipv4(d, pkt, payload, tleft, proto); + if (ret >= 0) + return (ret); + /* Bubble up the error if it wasn't successful */ if (errno != EAGAIN) - break; + return (-1); } - return (ret); + /* We've exhausted tleft; timeout */ + errno = ETIMEDOUT; + return (-1); } Index: stand/libsa/tftp.c =================================================================== --- stand/libsa/tftp.c +++ stand/libsa/tftp.c @@ -502,7 +502,7 @@ res = tftp_getnextblock(tftpfile); if (res) { /* no answer */ #ifdef TFTP_DEBUG - printf("tftp: read error\n"); + printf("tftp: read error res(%d)\n", res); #endif return (res); } @@ -616,14 +616,10 @@ struct iodesc *d = h->iodesc; ssize_t cc; time_t t, t1, tleft; + int eagain_counter = 0; -#ifdef TFTP_DEBUG - if (debug) - printf("sendrecv: called\n"); -#endif - tleft = MINTMO; - t = t1 = getsecs(); + t = getsecs(); for (;;) { if ((getsecs() - t) > MAXTMO) { errno = ETIMEDOUT; @@ -637,15 +633,20 @@ if (cc == -1) { /* Error on transmit; wait before retrying */ - while ((getsecs() - t1) < tleft); + while ((getsecs() - t) < tleft); continue; } + t1 = getsecs(); recvnext: /* Try to get a packet and process it. */ cc = (*rproc)(h, pkt, payload, tleft, rtype); +#ifdef TFTP_DEBUG + if (errno == ETIMEDOUT) + printf("%s: tftp ETIMEDOUT\n", __func__); +#endif /* Return on data, EOF or real error. */ - if (cc != -1 || errno != 0) + if (cc != -1 || errno != 0 && errno != ETIMEDOUT) return (cc); if ((getsecs() - t1) < tleft) { goto recvnext; @@ -653,8 +654,9 @@ /* Timed out or didn't get the packet we're waiting for */ tleft += MINTMO; - if (tleft > (2 * MINTMO)) { - tleft = (2 * MINTMO); + if ((getsecs() - t) > MAXTMO) { + errno = ETIMEDOUT; + return (-1); } t1 = getsecs(); }