From 240725528c5a756ee9aaff247e3731f4b8517c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= Date: Tue, 5 Jun 2018 17:38:08 +0200 Subject: [PATCH] mtr to a unreachable host is possible again. In mtr 0.87 it was possible to start mtr against unreachable host (that local kernel already knew that it is unreachable). Later it was broken. Make such tracing possible again. --- packet/probe.c | 28 +++++++++++++++++++++++----- ui/net.c | 10 ++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/packet/probe.c b/packet/probe.c index 27bf138..cf95f8a 100644 --- a/packet/probe.c +++ b/packet/probe.c @@ -356,14 +356,32 @@ int find_source_addr( return -1; } - if (connect(sock, (struct sockaddr *) &dest_with_port, len)) { - close(sock); - return -1; - } + if (connect(sock, (struct sockaddr *) &dest_with_port, len) == 0) { + if (getsockname(sock, (struct sockaddr *) srcaddr, &len)) { + close(sock); + return -1; + } + } else { +#ifdef __linux__ + /* Linux doesn't require source address, so we can support + * a case when mtr is run against unreachable host (that can become + * reachable) */ + if (errno != EHOSTUNREACH) { + close(sock); + return -1; + } - if (getsockname(sock, (struct sockaddr *) srcaddr, &len)) { + if (destaddr->ss_family == AF_INET6) { + srcaddr6 = (struct sockaddr_in6 *) srcaddr; + srcaddr6->sin6_addr = in6addr_any; + } else { + srcaddr4 = (struct sockaddr_in *) srcaddr; + srcaddr4->sin_addr.s_addr = INADDR_ANY; + } +#else close(sock); return -1; +#endif } close(sock); diff --git a/ui/net.c b/ui/net.c index 69d4477..11dd4c8 100644 --- a/ui/net.c +++ b/ui/net.c @@ -720,6 +720,16 @@ static void net_find_local_address( if (connect (udp_socket, (struct sockaddr *) &remote_sockaddr, addr_length)) { +#ifdef __linux__ + /* Linux doesn't require source address, so we can support + * a case when mtr is run against unreachable host (that can become + * reachable) */ + if (errno == EHOSTUNREACH) { + close(udp_socket); + localaddr[0] = '\0'; + return; + } +#endif error(EXIT_FAILURE, errno, "udp socket connect failed"); } -- 2.17.1