Try to clarify the new code in net_packet.c a bit.
Mainly by trying to reduce complex if statements, by splitting try_tx() into try_tx_legacy() and try_tx_sptps(), since they don't share a lot of code.
This commit is contained in:
parent
6056f1c13b
commit
0e65326047
1 changed files with 78 additions and 51 deletions
129
src/net_packet.c
129
src/net_packet.c
|
@ -948,9 +948,12 @@ static length_t choose_initial_maxmtu(node_t *n) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function tries to determines the MTU of a node.
|
/* This function tries to determines the MTU of a node.
|
||||||
// By calling this function repeatedly, n->minmtu will be progressively increased, and at some point, n->mtu will be fixed to n->minmtu.
|
By calling this function repeatedly, n->minmtu will be progressively
|
||||||
// If the MTU is already fixed, this function checks if it can be increased.
|
increased, and at some point, n->mtu will be fixed to n->minmtu. If the MTU
|
||||||
|
is already fixed, this function checks if it can be increased.
|
||||||
|
*/
|
||||||
|
|
||||||
static void try_mtu(node_t *n) {
|
static void try_mtu(node_t *n) {
|
||||||
if(!(n->options & OPTION_PMTU_DISCOVERY))
|
if(!(n->options & OPTION_PMTU_DISCOVERY))
|
||||||
return;
|
return;
|
||||||
|
@ -1046,44 +1049,65 @@ static void try_mtu(node_t *n) {
|
||||||
n->prev_received = n->received;
|
n->prev_received = n->received;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function tries to establish a tunnel to a node (or its relay) so that packets can be sent (e.g. get SPTPS keys).
|
/* These functions try to establish a tunnel to a node (or its relay) so that
|
||||||
// If a tunnel is already established, it tries to improve it (e.g. by trying to establish a UDP tunnel instead of TCP).
|
packets can be sent (e.g. exchange keys).
|
||||||
// This function makes no guarantees - it is up to the caller to check the node's state to figure out if TCP and/or UDP is usable.
|
If a tunnel is already established, it tries to improve it (e.g. by trying
|
||||||
// By calling this function repeatedly, the tunnel is gradually improved until we hit the wall imposed by the underlying network environment.
|
to establish a UDP tunnel instead of TCP). This function makes no
|
||||||
// It is recommended to call this function every time a packet is sent (or intended to be sent) to a node,
|
guarantees - it is up to the caller to check the node's state to figure out
|
||||||
// so that the tunnel keeps improving as packets flow, and then gracefully downgrades itself as it goes idle.
|
if TCP and/or UDP is usable. By calling this function repeatedly, the
|
||||||
static void try_tx(node_t *n) {
|
tunnel is gradually improved until we hit the wall imposed by the underlying
|
||||||
/* If n is a TCP-only neighbor, we'll only use "cleartext" PACKET
|
network environment. It is recommended to call this function every time a
|
||||||
messages anyway, so there's no need for SPTPS at all. Otherwise, get the keys. */
|
packet is sent (or intended to be sent) to a node, so that the tunnel keeps
|
||||||
if(n->status.sptps && !(n->connection && ((myself->options | n->options) & OPTION_TCPONLY))) {
|
improving as packets flow, and then gracefully downgrades itself as it goes
|
||||||
try_sptps(n);
|
idle.
|
||||||
if (!n->status.validkey)
|
*/
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
node_t *via = (n->via == myself) ? n->nexthop : n->via;
|
static void try_tx_sptps(node_t *n) {
|
||||||
|
/* If n is a TCP-only neighbor, we'll only use "cleartext" PACKET
|
||||||
if((myself->options | via->options) & OPTION_TCPONLY)
|
messages anyway, so there's no need for SPTPS at all. */
|
||||||
|
|
||||||
|
if(n->connection && ((myself->options | n->options) & OPTION_TCPONLY))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!n->status.sptps && !via->status.validkey && via->last_req_key + 10 <= now.tv_sec) {
|
/* Otherwise, try to do SPTPS authentication with n if necessary. */
|
||||||
send_req_key(via);
|
|
||||||
via->last_req_key = now.tv_sec;
|
|
||||||
} else if(via == n || !n->status.sptps || (via->options >> 24) >= 4) {
|
|
||||||
try_udp(via);
|
|
||||||
try_mtu(via);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we don't know how to reach "via" yet, then try to reach it through a relay. */
|
try_sptps(n);
|
||||||
if(n->status.sptps && !via->status.udp_confirmed && via->nexthop != via && (via->nexthop->options >> 24) >= 4)
|
|
||||||
try_tx(via->nexthop);
|
/* Do we need to relay packets? */
|
||||||
|
|
||||||
|
node_t *via = (n->via == myself) ? n->nexthop : n->via;
|
||||||
|
|
||||||
|
/* If the relay doesn't support SPTPS, everything goes via TCP anyway. */
|
||||||
|
|
||||||
|
if((via->options >> 24) < 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If we do have a relay, try everything with that one instead. */
|
||||||
|
|
||||||
|
if(via != n)
|
||||||
|
return try_tx_sptps(via);
|
||||||
|
|
||||||
|
try_udp(n);
|
||||||
|
try_mtu(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void try_tx_legacy(node_t *n) {
|
||||||
|
/* Check if we already have a key, or request one. */
|
||||||
|
|
||||||
|
if(!n->status.validkey) {
|
||||||
|
if(n->last_req_key + 10 <= now.tv_sec) {
|
||||||
|
send_req_key(n);
|
||||||
|
n->last_req_key = now.tv_sec;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try_udp(n);
|
||||||
|
try_mtu(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
send a packet to the given vpn ip.
|
|
||||||
*/
|
|
||||||
void send_packet(node_t *n, vpn_packet_t *packet) {
|
void send_packet(node_t *n, vpn_packet_t *packet) {
|
||||||
node_t *via;
|
// If it's for myself, write it to the tun/tap device.
|
||||||
|
|
||||||
if(n == myself) {
|
if(n == myself) {
|
||||||
if(overwrite_mac)
|
if(overwrite_mac)
|
||||||
|
@ -1094,44 +1118,47 @@ void send_packet(node_t *n, vpn_packet_t *packet) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger(DEBUG_TRAFFIC, LOG_ERR, "Sending packet of %d bytes to %s (%s)",
|
logger(DEBUG_TRAFFIC, LOG_ERR, "Sending packet of %d bytes to %s (%s)", packet->len, n->name, n->hostname);
|
||||||
packet->len, n->name, n->hostname);
|
|
||||||
|
// If the node is not reachable, drop it.
|
||||||
|
|
||||||
if(!n->status.reachable) {
|
if(!n->status.reachable) {
|
||||||
logger(DEBUG_TRAFFIC, LOG_INFO, "Node %s (%s) is not reachable",
|
logger(DEBUG_TRAFFIC, LOG_INFO, "Node %s (%s) is not reachable", n->name, n->hostname);
|
||||||
n->name, n->hostname);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep track of packet statistics.
|
||||||
|
|
||||||
n->out_packets++;
|
n->out_packets++;
|
||||||
n->out_bytes += packet->len;
|
n->out_bytes += packet->len;
|
||||||
|
|
||||||
|
// Check if it should be sent as an SPTPS packet.
|
||||||
|
|
||||||
if(n->status.sptps) {
|
if(n->status.sptps) {
|
||||||
send_sptps_packet(n, packet);
|
send_sptps_packet(n, packet);
|
||||||
goto end;
|
try_tx_sptps(n);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via;
|
// Determine which node to actually send it to.
|
||||||
|
|
||||||
|
node_t *via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via;
|
||||||
|
|
||||||
if(via != n)
|
if(via != n)
|
||||||
logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet to %s via %s (%s)",
|
logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet to %s via %s (%s)", n->name, via->name, n->via->hostname);
|
||||||
n->name, via->name, n->via->hostname);
|
|
||||||
|
// Try to send via UDP, unless TCP is forced.
|
||||||
|
|
||||||
if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) {
|
if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) {
|
||||||
if(!send_tcppacket(via->connection, packet))
|
if(!send_tcppacket(via->connection, packet))
|
||||||
terminate_connection(via->connection, true);
|
terminate_connection(via->connection, true);
|
||||||
} else
|
return;
|
||||||
send_udppacket(via, packet);
|
}
|
||||||
|
|
||||||
end:
|
send_udppacket(via, packet);
|
||||||
/* Try to improve the tunnel.
|
try_tx_legacy(via);
|
||||||
Note that we do this *after* we send the packet because sending actual packets take priority
|
|
||||||
with regard to the send buffer space and latency. */
|
|
||||||
try_tx(n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Broadcast a packet using the minimum spanning tree */
|
|
||||||
|
|
||||||
void broadcast_packet(const node_t *from, vpn_packet_t *packet) {
|
void broadcast_packet(const node_t *from, vpn_packet_t *packet) {
|
||||||
// Always give ourself a copy of the packet.
|
// Always give ourself a copy of the packet.
|
||||||
if(from != myself)
|
if(from != myself)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue