-From 240725528c5a756ee9aaff247e3731f4b8517c06 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= <arekm@maven.pl>
-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
-