From 7730d5f3ed9bd7c011dced5808130ffcbd74ea6b Mon Sep 17 00:00:00 2001 From: Etienne Dechamps Date: Sun, 12 Oct 2014 12:14:46 +0100 Subject: [PATCH] Use plain old PACKET for TCP packets sent directly to a neighbor. Currently, when sending packets over TCP where the final recipient is a node we have a direct metaconnection to, tinc first establishes a SPTPS handshake between the two neighbors. It turns out this SPTPS tunnel is not actually useful, because the packet is only being sent over one metaconnection with no intermediate nodes, and the metaconnection itself is already secured using a separate SPTPS handshake. Therefore it seems simpler and more efficient to simply send these packets directly over the metaconnection itself without any additional layer. This commits implements this solution without any changes to the metaprotocol, since the appropriate message already exists: it's the good old "plaintext" PACKET message. This change brings two significant benefits: - Packets to neighbors can be sent immediately - there is no initial delay and packet loss previously caused by the SPTPS handshake; - Performance of sending packets to neighbors over TCP is greatly improved since the data only goes through one round of encryption instead of two. Conflicts: src/net_packet.c --- src/net_packet.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/net_packet.c b/src/net_packet.c index 16dac43f..c1461091 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -514,6 +514,11 @@ static bool try_sptps(node_t *n) { if(n->status.validkey) return true; + /* If n is a TCP-only neighbor, we'll only use "cleartext" PACKET + messages anyway, so there's no need for SPTPS at all. */ + if(n->connection && ((myself->options | n->options) & OPTION_TCPONLY)) + return false; + logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); if(!n->status.waitingforkey) @@ -529,7 +534,10 @@ static bool try_sptps(node_t *n) { } static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { - if (!try_sptps(n)) + /* Note: condition order is as intended - even if we have a direct + metaconnection, we want to try SPTPS anyway as it's the only way to + get UDP going */ + if(!try_sptps(n) && !n->connection) return; uint8_t type = 0; @@ -562,7 +570,14 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { } } - sptps_send_record(&n->sptps, type, DATA(origpkt) + offset, origpkt->len - offset); + /* If we have a direct metaconnection to n, and we can't use UDP, then + don't bother with SPTPS and just use a "plaintext" PACKET message. + We don't really care about end-to-end security since we're not + sending the message through any intermediate nodes. */ + if(n->connection && origpkt->len > n->minmtu) + send_tcppacket(n->connection, origpkt); + else + sptps_send_record(&n->sptps, type, DATA(origpkt) + offset, origpkt->len - offset); return; } -- 2.20.1