From owner-freebsd-bugs@FreeBSD.ORG Thu Mar 13 11:00:02 2014 Return-Path: Delivered-To: freebsd-bugs@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 201A0F16 for ; Thu, 13 Mar 2014 11:00:02 +0000 (UTC) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id EC7AD83B for ; Thu, 13 Mar 2014 11:00:01 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.8/8.14.8) with ESMTP id s2DB01qW072132 for ; Thu, 13 Mar 2014 11:00:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.8/8.14.8/Submit) id s2DB01Bq072131; Thu, 13 Mar 2014 11:00:01 GMT (envelope-from gnats) Resent-Date: Thu, 13 Mar 2014 11:00:01 GMT Resent-Message-Id: <201403131100.s2DB01Bq072131@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Eugene Grosbein Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3A492DA4 for ; Thu, 13 Mar 2014 10:54:51 +0000 (UTC) Received: from hz.grosbein.net (hz.grosbein.net [78.47.246.247]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 701E37FE for ; Thu, 13 Mar 2014 10:54:48 +0000 (UTC) Received: from eg.sd.rdtc.ru (root@eg.sd.rdtc.ru [62.231.161.221]) by hz.grosbein.net (8.14.7/8.14.7) with ESMTP id s2DAsXTZ052980 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Thu, 13 Mar 2014 11:54:34 +0100 (CET) (envelope-from eugen@eg.sd.rdtc.ru) Received: from eg.sd.rdtc.ru (eugen@localhost [127.0.0.1]) by eg.sd.rdtc.ru (8.14.7/8.14.7) with ESMTP id s2DAsOb7062556 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 13 Mar 2014 17:54:24 +0700 (NOVT) (envelope-from eugen@eg.sd.rdtc.ru) Received: (from eugen@localhost) by eg.sd.rdtc.ru (8.14.7/8.14.7/Submit) id s2DAsOsa062555; Thu, 13 Mar 2014 17:54:24 +0700 (NOVT) (envelope-from eugen) Message-Id: <201403131054.s2DAsOsa062555@eg.sd.rdtc.ru> Date: Thu, 13 Mar 2014 17:54:24 +0700 (NOVT) From: Eugene Grosbein To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.114 Subject: bin/187526: [patch] traceroute -a breaks of "whois" socket timeout X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Mar 2014 11:00:02 -0000 >Number: 187526 >Category: bin >Synopsis: [patch] traceroute -a breaks of "whois" socket timeout >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Mar 13 11:00:00 UTC 2014 >Closed-Date: >Last-Modified: >Originator: Eugene Grosbein >Release: FreeBSD 8.4-STABLE amd64 >Organization: RDTC JSC >Environment: System: FreeBSD eg.sd.rdtc.ru 8.4-STABLE FreeBSD 8.4-STABLE #3 r251830M: Mon Sep 30 18:01:03 NOVT 2013 root@eg.sd.rdtc.ru:/usr/local/obj/usr/local/src/sys/EG amd64 >Description: "traceroute -a" opens TCP socket to whois server and fails to check if this socket stays valid during (sometimes long) runtime. If whois server closes this connection, traceroute gets EOF at next hop (and shows AS0) and is killed with SIGPIPE later. >How-To-Repeat: $ traceroute -Ia 194.150.149.239 traceroute to 194.150.149.239 (194.150.149.239), 64 hops max, 72 byte packets 1 [AS29072] 62.231.161.217 (62.231.161.217) 0.276 ms 0.268 ms 0.189 ms 2 [AS29072] k-45.rdtc.ru (62.231.160.42) 1.169 ms 0.496 ms 0.706 ms 3 [AS29072] asbr.rdtc.ru (62.231.191.137) 0.467 ms 0.548 ms 0.498 ms 4 [AS31133] 37.29.3.49 (37.29.3.49) 1.423 ms 1.650 ms 1.374 ms 5 * * * 6 * * * 7 * * * 8 * * * 9 * * * 10 * * * 11 [AS0] 37.29.107.202 (37.29.107.202) 70.641 ms 70.599 ms 70.525 ms Here traceroute is killed. Instead, it should show complete trace: 11 [AS31133] 37.29.107.202 (37.29.107.202) 104.550 ms 70.603 ms 72.888 ms 12 [AS12389] 95.167.91.93 (95.167.91.93) 166.594 ms 65.702 ms 65.790 ms 13 [AS12389] customer-as41440.xe-0-2-0.brnl-rgr3.sib.ip.rostelecom.ru (188.254.36.146) 68.412 ms 68.322 ms 68.287 ms 14 [AS41440] ge-0-0-0-v501.bar-csr1.ncc.sibirtelecom.ru (213.228.118.6) 85.369 ms 101.501 ms 85.300 ms 15 [AS12846] 212.94.98.54 (212.94.98.54) 85.021 ms 85.116 ms 85.004 ms 16 [AS12846] Bsk-ATS24-c7301.mss.ab.ru (212.94.101.129) 74.240 ms 74.504 ms 74.214 ms 17 [AS12846] adsl-149-239.biysk.ru (194.150.149.239) 103.236 ms 103.358 ms 103.013 ms >Fix: A workaround is to lower wait time for proble timeout using '-w 1' option. The following patch fixes the problem introducing proper error checking while reading/writing "whois" connection. In case of error it reconnects. --- as.h.orig 2013-06-17 11:18:23.000000000 +0700 +++ as.h 2014-03-13 17:13:48.000000000 +0700 @@ -31,5 +31,5 @@ */ void *as_setup(const char *); -unsigned int as_lookup(void *, char *, sa_family_t); +unsigned int as_lookup(void *, char *, sa_family_t, int *); void as_shutdown(void *); --- as.c.orig 2013-06-17 11:18:23.000000000 +0700 +++ as.c 2014-03-13 17:37:51.000000000 +0700 @@ -119,7 +119,7 @@ as_setup(const char *server) } unsigned int -as_lookup(void *_asn, char *addr, sa_family_t family) +as_lookup(void *_asn, char *addr, sa_family_t family, int *status) { struct aslookup *asn = _asn; char buf[1024]; @@ -129,8 +129,17 @@ as_lookup(void *_asn, char *addr, sa_fam as = 0; rc = dlen = 0; plen = (family == AF_INET6) ? 128 : 32; - (void)fprintf(asn->as_f, "!r%s/%d,l\n", addr, plen); - (void)fflush(asn->as_f); + *status = fprintf(asn->as_f, "!r%s/%d,l\n", addr, plen); + if (*status < 0) { + *status = errno; + return 0; + } + *status = fflush(asn->as_f); + if (*status == EOF) { + *status = errno; + return 0; + } + *status = 0; #ifdef AS_DEBUG_FILE if (asn->as_debug) { @@ -139,7 +148,14 @@ as_lookup(void *_asn, char *addr, sa_fam } #endif /* AS_DEBUG_FILE */ - while (fgets(buf, sizeof(buf), asn->as_f) != NULL) { + while (1) { + if (fgets(buf, sizeof(buf), asn->as_f) == NULL) { + if(feof(asn->as_f) || ferror(asn->as_f)) { + *status = EIO; + return 0; + } + break; + } buf[sizeof(buf) - 1] = '\0'; #ifdef AS_DEBUG_FILE --- traceroute.c.orig 2013-06-17 11:18:23.000000000 +0700 +++ traceroute.c 2014-03-13 17:27:14.000000000 +0700 @@ -931,6 +931,8 @@ as_path = 0; } } + if (as_path) + signal(SIGPIPE, SIG_IGN); #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) if (setpolicy(sndsock, "in bypass") < 0) @@ -1471,6 +1473,7 @@ { register struct ip *ip; register int hlen; + int as, status; char addr[INET_ADDRSTRLEN]; ip = (struct ip *) buf; @@ -1479,8 +1482,24 @@ strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr)); - if (as_path) - Printf(" [AS%u]", as_lookup(asn, addr, AF_INET)); + while(as_path) { + as = as_lookup(asn, addr, AF_INET, &status); + if (status) { + as_shutdown(asn); + asn = as_setup(as_server); + if (asn == NULL) { + Fprintf(stderr, "%s: as_setup failed, AS# lookups" + " disabled\n", prog); + (void)fflush(stderr); + as_path = 0; + break; + } + else + continue; + } + Printf(" [AS%u]", as); + break; + } if (nflag) Printf(" %s", addr); >Release-Note: >Audit-Trail: >Unformatted: