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
This commit is contained in:
Etienne Dechamps 2014-10-12 12:14:46 +01:00 committed by Guus Sliepen
parent 0356efecb6
commit 7730d5f3ed

View file

@ -514,6 +514,11 @@ static bool try_sptps(node_t *n) {
if(n->status.validkey) if(n->status.validkey)
return true; 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); logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname);
if(!n->status.waitingforkey) 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) { 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; return;
uint8_t type = 0; 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; return;
} }