]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
mtr to a unreachable host is possible again. 262/head
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Tue, 5 Jun 2018 15:38:08 +0000 (17:38 +0200)
committerArkadiusz Miśkiewicz <arekm@maven.pl>
Tue, 5 Jun 2018 15:38:08 +0000 (17:38 +0200)
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
ui/net.c

index 27bf138eff65fa1c2d5fd63461ab0bd662273039..cf95f8a3f1f3f6d655f60ecd85098ff3fb956e39 100644 (file)
@@ -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);
index 69d44775051772efb34df228a68da5c4da792352..11dd4c8a568dabcd487d722958db8798043b087c 100644 (file)
--- 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");
     }