X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fnet_packet.c;h=8313a54fd0e142c7a9106bd04bd43ddf3b5f661c;hb=1a7a9078c093f77950192c32be009bbe463fe372;hp=f734af299b985475ae80eb92e0b44b7b28d371ea;hpb=fd1cff6df23c3f16a46edaff8a52a7212914b2f0;p=tinc diff --git a/src/net_packet.c b/src/net_packet.c index f734af29..8313a54f 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -288,7 +288,14 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { n->status.udppacket = false; if(!result) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Got bad packet from %s (%s)", n->name, n->hostname); + /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, + so let's restart SPTPS in case that helps. But don't do that too often + to prevent storms, and because that would make life a little too easy + for external attackers trying to DoS us. */ + if(n->last_req_key < now.tv_sec - 10) { + logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode raw TCP packet from %s (%s), restarting SPTPS", n->name, n->hostname); + send_req_key(n); + } return false; } return true; @@ -464,11 +471,17 @@ bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { /* The packet is for us */ - if(!from->status.validkey) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Got SPTPS packet from %s (%s) but we don't have a valid key yet", from->name, from->hostname); + if(!sptps_receive_data(&from->sptps, data, len)) { + /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, + so let's restart SPTPS in case that helps. But don't do that too often + to prevent storms. */ + if(from->last_req_key < now.tv_sec - 10) { + logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode raw TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); + send_req_key(from); + } return true; } - sptps_receive_data(&from->sptps, data, len); + send_mtu_info(myself, from, MTU); return true; } @@ -735,7 +748,7 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ /* Send it via TCP if it is a handshake packet, TCPOnly is in use, this is a relay packet that the other node cannot understand, or this packet is larger than the MTU. */ if(type == SPTPS_HANDSHAKE || tcponly || (!direct && !relay_supported) || (type != PKT_PROBE && (len - SPTPS_DATAGRAM_OVERHEAD) > relay->minmtu)) { - if((from != myself || to->status.validkey) && (to->nexthop->connection->options >> 24) >= 7) { + if(type != SPTPS_HANDSHAKE && (to->nexthop->connection->options >> 24) >= 7) { char buf[len + sizeof to->id + sizeof from->id]; char* buf_ptr = buf; memcpy(buf_ptr, &to->id, sizeof to->id); buf_ptr += sizeof to->id; memcpy(buf_ptr, &from->id, sizeof from->id); buf_ptr += sizeof from->id; @@ -746,9 +759,10 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ char buf[len * 4 / 3 + 5]; b64encode(data, buf, len); - /* If no valid key is known yet, send the packets using ANS_KEY requests, - to ensure we get to learn the reflexive UDP address. */ - if(from == myself && !to->status.validkey) { + /* If this is a handshake packet, use ANS_KEY instead of REQ_KEY, for two reasons: + - We don't want intermediate nodes to switch to UDP to relay these packets; + - ANS_KEY allows us to learn the reflexive UDP address. */ + if(type == SPTPS_HANDSHAKE) { to->incompression = myself->incompression; return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, from->name, to->name, buf, to->incompression); } else {