tinc/src/connection.h

120 lines
5 KiB
C
Raw Normal View History

/*
2000-11-20 19:12:17 +00:00
connection.h -- header for connection.c
Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
2000-2005 Ivo Timmermans
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-11-20 19:12:17 +00:00
#ifndef __TINC_CONNECTION_H__
#define __TINC_CONNECTION_H__
#include "buffer.h"
#include "cipher.h"
#include "digest.h"
#include "rsa.h"
#include "list.h"
#include "sptps.h"
2012-10-10 15:17:49 +00:00
#define OPTION_INDIRECT 0x0001
#define OPTION_TCPONLY 0x0002
#define OPTION_PMTU_DISCOVERY 0x0004
#define OPTION_CLAMP_MSS 0x0008
#define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */
typedef struct connection_status_t {
2012-10-10 15:17:49 +00:00
unsigned int pinged:1; /* sent ping */
unsigned int unused_active:1;
2012-10-10 15:17:49 +00:00
unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */
unsigned int unused_termreq:1; /* the termination of this connection was requested */
unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */
unsigned int timeout_unused:1; /* 1 if gotten timeout */
unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */
unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */
unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */
unsigned int control:1; /* 1 if this is a control connection */
unsigned int pcap:1; /* 1 if this is a control connection requesting packet capture */
unsigned int log:1; /* 1 if this is a control connection requesting log dump */
Add an invitation protocol. Using the tinc command, an administrator of an existing VPN can generate invitations for new nodes. The invitation is a small URL that can easily be copy&pasted into email or live chat. Another person can have tinc automatically setup the necessary configuration files and exchange keys with the server, by only using the invitation URL. The invitation protocol uses temporary ECDSA keys. The invitation URL consists of the hostname and port of the server, a hash of the server's temporary ECDSA key and a cookie. When the client wants to accept an invitation, it also creates a temporary ECDSA key, connects to the server and says it wants to accept an invitation. Both sides exchange their temporary keys. The client verifies that the server's key matches the hash in the invitation URL. After setting up an SPTPS connection using the temporary keys, the client gives the cookie to the server. If the cookie is valid, the server sends the client an invitation file containing the client's new name and a copy of the server's host config file. If everything is ok, the client will generate a long-term ECDSA key and send it to the server, which will add it to a new host config file for the client. The invitation protocol currently allows multiple host config files to be send from the server to the client. However, the client filters out most configuration variables for its own host configuration file. In particular, it only accepts Name, Mode, Broadcast, ConnectTo, Subnet and AutoConnect. Also, at the moment no tinc-up script is generated. When an invitation has succesfully been accepted, the client needs to start the tinc daemon manually.
2013-05-29 16:31:10 +00:00
unsigned int invitation:1; /* 1 if this is an invitation */
unsigned int invitation_used:1; /* 1 if the invitation has been consumed */
unsigned int unused:18;
} connection_status_t;
2011-07-07 20:28:25 +00:00
#include "ecdsa.h"
2003-07-22 20:55:21 +00:00
#include "edge.h"
#include "net.h"
#include "node.h"
2000-11-20 19:12:17 +00:00
typedef struct connection_t {
2012-10-10 15:17:49 +00:00
char *name; /* name he claims to have */
char *hostname; /* the hostname of its real ip */
2012-10-10 15:17:49 +00:00
union sockaddr_t address; /* his real (internet) ip */
int protocol_major; /* used protocol */
int protocol_minor; /* used protocol */
int socket; /* socket used for this connection */
uint32_t options; /* options for this connection */
connection_status_t status; /* status info */
int estimated_weight; /* estimation for the weight of the edge for this connection */
struct timeval start; /* time this connection was started, used for above estimation */
struct outgoing_t *outgoing; /* used to keep track of outgoing connections */
struct node_t *node; /* node associated with the other end */
struct edge_t *edge; /* edge associated with this connection */
#ifndef DISABLE_LEGACY
rsa_t *rsa; /* his public RSA key */
cipher_t *incipher; /* Cipher he will use to send data to us */
cipher_t *outcipher; /* Cipher we will use to send data to him */
digest_t *indigest;
digest_t *outdigest;
#endif
ecdsa_t *ecdsa; /* his public ECDSA key */
sptps_t sptps;
2002-09-09 21:25:28 +00:00
int inmaclength;
int outmaclength;
int incompression;
int outcompression;
2012-10-10 15:17:49 +00:00
char *hischallenge; /* The challenge we sent to him */
2002-09-09 21:25:28 +00:00
struct buffer_t inbuf;
struct buffer_t outbuf;
io_t io; /* input/output event on this metadata connection */
2012-10-10 15:17:49 +00:00
int tcplen; /* length of incoming TCPpacket */
Introduce raw TCP SPTPS packet transport. Currently, SPTPS packets are transported over TCP metaconnections using extended REQ_KEY requests, in order for the packets to pass through tinc-1.0 nodes unaltered. Unfortunately, this method presents two significant downsides: - An already encrypted SPTPS packet is decrypted and then encrypted again every time it passes through a node, since it is transported over the SPTPS channels of the metaconnections. This double-encryption is unnecessary and wastes CPU cycles. - More importantly, the only way to transport binary data over standard metaconnection messages such as REQ_KEY is to encode it in base64, which has a 33% encoding overhead. This wastes 25% of the network bandwidth. This commit introduces a new protocol message, SPTPS_PACKET, which can be used to transport SPTPS packets over a TCP metaconnection in an efficient way. The new message is appropriately protected through a minor protocol version increment, and extended REQ_KEY messages are still used with nodes that do not support the new message, as well as for the intial handshake packets, for which efficiency is not a concern. The way SPTPS_PACKET works is very similar to how the traditional PACKET message works: after the SPTPS_PACKET message, the raw binary packet is sent directly over the metaconnection. There is one important difference, however: in the case of SPTPS_PACKET, the packet is sent directly over the TCP stream completely bypassing the SPTPS channel of the metaconnection itself for maximum efficiency. This is secure because the SPTPS packet that is being sent is already encrypted with an end-to-end key.
2015-05-10 18:00:03 +00:00
int sptpslen; /* length of incoming SPTPS packet */
2012-10-10 15:17:49 +00:00
int allow_request; /* defined if there's only one request possible */
2002-09-09 21:25:28 +00:00
struct timeval last_ping_time; /* last time we saw some activity from the other end or pinged them */
2002-09-09 21:25:28 +00:00
2012-10-10 15:17:49 +00:00
splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */
2000-11-20 19:12:17 +00:00
} connection_t;
extern list_t *connection_list;
extern connection_t *everyone;
2000-11-20 19:12:17 +00:00
extern void init_connections(void);
extern void exit_connections(void);
extern connection_t *new_connection(void) __attribute__ ((__malloc__));
extern void free_connection(connection_t *);
extern void connection_add(connection_t *);
extern void connection_del(connection_t *);
extern bool dump_connections(struct connection_t *);
2012-10-10 15:17:49 +00:00
#endif /* __TINC_CONNECTION_H__ */