X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet_packet.c;h=fe20a2581283f3d460cd5e0caa626806b63fbe9e;hp=b35f72d4aa744657ab95691cd6adf6b5d9fb07d7;hb=50af33d01f425983dd2b1d7b61092a6325be3f41;hpb=23acc19bc090051156ad895caed61848f5afb144 diff --git a/src/net_packet.c b/src/net_packet.c index b35f72d4..fe20a258 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -1,8 +1,9 @@ /* net_packet.c -- Handles in- and outgoing VPN packets Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2010 Guus Sliepen + 2000-2011 Guus Sliepen 2010 Timothy Redaelli + 2010 Brandon Black 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 @@ -42,7 +43,6 @@ #include "ethernet.h" #include "event.h" #include "graph.h" -#include "list.h" #include "logger.h" #include "net.h" #include "netutl.h" @@ -84,16 +84,21 @@ void send_mtu_probe(node_t *n) { } if(n->mtuprobes > 32) { + if(!n->minmtu) { + n->mtuprobes = 31; + timeout = pinginterval; + goto end; + } + ifdebug(TRAFFIC) logger(LOG_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname); n->mtuprobes = 1; n->minmtu = 0; n->maxmtu = MTU; } - if(n->mtuprobes >= 10 && !n->minmtu) { + if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) { ifdebug(TRAFFIC) logger(LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname); - n->mtuprobes = 0; - return; + n->mtuprobes = 31; } if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) { @@ -147,12 +152,17 @@ void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { packet->data[0] = 1; send_udppacket(n, packet); } else { + if(n->mtuprobes > 30) { + if(n->minmtu) + n->mtuprobes = 30; + else + n->mtuprobes = 1; + } + if(len > n->maxmtu) len = n->maxmtu; if(n->minmtu < len) n->minmtu = len; - if(n->mtuprobes > 30) - n->mtuprobes = 30; } } @@ -298,9 +308,13 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(replaywin) { if(inpkt->seqno != n->received_seqno + 1) { if(inpkt->seqno >= n->received_seqno + replaywin * 8) { + if(n->farfuture++ < replaywin >> 2) { + logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", + n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture); + return; + } logger(LOG_WARNING, "Lost %d packets from %s (%s)", inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); - memset(n->late, 0, replaywin); } else if (inpkt->seqno <= n->received_seqno) { if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) { @@ -313,7 +327,8 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { n->late[(i / 8) % replaywin] |= 1 << i % 8; } } - + + n->farfuture = 0; n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8); } @@ -349,7 +364,7 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { receive_packet(n, inpkt); } -void receive_tcppacket(connection_t *c, char *buffer, int len) { +void receive_tcppacket(connection_t *c, const char *buffer, int len) { vpn_packet_t outpkt; outpkt.len = len; @@ -388,7 +403,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { "No valid key known yet for %s (%s), forwarding via TCP", n->name, n->hostname); - if(n->last_req_key + 10 < now) { + if(n->last_req_key + 10 <= now) { send_req_key(n); n->last_req_key = now; } @@ -559,20 +574,21 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { avl_node_t *node; edge_t *e; node_t *n = NULL; + bool hard = false; static time_t last_hard_try = 0; for(node = edge_weight_tree->head; node; node = node->next) { e = node->data; + if(e->to == myself) + continue; + if(sockaddrcmp_noport(from, &e->address)) { if(last_hard_try == now) continue; - last_hard_try = now; + hard = true; } - if(!n) - n = e->to; - if(!try_mac(e->to, pkt)) continue; @@ -580,6 +596,9 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { break; } + if(hard) + last_hard_try = now; + return n; }