From fd4cc5ed91940167708c4e4d7f9080c417bb567a Mon Sep 17 00:00:00 2001 From: florian Date: Fri, 13 Jan 2017 18:00:10 +0000 Subject: traceroute 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 , thanks! Looks good to and input millert@ --- usr.sbin/traceroute/traceroute.c | 20 +++++++++++++++----- usr.sbin/traceroute/traceroute.h | 4 ++-- usr.sbin/traceroute/worker.c | 4 ++-- 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'usr.sbin/traceroute') diff --git a/usr.sbin/traceroute/traceroute.c b/usr.sbin/traceroute/traceroute.c index 1444de11f9e..093bedee6d8 100644 --- a/usr.sbin/traceroute/traceroute.c +++ b/usr.sbin/traceroute/traceroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: traceroute.c,v 1.149 2016/09/28 06:39:12 florian Exp $ */ +/* $OpenBSD: traceroute.c,v 1.150 2017/01/13 18:00:10 florian Exp $ */ /* $NetBSD: traceroute.c,v 1.10 1995/05/21 15:50:45 mycroft Exp $ */ /* @@ -296,7 +296,7 @@ u_int16_t port = 32768+666;/* start udp dest port # for probe packets */ 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 */ @@ -312,7 +312,7 @@ main(int argc, char *argv[]) int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL }; int ttl_flag = 0, incflag = 1, protoset = 0, sump = 0; int ch, i, lsrr = 0, on = 1, probe, seq = 0, tos = 0, error, packetlen; - int rcvcmsglen, rcvsock4, rcvsock6, sndsock4, sndsock6; + int rcvcmsglen, rcvsock4, rcvsock6, sndsock4, sndsock6, waittime; int v4sock_errno, v6sock_errno; struct addrinfo hints, *res; struct passwd *pw; @@ -336,6 +336,8 @@ main(int argc, char *argv[]) rcvsock4 = rcvsock6 = sndsock4 = sndsock6 = -1; v4sock_errno = v6sock_errno = 0; + waittime = 5 * 1000; + if ((rcvsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) v6sock_errno = errno; else if ((sndsock6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) @@ -533,6 +535,7 @@ main(int argc, char *argv[]) waittime = strtonum(optarg, 2, INT_MAX, &errstr); if (errstr) errx(1, "wait must be >1 sec."); + waittime *= 1000; break; case 'x': xflag = 1; @@ -838,13 +841,20 @@ main(int argc, char *argv[]) gettime(&t1); send_probe(++seq, ttl, incflag, to); + curwaittime = waittime; 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 - + ((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 a/usr.sbin/traceroute/traceroute.h b/usr.sbin/traceroute/traceroute.h index 8b9e435c119..2729ac30e9b 100644 --- a/usr.sbin/traceroute/traceroute.h +++ b/usr.sbin/traceroute/traceroute.h @@ -1,4 +1,4 @@ -/* $OpenBSD: traceroute.h,v 1.1 2016/09/03 22:00:06 benno Exp $ */ +/* $OpenBSD: traceroute.h,v 1.2 2017/01/13 18:00:10 florian Exp $ */ /* $NetBSD: traceroute.c,v 1.10 1995/05/21 15:50:45 mycroft Exp $ */ /* @@ -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 a/usr.sbin/traceroute/worker.c b/usr.sbin/traceroute/worker.c index d27e82abd52..ac13644eb5d 100644 --- a/usr.sbin/traceroute/worker.c +++ b/usr.sbin/traceroute/worker.c @@ -1,4 +1,4 @@ -/* $OpenBSD: worker.c,v 1.1 2016/09/03 22:00:06 benno Exp $ */ +/* $OpenBSD: worker.c,v 1.2 2017/01/13 18:00:10 florian Exp $ */ /* $NetBSD: traceroute.c,v 1.10 1995/05/21 15:50:45 mycroft Exp $ */ /* @@ -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); -- cgit v1.2.3-59-g8ed1b