Add the LocalDiscoveryAddress option.
[tinc] / src / net_packet.c
index c255261..4bbb2d6 100644 (file)
@@ -56,6 +56,7 @@ static void send_udppacket(node_t *, vpn_packet_t *);
 
 unsigned replaywin = 16;
 bool localdiscovery = false;
+sockaddr_t localdiscovery_address;
 
 #define MAX_SEQNO 1073741824
 
@@ -332,13 +333,21 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
        size_t outlen;
 
        if(n->status.sptps) {
+               if(!n->sptps.state) {
+                       if(!n->status.waitingforkey) {
+                               logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname);
+                               send_req_key(n);
+                       } else {
+                               logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname);
+                       }
+                       return;
+               }
                sptps_receive_data(&n->sptps, (char *)&inpkt->seqno, inpkt->len);
                return;
        }
 
        if(!cipher_active(n->incipher)) {
-               logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet",
-                                       n->name, n->hostname);
+               logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname);
                return;
        }
 
@@ -572,12 +581,22 @@ static void choose_broadcast_address(const node_t *n, const sockaddr_t **sa, int
        *sock = rand() % listen_sockets;
 
        if(listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
-               broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
-               broadcast_ipv6.in6.sin6_scope_id = listen_socket[*sock].sa.in6.sin6_scope_id;
-               *sa = &broadcast_ipv6;
+               if(localdiscovery_address.sa.sa_family == AF_INET6) {
+                       localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
+                       *sa = &localdiscovery_address;
+               } else {
+                       broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
+                       broadcast_ipv6.in6.sin6_scope_id = listen_socket[*sock].sa.in6.sin6_scope_id;
+                       *sa = &broadcast_ipv6;
+               }
        } else {
-               broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
-               *sa = &broadcast_ipv4;
+               if(localdiscovery_address.sa.sa_family == AF_INET) {
+                       localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
+                       *sa = &localdiscovery_address;
+               } else {
+                       broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
+                       *sa = &broadcast_ipv4;
+               }
        }
 }
 
@@ -669,7 +688,11 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
        /* Add the message authentication code */
 
        if(digest_active(n->outdigest)) {
-               digest_create(n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len);
+               if(!digest_create(n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len)) {
+                       logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname);
+                       goto end;
+               }
+
                inpkt->len += digest_length(n->outdigest);
        }