X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fnet_socket.c;h=160195455b450a9e1f1dc158df064bcf5a8a013c;hb=a1b50920b9a52f86ca6e33fcb24d7fa34313a1ee;hp=1521208f76986ef518ce73934bcac7bfab7de7a1;hpb=21f0bddfa4dca5fb21c9dc4970ac64fa8fe706e4;p=meshlink diff --git a/src/net_socket.c b/src/net_socket.c index 1521208f..16019545 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -37,14 +37,9 @@ #endif int addressfamily = AF_UNSPEC; -int maxtimeout = 900; int seconds_till_retry = 5; int max_connection_burst = 100; -listen_socket_t listen_socket[MAXSOCKETS]; -int listen_sockets; -list_t *outgoing_list = NULL; - /* Setup sockets */ static void configure_tcp(connection_t *c) { @@ -75,11 +70,11 @@ static void configure_tcp(connection_t *c) { #endif } -static bool bind_to_address(connection_t *c) { +static bool bind_to_address(meshlink_handle_t *mesh, connection_t *c) { int s = -1; - for(int i = 0; i < listen_sockets && listen_socket[i].bindto; i++) { - if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) + for(int i = 0; i < mesh->listen_sockets && mesh->listen_socket[i].bindto; i++) { + if(mesh->listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) continue; if(s >= 0) return false; @@ -89,7 +84,7 @@ static bool bind_to_address(connection_t *c) { if(s < 0) return false; - sockaddr_t sa = listen_socket[s].sa; + sockaddr_t sa = mesh->listen_socket[s].sa; if(sa.sa.sa_family == AF_INET) sa.in.sin_port = 0; else if(sa.sa.sa_family == AF_INET6) @@ -147,7 +142,7 @@ int setup_listen_socket(const sockaddr_t *sa) { return nfd; } -int setup_vpn_in_socket(const sockaddr_t *sa) { +int setup_vpn_in_socket(meshlink_handle_t *mesh, const sockaddr_t *sa) { int nfd; char *addrstr; int option; @@ -237,31 +232,33 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { return nfd; } /* int setup_vpn_in_socket */ -static void retry_outgoing_handler(void *data) { - setup_outgoing_connection(data); +static void retry_outgoing_handler(event_loop_t *loop, void *data) { + meshlink_handle_t *mesh = loop->data; + outgoing_t *outgoing = data; + setup_outgoing_connection(mesh, outgoing); } -void retry_outgoing(outgoing_t *outgoing) { +void retry_outgoing(meshlink_handle_t *mesh, outgoing_t *outgoing) { outgoing->timeout += 5; - if(outgoing->timeout > maxtimeout) - outgoing->timeout = maxtimeout; + if(outgoing->timeout > mesh->maxtimeout) + outgoing->timeout = mesh->maxtimeout; - timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval){outgoing->timeout, rand() % 100000}); + timeout_add(&mesh->loop, &outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval){outgoing->timeout, rand() % 100000}); logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout); } -void finish_connecting(connection_t *c) { +void finish_connecting(meshlink_handle_t *mesh, connection_t *c) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname); - c->last_ping_time = now.tv_sec; + 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(connection_t *c, char *command) { +static void do_outgoing_pipe(meshlink_handle_t *mesh, connection_t *c, char *command) { #ifndef HAVE_MINGW int fd[2]; @@ -307,7 +304,7 @@ static void do_outgoing_pipe(connection_t *c, char *command) { #endif } -static void handle_meta_write(connection_t *c) { +static void handle_meta_write(meshlink_handle_t *mesh, connection_t *c) { if(c->outbuf.len <= c->outbuf.offset) return; @@ -322,16 +319,17 @@ static void handle_meta_write(connection_t *c) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, strerror(errno)); } - terminate_connection(c, c->status.active); + terminate_connection(mesh, c, c->status.active); return; } buffer_read(&c->outbuf, outlen); if(!c->outbuf.len) - io_set(&c->io, IO_READ); + io_set(&mesh->loop, &c->io, IO_READ); } -static void handle_meta_io(void *data, int flags) { +static void handle_meta_io(event_loop_t *loop, void *data, int flags) { + meshlink_handle_t *mesh = loop->data; connection_t *c = data; if(c->status.connecting) { @@ -342,21 +340,21 @@ static void handle_meta_io(void *data, int flags) { getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&result, &len); if(!result) - finish_connecting(c); + finish_connecting(mesh, c); else { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(result)); - terminate_connection(c, false); + terminate_connection(mesh, c, false); return; } } if(flags & IO_WRITE) - handle_meta_write(c); + handle_meta_write(mesh, c); else - handle_meta_connection_data(c); + handle_meta_connection_data(mesh, c); } -bool do_outgoing_connection(outgoing_t *outgoing) { +bool do_outgoing_connection(meshlink_handle_t *mesh, outgoing_t *outgoing) { char *address, *port, *space; struct addrinfo *proxyai = NULL; int result; @@ -365,7 +363,7 @@ begin: if(!outgoing->ai) { if(!outgoing->cfg) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name); - retry_outgoing(outgoing); + retry_outgoing(mesh, outgoing); return false; } @@ -406,18 +404,18 @@ begin: logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->name, c->hostname); - if(!proxytype) { + if(!mesh->proxytype) { c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); configure_tcp(c); - } else if(proxytype == PROXY_EXEC) { - do_outgoing_pipe(c, proxyhost); + } else if(mesh->proxytype == PROXY_EXEC) { + do_outgoing_pipe(mesh, c, mesh->proxyhost); } else { - proxyai = str2addrinfo(proxyhost, proxyport, SOCK_STREAM); + proxyai = str2addrinfo(mesh->proxyhost, mesh->proxyport, SOCK_STREAM); if(!proxyai) { free_connection(c); goto begin; } - logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport); + logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", mesh->proxyhost, mesh->proxyport); c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP); configure_tcp(c); } @@ -432,21 +430,21 @@ begin: fcntl(c->socket, F_SETFD, FD_CLOEXEC); #endif - if(proxytype != PROXY_EXEC) { + if(mesh->proxytype != PROXY_EXEC) { #if defined(SOL_IPV6) && defined(IPV6_V6ONLY) int option = 1; if(c->address.sa.sa_family == AF_INET6) setsockopt(c->socket, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); #endif - bind_to_address(c); + bind_to_address(mesh, c); } /* Connect */ - if(!proxytype) { + if(!mesh->proxytype) { result = connect(c->socket, &c->address.sa, SALEN(c->address.sa)); - } else if(proxytype == PROXY_EXEC) { + } else if(mesh->proxytype == PROXY_EXEC) { result = 0; } else { result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen); @@ -465,11 +463,11 @@ begin: c->status.connecting = true; c->name = xstrdup(outgoing->name); c->outcompression = mesh->self->connection->outcompression; - c->last_ping_time = now.tv_sec; + c->last_ping_time = mesh->loop.now.tv_sec; - connection_add(c); + connection_add(mesh, c); - io_add(&c->io, handle_meta_io, c, c->socket, IO_READ|IO_WRITE); + io_add(&mesh->loop, &c->io, handle_meta_io, c, c->socket, IO_READ|IO_WRITE); return true; } @@ -507,10 +505,10 @@ static struct addrinfo *get_known_addresses(node_t *n) { return ai; } -void setup_outgoing_connection(outgoing_t *outgoing) { - timeout_del(&outgoing->ev); +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); @@ -520,7 +518,7 @@ void setup_outgoing_connection(outgoing_t *outgoing) { } init_configuration(&outgoing->config_tree); - read_host_config(outgoing->config_tree, outgoing->name); + read_host_config(mesh, outgoing->config_tree, outgoing->name); outgoing->cfg = lookup_config(outgoing->config_tree, "Address"); if(!outgoing->cfg) { @@ -532,14 +530,15 @@ void setup_outgoing_connection(outgoing_t *outgoing) { } } - do_outgoing_connection(outgoing); + do_outgoing_connection(mesh, outgoing); } /* accept a new tcp connect and create a new connection */ -void handle_new_meta_connection(void *data, int flags) { +void handle_new_meta_connection(event_loop_t *loop, void *data, int flags) { + meshlink_handle_t *mesh = loop->data; listen_socket_t *l = data; connection_t *c; sockaddr_t sa; @@ -569,12 +568,12 @@ void handle_new_meta_connection(void *data, int flags) { static int samehost_burst; static int samehost_burst_time; - if(now.tv_sec - samehost_burst_time > samehost_burst) + if(mesh->loop.now.tv_sec - samehost_burst_time > samehost_burst) samehost_burst = 0; else - samehost_burst -= now.tv_sec - samehost_burst_time; + samehost_burst -= mesh->loop.now.tv_sec - samehost_burst_time; - samehost_burst_time = now.tv_sec; + samehost_burst_time = mesh->loop.now.tv_sec; samehost_burst++; if(samehost_burst > max_connection_burst) { @@ -590,12 +589,12 @@ void handle_new_meta_connection(void *data, int flags) { static int connection_burst; static int connection_burst_time; - if(now.tv_sec - connection_burst_time > connection_burst) + if(mesh->loop.now.tv_sec - connection_burst_time > connection_burst) connection_burst = 0; else - connection_burst -= now.tv_sec - connection_burst_time; + connection_burst -= mesh->loop.now.tv_sec - connection_burst_time; - connection_burst_time = now.tv_sec; + connection_burst_time = mesh->loop.now.tv_sec; connection_burst++; if(connection_burst >= max_connection_burst) { @@ -613,22 +612,22 @@ void handle_new_meta_connection(void *data, int flags) { c->address = sa; c->hostname = sockaddr2hostname(&sa); c->socket = fd; - c->last_ping_time = now.tv_sec; + c->last_ping_time = mesh->loop.now.tv_sec; logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); - io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); + io_add(&mesh->loop, &c->io, handle_meta_io, c, c->socket, IO_READ); 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(outgoing_t *outgoing) { - timeout_del(&outgoing->ev); +static void free_outgoing(meshlink_handle_t *mesh, outgoing_t *outgoing) { + timeout_del(&mesh->loop, &outgoing->ev); if(outgoing->ai) freeaddrinfo(outgoing->ai); @@ -642,20 +641,20 @@ static void free_outgoing(outgoing_t *outgoing) { free(outgoing); } -void try_outgoing_connections(void) { +void try_outgoing_connections(meshlink_handle_t *mesh) { /* If there is no outgoing list yet, create one. Otherwise, mark all outgoings as deleted. */ - if(!outgoing_list) { - outgoing_list = list_alloc((list_action_t)free_outgoing); + if(!mesh->outgoings) { + mesh->outgoings = list_alloc((list_action_t)free_outgoing); } else { - for list_each(outgoing_t, outgoing, outgoing_list) + for list_each(outgoing_t, outgoing, mesh->outgoings) outgoing->timeout = -1; } /* Make sure there is one outgoing_t in the list for each ConnectTo. */ // TODO: Drop support for ConnectTo since AutoConnect is now always on? - for(config_t *cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + for(config_t *cfg = lookup_config(mesh->config, "ConnectTo"); cfg; cfg = lookup_config_next(mesh->config, cfg)) { char *name; get_config_string(cfg, &name); @@ -669,7 +668,7 @@ void try_outgoing_connections(void) { bool found = false; - for list_each(outgoing_t, outgoing, outgoing_list) { + for list_each(outgoing_t, outgoing, mesh->outgoings) { if(!strcmp(outgoing->name, name)) { found = true; outgoing->timeout = 0; @@ -680,8 +679,8 @@ void try_outgoing_connections(void) { if(!found) { outgoing_t *outgoing = xzalloc(sizeof *outgoing); outgoing->name = name; - list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing); + list_insert_tail(mesh->outgoings, outgoing); + setup_outgoing_connection(mesh, outgoing); } } @@ -691,13 +690,13 @@ void try_outgoing_connections(void) { if(c->outgoing && c->outgoing->timeout == -1) { c->outgoing = NULL; logger(DEBUG_CONNECTIONS, LOG_INFO, "No more outgoing connection to %s", c->name); - terminate_connection(c, c->status.active); + terminate_connection(mesh, c, c->status.active); } } /* Delete outgoing_ts for which there is no ConnectTo. */ - for list_each(outgoing_t, outgoing, outgoing_list) + for list_each(outgoing_t, outgoing, mesh->outgoings) if(outgoing->timeout == -1) - list_delete_node(outgoing_list, node); + list_delete_node(mesh->outgoings, node); }