X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Froute.c;h=fc08f5f7aae7c8cb3a1a87bb3c96821677e1a672;hb=d6b45d005530496e48325a6174ecdd889a17bfc1;hp=92dc1cd0a6755a62cc067821c157a3516dff3d4a;hpb=9ca5a3c43854fba782d87be080d7a97a88ef3427;p=tinc diff --git a/src/route.c b/src/route.c index 92dc1cd0..fc08f5f7 100644 --- a/src/route.c +++ b/src/route.c @@ -1,7 +1,7 @@ /* route.c -- routing Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2018 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -59,6 +59,7 @@ static const size_t opt_size = sizeof(struct nd_opt_hdr); #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif +volatile int dummy; static timeout_t age_subnets_timeout; /* RFC 1071 */ @@ -80,6 +81,11 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { checksum = (checksum & 0xFFFF) + (checksum >> 16); } + // Work around a compiler optimization bug. + if(checksum) { + dummy = 1; + } + return ~checksum; } @@ -159,7 +165,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ addr.sin_family = AF_INET; socklen_t addrlen = sizeof(addr); - if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && addrlen <= sizeof(addr)) { + if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && (size_t)addrlen <= sizeof(addr)) { ip_dst = addr.sin_addr; } } @@ -264,7 +270,7 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ addr.sin6_family = AF_INET6; socklen_t addrlen = sizeof(addr); - if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && addrlen <= sizeof(addr)) { + if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && (size_t)addrlen <= sizeof(addr)) { pseudo.ip6_src = addr.sin6_addr; } } @@ -489,6 +495,7 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac } static void age_subnets(void *data) { + (void)data; bool left = false; for splay_each(subnet_t, s, myself->subnet_tree) { @@ -591,7 +598,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et logger(DEBUG_TRAFFIC, LOG_INFO, "Fragmenting packet of %d bytes to %s (%s)", packet->len, dest->name, dest->hostname); offset = DATA(packet) + ether_size + ip_size; - maxlen = (dest->mtu - ether_size - ip_size) & ~0x7; + maxlen = (MAX(dest->mtu, 590) - ether_size - ip_size) & ~0x7; ip_off = ntohs(ip.ip_off); origf = ip_off & ~IP_OFFMASK; ip_off &= IP_OFFMASK; @@ -651,11 +658,13 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { } if(!subnet->owner->status.reachable) { - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + return; } if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + return; } if(decrement_ttl && source != myself && subnet->owner != myself) @@ -675,7 +684,8 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { } if(directonly && subnet->owner != via) { - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + return; } if(via && packet->len > MAX(via->mtu, 590) && via != myself) { @@ -742,11 +752,13 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { } if(!subnet->owner->status.reachable) { - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + return; } if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + return; } if(decrement_ttl && source != myself && subnet->owner != myself) @@ -766,7 +778,8 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { } if(directonly && subnet->owner != via) { - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + return; } if(via && packet->len > MAX(via->mtu, 1294) && via != myself) { @@ -894,7 +907,7 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { memcpy(DATA(packet), DATA(packet) + ETH_ALEN, ETH_ALEN); /* copy destination address */ DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ - ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */ + ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocol address */ ip6.ip6_src = ns.nd_ns_target; if(has_opt) {