From a1b50920b9a52f86ca6e33fcb24d7fa34313a1ee Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 26 Apr 2014 17:06:42 +0200 Subject: [PATCH] Stop using the global variable mesh in most of the rest of the code. --- src/connection.c | 13 +++++---- src/connection.h | 9 +++--- src/edge.c | 8 +++--- src/edge.h | 8 +++--- src/graph.c | 20 ++++++------- src/graph.h | 2 +- src/logger.c | 5 ++-- src/meshlink.c | 12 ++------ src/meshlink_internal.h | 6 ---- src/meta.c | 16 ++++++----- src/meta.h | 6 ++-- src/net.c | 16 +++++------ src/net_packet.c | 18 ++++++------ src/net_setup.c | 24 ++++++++-------- src/net_socket.c | 10 +++---- src/node.c | 22 ++++++++------ src/node.h | 16 ++++++----- src/protocol.c | 26 +++++++++-------- src/protocol.h | 64 ++++++++++++++++++++--------------------- src/protocol_auth.c | 47 +++++++++++++++--------------- src/protocol_edge.c | 54 +++++++++++++++++----------------- src/protocol_key.c | 51 ++++++++++++++++---------------- src/protocol_misc.c | 40 +++++++++++++------------- src/route.c | 20 ++----------- src/route.h | 2 +- 25 files changed, 252 insertions(+), 263 deletions(-) diff --git a/src/connection.c b/src/connection.c index 0a7662db..05a9d653 100644 --- a/src/connection.c +++ b/src/connection.c @@ -28,14 +28,14 @@ #include "utils.h" #include "xalloc.h" -void init_connections(void) { +void init_connections(meshlink_handle_t *mesh) { mesh->connections = list_alloc((list_action_t) free_connection); mesh->everyone = new_connection(); mesh->everyone->name = xstrdup("mesh->everyone"); mesh->everyone->hostname = xstrdup("BROADCAST"); } -void exit_connections(void) { +void exit_connections(meshlink_handle_t *mesh) { list_delete_list(mesh->connections); free_connection(mesh->everyone); } @@ -54,7 +54,8 @@ void free_connection(connection_t *c) { buffer_clear(&c->inbuf); buffer_clear(&c->outbuf); - io_del(&mesh->loop, &c->io); + if(c->io.cb) + abort(); if(c->socket > 0) closesocket(c->socket); @@ -68,10 +69,12 @@ void free_connection(connection_t *c) { free(c); } -void connection_add(connection_t *c) { +void connection_add(meshlink_handle_t *mesh, connection_t *c) { + c->mesh = mesh; list_insert_tail(mesh->connections, c); } -void connection_del(connection_t *c) { +void connection_del(meshlink_handle_t *mesh, connection_t *c) { + io_del(&mesh->loop, &c->io); list_delete(mesh->connections, c); } diff --git a/src/connection.h b/src/connection.h index d4169bcc..443930b5 100644 --- a/src/connection.h +++ b/src/connection.h @@ -68,6 +68,7 @@ typedef struct connection_t { struct timeval start; /* time this connection was started, used for above estimation */ struct outgoing_t *outgoing; /* used to keep track of outgoing connections */ + 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 */ @@ -88,11 +89,11 @@ typedef struct connection_t { splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */ } connection_t; -extern void init_connections(void); -extern void exit_connections(void); +extern void init_connections(struct meshlink_handle *mesh); +extern void exit_connections(struct meshlink_handle *mesh); 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 void connection_add(struct meshlink_handle *mesh, connection_t *); +extern void connection_del(struct meshlink_handle *mesh, connection_t *); #endif /* __TINC_CONNECTION_H__ */ diff --git a/src/edge.c b/src/edge.c index d3dbf78e..455b2301 100644 --- a/src/edge.c +++ b/src/edge.c @@ -48,7 +48,7 @@ static int edge_weight_compare(const edge_t *a, const edge_t *b) { return strcmp(a->to->name, b->to->name); } -void init_edges(void) { +void init_edges(meshlink_handle_t *mesh) { mesh->edges = splay_alloc_tree((splay_compare_t) edge_weight_compare, NULL); } @@ -60,7 +60,7 @@ void free_edge_tree(splay_tree_t *edge_tree) { splay_delete_tree(edge_tree); } -void exit_edges(void) { +void exit_edges(meshlink_handle_t *mesh) { splay_delete_tree(mesh->edges); } @@ -76,7 +76,7 @@ void free_edge(edge_t *e) { free(e); } -void edge_add(edge_t *e) { +void edge_add(meshlink_handle_t *mesh, edge_t *e) { splay_insert(mesh->edges, e); splay_insert(e->from->edge_tree, e); @@ -86,7 +86,7 @@ void edge_add(edge_t *e) { e->reverse->reverse = e; } -void edge_del(edge_t *e) { +void edge_del(meshlink_handle_t *mesh, edge_t *e) { if(e->reverse) e->reverse->reverse = NULL; diff --git a/src/edge.h b/src/edge.h index 75d4f94e..1e1801e5 100644 --- a/src/edge.h +++ b/src/edge.h @@ -37,14 +37,14 @@ typedef struct edge_t { struct edge_t *reverse; /* edge in the opposite direction, if available */ } edge_t; -extern void init_edges(void); -extern void exit_edges(void); +extern void init_edges(struct meshlink_handle *mesh); +extern void exit_edges(struct meshlink_handle *mesh); extern edge_t *new_edge(void) __attribute__ ((__malloc__)); extern void free_edge(edge_t *); extern struct splay_tree_t *new_edge_tree(void) __attribute__ ((__malloc__)); extern void free_edge_tree(struct splay_tree_t *); -extern void edge_add(edge_t *); -extern void edge_del(edge_t *); +extern void edge_add(struct meshlink_handle *mesh, edge_t *); +extern void edge_del(struct meshlink_handle *mesh, edge_t *); extern edge_t *lookup_edge(struct node_t *, struct node_t *); #endif /* __TINC_EDGE_H__ */ diff --git a/src/graph.c b/src/graph.c index ef152a06..3cf45893 100644 --- a/src/graph.c +++ b/src/graph.c @@ -61,7 +61,7 @@ Please note that sorting on weight is already done by add_edge(). */ -static void mst_kruskal(void) { +static void mst_kruskal(meshlink_handle_t *mesh) { /* Clear MST status on connections */ for list_each(connection_t, c, mesh->connections) @@ -115,7 +115,7 @@ static void mst_kruskal(void) { Running time: O(E) */ -static void sssp_bfs(void) { +static void sssp_bfs(meshlink_handle_t *mesh) { list_t *todo_list = list_alloc(NULL); /* Clear visited status on nodes */ @@ -181,7 +181,7 @@ static void sssp_bfs(void) { e->to->distance = n->distance + 1; if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)) - update_node_udp(e->to, &e->address); + update_node_udp(mesh, e->to, &e->address); list_insert_tail(todo_list, e->to); } @@ -193,7 +193,7 @@ static void sssp_bfs(void) { list_free(todo_list); } -static void check_reachability(void) { +static void check_reachability(meshlink_handle_t *mesh) { /* Check reachability status. */ for splay_each(node_t, n, mesh->nodes) { @@ -226,19 +226,19 @@ static void check_reachability(void) { //TODO: callback to application to inform of this node going up/down if(!n->status.reachable) { - update_node_udp(n, NULL); + update_node_udp(mesh, n, NULL); memset(&n->status, 0, sizeof n->status); n->options = 0; } else if(n->connection) { if(n->connection->outgoing) - send_req_key(n); + send_req_key(mesh, n); } } } } -void graph(void) { - sssp_bfs(); - check_reachability(); - mst_kruskal(); +void graph(meshlink_handle_t *mesh) { + sssp_bfs(mesh); + check_reachability(mesh); + mst_kruskal(mesh); } diff --git a/src/graph.h b/src/graph.h index 23fae8d2..e1bae597 100644 --- a/src/graph.h +++ b/src/graph.h @@ -20,6 +20,6 @@ #ifndef __TINC_GRAPH_H__ #define __TINC_GRAPH_H__ -extern void graph(void); +extern void graph(struct meshlink_handle *mesh); #endif /* __TINC_GRAPH_H__ */ diff --git a/src/logger.c b/src/logger.c index e6303c66..5f3bbbbf 100644 --- a/src/logger.c +++ b/src/logger.c @@ -23,9 +23,10 @@ #include "meshlink_internal.h" #include "sptps.h" +// TODO: refactor logging code to use a meshlink_handle_t *. void logger(int level, int priority, const char *format, ...) { - if(level > mesh->debug_level) - return; + //if(level > mesh->debug_level) + // return; va_list ap; char message[1024] = ""; diff --git a/src/meshlink.c b/src/meshlink.c index 8e94fa1e..7552c9f0 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -28,8 +28,6 @@ #include "route.h" #include "xalloc.h" -meshlink_handle_t *mesh; - static const char *errstr[] = { [MESHLINK_OK] = "No error", [MESHLINK_ENOMEM] = "Out of memory", @@ -40,11 +38,6 @@ const char *meshlink_strerror(meshlink_errno_t errno) { return errstr[errno]; } -// TODO: hack, remove once all global variables are gone. -static void set_mesh(meshlink_handle_t *localmesh) { - mesh = localmesh; -} - static bool ecdsa_keygen(meshlink_handle_t *mesh) { ecdsa_t *key; FILE *f; @@ -214,7 +207,6 @@ meshlink_handle_t *meshlink_open(const char *confbase, const char *name) { mesh->name = xstrdup(name); event_loop_init(&mesh->loop); mesh->loop.data = mesh; - set_mesh(mesh); // TODO: should be set by a function. mesh->debug_level = 5; @@ -324,12 +316,12 @@ bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const mesh->self->in_packets++; mesh->self->in_bytes += packet.len; - route(mesh->self, &packet); + route(mesh, mesh->self, &packet); return false; } meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) { - return (meshlink_node_t *)lookup_node(name); + return (meshlink_node_t *)lookup_node(mesh, name); return NULL; } diff --git a/src/meshlink_internal.h b/src/meshlink_internal.h index db69e6fd..6d0d3c0f 100644 --- a/src/meshlink_internal.h +++ b/src/meshlink_internal.h @@ -104,12 +104,6 @@ struct meshlink_node { void *priv; }; -// This is a *temporary* global variable which will keep the compiler happy -// while refactoring the code to get rid of global variables. -// TODO: remove this when no other global variables remain. - -extern meshlink_handle_t *mesh; - /// Header for data packets routed between nodes typedef struct meshlink_packethdr { uint8_t destination[16]; diff --git a/src/meta.c b/src/meta.c index 42e94710..e31c171c 100644 --- a/src/meta.c +++ b/src/meta.c @@ -30,6 +30,7 @@ bool send_meta_sptps(void *handle, uint8_t type, const char *buffer, size_t length) { connection_t *c = handle; + meshlink_handle_t *mesh = c->mesh; if(!c) { logger(DEBUG_ALWAYS, LOG_ERR, "send_meta_sptps() called with NULL pointer!"); @@ -42,7 +43,7 @@ bool send_meta_sptps(void *handle, uint8_t type, const char *buffer, size_t leng return true; } -bool send_meta(connection_t *c, const char *buffer, int length) { +bool send_meta(meshlink_handle_t *mesh, connection_t *c, const char *buffer, int length) { if(!c) { logger(DEBUG_ALWAYS, LOG_ERR, "send_meta() called with NULL pointer!"); abort(); @@ -60,14 +61,15 @@ bool send_meta(connection_t *c, const char *buffer, int length) { return sptps_send_record(&c->sptps, 0, buffer, length); } -void broadcast_meta(connection_t *from, const char *buffer, int length) { +void broadcast_meta(meshlink_handle_t *mesh, connection_t *from, const char *buffer, int length) { for list_each(connection_t, c, mesh->connections) if(c != from && c->status.active) - send_meta(c, buffer, length); + send_meta(mesh, c, buffer, length); } bool receive_meta_sptps(void *handle, uint8_t type, const char *data, uint16_t length) { connection_t *c = handle; + meshlink_handle_t *mesh = c->mesh; if(!c) { logger(DEBUG_ALWAYS, LOG_ERR, "receive_meta_sptps() called with NULL pointer!"); @@ -76,7 +78,7 @@ bool receive_meta_sptps(void *handle, uint8_t type, const char *data, uint16_t l if(type == SPTPS_HANDSHAKE) { if(c->allow_request == ACK) - return send_ack(c); + return send_ack(mesh, c); else return true; } @@ -101,10 +103,10 @@ bool receive_meta_sptps(void *handle, uint8_t type, const char *data, uint16_t l /* Otherwise we are waiting for a request */ - return receive_request(c, data); + return receive_request(mesh, c, data); } -bool receive_meta(connection_t *c) { +bool receive_meta(meshlink_handle_t *mesh, connection_t *c) { int inlen; char inbuf[MAXBUFSIZE]; char *bufp = inbuf, *endp; @@ -154,7 +156,7 @@ bool receive_meta(connection_t *c) { while(c->inbuf.len) { char *request = buffer_readline(&c->inbuf); if(request) { - bool result = receive_request(c, request); + bool result = receive_request(mesh, c, request); if(!result) return false; continue; diff --git a/src/meta.h b/src/meta.h index 646ddbaa..00cdc175 100644 --- a/src/meta.h +++ b/src/meta.h @@ -22,10 +22,10 @@ #include "connection.h" -extern bool send_meta(struct connection_t *, const char *, int); +extern bool send_meta(struct meshlink_handle *mesh, struct connection_t *, const char *, int); extern bool send_meta_sptps(void *, uint8_t, const char *, size_t); extern bool receive_meta_sptps(void *, uint8_t, const char *, uint16_t); -extern void broadcast_meta(struct connection_t *, const char *, int); -extern bool receive_meta(struct connection_t *); +extern void broadcast_meta(struct meshlink_handle *mesh, struct connection_t *, const char *, int); +extern bool receive_meta(struct meshlink_handle *mesh, struct connection_t *); #endif /* __TINC_META_H__ */ diff --git a/src/net.c b/src/net.c index 1fe33342..866bacb1 100644 --- a/src/net.c +++ b/src/net.c @@ -48,14 +48,14 @@ void terminate_connection(meshlink_handle_t *mesh, connection_t *c, bool report) if(c->edge) { if(report) - send_del_edge(mesh->everyone, c->edge); + send_del_edge(mesh, mesh->everyone, c->edge); - edge_del(c->edge); + edge_del(mesh, c->edge); c->edge = NULL; /* Run MST and SSSP algorithms */ - graph(); + graph(mesh); /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */ @@ -63,14 +63,14 @@ void terminate_connection(meshlink_handle_t *mesh, connection_t *c, bool report) edge_t *e; e = lookup_edge(c->node, mesh->self); if(e) { - send_del_edge(mesh->everyone, e); - edge_del(e); + send_del_edge(mesh, mesh->everyone, e); + edge_del(mesh, e); } } } outgoing_t *outgoing = c->outgoing; - connection_del(c); + connection_del(mesh, c); /* Check if this was our outgoing connection */ @@ -101,7 +101,7 @@ static void timeout_handler(event_loop_t *loop, void *data) { if(c->status.pinged) { logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)mesh->loop.now.tv_sec - c->last_ping_time); } else if(c->last_ping_time + mesh->pinginterval <= mesh->loop.now.tv_sec) { - send_ping(c); + send_ping(mesh, c); continue; } else { continue; @@ -236,7 +236,7 @@ static void periodic_handler(event_loop_t *loop, void *data) { } void handle_meta_connection_data(meshlink_handle_t *mesh, connection_t *c) { - if (!receive_meta(c)) { + if (!receive_meta(mesh, c)) { terminate_connection(mesh, c, c->status.active); return; } diff --git a/src/net_packet.c b/src/net_packet.c index 9ca6b3cf..978915c3 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -279,7 +279,7 @@ static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *pac n->in_packets++; n->in_bytes += packet->len; - route(n, packet); + route(mesh, n, packet); } static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) { @@ -290,7 +290,7 @@ static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t * if(!n->sptps.state) { if(!n->status.waitingforkey) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname); - send_req_key(n); + send_req_key(mesh, n); } else { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); } @@ -316,12 +316,12 @@ static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t * if(!n->status.validkey) { logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); if(!n->status.waitingforkey) - send_req_key(n); + send_req_key(mesh, n); else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) { logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); sptps_stop(&n->sptps); n->status.waitingforkey = false; - send_req_key(n); + send_req_key(mesh, n); } return; } @@ -458,6 +458,7 @@ static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *ori bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { node_t *to = handle; + meshlink_handle_t *mesh = to->mesh; /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */ @@ -468,9 +469,9 @@ bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { to ensure we get to learn the reflexive UDP address. */ if(!to->status.validkey) { to->incompression = mesh->self->incompression; - return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, mesh->self->name, to->name, buf, to->incompression); + return send_request(mesh, to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, mesh->self->name, to->name, buf, to->incompression); } else { - return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf); + return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf); } } @@ -501,6 +502,7 @@ bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t len) { node_t *from = handle; + meshlink_handle_t *mesh = from->mesh; if(type == SPTPS_HANDSHAKE) { if(!from->status.validkey) { @@ -646,12 +648,12 @@ void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) { sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */ - n = lookup_node_udp(&from); + n = lookup_node_udp(mesh, &from); if(!n) { n = try_harder(mesh, &from, &pkt); if(n) - update_node_udp(n, &from); + update_node_udp(mesh, n, &from); else if(mesh->debug_level >= DEBUG_PROTOCOL) { hostname = sockaddr2hostname(&from); logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); diff --git a/src/net_setup.c b/src/net_setup.c index eae283d6..298a1819 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -140,13 +140,13 @@ static void load_all_nodes(meshlink_handle_t *mesh) { if(!check_id(ent->d_name)) continue; - node_t *n = lookup_node(ent->d_name); + node_t *n = lookup_node(mesh, ent->d_name); if(n) continue; n = new_node(); n->name = xstrdup(ent->d_name); - node_add(n); + node_add(mesh, n); } closedir(dir); @@ -323,9 +323,9 @@ bool setup_myself(meshlink_handle_t *mesh) { mesh->self->via = mesh->self; mesh->self->status.reachable = true; mesh->self->last_state_change = mesh->loop.now.tv_sec; - node_add(mesh->self); + node_add(mesh, mesh->self); - graph(); + graph(mesh); if(autoconnect) load_all_nodes(mesh); @@ -362,10 +362,10 @@ bool setup_myself(meshlink_handle_t *mesh) { initialize network */ bool setup_network(meshlink_handle_t *mesh) { - init_connections(); - init_nodes(); - init_edges(); - init_requests(); + init_connections(mesh); + init_nodes(mesh); + init_edges(mesh); + init_requests(mesh); mesh->pinginterval = 60; mesh->pingtimeout = 5; @@ -403,10 +403,10 @@ void close_network_connections(meshlink_handle_t *mesh) { close(mesh->listen_socket[i].udp.fd); } - exit_requests(); - exit_edges(); - exit_nodes(); - exit_connections(); + exit_requests(mesh); + exit_edges(mesh); + exit_nodes(mesh); + exit_connections(mesh); if(mesh->myport) free(mesh->myport); diff --git a/src/net_socket.c b/src/net_socket.c index a6adb2a6..16019545 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -255,7 +255,7 @@ void finish_connecting(meshlink_handle_t *mesh, connection_t *c) { c->last_ping_time = mesh->loop.now.tv_sec; c->status.connecting = false; - send_id(c); + send_id(mesh, c); } static void do_outgoing_pipe(meshlink_handle_t *mesh, connection_t *c, char *command) { @@ -465,7 +465,7 @@ begin: c->outcompression = mesh->self->connection->outcompression; c->last_ping_time = mesh->loop.now.tv_sec; - connection_add(c); + connection_add(mesh, c); io_add(&mesh->loop, &c->io, handle_meta_io, c, c->socket, IO_READ|IO_WRITE); @@ -508,7 +508,7 @@ static struct addrinfo *get_known_addresses(node_t *n) { void setup_outgoing_connection(meshlink_handle_t *mesh, outgoing_t *outgoing) { timeout_del(&mesh->loop, &outgoing->ev); - node_t *n = lookup_node(outgoing->name); + node_t *n = lookup_node(mesh, outgoing->name); if(n && n->connection) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", outgoing->name); @@ -620,10 +620,10 @@ void handle_new_meta_connection(event_loop_t *loop, void *data, int flags) { configure_tcp(c); - connection_add(c); + connection_add(mesh, c); c->allow_request = ID; - send_id(c); + send_id(mesh, c); } static void free_outgoing(meshlink_handle_t *mesh, outgoing_t *outgoing) { diff --git a/src/node.c b/src/node.c index 54887a3b..3e4dec95 100644 --- a/src/node.c +++ b/src/node.c @@ -35,12 +35,12 @@ static int node_compare(const node_t *a, const node_t *b) { return strcmp(a->name, b->name); } -void init_nodes(void) { +void init_nodes(meshlink_handle_t *mesh) { mesh->nodes = splay_alloc_tree((splay_compare_t) node_compare, (splay_action_t) free_node); node_udp_cache = hash_alloc(0x100, sizeof(sockaddr_t)); } -void exit_nodes(void) { +void exit_nodes(meshlink_handle_t *mesh) { hash_free(node_udp_cache); splay_delete_tree(mesh->nodes); } @@ -65,7 +65,8 @@ void free_node(node_t *n) { ecdsa_free(n->ecdsa); sptps_stop(&n->sptps); - timeout_del(&mesh->loop, &n->mtutimeout); + if(n->mtutimeout.cb) + abort(); if(n->hostname) free(n->hostname); @@ -79,18 +80,21 @@ void free_node(node_t *n) { free(n); } -void node_add(node_t *n) { +void node_add(meshlink_handle_t *mesh, node_t *n) { + n->mesh = mesh; splay_insert(mesh->nodes, n); } -void node_del(node_t *n) { +void node_del(meshlink_handle_t *mesh, node_t *n) { + timeout_del(&mesh->loop, &n->mtutimeout); + for splay_each(edge_t, e, n->edge_tree) - edge_del(e); + edge_del(mesh, e); splay_delete(mesh->nodes, n); } -node_t *lookup_node(char *name) { +node_t *lookup_node(meshlink_handle_t *mesh, char *name) { node_t n = {NULL}; n.name = name; @@ -98,11 +102,11 @@ node_t *lookup_node(char *name) { return splay_search(mesh->nodes, &n); } -node_t *lookup_node_udp(const sockaddr_t *sa) { +node_t *lookup_node_udp(meshlink_handle_t *mesh, const sockaddr_t *sa) { return hash_search(node_udp_cache, sa); } -void update_node_udp(node_t *n, const sockaddr_t *sa) { +void update_node_udp(meshlink_handle_t *mesh, node_t *n, const sockaddr_t *sa) { if(n == mesh->self) { logger(DEBUG_ALWAYS, LOG_WARNING, "Trying to update UDP address of mesh->self!"); return; diff --git a/src/node.h b/src/node.h index f6415a1d..3a779af9 100644 --- a/src/node.h +++ b/src/node.h @@ -41,6 +41,8 @@ typedef struct node_t { char *name; /* name of this node */ uint32_t options; /* options turned on for this node */ + struct meshlink_handle *mesh; /* The mesh this node belongs to */ + 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 */ @@ -88,14 +90,14 @@ typedef struct node_t { uint64_t out_bytes; } node_t; -extern void init_nodes(void); -extern void exit_nodes(void); +extern void init_nodes(struct meshlink_handle *mesh); +extern void exit_nodes(struct meshlink_handle *mesh); extern node_t *new_node(void) __attribute__ ((__malloc__)); extern void free_node(node_t *); -extern void node_add(node_t *); -extern void node_del(node_t *); -extern node_t *lookup_node(char *); -extern node_t *lookup_node_udp(const sockaddr_t *); -extern void update_node_udp(node_t *, const sockaddr_t *); +extern void node_add(struct meshlink_handle *mesh, node_t *); +extern void node_del(struct meshlink_handle *mesh, node_t *); +extern node_t *lookup_node(struct meshlink_handle *mesh, char *); +extern node_t *lookup_node_udp(struct meshlink_handle *mesh, const sockaddr_t *); +extern void update_node_udp(struct meshlink_handle *mesh, node_t *, const sockaddr_t *); #endif /* __TINC_NODE_H__ */ diff --git a/src/protocol.c b/src/protocol.c index c1d635d0..4018ef0e 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -30,7 +30,7 @@ /* Jumptable for the request handlers */ -static bool (*request_handlers[])(connection_t *, const char *) = { +static bool (*request_handlers[])(meshlink_handle_t *, connection_t *, const char *) = { id_h, NULL, NULL, NULL /* metakey_h, challenge_h, chal_reply_h */, ack_h, status_h, error_h, termreq_h, ping_h, pong_h, @@ -65,7 +65,7 @@ bool check_id(const char *id) { /* Generic request routines - takes care of logging and error detection as well */ -bool send_request(connection_t *c, const char *format, ...) { +bool send_request(meshlink_handle_t *mesh, connection_t *c, const char *format, ...) { va_list args; char request[MAXBUFSIZE]; int len; @@ -89,13 +89,13 @@ bool send_request(connection_t *c, const char *format, ...) { request[len++] = '\n'; if(c == mesh->everyone) { - broadcast_meta(NULL, request, len); + broadcast_meta(mesh, NULL, request, len); return true; } else - return send_meta(c, request, len); + return send_meta(mesh, c, request, len); } -void forward_request(connection_t *from, const char *request) { +void forward_request(meshlink_handle_t *mesh, connection_t *from, const char *request) { logger(DEBUG_META, LOG_DEBUG, "Forwarding %s from %s (%s): %s", request_name[atoi(request)], from->name, from->hostname, request); // Create a temporary newline-terminated copy of the request @@ -103,10 +103,10 @@ void forward_request(connection_t *from, const char *request) { char tmp[len + 1]; memcpy(tmp, request, len); tmp[len] = '\n'; - broadcast_meta(from, tmp, sizeof tmp); + broadcast_meta(mesh, from, tmp, sizeof tmp); } -bool receive_request(connection_t *c, const char *request) { +bool receive_request(meshlink_handle_t *mesh, connection_t *c, const char *request) { if(c->outgoing && mesh->proxytype == PROXY_HTTP && c->allow_request == ID) { if(!request[0] || request[0] == '\r') return true; @@ -136,7 +136,7 @@ bool receive_request(connection_t *c, const char *request) { return false; } - if(!request_handlers[reqno](c, request)) { + if(!request_handlers[reqno](mesh, c, request)) { /* Something went wrong. Probably scriptkiddies. Terminate. */ logger(DEBUG_ALWAYS, LOG_ERR, "Error while processing %s from %s (%s)", request_name[reqno], c->name, c->hostname); @@ -156,7 +156,7 @@ static int past_request_compare(const past_request_t *a, const past_request_t *b static void free_past_request(past_request_t *r) { if(r->request) - free((char *)r->request); + free(r->request); free(r); } @@ -164,6 +164,7 @@ static void free_past_request(past_request_t *r) { static timeout_t past_request_timeout; static void age_past_requests(event_loop_t *loop, void *data) { + meshlink_handle_t *mesh = loop->data; int left = 0, deleted = 0; for splay_each(past_request_t, p, past_request_tree) { @@ -180,7 +181,7 @@ static void age_past_requests(event_loop_t *loop, void *data) { timeout_set(&mesh->loop, &past_request_timeout, &(struct timeval){10, rand() % 100000}); } -bool seen_request(const char *request) { +bool seen_request(meshlink_handle_t *mesh, const char *request) { past_request_t *new, p = {NULL}; p.request = request; @@ -198,11 +199,12 @@ bool seen_request(const char *request) { } } -void init_requests(void) { +// TODO: move past_request_tree to meshlink_handle_t +void init_requests(meshlink_handle_t *mesh) { past_request_tree = splay_alloc_tree((splay_compare_t) past_request_compare, (splay_action_t) free_past_request); } -void exit_requests(void) { +void exit_requests(meshlink_handle_t *mesh) { splay_delete_tree(past_request_tree); timeout_del(&mesh->loop, &past_request_timeout); diff --git a/src/protocol.h b/src/protocol.h index 8e2258fc..c3b3b383 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -70,45 +70,45 @@ typedef struct past_request_t { /* Basic functions */ -extern bool send_request(struct connection_t *, const char *, ...) __attribute__ ((__format__(printf, 2, 3))); -extern void forward_request(struct connection_t *, const char *); -extern bool receive_request(struct connection_t *, const char *); +extern bool send_request(struct meshlink_handle *mesh, struct connection_t *, const char *, ...) __attribute__ ((__format__(printf, 3, 4))); +extern void forward_request(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool receive_request(struct meshlink_handle *mesh, struct connection_t *, const char *); extern bool check_id(const char *); -extern void init_requests(void); -extern void exit_requests(void); -extern bool seen_request(const char *); +extern void init_requests(struct meshlink_handle *mesh); +extern void exit_requests(struct meshlink_handle *mesh); +extern bool seen_request(struct meshlink_handle *mesh, const char *); /* Requests */ -extern bool send_id(struct connection_t *); -extern bool send_ack(struct connection_t *); -extern bool send_status(struct connection_t *, int, const char *); -extern bool send_error(struct connection_t *, int, const char *); -extern bool send_termreq(struct connection_t *); -extern bool send_ping(struct connection_t *); -extern bool send_pong(struct connection_t *); -extern bool send_add_edge(struct connection_t *, const struct edge_t *); -extern bool send_del_edge(struct connection_t *, const struct edge_t *); -extern void send_key_changed(void); -extern bool send_req_key(struct node_t *); -extern bool send_ans_key(struct node_t *); -extern bool send_tcppacket(struct connection_t *, const struct vpn_packet_t *); +extern bool send_id(struct meshlink_handle *mesh, struct connection_t *); +extern bool send_ack(struct meshlink_handle *mesh, struct connection_t *); +extern bool send_status(struct meshlink_handle *mesh, struct connection_t *, int, const char *); +extern bool send_error(struct meshlink_handle *mesh, struct connection_t *, int, const char *); +extern bool send_termreq(struct meshlink_handle *mesh, struct connection_t *); +extern bool send_ping(struct meshlink_handle *mesh, struct connection_t *); +extern bool send_pong(struct meshlink_handle *mesh, struct connection_t *); +extern bool send_add_edge(struct meshlink_handle *mesh, struct connection_t *, const struct edge_t *); +extern bool send_del_edge(struct meshlink_handle *mesh, struct connection_t *, const struct edge_t *); +extern void send_key_changed(struct meshlink_handle *mesh); +extern bool send_req_key(struct meshlink_handle *mesh, struct node_t *); +extern bool send_ans_key(struct meshlink_handle *mesh, struct node_t *); +extern bool send_tcppacket(struct meshlink_handle *mesh, struct connection_t *, const struct vpn_packet_t *); /* Request handlers */ -extern bool id_h(struct connection_t *, const char *); -extern bool ack_h(struct connection_t *, const char *); -extern bool status_h(struct connection_t *, const char *); -extern bool error_h(struct connection_t *, const char *); -extern bool termreq_h(struct connection_t *, const char *); -extern bool ping_h(struct connection_t *, const char *); -extern bool pong_h(struct connection_t *, const char *); -extern bool add_edge_h(struct connection_t *, const char *); -extern bool del_edge_h(struct connection_t *, const char *); -extern bool key_changed_h(struct connection_t *, const char *); -extern bool req_key_h(struct connection_t *, const char *); -extern bool ans_key_h(struct connection_t *, const char *); -extern bool tcppacket_h(struct connection_t *, const char *); +extern bool id_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool ack_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool status_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool error_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool termreq_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool ping_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool pong_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool add_edge_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool del_edge_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool key_changed_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool req_key_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool ans_key_h(struct meshlink_handle *mesh, struct connection_t *, const char *); +extern bool tcppacket_h(struct meshlink_handle *mesh, struct connection_t *, const char *); #endif /* __TINC_PROTOCOL_H__ */ diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 8fad8cc0..be4d2ea0 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -37,14 +37,14 @@ #include "xalloc.h" #include "ed25519/sha512.h" -static bool send_proxyrequest(connection_t *c) { +static bool send_proxyrequest(meshlink_handle_t *mesh, connection_t *c) { switch(mesh->proxytype) { case PROXY_HTTP: { char *host; char *port; sockaddr2str(&c->address, &host, &port); - send_request(c, "CONNECT %s:%s HTTP/1.1\r\n\r", host, port); + send_request(mesh, c, "CONNECT %s:%s HTTP/1.1\r\n\r", host, port); free(host); free(port); return true; @@ -63,7 +63,7 @@ static bool send_proxyrequest(connection_t *c) { memcpy(s4req + 8, mesh->proxyuser, strlen(mesh->proxyuser)); s4req[sizeof s4req - 1] = 0; c->tcplen = 8; - return send_meta(c, s4req, sizeof s4req); + return send_meta(mesh, c, s4req, sizeof s4req); } case PROXY_SOCKS5: { int len = 3 + 6 + (c->address.sa.sa_family == AF_INET ? 4 : 16); @@ -110,7 +110,7 @@ static bool send_proxyrequest(connection_t *c) { } if(i > len) abort(); - return send_meta(c, s5req, sizeof s5req); + return send_meta(mesh, c, s5req, sizeof s5req); } case PROXY_SOCKS4A: logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type not implemented yet"); @@ -123,19 +123,19 @@ static bool send_proxyrequest(connection_t *c) { } } -bool send_id(connection_t *c) { +bool send_id(meshlink_handle_t *mesh, connection_t *c) { gettimeofday(&c->start, NULL); int minor = mesh->self->connection->protocol_minor; if(mesh->proxytype && c->outgoing) - if(!send_proxyrequest(c)) + if(!send_proxyrequest(mesh, c)) return false; - return send_request(c, "%d %s %d.%d", ID, mesh->self->connection->name, mesh->self->connection->protocol_major, minor); + return send_request(mesh, c, "%d %s %d.%d", ID, mesh->self->connection->name, mesh->self->connection->protocol_major, minor); } -static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) { +static bool finalize_invitation(meshlink_handle_t *mesh, connection_t *c, const char *data, uint16_t len) { if(strchr(data, '\n')) { logger(DEBUG_ALWAYS, LOG_ERR, "Received invalid key from invited node %s (%s)!\n", c->name, c->hostname); return false; @@ -168,12 +168,13 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) static bool receive_invitation_sptps(void *handle, uint8_t type, const char *data, uint16_t len) { connection_t *c = handle; + meshlink_handle_t *mesh = c->mesh; if(type == 128) return true; if(type == 1 && c->status.invitation_used) - return finalize_invitation(c, data, len); + return finalize_invitation(mesh, c, data, len); if(type != 0 || len != 18 || c->status.invitation_used) return false; @@ -248,7 +249,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const char *dat return true; } -bool id_h(connection_t *c, const char *request) { +bool id_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { char name[MAX_STRING_SIZE]; if(sscanf(request, "%*d " MAX_STRING " %d.%d", name, &c->protocol_major, &c->protocol_minor) < 2) { @@ -275,7 +276,7 @@ bool id_h(connection_t *c, const char *request) { char *mykey = ecdsa_get_base64_public_key(mesh->invitation_key); if(!mykey) return false; - if(!send_request(c, "%d %s", ACK, mykey)) + if(!send_request(mesh, c, "%d %s", ACK, mykey)) return false; free(mykey); @@ -347,7 +348,7 @@ bool id_h(connection_t *c, const char *request) { return sptps_start(&c->sptps, c, c->outgoing, false, mesh->self->connection->ecdsa, c->ecdsa, label, sizeof label, send_meta_sptps, receive_meta_sptps); } -bool send_ack(connection_t *c) { +bool send_ack(meshlink_handle_t *mesh, connection_t *c) { /* ACK message contains rest of the information the other end needs to create node_t and edge_t structures. */ @@ -364,19 +365,19 @@ bool send_ack(connection_t *c) { if(mesh->self->options & OPTION_PMTU_DISCOVERY) c->options |= OPTION_PMTU_DISCOVERY; - return send_request(c, "%d %s %d %x", ACK, mesh->myport, c->estimated_weight, (c->options & 0xffffff) | (PROT_MINOR << 24)); + return send_request(mesh, c, "%d %s %d %x", ACK, mesh->myport, c->estimated_weight, (c->options & 0xffffff) | (PROT_MINOR << 24)); } -static void send_everything(connection_t *c) { +static void send_everything(meshlink_handle_t *mesh, connection_t *c) { /* Send all known subnets and edges */ for splay_each(node_t, n, mesh->nodes) { for splay_each(edge_t, e, n->edge_tree) - send_add_edge(c, e); + send_add_edge(mesh, c, e); } } -bool ack_h(connection_t *c, const char *request) { +bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { char hisport[MAX_STRING_SIZE]; char *hisaddress; int weight, mtu; @@ -392,12 +393,12 @@ bool ack_h(connection_t *c, const char *request) { /* Check if we already have a node_t for him */ - n = lookup_node(c->name); + n = lookup_node(mesh, c->name); if(!n) { n = new_node(); n->name = xstrdup(c->name); - node_add(n); + node_add(mesh, n); } else { if(n->connection) { /* Oh dear, we already have a connection to this node. */ @@ -414,7 +415,7 @@ bool ack_h(connection_t *c, const char *request) { terminate_connection(mesh, n->connection, false); /* Run graph algorithm to keep things in sync */ - graph(); + graph(mesh); } } @@ -436,7 +437,7 @@ bool ack_h(connection_t *c, const char *request) { /* Send him everything we know */ - send_everything(c); + send_everything(mesh, c); /* Create an edge_t for this connection */ @@ -450,15 +451,15 @@ bool ack_h(connection_t *c, const char *request) { c->edge->connection = c; c->edge->options = c->options; - edge_add(c->edge); + edge_add(mesh, c->edge); /* Notify everyone of the new edge */ - send_add_edge(mesh->everyone, c->edge); + send_add_edge(mesh, mesh->everyone, c->edge); /* Run MST and SSSP algorithms */ - graph(); + graph(mesh); return true; } diff --git a/src/protocol_edge.c b/src/protocol_edge.c index 6eb205fd..3b89cdec 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -33,13 +33,13 @@ #include "utils.h" #include "xalloc.h" -bool send_add_edge(connection_t *c, const edge_t *e) { +bool send_add_edge(meshlink_handle_t *mesh, connection_t *c, const edge_t *e) { bool x; char *address, *port; sockaddr2str(&e->address, &address, &port); - x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(), + x = send_request(mesh, c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(), e->from->name, e->to->name, address, port, e->options, e->weight); free(address); @@ -48,7 +48,7 @@ bool send_add_edge(connection_t *c, const edge_t *e) { return x; } -bool add_edge_h(connection_t *c, const char *request) { +bool add_edge_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { edge_t *e; node_t *from, *to; char from_name[MAX_STRING_SIZE]; @@ -74,24 +74,24 @@ bool add_edge_h(connection_t *c, const char *request) { return false; } - if(seen_request(request)) + if(seen_request(mesh, request)) return true; /* Lookup nodes */ - from = lookup_node(from_name); - to = lookup_node(to_name); + from = lookup_node(mesh, from_name); + to = lookup_node(mesh, to_name); if(!from) { from = new_node(); from->name = xstrdup(from_name); - node_add(from); + node_add(mesh, from); } if(!to) { to = new_node(); to->name = xstrdup(to_name); - node_add(to); + node_add(mesh, to); } @@ -108,13 +108,13 @@ bool add_edge_h(connection_t *c, const char *request) { if(from == mesh->self) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", "ADD_EDGE", c->name, c->hostname); - send_add_edge(c, e); + send_add_edge(mesh, c, e); return true; } else { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", "ADD_EDGE", c->name, c->hostname); - edge_del(e); - graph(); + edge_del(mesh, e); + graph(mesh); } } else return true; @@ -125,7 +125,7 @@ bool add_edge_h(connection_t *c, const char *request) { e = new_edge(); e->from = from; e->to = to; - send_del_edge(c, e); + send_del_edge(mesh, c, e); free_edge(e); return true; } @@ -136,25 +136,25 @@ bool add_edge_h(connection_t *c, const char *request) { e->address = address; e->options = options; e->weight = weight; - edge_add(e); + edge_add(mesh, e); /* Tell the rest about the new edge */ - forward_request(c, request); + forward_request(mesh, c, request); /* Run MST before or after we tell the rest? */ - graph(); + graph(mesh); return true; } -bool send_del_edge(connection_t *c, const edge_t *e) { - return send_request(c, "%d %x %s %s", DEL_EDGE, rand(), +bool send_del_edge(meshlink_handle_t *mesh, connection_t *c, const edge_t *e) { + return send_request(mesh, c, "%d %x %s %s", DEL_EDGE, rand(), e->from->name, e->to->name); } -bool del_edge_h(connection_t *c, const char *request) { +bool del_edge_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { edge_t *e; char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; @@ -174,13 +174,13 @@ bool del_edge_h(connection_t *c, const char *request) { return false; } - if(seen_request(request)) + if(seen_request(mesh, request)) return true; /* Lookup nodes */ - from = lookup_node(from_name); - to = lookup_node(to_name); + from = lookup_node(mesh, from_name); + to = lookup_node(mesh, to_name); if(!from) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", @@ -208,29 +208,29 @@ bool del_edge_h(connection_t *c, const char *request) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", "DEL_EDGE", c->name, c->hostname); mesh->contradicting_del_edge++; - send_add_edge(c, e); /* Send back a correction */ + send_add_edge(mesh, c, e); /* Send back a correction */ return true; } /* Tell the rest about the deleted edge */ - forward_request(c, request); + forward_request(mesh, c, request); /* Delete the edge */ - edge_del(e); + edge_del(mesh, e); /* Run MST before or after we tell the rest? */ - graph(); + graph(mesh); /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */ if(!to->status.reachable) { e = lookup_edge(to, mesh->self); if(e) { - send_del_edge(mesh->everyone, e); - edge_del(e); + send_del_edge(mesh, mesh->everyone, e); + edge_del(mesh, e); } } diff --git a/src/protocol_key.c b/src/protocol_key.c index f3d801f1..b1be1866 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -33,8 +33,8 @@ static bool mykeyused = false; -void send_key_changed(void) { - send_request(mesh->everyone, "%d %x %s", KEY_CHANGED, rand(), mesh->self->name); +void send_key_changed(meshlink_handle_t *mesh) { + send_request(mesh, mesh->everyone, "%d %x %s", KEY_CHANGED, rand(), mesh->self->name); /* Force key exchange for connections using SPTPS */ @@ -43,7 +43,7 @@ void send_key_changed(void) { sptps_force_kex(&n->sptps); } -bool key_changed_h(connection_t *c, const char *request) { +bool key_changed_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { char name[MAX_STRING_SIZE]; node_t *n; @@ -53,10 +53,10 @@ bool key_changed_h(connection_t *c, const char *request) { return false; } - if(seen_request(request)) + if(seen_request(mesh, request)) return true; - n = lookup_node(name); + n = lookup_node(mesh, name); if(!n) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist", @@ -66,23 +66,24 @@ bool key_changed_h(connection_t *c, const char *request) { /* Tell the others */ - forward_request(c, request); + forward_request(mesh, c, request); return true; } static bool send_initial_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { node_t *to = handle; + meshlink_handle_t *mesh = to->mesh; to->sptps.send_data = send_sptps_data; char buf[len * 4 / 3 + 5]; b64encode(data, buf, len); - return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_KEY, buf); + return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_KEY, buf); } -bool send_req_key(node_t *to) { +bool send_req_key(meshlink_handle_t *mesh, node_t *to) { if(!node_read_ecdsa_public_key(mesh, to)) { logger(DEBUG_PROTOCOL, LOG_DEBUG, "No ECDSA key known for %s (%s)", to->name, to->hostname); - send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, mesh->self->name, to->name, REQ_PUBKEY); + send_request(mesh, to->nexthop->connection, "%d %s %s %d", REQ_KEY, mesh->self->name, to->name, REQ_PUBKEY); return true; } @@ -101,11 +102,11 @@ bool send_req_key(node_t *to) { /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */ -static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, int reqno) { +static bool req_key_ext_h(meshlink_handle_t *mesh, connection_t *c, const char *request, node_t *from, int reqno) { switch(reqno) { case REQ_PUBKEY: { char *pubkey = ecdsa_get_base64_public_key(mesh->self->connection->ecdsa); - send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, from->name, ANS_PUBKEY, pubkey); + send_request(mesh, from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, from->name, ANS_PUBKEY, pubkey); free(pubkey); return true; } @@ -130,7 +131,7 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in case REQ_KEY: { if(!node_read_ecdsa_public_key(mesh, from)) { logger(DEBUG_PROTOCOL, LOG_DEBUG, "No ECDSA key known for %s (%s)", from->name, from->hostname); - send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, mesh->self->name, from->name, REQ_PUBKEY); + send_request(mesh, from->nexthop->connection, "%d %s %s %d", REQ_KEY, mesh->self->name, from->name, REQ_PUBKEY); return true; } @@ -178,7 +179,7 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in } } -bool req_key_h(connection_t *c, const char *request) { +bool req_key_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; node_t *from, *to; @@ -195,7 +196,7 @@ bool req_key_h(connection_t *c, const char *request) { return false; } - from = lookup_node(from_name); + from = lookup_node(mesh, from_name); if(!from) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", @@ -203,7 +204,7 @@ bool req_key_h(connection_t *c, const char *request) { return true; } - to = lookup_node(to_name); + to = lookup_node(mesh, to_name); if(!to) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", @@ -216,10 +217,10 @@ bool req_key_h(connection_t *c, const char *request) { if(to == mesh->self) { /* Yes */ /* Is this an extended REQ_KEY message? */ if(reqno) - return req_key_ext_h(c, request, from, reqno); + return req_key_ext_h(mesh, c, request, from, reqno); /* No, just send our key back */ - send_ans_key(from); + send_ans_key(mesh, from); } else { if(!to->status.reachable) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", @@ -227,17 +228,17 @@ bool req_key_h(connection_t *c, const char *request) { return true; } - send_request(to->nexthop->connection, "%s", request); + send_request(mesh, to->nexthop->connection, "%s", request); } return true; } -bool send_ans_key(node_t *to) { +bool send_ans_key(meshlink_handle_t *mesh, node_t *to) { abort(); } -bool ans_key_h(connection_t *c, const char *request) { +bool ans_key_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; char key[MAX_STRING_SIZE]; @@ -259,7 +260,7 @@ bool ans_key_h(connection_t *c, const char *request) { return false; } - from = lookup_node(from_name); + from = lookup_node(mesh, from_name); if(!from) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", @@ -267,7 +268,7 @@ bool ans_key_h(connection_t *c, const char *request) { return true; } - to = lookup_node(to_name); + to = lookup_node(mesh, to_name); if(!to) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", @@ -288,13 +289,13 @@ bool ans_key_h(connection_t *c, const char *request) { char *address, *port; logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name); sockaddr2str(&from->address, &address, &port); - send_request(to->nexthop->connection, "%s %s %s", request, address, port); + send_request(mesh, to->nexthop->connection, "%s %s %s", request, address, port); free(address); free(port); return true; } - return send_request(to->nexthop->connection, "%s", request); + return send_request(mesh, to->nexthop->connection, "%s", request); } /* Don't use key material until every check has passed. */ @@ -319,7 +320,7 @@ bool ans_key_h(connection_t *c, const char *request) { if(*address && *port) { logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port); sockaddr_t sa = str2sockaddr(address, port); - update_node_udp(from, &sa); + update_node_udp(mesh, from, &sa); } if(from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY)) diff --git a/src/protocol_misc.c b/src/protocol_misc.c index c95c9cb9..84a2531c 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -33,14 +33,14 @@ int maxoutbufsize = 0; /* Status and error notification routines */ -bool send_status(connection_t *c, int statusno, const char *statusstring) { +bool send_status(meshlink_handle_t *mesh, connection_t *c, int statusno, const char *statusstring) { if(!statusstring) statusstring = "Status"; - return send_request(c, "%d %d %s", STATUS, statusno, statusstring); + return send_request(mesh, c, "%d %d %s", STATUS, statusno, statusstring); } -bool status_h(connection_t *c, const char *request) { +bool status_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { int statusno; char statusstring[MAX_STRING_SIZE]; @@ -56,14 +56,14 @@ bool status_h(connection_t *c, const char *request) { return true; } -bool send_error(connection_t *c, int err, const char *errstring) { +bool send_error(meshlink_handle_t *mesh, connection_t *c, int err, const char *errstring) { if(!errstring) errstring = "Error"; - return send_request(c, "%d %d %s", ERROR, err, errstring); + return send_request(mesh, c, "%d %d %s", ERROR, err, errstring); } -bool error_h(connection_t *c, const char *request) { +bool error_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { int err; char errorstring[MAX_STRING_SIZE]; @@ -79,30 +79,30 @@ bool error_h(connection_t *c, const char *request) { return false; } -bool send_termreq(connection_t *c) { - return send_request(c, "%d", TERMREQ); +bool send_termreq(meshlink_handle_t *mesh, connection_t *c) { + return send_request(mesh, c, "%d", TERMREQ); } -bool termreq_h(connection_t *c, const char *request) { +bool termreq_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { return false; } -bool send_ping(connection_t *c) { +bool send_ping(meshlink_handle_t *mesh, connection_t *c) { c->status.pinged = true; c->last_ping_time = mesh->loop.now.tv_sec; - return send_request(c, "%d", PING); + return send_request(mesh, c, "%d", PING); } -bool ping_h(connection_t *c, const char *request) { - return send_pong(c); +bool ping_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { + return send_pong(mesh, c); } -bool send_pong(connection_t *c) { - return send_request(c, "%d", PONG); +bool send_pong(meshlink_handle_t *mesh, connection_t *c) { + return send_request(mesh, c, "%d", PONG); } -bool pong_h(connection_t *c, const char *request) { +bool pong_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { c->status.pinged = false; /* Succesful connection, reset timeout if this is an outgoing connection. */ @@ -121,20 +121,20 @@ bool pong_h(connection_t *c, const char *request) { /* Sending and receiving packets via TCP */ -bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) { +bool send_tcppacket(meshlink_handle_t *mesh, connection_t *c, const vpn_packet_t *packet) { /* If there already is a lot of data in the outbuf buffer, discard this packet. We use a very simple Random Early Drop algorithm. */ if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX) return true; - if(!send_request(c, "%d %hd", PACKET, packet->len)) + if(!send_request(mesh, c, "%d %hd", PACKET, packet->len)) return false; - return send_meta(c, (char *)packet->data, packet->len); + return send_meta(mesh, c, (char *)packet->data, packet->len); } -bool tcppacket_h(connection_t *c, const char *request) { +bool tcppacket_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { short int len; if(sscanf(request, "%*d %hd", &len) != 1) { diff --git a/src/route.c b/src/route.c index 9a0c6434..242b5864 100644 --- a/src/route.c +++ b/src/route.c @@ -27,22 +27,6 @@ bool decrement_ttl = false; -static bool ratelimit(int frequency) { - static time_t lasttime = 0; - static int count = 0; - - if(lasttime == mesh->loop.now.tv_sec) { - if(count >= frequency) - return true; - } else { - lasttime = mesh->loop.now.tv_sec; - count = 0; - } - - count++; - return false; -} - static bool checklength(node_t *source, vpn_packet_t *packet, uint16_t length) { if(packet->len < length) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Got too short packet from %s (%s)", source->name, source->hostname); @@ -51,13 +35,13 @@ static bool checklength(node_t *source, vpn_packet_t *packet, uint16_t length) { return true; } -void route(node_t *source,vpn_packet_t *packet) { +void route(meshlink_handle_t *mesh, node_t *source, vpn_packet_t *packet) { // TODO: route on name or key node_t* owner = NULL; node_t* via = NULL; meshlink_packethdr_t* hdr = (meshlink_packethdr_t*)packet->data; - owner = lookup_node(hdr->destination); + owner = lookup_node(mesh, hdr->destination); logger(DEBUG_TRAFFIC, LOG_WARNING, "Routing packet from: %s . To: %s \n",hdr->source,hdr->destination); //Check Lenght diff --git a/src/route.h b/src/route.h index 4180d4a2..0d13ad60 100644 --- a/src/route.h +++ b/src/route.h @@ -25,6 +25,6 @@ extern bool decrement_ttl; -extern void route(struct node_t *, struct vpn_packet_t *); +extern void route(struct meshlink_handle *mesh, struct node_t *, struct vpn_packet_t *); #endif /* __TINC_ROUTE_H__ */ -- 2.39.2