Introduce raw TCP SPTPS packet transport.
Currently, SPTPS packets are transported over TCP metaconnections using extended REQ_KEY requests, in order for the packets to pass through tinc-1.0 nodes unaltered. Unfortunately, this method presents two significant downsides: - An already encrypted SPTPS packet is decrypted and then encrypted again every time it passes through a node, since it is transported over the SPTPS channels of the metaconnections. This double-encryption is unnecessary and wastes CPU cycles. - More importantly, the only way to transport binary data over standard metaconnection messages such as REQ_KEY is to encode it in base64, which has a 33% encoding overhead. This wastes 25% of the network bandwidth. This commit introduces a new protocol message, SPTPS_PACKET, which can be used to transport SPTPS packets over a TCP metaconnection in an efficient way. The new message is appropriately protected through a minor protocol version increment, and extended REQ_KEY messages are still used with nodes that do not support the new message, as well as for the intial handshake packets, for which efficiency is not a concern. The way SPTPS_PACKET works is very similar to how the traditional PACKET message works: after the SPTPS_PACKET message, the raw binary packet is sent directly over the metaconnection. There is one important difference, however: in the case of SPTPS_PACKET, the packet is sent directly over the TCP stream completely bypassing the SPTPS channel of the metaconnection itself for maximum efficiency. This is secure because the SPTPS packet that is being sent is already encrypted with an end-to-end key.
This commit is contained in:
parent
d237efd325
commit
7e6b2dd1ea
8 changed files with 126 additions and 3 deletions
33
src/meta.c
33
src/meta.c
|
|
@ -78,6 +78,20 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void send_meta_raw(connection_t *c, const char *buffer, int length) {
|
||||
if(!c) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "send_meta() called with NULL pointer!");
|
||||
abort();
|
||||
}
|
||||
|
||||
logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes of raw metadata to %s (%s)", length,
|
||||
c->name, c->hostname);
|
||||
|
||||
buffer_add(&c->outbuf, buffer, length);
|
||||
|
||||
io_set(&c->io, IO_READ | IO_WRITE);
|
||||
}
|
||||
|
||||
void broadcast_meta(connection_t *from, const char *buffer, int length) {
|
||||
for list_each(connection_t, c, connection_list)
|
||||
if(c != from && c->edge)
|
||||
|
|
@ -159,6 +173,25 @@ bool receive_meta(connection_t *c) {
|
|||
}
|
||||
|
||||
do {
|
||||
/* Are we receiving a SPTPS packet? */
|
||||
|
||||
if(c->sptpslen) {
|
||||
int len = MIN(inlen, c->sptpslen - c->inbuf.len);
|
||||
buffer_add(&c->inbuf, bufp, len);
|
||||
|
||||
char *sptpspacket = buffer_read(&c->inbuf, c->sptpslen);
|
||||
if(!sptpspacket)
|
||||
return true;
|
||||
|
||||
if(!receive_tcppacket_sptps(c, sptpspacket, c->sptpslen))
|
||||
return false;
|
||||
c->sptpslen = 0;
|
||||
|
||||
bufp += len;
|
||||
inlen -= len;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(c->protocol_minor >= 2) {
|
||||
int len = sptps_receive_data(&c->sptps, bufp, inlen);
|
||||
if(!len)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue