From 67df7fb7e1c9eefe4bbc920fdc68b595ef28abd9 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 3 Jan 2009 22:33:55 +0100 Subject: [PATCH] Only send packets via UDP if UDP communication is possible. 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 | 4 +++- src/net.h | 2 -- src/net_packet.c | 50 +++++++++++++++++++--------------------------- src/node.c | 4 ---- src/node.h | 2 -- src/protocol_key.c | 2 -- src/route.c | 4 ++-- src/tincd.c | 1 + 8 files changed, 27 insertions(+), 42 deletions(-) diff --git a/src/net.c b/src/net.c index 1682705d..9e4829a3 100644 --- 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 */ diff --git a/src/net.h b/src/net.h index d63c0522..d845f1a8 100644 --- 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; diff --git a/src/net_packet.c b/src/net_packet.c index 105cafbb..c159efb3 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -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; diff --git a/src/node.c b/src/node.c index 5dad0aaf..b0965301 100644 --- a/src/node.c +++ b/src/node.c @@ -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); diff --git a/src/node.h b/src/node.h index 4b3224e3..6e48f3b3 100644 --- a/src/node.h +++ b/src/node.h @@ -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 */ diff --git a/src/protocol_key.c b/src/protocol_key.c index f0fe316b..ab73275f 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -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; } diff --git a/src/route.c b/src/route.c index ec01491c..c458ea4f 100644 --- a/src/route.c +++ b/src/route.c @@ -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); diff --git a/src/tincd.c b/src/tincd.c index e65fec4d..746fff41 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -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(); -- 2.20.1