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.
This commit is contained in:
parent
b069da90d6
commit
67df7fb7e1
8 changed files with 27 additions and 42 deletions
|
@ -295,9 +295,11 @@ static void check_network_activity(fd_set * readset, fd_set * writeset)
|
||||||
|
|
||||||
/* check input from kernel */
|
/* check input from kernel */
|
||||||
if(FD_ISSET(device_fd, readset)) {
|
if(FD_ISSET(device_fd, readset)) {
|
||||||
if(read_packet(&packet))
|
if(read_packet(&packet)) {
|
||||||
|
packet.priority = 0;
|
||||||
route(myself, &packet);
|
route(myself, &packet);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* check meta connections */
|
/* check meta connections */
|
||||||
for(node = connection_tree->head; node; node = node->next) {
|
for(node = connection_tree->head; node; node = node->next) {
|
||||||
|
|
|
@ -38,8 +38,6 @@
|
||||||
|
|
||||||
#define MAXSOCKETS 128 /* Overkill... */
|
#define MAXSOCKETS 128 /* Overkill... */
|
||||||
|
|
||||||
#define MAXQUEUELENGTH 8 /* Maximum number of packats in a single queue */
|
|
||||||
|
|
||||||
typedef struct mac_t {
|
typedef struct mac_t {
|
||||||
uint8_t x[6];
|
uint8_t x[6];
|
||||||
} mac_t;
|
} mac_t;
|
||||||
|
|
|
@ -90,6 +90,7 @@ void send_mtu_probe(node_t *n)
|
||||||
memset(packet.data, 0, 14);
|
memset(packet.data, 0, 14);
|
||||||
RAND_pseudo_bytes(packet.data + 14, len - 14);
|
RAND_pseudo_bytes(packet.data + 14, len - 14);
|
||||||
packet.len = len;
|
packet.len = len;
|
||||||
|
packet.priority = 0;
|
||||||
|
|
||||||
ifdebug(TRAFFIC) logger(LOG_INFO, _("Sending MTU probe length %d to %s (%s)"), len, n->name, n->hostname);
|
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 = outpkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inpkt->priority = 0;
|
||||||
|
|
||||||
if(n->connection)
|
if(n->connection)
|
||||||
n->connection->last_ping_time = now;
|
n->connection->last_ping_time = now;
|
||||||
|
|
||||||
|
@ -280,6 +283,10 @@ void receive_tcppacket(connection_t *c, char *buffer, int len)
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
outpkt.len = len;
|
outpkt.len = len;
|
||||||
|
if(c->options & OPTION_TCPONLY)
|
||||||
|
outpkt.priority = 0;
|
||||||
|
else
|
||||||
|
outpkt.priority = -1;
|
||||||
memcpy(outpkt.data, buffer, len);
|
memcpy(outpkt.data, buffer, len);
|
||||||
|
|
||||||
receive_packet(c->node, &outpkt);
|
receive_packet(c->node, &outpkt);
|
||||||
|
@ -294,7 +301,6 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt)
|
||||||
vpn_packet_t *outpkt;
|
vpn_packet_t *outpkt;
|
||||||
int origlen;
|
int origlen;
|
||||||
int outlen, outpad;
|
int outlen, outpad;
|
||||||
vpn_packet_t *copy;
|
|
||||||
static int priority = 0;
|
static int priority = 0;
|
||||||
int origpriority;
|
int origpriority;
|
||||||
int sock;
|
int sock;
|
||||||
|
@ -305,26 +311,27 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt)
|
||||||
|
|
||||||
if(!n->status.validkey) {
|
if(!n->status.validkey) {
|
||||||
ifdebug(TRAFFIC) logger(LOG_INFO,
|
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);
|
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)
|
if(!n->status.waitingforkey)
|
||||||
send_req_key(n->nexthop->connection, myself, n);
|
send_req_key(n->nexthop->connection, myself, n);
|
||||||
|
|
||||||
n->status.waitingforkey = true;
|
n->status.waitingforkey = true;
|
||||||
|
|
||||||
|
send_tcppacket(n->nexthop->connection, origpkt);
|
||||||
|
|
||||||
return;
|
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;
|
origlen = inpkt->len;
|
||||||
origpriority = inpkt->priority;
|
origpriority = inpkt->priority;
|
||||||
|
|
||||||
|
@ -433,13 +440,13 @@ void send_packet(const node_t *n, vpn_packet_t *packet)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
via = (n->via == myself) ? n->nexthop : n->via;
|
via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via;
|
||||||
|
|
||||||
if(via != n)
|
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);
|
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))
|
if(!send_tcppacket(via->connection, packet))
|
||||||
terminate_connection(via->connection, true);
|
terminate_connection(via->connection, true);
|
||||||
} else
|
} 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)
|
void handle_incoming_vpn_data(int sock)
|
||||||
{
|
{
|
||||||
vpn_packet_t pkt;
|
vpn_packet_t pkt;
|
||||||
|
|
|
@ -78,7 +78,6 @@ node_t *new_node(void)
|
||||||
|
|
||||||
n->subnet_tree = new_subnet_tree();
|
n->subnet_tree = new_subnet_tree();
|
||||||
n->edge_tree = new_edge_tree();
|
n->edge_tree = new_edge_tree();
|
||||||
n->queue = list_alloc((list_action_t) free);
|
|
||||||
EVP_CIPHER_CTX_init(&n->packet_ctx);
|
EVP_CIPHER_CTX_init(&n->packet_ctx);
|
||||||
n->mtu = MTU;
|
n->mtu = MTU;
|
||||||
n->maxmtu = MTU;
|
n->maxmtu = MTU;
|
||||||
|
@ -90,9 +89,6 @@ void free_node(node_t *n)
|
||||||
{
|
{
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
if(n->queue)
|
|
||||||
list_delete_list(n->queue);
|
|
||||||
|
|
||||||
if(n->key)
|
if(n->key)
|
||||||
free(n->key);
|
free(n->key);
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,6 @@ typedef struct node_t {
|
||||||
|
|
||||||
int compression; /* Compressionlevel, 0 = no compression */
|
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 *nexthop; /* nearest node from us to him */
|
||||||
struct node_t *via; /* next hop for UDP packets */
|
struct node_t *via; /* next hop for UDP packets */
|
||||||
|
|
||||||
|
|
|
@ -283,7 +283,5 @@ bool ans_key_h(connection_t *c)
|
||||||
if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes)
|
if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes)
|
||||||
send_mtu_probe(from);
|
send_mtu_probe(from);
|
||||||
|
|
||||||
flush_queue(from);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -376,11 +376,11 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet)
|
||||||
if(!checklength(source, packet, ether_size + ip_size))
|
if(!checklength(source, packet, ether_size + ip_size))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(((packet->data[30] & 0xf0) == 0xe0) ||
|
if(((packet->data[30] & 0xf0) == 0xe0) || (
|
||||||
packet->data[30] == 255 &&
|
packet->data[30] == 255 &&
|
||||||
packet->data[31] == 255 &&
|
packet->data[31] == 255 &&
|
||||||
packet->data[32] == 255 &&
|
packet->data[32] == 255 &&
|
||||||
packet->data[33] == 255)
|
packet->data[33] == 255))
|
||||||
broadcast_packet(source, packet);
|
broadcast_packet(source, packet);
|
||||||
else
|
else
|
||||||
route_ipv4_unicast(source, packet);
|
route_ipv4_unicast(source, packet);
|
||||||
|
|
|
@ -516,6 +516,7 @@ end:
|
||||||
if (logfilename) free(logfilename);
|
if (logfilename) free(logfilename);
|
||||||
if (myport) free(myport);
|
if (myport) free(myport);
|
||||||
if (device) free(device);
|
if (device) free(device);
|
||||||
|
if (iface) free(iface);
|
||||||
if (confbase) free(confbase);
|
if (confbase) free(confbase);
|
||||||
|
|
||||||
EVP_cleanup();
|
EVP_cleanup();
|
||||||
|
|
Loading…
Reference in a new issue