tinc/src/net.h

220 lines
6.3 KiB
C
Raw Normal View History

2000-03-26 00:33:07 +00:00
/*
net.h -- header for net.c
2009-09-24 21:42:30 +00:00
Copyright (C) 1998-2005 Ivo Timmermans
2014-02-07 19:38:48 +00:00
2000-2014 Guus Sliepen <guus@tinc-vpn.org>
2000-03-26 00:33:07 +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.
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.
2000-03-26 00:33:07 +00:00
*/
#ifndef __TINC_NET_H__
#define __TINC_NET_H__
2003-07-18 12:16:24 +00:00
#include "ipv6.h"
#include "cipher.h"
#include "digest.h"
#include "event.h"
2003-07-18 12:16:24 +00:00
#ifdef ENABLE_JUMBOGRAMS
2012-10-10 15:17:49 +00:00
#define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */
#else
2012-10-10 15:17:49 +00:00
#define MTU 1518 /* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */
#endif
2000-03-26 00:33:07 +00:00
Add UDP datagram relay support to SPTPS. This commit changes the layout of UDP datagrams to include a 6-byte destination node ID at the very beginning of the datagram (i.e. before the source node ID and the seqno). Note that this only applies to SPTPS. Thanks to this new field, it is now possible to send SPTPS datagrams to nodes that are not the final recipient of the packets, thereby using these nodes as relay nodes. Previously SPTPS was unable to relay packets using UDP, and required a fallback to TCP if the final recipient could not be contacted directly using UDP. In that sense it fixes a regression that SPTPS introduced with regard to the legacy protocol. This change also updates tinc's low-level routing logic (i.e. send_sptps_data()) to automatically use this relaying facility if at all possible. Specifically, it will relay packets if we don't have a confirmed UDP link to the final recipient (but we have one with the next hop node), or if IndirectData is specified. This is similar to how the legacy protocol forwards packets. When sending packets directly without any relaying, the sender node uses a special value for the destination node ID: instead of setting the field to the ID of the recipient node, it writes a zero ID instead. This allows the recipient node to distinguish between a relayed packet and a direct packet, which is important when determining the UDP address of the sending node. On the relay side, relay nodes will happily relay packets that have a destination ID which is non-zero *and* is different from their own, provided that the source IP address of the packet is known. This is to prevent abuse by random strangers, since a node can't authenticate the packets that are being relayed through it. This change keeps the protocol number from the previous datagram format change (source IDs), 17.4. Compatibility is still preserved with 1.0 and with pre-1.1 releases. Note, however, that nodes running this code won't understand datagrams sent from nodes that only use source IDs and vice-versa (not that we really care). There is one caveat: in the current state, there is no way for the original sender to know what the PMTU is beyond the first hop, and contrary to the legacy protocol, relay nodes can't apply MSS clamping because they can't decrypt the relayed packets. This leads to inefficient scenarios where a reduced PMTU over some link that's part of the relay path will result in relays falling back to TCP to send packets to their final destinations. Another caveat is that once a packet gets sent over TCP, it will use TCP over the entire path, even if it is technically possible to use UDP beyond the TCP-only link(s). Arguably, these two caveats can be fixed by improving the metaconnection protocol, but that's out of scope for this change. TODOs are added instead. In any case, this is no worse than before. In addition, this change increases SPTPS datagram overhead by another 6 bytes for the destination ID, on top of the existing 6-byte overhead from the source ID.
2014-09-28 11:38:06 +00:00
/* MAXSIZE is the maximum size of an encapsulated packet: MTU + seqno + srcid + dstid + padding + HMAC + compressor overhead */
#define MAXSIZE (MTU + 4 + sizeof(node_id_t) + sizeof(node_id_t) + CIPHER_MAX_BLOCK_SIZE + DIGEST_MAX_SIZE + MTU/64 + 20)
2012-10-10 15:17:49 +00:00
/* MAXBUFSIZE is the maximum size of a request: enough for a MAXSIZEd packet or a 8192 bits RSA key */
#define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128)
#define MAXSOCKETS 8 /* Probably overkill... */
2002-09-09 21:25:28 +00:00
typedef struct mac_t {
uint8_t x[6];
} mac_t;
2002-09-09 21:25:28 +00:00
typedef struct ipv4_t {
uint8_t x[4];
} ipv4_t;
2002-02-10 21:57:54 +00:00
2002-09-09 21:25:28 +00:00
typedef struct ipv6_t {
uint16_t x[8];
2002-02-10 21:57:54 +00:00
} ipv6_t;
typedef struct node_id_t {
uint8_t x[6];
} node_id_t;
typedef short length_t;
#define AF_UNKNOWN 255
struct sockaddr_unknown {
uint16_t family;
uint16_t pad1;
uint32_t pad2;
char *address;
char *port;
};
2003-07-22 20:55:21 +00:00
typedef union sockaddr_t {
2002-09-09 21:25:28 +00:00
struct sockaddr sa;
struct sockaddr_in in;
struct sockaddr_in6 in6;
struct sockaddr_unknown unknown;
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
struct sockaddr_storage storage;
#endif
} sockaddr_t;
2002-02-26 22:47:51 +00:00
#ifdef SA_LEN
#define SALEN(s) SA_LEN(&s)
#else
2002-02-26 22:47:51 +00:00
#define SALEN(s) (s.sa_family==AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6))
#endif
2000-03-26 00:33:07 +00:00
typedef struct vpn_packet_t {
2012-10-10 15:17:49 +00:00
length_t len; /* the actual number of bytes in the `data' field */
int priority; /* priority or TOS */
uint32_t seqno; /* 32 bits sequence number (network byte order of course) */
2002-09-09 21:25:28 +00:00
uint8_t data[MAXSIZE];
2000-03-26 00:33:07 +00:00
} vpn_packet_t;
typedef struct sptps_packet_t {
length_t len; /* the actual number of bytes in the `data' field */
int priority; /* priority or TOS */
node_id_t dstid; /* node ID of the final recipient */
node_id_t srcid; /* node ID of the original sender */
char data[MAXSIZE];
} sptps_packet_t;
/* Packet types when using SPTPS */
#define PKT_COMPRESSED 1
#define PKT_MAC 2
#define PKT_PROBE 4
typedef enum packet_type_t {
PACKET_NORMAL,
PACKET_COMPRESSED,
PACKET_PROBE
} packet_type_t;
2003-07-22 20:55:21 +00:00
typedef struct listen_socket_t {
io_t tcp;
io_t udp;
2003-07-22 20:55:21 +00:00
sockaddr_t sa;
bool bindto;
2003-07-22 20:55:21 +00:00
} listen_socket_t;
#include "conf.h"
#include "list.h"
2002-02-10 21:57:54 +00:00
typedef struct outgoing_t {
2002-09-09 21:25:28 +00:00
char *name;
int timeout;
splay_tree_t *config_tree;
2002-09-09 21:25:28 +00:00
struct config_t *cfg;
struct addrinfo *ai;
struct addrinfo *aip;
timeout_t ev;
2002-02-10 21:57:54 +00:00
} outgoing_t;
extern list_t *outgoing_list;
extern int maxoutbufsize;
extern int seconds_till_retry;
extern int addressfamily;
extern unsigned replaywin;
extern bool localdiscovery;
extern listen_socket_t listen_socket[MAXSOCKETS];
extern int listen_sockets;
extern io_t unix_socket;
extern int keylifetime;
extern int udp_rcvbuf;
extern int udp_sndbuf;
extern int max_connection_burst;
2003-07-22 20:55:21 +00:00
extern bool do_prune;
extern char *myport;
extern bool device_standby;
extern bool autoconnect;
extern bool disablebuggypeers;
extern int contradicting_add_edge;
extern int contradicting_del_edge;
extern time_t last_config_check;
extern char *proxyhost;
extern char *proxyport;
extern char *proxyuser;
extern char *proxypass;
typedef enum proxytype_t {
PROXY_NONE = 0,
PROXY_SOCKS4,
PROXY_SOCKS4A,
PROXY_SOCKS5,
PROXY_HTTP,
PROXY_EXEC,
} proxytype_t;
extern proxytype_t proxytype;
2012-10-07 15:53:23 +00:00
extern char *scriptinterpreter;
extern char *scriptextension;
/* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */
#include "connection.h"
#include "node.h"
extern void retry_outgoing(outgoing_t *);
extern void handle_incoming_vpn_data(void *, int);
extern void finish_connecting(struct connection_t *);
extern bool do_outgoing_connection(struct outgoing_t *);
extern void handle_new_meta_connection(void *, int);
extern void handle_new_unix_connection(void *, int);
extern int setup_listen_socket(const sockaddr_t *);
extern int setup_vpn_in_socket(const sockaddr_t *);
extern bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len);
extern bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t len);
2011-05-14 22:42:29 +00:00
extern void send_packet(struct node_t *, vpn_packet_t *);
extern void receive_tcppacket(struct connection_t *, const char *, int);
extern void broadcast_packet(const struct node_t *, vpn_packet_t *);
extern char *get_name(void);
extern void device_enable(void);
extern void device_disable(void);
extern bool setup_myself_reloadable(void);
extern bool setup_network(void);
2002-02-10 21:57:54 +00:00
extern void setup_outgoing_connection(struct outgoing_t *);
extern void try_outgoing_connections(void);
2000-03-26 00:33:07 +00:00
extern void close_network_connections(void);
extern int main_loop(void);
2003-07-22 20:55:21 +00:00
extern void terminate_connection(struct connection_t *, bool);
extern bool node_read_ecdsa_public_key(struct node_t *);
2011-07-07 20:28:25 +00:00
extern bool read_ecdsa_public_key(struct connection_t *);
2003-07-22 20:55:21 +00:00
extern bool read_rsa_public_key(struct connection_t *);
extern void send_mtu_probe(struct node_t *);
extern void handle_device_data(void *, int);
extern void handle_meta_connection_data(struct connection_t *);
extern void regenerate_key(void);
2007-11-07 02:49:57 +00:00
extern void purge(void);
extern void retry(void);
extern int reload_configuration(void);
extern void load_all_subnets(void);
extern void load_all_nodes(void);
2003-07-29 22:59:01 +00:00
#ifndef HAVE_MINGW
#define closesocket(s) close(s)
#endif
2012-10-10 15:17:49 +00:00
#endif /* __TINC_NET_H__ */