From 3d02192c9bd42a979d8d5b109b0475dd0566e99f Mon Sep 17 00:00:00 2001 From: "Vittorio Gambaletta (VittGam)" Date: Fri, 4 Sep 2015 17:04:03 +0200 Subject: [PATCH] Try to reply with node address only when decrementing the TTL. Signed-off-by: Vittorio Gambaletta --- src/route.c | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/route.c b/src/route.c index f046e6e..324212b 100644 --- a/src/route.c +++ b/src/route.c @@ -258,7 +258,6 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ struct in_addr ip_src; struct in_addr ip_dst; uint32_t oldlen; - int sockfd; if(ratelimit(3)) return; @@ -278,21 +277,23 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Try to reply with an IP address assigned to the local machine */ - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd != -1) { - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr = ip.ip_src; - if (!connect(sockfd, (const struct sockaddr*) &addr, sizeof(addr))) { + if (type == ICMP_TIME_EXCEEDED && code == ICMP_EXC_TTL) { + int sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd != -1) { + struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - socklen_t addrlen = sizeof(addr); - if (!getsockname(sockfd, (struct sockaddr*) &addr, &addrlen) && addrlen <= sizeof(addr)) { - ip_dst = addr.sin_addr; + addr.sin_addr = ip.ip_src; + if (!connect(sockfd, (const struct sockaddr*) &addr, sizeof(addr))) { + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + socklen_t addrlen = sizeof(addr); + if (!getsockname(sockfd, (struct sockaddr*) &addr, &addrlen) && addrlen <= sizeof(addr)) { + ip_dst = addr.sin_addr; + } } + close(sockfd); } - close(sockfd); } oldlen = packet->len - ether_size; @@ -473,7 +474,6 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ struct ip6_hdr ip6; struct icmp6_hdr icmp6 = {0}; uint16_t checksum; - int sockfd; struct { struct in6_addr ip6_src; /* source address */ @@ -500,21 +500,23 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Try to reply with an IP address assigned to the local machine */ - sockfd = socket(AF_INET6, SOCK_DGRAM, 0); - if (sockfd != -1) { - struct sockaddr_in6 addr; - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_addr = ip6.ip6_src; - if (!connect(sockfd, (const struct sockaddr*) &addr, sizeof(addr))) { + if (type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) { + int sockfd = socket(AF_INET6, SOCK_DGRAM, 0); + if (sockfd != -1) { + struct sockaddr_in6 addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; - socklen_t addrlen = sizeof(addr); - if (!getsockname(sockfd, (struct sockaddr*) &addr, &addrlen) && addrlen <= sizeof(addr)) { - pseudo.ip6_src = addr.sin6_addr; + addr.sin6_addr = ip6.ip6_src; + if (!connect(sockfd, (const struct sockaddr*) &addr, sizeof(addr))) { + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + socklen_t addrlen = sizeof(addr); + if (!getsockname(sockfd, (struct sockaddr*) &addr, &addrlen) && addrlen <= sizeof(addr)) { + pseudo.ip6_src = addr.sin6_addr; + } } + close(sockfd); } - close(sockfd); } pseudo.length = packet->len - ether_size; -- 2.25.1