#define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */
typedef struct connection_status_t {
- unsigned int pinged: 1; /* sent ping */
- unsigned int active: 1; /* 1 if active.. */
- 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 unused_encryptout: 1; /* 1 if we can encrypt outgoing traffic */
- unsigned int unused_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 */
- 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: 19;
+ uint16_t pinged: 1; /* sent ping */
+ uint16_t active: 1; /* 1 if active.. */
+ uint16_t connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */
+ uint16_t mst: 1; /* 1 if this connection is part of a minimum spanning tree */
+ uint16_t control: 1; /* 1 if this is a control connection */
+ uint16_t pcap: 1; /* 1 if this is a control connection requesting packet capture */
+ uint16_t log: 1; /* 1 if this is a control connection requesting log dump */
+ uint16_t invitation: 1; /* 1 if this is an invitation */
+ uint16_t invitation_used: 1; /* 1 if the invitation has been consumed */
} connection_status_t;
#include "ecdsa.h"
typedef struct connection_t {
char *name; /* name he claims to have */
+ struct node_t *node; /* node associated with the other end */
- 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 */
- struct outgoing_t *outgoing; /* used to keep track of outgoing connections */
+ int socket; /* socket used for this connection */
+ union sockaddr_t address; /* his real (internet) ip */
struct meshlink_handle *mesh; /* the mesh this connection belongs to */
- struct node_t *node; /* node associated with the other end */
- struct edge_t *edge; /* edge associated with this connection */
- ecdsa_t *ecdsa; /* his public ECDSA key */
+ // I/O
sptps_t sptps;
- struct submesh_t *submesh; /* his submesh handle if available in invitation file */
-
- int incompression;
- int outcompression;
-
struct buffer_t inbuf;
struct buffer_t outbuf;
io_t io; /* input/output event on this metadata connection */
int tcplen; /* length of incoming TCPpacket */
int allow_request; /* defined if there's only one request possible */
-
time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */
+
+ struct outgoing_t *outgoing; /* used to keep track of outgoing connections */
+
+ struct edge_t *edge; /* edge associated with this connection */
+ struct submesh_t *submesh; /* his submesh handle if available in invitation file */
+
+ // Only used during authentication
+ ecdsa_t *ecdsa; /* his public ECDSA key */
+ int protocol_major; /* used protocol */
+ int protocol_minor; /* used protocol */
+
+ // Unused/deprecated
+ uint32_t options; /* options for this connection */
+ int incompression;
+ int outcompression;
} connection_t;
extern void init_connections(struct meshlink_handle *mesh);
struct node_t *to;
sockaddr_t address;
- uint32_t options; /* options turned on for this edge */
- int weight; /* weight of this edge */
-
struct connection_t *connection; /* connection associated with this edge, if available */
struct edge_t *reverse; /* edge in the opposite direction, if available */
+
+ int weight; /* weight of this edge */
+
+ // Deprecated
+ uint32_t options; /* options turned on for this edge */
} edge_t;
extern void init_edges(struct meshlink_handle *mesh);
}
void signal_trigger(event_loop_t *loop, signal_t *sig) {
-
uint8_t signum = sig->signum;
write(loop->pipefd[1], &signum, 1);
return;
-
}
void signal_add(event_loop_t *loop, signal_t *sig, signal_cb_t cb, void *data, uint8_t signum) {
typedef struct timeval(*idle_cb_t)(event_loop_t *loop, void *data);
typedef struct io_t {
+ struct splay_node_t node;
int fd;
int flags;
io_cb_t cb;
void *data;
- struct splay_node_t node;
} io_t;
typedef struct timeout_t {
+ struct splay_node_t node;
struct timeval tv;
timeout_cb_t cb;
void *data;
- struct splay_node_t node;
} timeout_t;
typedef struct signal_t {
+ struct splay_node_t node;
int signum;
signal_cb_t cb;
void *data;
- struct splay_node_t node;
} signal_t;
struct event_loop_t {
- fd_set readfds;
- fd_set writefds;
+ void *data;
volatile bool running;
- struct timeval now;
bool deletion;
- splay_tree_t ios;
- splay_tree_t timeouts;
- splay_tree_t signals;
+ struct timeval now;
+ splay_tree_t timeouts;
idle_cb_t idle_cb;
void *idle_data;
+ splay_tree_t ios;
+ splay_tree_t signals;
+
+ fd_set readfds;
+ fd_set writefds;
io_t signalio;
int pipefd[2];
-
- void *data;
};
extern void io_add(event_loop_t *loop, io_t *io, io_cb_t cb, void *data, int fd, int flags);
#include <pthread.h>
-#define MAXSOCKETS 8 /* Probably overkill... */
+#define MAXSOCKETS 4 /* Probably overkill... */
static const char meshlink_invitation_label[] = "MeshLink invitation";
static const char meshlink_tcp_label[] = "MeshLink TCP";
/// A handle for an instance of MeshLink.
struct meshlink_handle {
+ // public members
char *name;
void *priv;
- char *appname;
- int32_t devclass;
-
- char *confbase;
- FILE *conffile;
-
- meshlink_receive_cb_t receive_cb;
- meshlink_node_status_cb_t node_status_cb;
+ // private members
+ pthread_mutex_t mesh_mutex;
+ event_loop_t loop;
+ struct node_t *self;
meshlink_log_cb_t log_cb;
meshlink_log_level_t log_level;
- meshlink_channel_accept_cb_t channel_accept_cb;
- meshlink_node_duplicate_cb_t node_duplicate_cb;
- meshlink_connection_try_cb_t connection_try_cb;
-
- pthread_t thread;
- bool threadstarted;
- pthread_mutex_t mesh_mutex;
- event_loop_t loop;
- listen_socket_t listen_socket[MAXSOCKETS];
+ // The most important network-related members come first
int listen_sockets;
+ listen_socket_t listen_socket[MAXSOCKETS];
+
+ meshlink_receive_cb_t receive_cb;
+ meshlink_queue_t outpacketqueue;
signal_t datafromapp;
- struct node_t *self;
+ hash_t *node_udp_cache;
- struct splay_tree_t *edges;
struct splay_tree_t *nodes;
+ struct splay_tree_t *edges;
struct list_t *connections;
struct list_t *outgoings;
struct list_t *submeshes;
- meshlink_queue_t outpacketqueue;
-
+ // Meta-connection-related members
struct splay_tree_t *past_request_tree;
timeout_t past_request_timeout;
timeout_t pingtimer;
timeout_t periodictimer;
- char *myport;
-
- char *proxyhost;
- char *proxyport;
- char *proxyuser;
- char *proxypass;
- proxytype_t proxytype;
+ struct connection_t *everyone;
- bool discovery; // Whether Catta is enabled or not
- bool localdiscovery;
- sockaddr_t localdiscovery_address;
+ // Infrequently used callbacks
+ meshlink_node_status_cb_t node_status_cb;
+ meshlink_channel_accept_cb_t channel_accept_cb;
+ meshlink_node_duplicate_cb_t node_duplicate_cb;
+ meshlink_connection_try_cb_t connection_try_cb;
- bool default_blacklist;
+ // Mesh parameters
+ char *appname;
+ char *myport;
- hash_t *node_udp_cache;
- struct connection_t *everyone;
struct ecdsa *private_key;
struct ecdsa *invitation_key;
- int invitation_timeout;
+ int32_t devclass;
+
+ int invitation_timeout;
int pinginterval; /* seconds between pings */
int pingtimeout; /* seconds to wait for response */
int maxtimeout;
- int sock;
- sptps_t sptps;
- char cookie[18], hash[18];
- char *data;
- size_t thedatalen;
- bool success;
- char line[4096];
- char buffer[4096];
- size_t blen;
+ int netns;
- pthread_t discovery_thread;
+ bool default_blacklist;
+ bool discovery; // Whether Catta is enabled or not
+
+
+ // Configuration
+ char *confbase;
+ FILE *conffile;
+ void *config_key;
+
+ // Thread management
+ pthread_t thread;
+ bool threadstarted;
bool discovery_threadstarted;
+
+ // Catta
+ pthread_t discovery_thread;
struct CattaServer *catta_server;
struct CattaSServiceBrowser *catta_browser;
struct CattaSimplePoll *catta_poll;
char *catta_servicetype;
unsigned int catta_interfaces;
- int netns;
- void *config_key;
+ // State used for meshlink_join()
+ int sock;
+ char cookie[18], hash[18];
+ bool success;
+ sptps_t sptps;
+ char *data;
+ size_t thedatalen;
+ size_t blen;
+ char line[4096];
+ char buffer[4096];
+
+ // Unused variables
+ char *proxyhost;
+ char *proxyport;
+ char *proxyuser;
+ char *proxypass;
+ proxytype_t proxytype;
+ sockaddr_t localdiscovery_address;
+ bool localdiscovery;
};
/// A handle for a MeshLink node.
#define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128)
typedef struct vpn_packet_t {
- unsigned int probe: 1;
- unsigned int tcp: 1;
+ uint16_t probe: 1;
+ int16_t tcp: 1;
uint16_t len; /* the actual number of bytes in the `data' field */
uint8_t data[MAXSIZE];
} vpn_packet_t;
#include "submesh.h"
typedef struct node_status_t {
- 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 */
- unsigned int unused_sptps: 1; /* 1 if this node supports SPTPS */
- unsigned int udp_confirmed: 1; /* 1 if the address is one that we received UDP traffic on */
- unsigned int broadcast: 1; /* 1 if the next UDP packet should be broadcast to the local network */
- unsigned int blacklisted: 1; /* 1 if the node is blacklist so we never want to speak with him anymore */
- unsigned int destroyed: 1; /* 1 if the node is being destroyed, deallocate channels when any callback is triggered */
- unsigned int duplicate: 1; /* 1 if the node is duplicate, ie. multiple nodes using the same Name are online */
- unsigned int dirty: 1; /* 1 if the configuration of the node is dirty and needs to be written out */
- unsigned int unused: 19;
+ uint16_t validkey: 1; /* 1 if we currently have a valid key for him */
+ uint16_t waitingforkey: 1; /* 1 if we already sent out a request */
+ uint16_t visited: 1; /* 1 if this node has been visited by one of the graph algorithms */
+ uint16_t reachable: 1; /* 1 if this node is reachable in the graph */
+ uint16_t indirect: 1; /* 1 if this node is not directly reachable by us */
+ uint16_t udp_confirmed: 1; /* 1 if the address is one that we received UDP traffic on */
+ uint16_t broadcast: 1; /* 1 if the next UDP packet should be broadcast to the local network */
+ uint16_t blacklisted: 1; /* 1 if the node is blacklist so we never want to speak with him anymore */
+ uint16_t destroyed: 1; /* 1 if the node is being destroyed, deallocate channels when any callback is triggered */
+ uint16_t duplicate: 1; /* 1 if the node is duplicate, ie. multiple nodes using the same Name are online */
+ uint16_t dirty: 1; /* 1 if the configuration of the node is dirty and needs to be written out */
} node_status_t;
typedef struct node_t {
+ // Public member variables
char *name; /* name of this node */
void *priv;
- uint32_t options; /* options turned on for this node */
+ // Private member variables
+ node_status_t status;
+ uint16_t minmtu; /* Probed minimum MTU */
int32_t devclass;
- struct meshlink_handle *mesh; /* The mesh this node belongs to */
- struct submesh_t *submesh; /* Nodes Sub-Mesh Handle*/
-
+ // Used for packet I/O
+ sptps_t sptps;
int sock; /* Socket to use for outgoing UDP packets */
sockaddr_t address; /* his real (internet) ip to send UDP packets to */
- node_status_t status;
+ struct utcp *utcp;
+
+ // Traffic counters
+ uint64_t in_packets;
+ uint64_t in_bytes;
+ uint64_t out_packets;
+ uint64_t out_bytes;
+
+ // MTU probes
+ timeout_t mtutimeout; /* Probe event */
+ int mtuprobes; /* Number of probes */
+ uint16_t mtu; /* Maximum size of packets to send to this node */
+ uint16_t maxmtu; /* Probed maximum MTU */
+
+ // Used for meta-connection I/O, timeouts
+ struct meshlink_handle *mesh; /* The mesh this node belongs to */
+ struct submesh_t *submesh; /* Nodes Sub-Mesh Handle*/
+
time_t last_state_change;
time_t last_req_key;
struct ecdsa *ecdsa; /* His public ECDSA key */
- sptps_t sptps;
- int incompression; /* Compressionlevel, 0 = no compression */
- int outcompression; /* Compressionlevel, 0 = no compression */
+ struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */
+ time_t last_connect_try;
+ time_t last_successfull_connection;
+ char *canonical_address; /* The canonical address of this node, if known */
+ sockaddr_t recent[5]; /* Recently seen addresses */
+
+ // Graph-related member variables
int distance;
struct node_t *nexthop; /* nearest node from us to him */
struct edge_t *prevedge; /* nearest node from him to us */
struct splay_tree_t *edge_tree; /* Edges with this node as one of the endpoints */
- struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */
- time_t last_connect_try;
- time_t last_successfull_connection;
-
- uint16_t mtu; /* Maximum size of packets to send to this node */
- uint16_t minmtu; /* Probed minimum MTU */
- uint16_t maxmtu; /* Probed maximum MTU */
- int mtuprobes; /* Number of probes */
- timeout_t mtutimeout; /* Probe event */
-
- struct utcp *utcp;
-
- uint64_t in_packets;
- uint64_t in_bytes;
- uint64_t out_packets;
- uint64_t out_bytes;
-
- char *canonical_address; /* The canonical address of this node, if known */
- sockaddr_t recent[5]; /* Recently seen addresses */
+ // Unused
+ uint32_t options; /* options turned on for this node */
+ int incompression; /* Compressionlevel, 0 = no compression */
+ int outcompression; /* Compressionlevel, 0 = no compression */
} node_t;
extern void init_nodes(struct meshlink_handle *mesh);
typedef bool (*receive_record_t)(void *handle, uint8_t type, const void *data, uint16_t len);
typedef struct sptps {
+ // State
bool initiator;
bool datagram;
+ bool instate;
+ bool outstate;
+
int state;
+ // Main member variables
char *inbuf;
size_t buflen;
- uint16_t reclen;
- bool instate;
chacha_poly1305_ctx_t *incipher;
+ uint32_t replaywin;
uint32_t inseqno;
uint32_t received;
- unsigned int replaywin;
- char *late;
+ uint16_t reclen;
- bool outstate;
chacha_poly1305_ctx_t *outcipher;
uint32_t outseqno;
+ char *late;
+
+ // Callbacks
+ void *handle;
+ send_data_t send_data;
+ receive_record_t receive_record;
+
+ // Variables used for the authentication phase
ecdsa_t *mykey;
ecdsa_t *hiskey;
ecdh_t *ecdh;
char *label;
size_t labellen;
- void *handle;
- send_data_t send_data;
- receive_record_t receive_record;
} sptps_t;
extern unsigned int sptps_replaywin;