Log warnings about dropped packets only with debug level 5 or higher.
[tinc] / src / net_packet.c
index 905b944..18eaf34 100644 (file)
@@ -1,7 +1,7 @@
 /*
     net_packet.c -- Handles in- and outgoing VPN packets
     Copyright (C) 1998-2005 Ivo Timmermans,
-                  2000-2013 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2016 Guus Sliepen <guus@tinc-vpn.org>
                   2010      Timothy Redaelli <timothy@redaelli.eu>
                   2010      Brandon Black <blblack@gmail.com>
 
@@ -145,7 +145,7 @@ void send_mtu_probe(node_t *n) {
                        len = 64;
                
                memset(packet.data, 0, 14);
-               RAND_pseudo_bytes(packet.data + 14, len - 14);
+               RAND_bytes(packet.data + 14, len - 14);
                packet.len = len;
                if(i >= 4 && n->mtuprobes <= 10)
                        packet.priority = -1;
@@ -269,14 +269,14 @@ static bool try_mac(const node_t *n, const vpn_packet_t *inpkt) {
 
        HMAC(n->indigest, n->inkey, n->inkeylength, (unsigned char *) &inpkt->seqno, inpkt->len - n->inmaclength, (unsigned char *)hmac, NULL);
 
-       return !memcmp(hmac, (char *) &inpkt->seqno + inpkt->len - n->inmaclength, n->inmaclength);
+       return !memcmp_constant_time(hmac, (char *) &inpkt->seqno + inpkt->len - n->inmaclength, n->inmaclength);
 }
 
 static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
        vpn_packet_t pkt1, pkt2;
        vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
        int nextpkt = 0;
-       vpn_packet_t *outpkt = pkt[0];
+       vpn_packet_t *outpkt;
        int outlen, outpad;
        unsigned char hmac[EVP_MAX_MD_SIZE];
        int i;
@@ -302,7 +302,7 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
                HMAC(n->indigest, n->inkey, n->inkeylength,
                         (unsigned char *) &inpkt->seqno, inpkt->len, (unsigned char *)hmac, NULL);
 
-               if(memcmp(hmac, (char *) &inpkt->seqno + inpkt->len, n->inmaclength)) {
+               if(memcmp_constant_time(hmac, (char *) &inpkt->seqno + inpkt->len, n->inmaclength)) {
                        ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got unauthenticated packet from %s (%s)",
                                           n->name, n->hostname);
                        return;
@@ -314,10 +314,10 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
        if(n->incipher) {
                outpkt = pkt[nextpkt++];
 
-               if(!EVP_DecryptInit_ex(&n->inctx, NULL, NULL, NULL, NULL)
-                               || !EVP_DecryptUpdate(&n->inctx, (unsigned char *) &outpkt->seqno, &outlen,
+               if(!EVP_DecryptInit_ex(n->inctx, NULL, NULL, NULL, NULL)
+                               || !EVP_DecryptUpdate(n->inctx, (unsigned char *) &outpkt->seqno, &outlen,
                                        (unsigned char *) &inpkt->seqno, inpkt->len)
-                               || !EVP_DecryptFinal_ex(&n->inctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) {
+                               || !EVP_DecryptFinal_ex(n->inctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) {
                        ifdebug(TRAFFIC) logger(LOG_DEBUG, "Error decrypting packet from %s (%s): %s",
                                                n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
                        return;
@@ -336,16 +336,16 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
                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)",
+                                       ifdebug(TRAFFIC) 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)",
+                               ifdebug(TRAFFIC) 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))) {
-                                       logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d",
+                                       ifdebug(TRAFFIC) logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d",
                                                n->name, n->hostname, inpkt->seqno, n->received_seqno);
                                        return;
                                }
@@ -415,9 +415,6 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
        vpn_packet_t *outpkt;
        int origlen;
        int outlen, outpad;
-#if defined(SOL_IP) && defined(IP_TOS)
-       static int priority = 0;
-#endif
        int origpriority;
 
        if(!n->status.reachable) {
@@ -482,10 +479,10 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
        if(n->outcipher) {
                outpkt = pkt[nextpkt++];
 
-               if(!EVP_EncryptInit_ex(&n->outctx, NULL, NULL, NULL, NULL)
-                               || !EVP_EncryptUpdate(&n->outctx, (unsigned char *) &outpkt->seqno, &outlen,
+               if(!EVP_EncryptInit_ex(n->outctx, NULL, NULL, NULL, NULL)
+                               || !EVP_EncryptUpdate(n->outctx, (unsigned char *) &outpkt->seqno, &outlen,
                                        (unsigned char *) &inpkt->seqno, inpkt->len)
-                               || !EVP_EncryptFinal_ex(&n->outctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) {
+                               || !EVP_EncryptFinal_ex(n->outctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) {
                        ifdebug(TRAFFIC) logger(LOG_ERR, "Error while encrypting packet to %s (%s): %s",
                                                n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
                        goto end;
@@ -549,15 +546,27 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
                sock = n->sock;
        }
 
+       if(priorityinheritance && origpriority != listen_socket[n->sock].priority) {
+               listen_socket[n->sock].priority = origpriority;
+               switch(listen_socket[n->sock].sa.sa.sa_family) {
 #if defined(SOL_IP) && defined(IP_TOS)
-       if(priorityinheritance && origpriority != priority
-          && listen_socket[n->sock].sa.sa.sa_family == AF_INET) {
-               priority = origpriority;
-               ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting outgoing packet priority to %d", priority);
-               if(setsockopt(listen_socket[n->sock].udp, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */
-                       logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno));
-       }
+               case AF_INET:
+                       ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting IPv4 outgoing packet priority to %d", origpriority);
+                       if(setsockopt(listen_socket[n->sock].udp, SOL_IP, IP_TOS, (void *)&origpriority, sizeof(origpriority))) /* SO_PRIORITY doesn't seem to work */
+                               logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno));
+                       break;
 #endif
+#if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS)
+               case AF_INET6:
+                       ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting IPv6 outgoing packet priority to %d", origpriority);
+                       if(setsockopt(listen_socket[n->sock].udp, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof(origpriority)))
+                               logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno));
+                       break;
+#endif
+               default:
+                       break;
+               }
+       }
 
        if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, sa, sl) < 0 && !sockwouldblock(sockerrno)) {
                if(sockmsgsize(sockerrno)) {