2001-10-09 19:30:30 +00:00
|
|
|
/*
|
|
|
|
node.h -- header for node.c
|
2013-01-20 20:03:22 +00:00
|
|
|
Copyright (C) 2001-2013 Guus Sliepen <guus@tinc-vpn.org>,
|
2006-04-26 13:52:58 +00:00
|
|
|
2001-2005 Ivo Timmermans
|
2001-10-09 19:30:30 +00:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
2009-09-24 22:01:00 +00:00
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2001-10-09 19:30:30 +00:00
|
|
|
*/
|
|
|
|
|
2001-10-10 08:49:47 +00:00
|
|
|
#ifndef __TINC_NODE_H__
|
|
|
|
#define __TINC_NODE_H__
|
|
|
|
|
2007-05-18 10:05:26 +00:00
|
|
|
#include "splay_tree.h"
|
2008-12-11 14:44:44 +00:00
|
|
|
#include "cipher.h"
|
2001-10-27 12:13:17 +00:00
|
|
|
#include "connection.h"
|
2008-12-11 14:44:44 +00:00
|
|
|
#include "digest.h"
|
2012-11-29 11:28:23 +00:00
|
|
|
#include "event.h"
|
2003-07-17 15:06:27 +00:00
|
|
|
#include "subnet.h"
|
2001-10-27 12:13:17 +00:00
|
|
|
|
2009-09-08 19:45:24 +00:00
|
|
|
typedef struct node_status_t {
|
2012-10-10 15:17:49 +00:00
|
|
|
unsigned int unused_active:1; /* 1 if active (not used for nodes) */
|
|
|
|
unsigned int validkey:1; /* 1 if we currently have a valid key for him */
|
|
|
|
unsigned int waitingforkey:1; /* 1 if we already sent out a request */
|
|
|
|
unsigned int visited:1; /* 1 if this node has been visited by one of the graph algorithms */
|
|
|
|
unsigned int reachable:1; /* 1 if this node is reachable in the graph */
|
|
|
|
unsigned int indirect:1; /* 1 if this node is not directly reachable by us */
|
2012-07-31 19:43:49 +00:00
|
|
|
unsigned int sptps:1; /* 1 if this node supports SPTPS */
|
2012-10-10 15:17:49 +00:00
|
|
|
unsigned int udp_confirmed:1; /* 1 if the address is one that we received UDP traffic on */
|
2014-06-22 16:27:55 +00:00
|
|
|
unsigned int send_locally:1; /* 1 if the next UDP packet should be sent on the local network */
|
2013-11-21 21:13:14 +00:00
|
|
|
unsigned int unused:23;
|
2001-10-27 12:13:17 +00:00
|
|
|
} node_status_t;
|
|
|
|
|
2001-10-09 19:30:30 +00:00
|
|
|
typedef struct node_t {
|
2012-10-10 15:17:49 +00:00
|
|
|
char *name; /* name of this node */
|
2014-09-21 17:17:02 +00:00
|
|
|
node_id_t id; /* unique node ID (name hash) */
|
2012-10-10 15:17:49 +00:00
|
|
|
uint32_t options; /* options turned on for this node */
|
2001-10-09 19:30:30 +00:00
|
|
|
|
2012-10-10 15:17:49 +00:00
|
|
|
int sock; /* Socket to use for outgoing UDP packets */
|
|
|
|
sockaddr_t address; /* his real (internet) ip to send UDP packets to */
|
|
|
|
char *hostname; /* the hostname of its real ip */
|
2001-10-09 19:30:30 +00:00
|
|
|
|
2003-07-22 20:55:21 +00:00
|
|
|
node_status_t status;
|
2012-09-26 20:20:43 +00:00
|
|
|
time_t last_state_change;
|
2010-01-23 17:48:01 +00:00
|
|
|
time_t last_req_key;
|
2001-10-27 12:13:17 +00:00
|
|
|
|
2013-05-01 15:17:22 +00:00
|
|
|
ecdsa_t *ecdsa; /* His public ECDSA key */
|
2012-07-30 16:36:59 +00:00
|
|
|
sptps_t sptps;
|
2011-07-03 11:17:28 +00:00
|
|
|
|
2014-12-29 21:57:18 +00:00
|
|
|
#ifndef DISABLE_LEGACY
|
2013-05-01 15:17:22 +00:00
|
|
|
cipher_t *incipher; /* Cipher for UDP packets */
|
|
|
|
digest_t *indigest; /* Digest for UDP packets */
|
2002-02-10 21:57:54 +00:00
|
|
|
|
2013-05-01 15:17:22 +00:00
|
|
|
cipher_t *outcipher; /* Cipher for UDP packets */
|
|
|
|
digest_t *outdigest; /* Digest for UDP packets */
|
2014-12-29 21:57:18 +00:00
|
|
|
#endif
|
2002-02-10 21:57:54 +00:00
|
|
|
|
2012-10-10 15:17:49 +00:00
|
|
|
int incompression; /* Compressionlevel, 0 = no compression */
|
|
|
|
int outcompression; /* Compressionlevel, 0 = no compression */
|
2002-02-11 15:59:18 +00:00
|
|
|
|
2008-12-11 18:07:26 +00:00
|
|
|
int distance;
|
2012-10-10 15:17:49 +00:00
|
|
|
struct node_t *nexthop; /* nearest node from us to him */
|
|
|
|
struct edge_t *prevedge; /* nearest node from him to us */
|
|
|
|
struct node_t *via; /* next hop for UDP packets */
|
2001-10-09 19:30:30 +00:00
|
|
|
|
2012-10-10 15:17:49 +00:00
|
|
|
splay_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */
|
2002-09-04 13:48:52 +00:00
|
|
|
|
2012-10-10 15:17:49 +00:00
|
|
|
splay_tree_t *edge_tree; /* Edges with this node as one of the endpoints */
|
2002-02-10 21:57:54 +00:00
|
|
|
|
2012-10-10 15:17:49 +00:00
|
|
|
struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */
|
2002-09-09 21:25:28 +00:00
|
|
|
|
2012-10-10 15:17:49 +00:00
|
|
|
uint32_t sent_seqno; /* Sequence number last sent to this node */
|
|
|
|
uint32_t received_seqno; /* Sequence number last received from this node */
|
2013-01-15 12:33:16 +00:00
|
|
|
uint32_t received; /* Total valid packets received from this node */
|
2013-01-16 15:31:56 +00:00
|
|
|
uint32_t prev_received_seqno;
|
|
|
|
uint32_t prev_received;
|
2012-10-10 15:17:49 +00:00
|
|
|
uint32_t farfuture; /* Packets in a row that have arrived from the far future */
|
|
|
|
unsigned char* late; /* Bitfield marking late packets */
|
2003-12-20 19:47:53 +00:00
|
|
|
|
Add UDP discovery mechanism.
This adds a new mechanism by which tinc can determine if a node is
reachable via UDP. The new mechanism is currently redundant with the
PMTU discovery mechanism - that will be fixed in a future commit.
Conceptually, the UDP discovery mechanism works similarly to PMTU
discovery: it sends UDP probes (of minmtu size, to make sure the tunnel
is fully usable), and assumes UDP is usable if it gets replies. It
assumes UDP is broken if too much time has passed since the last reply.
The big difference with the current PMTU discovery mechanism, however,
is that UDP discovery probes are only triggered as part of the
packet TX path (through try_tx()). This is quite interesting, because
it means tinc will never send UDP pings more often than normal packets,
and most importantly, it will automatically stop sending pings as soon
as packets stop flowing, thereby nicely reducing network chatter.
Of course, there are small drawbacks in some edge cases: for example,
if a node only sends one packet every minute to another node, these
packets will only be sent over TCP, because the interval between packets
is too long for tinc to maintain the UDP tunnel. I consider this a
feature, not a bug: I believe it is appropriate to use TCP in scenarios
where traffic is negligible, so that we don't pollute the network with
pings just to maintain a UDP tunnel that's seeing negligible usage.
2014-12-29 10:34:39 +00:00
|
|
|
struct timeval udp_ping_sent; /* Last time a ping probe was sent */
|
|
|
|
timeout_t udp_ping_timeout; /* Ping timeout event */
|
|
|
|
|
2012-10-10 15:17:49 +00:00
|
|
|
length_t mtu; /* Maximum size of packets to send to this node */
|
|
|
|
length_t minmtu; /* Probed minimum MTU */
|
|
|
|
length_t maxmtu; /* Probed maximum MTU */
|
|
|
|
int mtuprobes; /* Number of probes */
|
Move PMTU discovery code into the TX path.
Currently, the PMTU discovery code is run by a timeout callback,
independently of tunnel activity. This commit moves it into the TX
path, meaning that send_mtu_probe_handler() is only called if a
packet is about to be sent. Consequently, it has been renamed to
try_mtu() for consistency with try_tx(), try_udp() and try_sptps().
Running PMTU discovery code only as part of the TX path prevents
PMTU discovery from generating unreasonable amounts of traffic when
the "real" traffic is negligible. One extreme example is sending one
real packet and then going silent: in the current code this one little
packet will result in the entire PMTU discovery algorithm being run
from start to finish, resulting in absurd write traffic amplification.
With this patch, PMTU discovery stops as soon as "real" packets stop
flowing, and will be no more aggressive than the underlying traffic.
Furthermore, try_mtu() only runs if there is confirmed UDP
connectivity as per the UDP discovery mechanism. This prevents
unnecessary network chatter - previously, the PMTU discovery code
would send bursts of (potentially large) probe packets every second
even if there was nothing on the other side. With this patch, the
PMTU code only does that if something replied to the lightweight UDP
discovery pings.
These inefficiencies were made even worse when the node is not a
direct neighbour, as tinc will use PMTU discovery both on the
destination node *and* the relay. UDP discovery is more lightweight for
this purpose.
As a bonus, this code simplifies overall code somewhat - state is
easier to manage when code is run in predictable contexts as opposed
to "surprise callbacks". In addition, there is no need to call PMTU
discovery code outside of net_packet.c anymore, thereby simplifying
module boundaries.
2014-12-29 16:47:49 +00:00
|
|
|
struct timeval probe_sent_time; /* Time the last probe was sent */
|
2013-01-16 15:31:56 +00:00
|
|
|
struct timeval probe_time; /* Time the last probe was sent or received */
|
|
|
|
int probe_counter; /* Number of probes received since last burst was sent */
|
|
|
|
float rtt; /* Last measured round trip time */
|
|
|
|
float packetloss; /* Last measured packet loss rate */
|
2011-05-14 22:42:29 +00:00
|
|
|
|
|
|
|
uint64_t in_packets;
|
|
|
|
uint64_t in_bytes;
|
|
|
|
uint64_t out_packets;
|
|
|
|
uint64_t out_bytes;
|
2001-10-09 19:30:30 +00:00
|
|
|
} node_t;
|
2001-10-10 08:49:47 +00:00
|
|
|
|
2001-10-27 12:13:17 +00:00
|
|
|
extern struct node_t *myself;
|
2007-05-18 10:05:26 +00:00
|
|
|
extern splay_tree_t *node_tree;
|
2001-10-10 08:49:47 +00:00
|
|
|
|
2001-10-27 12:13:17 +00:00
|
|
|
extern void init_nodes(void);
|
|
|
|
extern void exit_nodes(void);
|
2003-07-30 21:52:41 +00:00
|
|
|
extern node_t *new_node(void) __attribute__ ((__malloc__));
|
2002-02-18 16:25:19 +00:00
|
|
|
extern void free_node(node_t *);
|
|
|
|
extern void node_add(node_t *);
|
|
|
|
extern void node_del(node_t *);
|
2003-07-29 10:50:15 +00:00
|
|
|
extern node_t *lookup_node(char *);
|
2014-09-21 17:17:02 +00:00
|
|
|
extern node_t *lookup_node_id(const node_id_t *);
|
2003-07-24 12:08:16 +00:00
|
|
|
extern node_t *lookup_node_udp(const sockaddr_t *);
|
2009-11-07 22:43:25 +00:00
|
|
|
extern bool dump_nodes(struct connection_t *);
|
2011-05-17 08:58:22 +00:00
|
|
|
extern bool dump_traffic(struct connection_t *);
|
2009-04-02 23:05:23 +00:00
|
|
|
extern void update_node_udp(node_t *, const sockaddr_t *);
|
2001-10-27 12:13:17 +00:00
|
|
|
|
2012-10-10 15:17:49 +00:00
|
|
|
#endif /* __TINC_NODE_H__ */
|