Only send packets via UDP if UDP communication is possible.
authorGuus Sliepen <guus@tinc-vpn.org>
Sat, 3 Jan 2009 21:33:55 +0000 (22:33 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Sat, 3 Jan 2009 21:33:55 +0000 (22:33 +0100)
When no session key is known for a node, or when it is doing PMTU discovery but
no MTU probes have returned yet, packets are sent via TCP. Some logic is added
to make sure intermediate nodes continue forwarding via TCP.  The per-node
packet queue is now no longer necessary and has been removed.

src/net.c
src/net.h
src/net_packet.c
src/node.c
src/node.h
src/protocol_key.c
src/route.c
src/tincd.c

index 1682705da74153241b3a96571ab5f8b6f37bdf54..9e4829a35b75fcefba7eaaab3d044db8c2071d00 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -295,8 +295,10 @@ static void check_network_activity(fd_set * readset, fd_set * writeset)
 
        /* check input from kernel */
        if(FD_ISSET(device_fd, readset)) {
-               if(read_packet(&packet))
+               if(read_packet(&packet)) {
+                       packet.priority = 0;
                        route(myself, &packet);
+               }
        }
 
        /* check meta connections */
index d63c0522172071fb36b2fc4b95f1db8a60c59785..d845f1a8e35c53da8699c686e3e93e8c6a873b6e 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -38,8 +38,6 @@
 
 #define MAXSOCKETS 128                 /* Overkill... */
 
-#define MAXQUEUELENGTH 8               /* Maximum number of packats in a single queue */
-
 typedef struct mac_t {
        uint8_t x[6];
 } mac_t;
index 105cafbb21e3d2b90368fa739de5a1aafff95d8e..c159efb3fc8e7723ec94bc8b7388627aa339ea72 100644 (file)
@@ -90,6 +90,7 @@ void send_mtu_probe(node_t *n)
                memset(packet.data, 0, 14);
                RAND_pseudo_bytes(packet.data + 14, len - 14);
                packet.len = len;
+               packet.priority = 0;
 
                ifdebug(TRAFFIC) logger(LOG_INFO, _("Sending MTU probe length %d to %s (%s)"), len, n->name, n->hostname);
 
@@ -264,6 +265,8 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
                inpkt = outpkt;
        }
 
+       inpkt->priority = 0;
+
        if(n->connection)
                n->connection->last_ping_time = now;
 
@@ -280,6 +283,10 @@ void receive_tcppacket(connection_t *c, char *buffer, int len)
        cp();
 
        outpkt.len = len;
+       if(c->options & OPTION_TCPONLY)
+               outpkt.priority = 0;
+       else
+               outpkt.priority = -1;
        memcpy(outpkt.data, buffer, len);
 
        receive_packet(c->node, &outpkt);
@@ -294,7 +301,6 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt)
        vpn_packet_t *outpkt;
        int origlen;
        int outlen, outpad;
-       vpn_packet_t *copy;
        static int priority = 0;
        int origpriority;
        int sock;
@@ -305,26 +311,27 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt)
 
        if(!n->status.validkey) {
                ifdebug(TRAFFIC) logger(LOG_INFO,
-                                  _("No valid key known yet for %s (%s), queueing packet"),
+                                  _("No valid key known yet for %s (%s), forwarding via TCP"),
                                   n->name, n->hostname);
 
-               /* Since packet is on the stack of handle_tap_input(), we have to make a copy of it first. */
-
-               *(copy = xmalloc(sizeof(*copy))) = *inpkt;
-
-               list_insert_tail(n->queue, copy);
-
-               if(n->queue->count > MAXQUEUELENGTH)
-                       list_delete_head(n->queue);
-
                if(!n->status.waitingforkey)
                        send_req_key(n->nexthop->connection, myself, n);
 
                n->status.waitingforkey = true;
 
+               send_tcppacket(n->nexthop->connection, origpkt);
+
                return;
        }
 
+       if(!n->minmtu && (inpkt->data[12] | inpkt->data[13])) {
+               ifdebug(TRAFFIC) logger(LOG_INFO,
+                               _("No minimum MTU established yet for %s (%s), forwarding via TCP"),
+                               n->name, n->hostname);
+
+               send_tcppacket(n->nexthop->connection, origpkt);
+       }
+
        origlen = inpkt->len;
        origpriority = inpkt->priority;
 
