X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fnet_packet.c;h=6ce6431dee9288a595731163b819a2eccfe36810;hb=0f0585d71b28428792e53258bc570dddc17b0b27;hp=5709d49a93962bcfaac3ab11a00f58a7eedfd426;hpb=f6e87ab476a0faf8b124ecaaa27f967d825e6457;p=tinc diff --git a/src/net_packet.c b/src/net_packet.c index 5709d49a..6ce6431d 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -23,6 +23,7 @@ #include "system.h" #ifdef HAVE_ZLIB +#define ZLIB_CONST #include #endif @@ -30,6 +31,7 @@ #include LZO1X_H #endif +#include "address_cache.h" #include "cipher.h" #include "conf.h" #include "connection.h" @@ -100,6 +102,7 @@ static void udp_probe_timeout_handler(void *data) { logger(DEBUG_TRAFFIC, LOG_INFO, "Too much time has elapsed since last UDP ping response from %s (%s), stopping UDP communication", n->name, n->hostname); n->status.udp_confirmed = false; + n->udp_ping_rtt = -1; n->maxrecentlen = 0; n->mtuprobes = 0; n->minmtu = 0; @@ -138,7 +141,8 @@ static void send_udp_probe_reply(node_t *n, vpn_packet_t *packet, length_t len) static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { if(!DATA(packet)[0]) { logger(DEBUG_TRAFFIC, LOG_INFO, "Got UDP probe request %d from %s (%s)", packet->len, n->name, n->hostname); - return send_udp_probe_reply(n, packet, len); + send_udp_probe_reply(n, packet, len); + return; } if(DATA(packet)[0] == 2) { @@ -148,15 +152,32 @@ static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { len = ntohs(len16); } - logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s)", DATA(packet)[0], len, n->name, n->hostname); + if (n->udp_ping_sent.tv_sec != 0) { // a probe in flight + gettimeofday(&now, NULL); + struct timeval rtt; + timersub(&now, &n->udp_ping_sent, &rtt); + n->udp_ping_rtt = rtt.tv_sec*1000000L + rtt.tv_usec; + logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s) rtt=%ld.%03ld", DATA(packet)[0], len, n->name, n->hostname, n->udp_ping_rtt/1000, n->udp_ping_rtt%1000); + } else { + logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s)", DATA(packet)[0], len, n->name, n->hostname); + } /* It's a valid reply: now we know bidirectional communication is possible using the address and socket that the reply packet used. */ - n->status.udp_confirmed = true; + if(!n->status.udp_confirmed) { + n->status.udp_confirmed = true; + fprintf(stderr, "Updating address cache...\n"); + + if(!n->address_cache) { + n->address_cache = open_address_cache(n); + } + + reset_address_cache(n->address_cache, &n->address); + } - // Reset the UDP ping timer. - n->udp_ping_sent = now; + // Reset the UDP ping timer. (no probe in flight) + n->udp_ping_sent.tv_sec = 0; if(udp_discovery) { timeout_del(&n->udp_ping_timeout); @@ -238,9 +259,22 @@ static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t #ifdef HAVE_ZLIB else { unsigned long destlen = MAXSIZE; + static z_stream stream; - if(uncompress(dest, &destlen, source, len) == Z_OK) { - return destlen; + if(stream.next_in) { + inflateReset(&stream); + } else { + inflateInit(&stream); + } + + stream.next_in = source; + stream.avail_in = len; + stream.next_out = dest; + stream.avail_out = destlen; + stream.total_out = 0; + + if(inflate(&stream, Z_FINISH) == Z_STREAM_END) { + return stream.total_out; } else { return -1; } @@ -680,7 +714,8 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { } if(n->status.sptps) { - return send_sptps_packet(n, origpkt); + send_sptps_packet(n, origpkt); + return; } #ifdef DISABLE_LEGACY @@ -773,7 +808,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { listen_socket[sock].priority = origpriority; switch(sa->sa.sa_family) { -#if defined(IPPROTO_IP) && defined(IP_TOS) +#if defined(IP_TOS) case AF_INET: logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv4 outgoing packet priority to %d", origpriority); @@ -784,7 +819,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { break; #endif -#if defined(IPPROTO_IPV6) & defined(IPV6_TCLASS) +#if defined(IPV6_TCLASS) case AF_INET6: logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv6 outgoing packet priority to %d", origpriority); @@ -832,12 +867,12 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ if(type == SPTPS_HANDSHAKE || tcponly || (!direct && !relay_supported) || (type != PKT_PROBE && (len - SPTPS_DATAGRAM_OVERHEAD) > relay->minmtu)) { if(type != SPTPS_HANDSHAKE && (to->nexthop->connection->options >> 24) >= 7) { - char buf[len + sizeof(to->id) + sizeof from->id]; + char buf[len + sizeof(to->id) + sizeof(from->id)]; char *buf_ptr = buf; memcpy(buf_ptr, &to->id, sizeof(to->id)); - buf_ptr += sizeof to->id; + buf_ptr += sizeof(to->id); memcpy(buf_ptr, &from->id, sizeof(from->id)); - buf_ptr += sizeof from->id; + buf_ptr += sizeof(from->id); memcpy(buf_ptr, data, len); logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (TCP)", from->name, from->hostname, to->name, to->hostname, to->nexthop->name, to->nexthop->hostname); return send_sptps_tcppacket(to->nexthop->connection, buf, sizeof(buf)); @@ -860,7 +895,7 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ size_t overhead = 0; if(relay_supported) { - overhead += sizeof(to->id) + sizeof from->id; + overhead += sizeof(to->id) + sizeof(from->id); } char buf[len + overhead]; @@ -869,16 +904,16 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ if(relay_supported) { if(direct) { /* Inform the recipient that this packet was sent directly. */ - node_id_t nullid = {}; + node_id_t nullid = {{0}}; memcpy(buf_ptr, &nullid, sizeof(nullid)); - buf_ptr += sizeof nullid; + buf_ptr += sizeof(nullid); } else { memcpy(buf_ptr, &to->id, sizeof(to->id)); - buf_ptr += sizeof to->id; + buf_ptr += sizeof(to->id); } memcpy(buf_ptr, &from->id, sizeof(from->id)); - buf_ptr += sizeof from->id; + buf_ptr += sizeof(from->id); } @@ -929,7 +964,7 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t if(!from->status.validkey) { from->status.validkey = true; from->status.waitingforkey = false; - logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname); + logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) successful", from->name, from->hostname); } return true; @@ -1093,8 +1128,9 @@ static void try_udp(node_t *n) { int interval = n->status.udp_confirmed ? udp_discovery_keepalive_interval : udp_discovery_interval; if(ping_tx_elapsed.tv_sec >= interval) { + gettimeofday(&now, NULL); + n->udp_ping_sent = now; // a probe in flight send_udp_probe_packet(n, MIN_PROBE_SIZE); - n->udp_ping_sent = now; if(localdiscovery && !n->status.udp_confirmed && n->prevedge) { n->status.send_locally = true; @@ -1347,7 +1383,8 @@ static void try_tx_sptps(node_t *n, bool mtu) { return; } - return try_tx(via, mtu); + try_tx(via, mtu); + return; } /* Otherwise, try to establish UDP connectivity. */ @@ -1569,7 +1606,7 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { static void handle_incoming_vpn_packet(listen_socket_t *ls, vpn_packet_t *pkt, sockaddr_t *addr) { char *hostname; - node_id_t nullid = {}; + node_id_t nullid = {{0}}; node_t *from, *to; bool direct = false; @@ -1701,14 +1738,14 @@ void handle_incoming_vpn_data(void *data, int flags) { iov[i] = (struct iovec) { .iov_base = DATA(&pkt[i]), - .iov_len = MAXSIZE, + .iov_len = MAXSIZE, }; msg[i].msg_hdr = (struct msghdr) { .msg_name = &addr[i].sa, - .msg_namelen = sizeof(addr)[i], - .msg_iov = &iov[i], - .msg_iovlen = 1, + .msg_namelen = sizeof(addr)[i], + .msg_iov = &iov[i], + .msg_iovlen = 1, }; }