traceroute(8) never sees a timeout when poll(2) returns when it receives
a packet not intended for us. E.g. a ping(8) is running in parallel.
In this case we need to account for the time we already waited.
    
Pointed out by Gabriel Nieto on bugs@, thanks!

OK?

diff --git traceroute.c traceroute.c
index 1444de11f9e..7c6f69c21c5 100644
--- traceroute.c
+++ traceroute.c
@@ -297,6 +297,7 @@ u_char              proto = IPPROTO_UDP;
 
 int            verbose;
 int            waittime = 5;   /* time to wait for response (in seconds) */
+int            curwaittime;    /* time left to wait for response */
 int            nflag;          /* print addresses numerically */
 int            dump;
 int            Aflag;          /* lookup ASN */
@@ -838,13 +839,20 @@ main(int argc, char *argv[])
 
                        gettime(&t1);
                        send_probe(++seq, ttl, incflag, to);
+                       curwaittime = waittime * 1000;
                        while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
                                gettime(&t2);
                                i = packet_ok(to->sa_family, &rcvmhdr, cc, seq,
                                    incflag);
-                               /* Skip short packet */
-                               if (i == 0)
+                               /* Skip wrong packet */
+                               if (i == 0) {
+                                       curwaittime = waittime * 1000 -
+                                           ((t2.tv_sec - t1.tv_sec) * 1000 +
+                                           (t2.tv_usec - t1.tv_usec) / 1000);
+                                       if (curwaittime < 0)
+                                               curwaittime = 0;
                                        continue;
+                               }
                                if (to->sa_family == AF_INET) {
                                        ip = (struct ip *)packet;
                                        if (from4.sin_addr.s_addr != lastaddr) {
diff --git traceroute.h traceroute.h
index 8b9e435c119..419168c2b4e 100644
--- traceroute.h
+++ traceroute.h
@@ -137,7 +137,7 @@ extern u_char                proto;
 #define ICMP_CODE 0;
 
 extern int verbose;
-extern int waittime;           /* time to wait for response (in seconds) */
+extern int curwaittime;                /* time left to wait for response */
 extern int nflag;              /* print addresses numerically */
 extern int dump;
 extern int Aflag;              /* lookup ASN */
diff --git worker.c worker.c
index d27e82abd52..7d0ad0fe496 100644
--- worker.c
+++ worker.c
@@ -227,7 +227,7 @@ wait_for_reply(int sock, struct msghdr *mhdr)
        pfd[0].events = POLLIN;
        pfd[0].revents = 0;
 
-       if (poll(pfd, 1, waittime * 1000) > 0)
+       if (poll(pfd, 1, curwaittime) > 0)
                cc = recvmsg(rcvsock, mhdr, 0);
 
        return (cc);

-- 
I'm not entirely sure you are real.

Reply via email to