@@ -433,13 +440,13 @@ void send_packet(const node_t *n, vpn_packet_t *packet)
                return;
        }
 
-       via = (n->via == myself) ? n->nexthop : n->via;
+       via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via;
 
        if(via != n)
-               ifdebug(TRAFFIC) logger(LOG_ERR, _("Sending packet to %s via %s (%s)"),
+               ifdebug(TRAFFIC) logger(LOG_INFO, _("Sending packet to %s via %s (%s)"),
                           n->name, via->name, n->via->hostname);
 
-       if((myself->options | via->options) & OPTION_TCPONLY) {
+       if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) {
                if(!send_tcppacket(via->connection, packet))
                        terminate_connection(via->connection, true);
        } else
@@ -469,21 +476,6 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet)
        }
 }
 
-void flush_queue(node_t *n)
-{
-       list_node_t *node, *next;
-
-       cp();
-
-       ifdebug(TRAFFIC) logger(LOG_INFO, _("Flushing queue for %s (%s)"), n->name, n->hostname);
-
-       for(node = n->queue->head; node; node = next) {
-               next = node->next;
-               send_udppacket(n, node->data);
-               list_delete_node(n->queue, node);
-       }
-}
-
 void handle_incoming_vpn_data(int sock)
 {
        vpn_packet_t pkt;
index 5dad0aaf379851c2518c586cb8fe43e63036ddbb..b0965301c05ea7bd507499dc1e5d7e6b66dfd259 100644 (file)
@@ -78,7 +78,6 @@ node_t *new_node(void)
 
        n->subnet_tree = new_subnet_tree();
        n->edge_tree = new_edge_tree();
-       n->queue = list_alloc((list_action_t) free);
        EVP_CIPHER_CTX_init(&n->packet_ctx);
        n->mtu = MTU;
        n->maxmtu = MTU;
@@ -90,9 +89,6 @@ void free_node(node_t *n)
 {
        cp();
 
-       if(n->queue)
-               list_delete_list(n->queue);
-
        if(n->key)
                free(n->key);
 
index 4b3224e3cab4da7822f5441c729598a03a50a8de..6e48f3b3f797691cfaf06742f82a47c099f5d9bf 100644 (file)
@@ -61,8 +61,6 @@ typedef struct node_t {
 
        int compression;                        /* Compressionlevel, 0 = no compression */
 
-       list_t *queue;                          /* Queue for packets awaiting to be encrypted */
-
        struct node_t *nexthop;                 /* nearest node from us to him */
        struct node_t *via;                     /* next hop for UDP packets */
 
index f0fe316b2f65f5496b7acf829f6a25a9b5682e98..ab73275f7ffd48b0146758c93dc09ab629a6ccb4 100644 (file)
@@ -283,7 +283,5 @@ bool ans_key_h(connection_t *c)
        if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes)
                send_mtu_probe(from);
 
-       flush_queue(from);
-
        return true;
 }
index ec01491cd5f35979f1269c5d2a2c5357ea006c0d..c458ea4f67ee8d9cc06b273381b526fd3607f11a 100644 (file)
@@ -376,11 +376,11 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet)
        if(!checklength(source, packet, ether_size + ip_size))
                return;
 
-       if(((packet->data[30] & 0xf0) == 0xe0) ||
+       if(((packet->data[30] & 0xf0) == 0xe0) || (
                        packet->data[30] == 255 &&
                        packet->data[31] == 255 &&
                        packet->data[32] == 255 &&
-                       packet->data[33] == 255)
+                       packet->data[33] == 255))
                broadcast_packet(source, packet);
        else
                route_ipv4_unicast(source, packet);
index e65fec4d30552e0196d4098e2653978053fb5b93..746fff41129ba6c148b9ddd4f8f7b2fbfdcd8212 100644 (file)
@@ -516,6 +516,7 @@ end:
        if (logfilename) free(logfilename);
        if (myport) free(myport);
        if (device) free(device);
+       if (iface) free(iface);
        if (confbase) free(confbase);
 
        EVP_cleanup();