Optionally compress and/or strip Ethernet header from SPTPS packets.
This commit is contained in:
parent
73348be58e
commit
8af2f3f5a4
2 changed files with 75 additions and 23 deletions
|
@ -253,7 +253,7 @@ static void receive_packet(node_t *n, vpn_packet_t *packet) {
|
||||||
|
|
||||||
static bool try_mac(node_t *n, const vpn_packet_t *inpkt) {
|
static bool try_mac(node_t *n, const vpn_packet_t *inpkt) {
|
||||||
if(n->status.sptps)
|
if(n->status.sptps)
|
||||||
return sptps_verify_datagram(&n->sptps, (char *)inpkt->data - 4, inpkt->len);
|
return sptps_verify_datagram(&n->sptps, (char *)&inpkt->seqno, inpkt->len);
|
||||||
|
|
||||||
if(!digest_active(&n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest))
|
if(!digest_active(&n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest))
|
||||||
return false;
|
return false;
|
||||||
|
@ -269,7 +269,7 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
|
||||||
size_t outlen;
|
size_t outlen;
|
||||||
|
|
||||||
if(n->status.sptps) {
|
if(n->status.sptps) {
|
||||||
sptps_receive_data(&n->sptps, (char *)inpkt->data - 4, inpkt->len);
|
sptps_receive_data(&n->sptps, (char *)&inpkt->seqno, inpkt->len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,6 +388,42 @@ void receive_tcppacket(connection_t *c, const char *buffer, int len) {
|
||||||
receive_packet(c->node, &outpkt);
|
receive_packet(c->node, &outpkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) {
|
||||||
|
if(n->status.sptps) {
|
||||||
|
uint8_t type = 0;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
if(!(origpkt->data[12] | origpkt->data[13])) {
|
||||||
|
sptps_send_record(&n->sptps, PKT_PROBE, (char *)origpkt->data, origpkt->len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(routing_mode == RMODE_ROUTER)
|
||||||
|
offset = 14;
|
||||||
|
else
|
||||||
|
type = PKT_MAC;
|
||||||
|
|
||||||
|
if(origpkt->len < offset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vpn_packet_t outpkt;
|
||||||
|
|
||||||
|
if(n->outcompression) {
|
||||||
|
int len = compress_packet(outpkt.data + offset, origpkt->data + offset, origpkt->len - offset, n->outcompression);
|
||||||
|
if(len < 0) {
|
||||||
|
logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname);
|
||||||
|
} else if(len < origpkt->len - offset) {
|
||||||
|
outpkt.len = len + offset;
|
||||||
|
origpkt = &outpkt;
|
||||||
|
type |= PKT_COMPRESSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sptps_send_record(&n->sptps, type, (char *)origpkt->data + offset, origpkt->len - offset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
||||||
vpn_packet_t pkt1, pkt2;
|
vpn_packet_t pkt1, pkt2;
|
||||||
vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
|
vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
|
||||||
|
@ -406,6 +442,9 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(n->status.sptps)
|
||||||
|
return send_sptps_packet(n, origpkt);
|
||||||
|
|
||||||
/* Make sure we have a valid key */
|
/* Make sure we have a valid key */
|
||||||
|
|
||||||
if(!n->status.validkey) {
|
if(!n->status.validkey) {
|
||||||
|
@ -438,14 +477,6 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n->status.sptps) {
|
|
||||||
uint8_t type = 0;
|
|
||||||
if(!(inpkt->data[12] | inpkt->data[13]))
|
|
||||||
type = PKT_PROBE;
|
|
||||||
sptps_send_record(&n->sptps, type, (char *)inpkt->data, inpkt->len);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compress the packet */
|
/* Compress the packet */
|
||||||
|
|
||||||
if(n->outcompression) {
|
if(n->outcompression) {
|
||||||
|
@ -550,11 +581,11 @@ end:
|
||||||
bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) {
|
bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) {
|
||||||
node_t *to = handle;
|
node_t *to = handle;
|
||||||
|
|
||||||
if(type >= SPTPS_HANDSHAKE) {
|
if(type >= SPTPS_HANDSHAKE || ((myself->options | to->options) & OPTION_TCPONLY)) {
|
||||||
char buf[len * 4 / 3 + 5];
|
char buf[len * 4 / 3 + 5];
|
||||||
b64encode(data, buf, len);
|
b64encode(data, buf, len);
|
||||||
if(!to->status.validkey)
|
if(!to->status.validkey)
|
||||||
return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 -1", ANS_KEY, myself->name, to->name, buf);
|
return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, myself->name, to->name, buf, myself->incompression);
|
||||||
else
|
else
|
||||||
return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_SPTPS, buf);
|
return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_SPTPS, buf);
|
||||||
}
|
}
|
||||||
|
@ -599,19 +630,34 @@ bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t
|
||||||
}
|
}
|
||||||
|
|
||||||
vpn_packet_t inpkt;
|
vpn_packet_t inpkt;
|
||||||
inpkt.len = len;
|
|
||||||
memcpy(inpkt.data, data, len);
|
|
||||||
|
|
||||||
if(type == PKT_PROBE) {
|
if(type == PKT_PROBE) {
|
||||||
|
inpkt.len = len;
|
||||||
|
memcpy(inpkt.data, data, len);
|
||||||
mtu_probe_h(from, &inpkt, len);
|
mtu_probe_h(from, &inpkt, len);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
if(type != 0) {
|
|
||||||
|
if(type & ~(PKT_COMPRESSED | PKT_MAC)) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname);
|
logger(DEBUG_ALWAYS, LOG_ERR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int offset = (type & PKT_MAC) ? 0 : 14;
|
||||||
|
if(type & PKT_COMPRESSED) {
|
||||||
|
len = uncompress_packet(inpkt.data + offset, (const uint8_t *)data, len, from->incompression);
|
||||||
|
if(len < 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
inpkt.len = len + offset;
|
||||||
|
}
|
||||||
|
if(inpkt.len > MAXSIZE)
|
||||||
|
abort();
|
||||||
|
} else {
|
||||||
|
memcpy(inpkt.data + offset, data, len);
|
||||||
|
inpkt.len = len + offset;
|
||||||
|
}
|
||||||
|
|
||||||
receive_packet(from, &inpkt);
|
receive_packet(from, &inpkt);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -643,6 +689,11 @@ void send_packet(node_t *n, vpn_packet_t *packet) {
|
||||||
n->out_packets++;
|
n->out_packets++;
|
||||||
n->out_bytes += packet->len;
|
n->out_bytes += packet->len;
|
||||||
|
|
||||||
|
if(n->status.sptps) {
|
||||||
|
send_sptps_packet(n, packet);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via;
|
via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via;
|
||||||
|
|
||||||
if(via != n)
|
if(via != n)
|
||||||
|
|
|
@ -116,6 +116,7 @@ bool send_req_key(node_t *to) {
|
||||||
snprintf(label, sizeof label, "tinc UDP key expansion %s %s", myself->name, to->name);
|
snprintf(label, sizeof label, "tinc UDP key expansion %s %s", myself->name, to->name);
|
||||||
sptps_stop(&to->sptps);
|
sptps_stop(&to->sptps);
|
||||||
to->status.validkey = false;
|
to->status.validkey = false;
|
||||||
|
to->incompression = myself->incompression;
|
||||||
return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof label, send_initial_sptps_data, receive_sptps_record);
|
return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof label, send_initial_sptps_data, receive_sptps_record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +334,13 @@ bool ans_key_h(connection_t *c, const char *request) {
|
||||||
return send_request(to->nexthop->connection, "%s", request);
|
return send_request(to->nexthop->connection, "%s", request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(compression < 0 || compression > 11) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
from->outcompression = compression;
|
||||||
|
|
||||||
/* SPTPS or old-style key exchange? */
|
/* SPTPS or old-style key exchange? */
|
||||||
|
|
||||||
if(from->status.sptps) {
|
if(from->status.sptps) {
|
||||||
|
@ -373,13 +381,6 @@ bool ans_key_h(connection_t *c, const char *request) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(compression < 0 || compression > 11) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
from->outcompression = compression;
|
|
||||||
|
|
||||||
/* Process key */
|
/* Process key */
|
||||||
|
|
||||||
keylen = hex2bin(key, key, sizeof key);
|
keylen = hex2bin(key, key, sizeof key);
|
||||||
|
|
Loading…
Reference in a new issue