X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fnet_socket.c;h=d5f85d5a0ceac9a3ed59f9f952c4a85136d6ad77;hb=cc3c69c892b0dad9a6ece0a0f4ccd429a22fcbff;hp=a39c2d2813f8532e32634ca01907cbf53fd3c8ee;hpb=ff306f0cdaedb50de1472e7c1fb55de922a6ca60;p=tinc diff --git a/src/net_socket.c b/src/net_socket.c index a39c2d28..d5f85d5a 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -1,7 +1,7 @@ /* net_socket.c -- Handle various kinds of sockets. Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2013 Guus Sliepen 2006 Scott Lamb 2009 Florian Forster @@ -24,8 +24,11 @@ #include "conf.h" #include "connection.h" +#include "control_common.h" +#include "list.h" #include "logger.h" #include "meta.h" +#include "names.h" #include "net.h" #include "netutl.h" #include "protocol.h" @@ -45,6 +48,9 @@ int udp_sndbuf = 0; listen_socket_t listen_socket[MAXSOCKETS]; int listen_sockets; +#ifndef HAVE_MINGW +io_t unix_socket; +#endif list_t *outgoing_list = NULL; /* Setup sockets */ @@ -62,7 +68,7 @@ static void configure_tcp(connection_t *c) { unsigned long arg = 1; if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s: %d", c->hostname, sockstrerror(sockerrno)); + logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno)); } #endif @@ -270,7 +276,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { return nfd; } /* int setup_vpn_in_socket */ -static void retry_outgoing_handler(int fd, short events, void *data) { +static void retry_outgoing_handler(void *data) { setup_outgoing_connection(data); } @@ -280,12 +286,9 @@ void retry_outgoing(outgoing_t *outgoing) { if(outgoing->timeout > maxtimeout) outgoing->timeout = maxtimeout; - timeout_set(&outgoing->ev, retry_outgoing_handler, outgoing); - event_add(&outgoing->ev, &(struct timeval){outgoing->timeout, 0}); + timeout_add(&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); + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout); } void finish_connecting(connection_t *c) { @@ -348,9 +351,7 @@ static void do_outgoing_pipe(connection_t *c, char *command) { #endif } -static void handle_meta_write(int sock, short events, void *data) { - connection_t *c = data; - +static void handle_meta_write(connection_t *c) { ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); if(outlen <= 0) { if(!errno || errno == EPIPE) { @@ -367,10 +368,16 @@ static void handle_meta_write(int sock, short events, void *data) { } buffer_read(&c->outbuf, outlen); - if(!c->outbuf.len && event_initialized(&c->outevent)) - event_del(&c->outevent); + if(!c->outbuf.len) + io_set(&c->io, IO_READ); } +static void handle_meta_io(void *data, int flags) { + if(flags & IO_WRITE) + handle_meta_write(data); + else + handle_meta_connection_data(data); +} bool do_outgoing_connection(outgoing_t *outgoing) { char *address, *port, *space; @@ -486,16 +493,13 @@ begin: connection_add(c); - event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c); - event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c); - event_add(&c->inevent, NULL); + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); return true; } void setup_outgoing_connection(outgoing_t *outgoing) { - if(event_initialized(&outgoing->ev)) - event_del(&outgoing->ev); + timeout_del(&outgoing->ev); node_t *n = lookup_node(outgoing->name); @@ -522,13 +526,14 @@ void setup_outgoing_connection(outgoing_t *outgoing) { accept a new tcp connect and create a new connection */ -void handle_new_meta_connection(int sock, short events, void *data) { +void handle_new_meta_connection(void *data, int flags) { + listen_socket_t *l = data; connection_t *c; sockaddr_t sa; int fd; socklen_t len = sizeof sa; - fd = accept(sock, &sa.sa, &len); + fd = accept(l->tcp.fd, &sa.sa, &len); if(fd < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); @@ -551,10 +556,8 @@ void handle_new_meta_connection(int sock, short events, void *data) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); - event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c); - event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c); - event_add(&c->inevent, NULL); - + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); + configure_tcp(c); connection_add(c); @@ -563,13 +566,54 @@ void handle_new_meta_connection(int sock, short events, void *data) { send_id(c); } +#ifndef HAVE_MINGW +/* + accept a new UNIX socket connection +*/ +void handle_new_unix_connection(void *data, int flags) { + io_t *io = data; + connection_t *c; + sockaddr_t sa; + int fd; + socklen_t len = sizeof sa; + + fd = accept(io->fd, &sa.sa, &len); + + if(fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); + return; + } + + sockaddrunmap(&sa); + + c = new_connection(); + c->name = xstrdup(""); + c->address = sa; + c->hostname = xstrdup("localhost port unix"); + c->socket = fd; + c->last_ping_time = time(NULL); + + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); + + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); + + connection_add(c); + + c->allow_request = ID; + + send_id(c); +} +#endif + static void free_outgoing(outgoing_t *outgoing) { - if(event_initialized(&outgoing->ev)) - event_del(&outgoing->ev); + timeout_del(&outgoing->ev); if(outgoing->ai) freeaddrinfo(outgoing->ai); + if(outgoing->config_tree) + exit_configuration(&outgoing->config_tree); + if(outgoing->name) free(outgoing->name); @@ -577,24 +621,19 @@ static void free_outgoing(outgoing_t *outgoing) { } void try_outgoing_connections(void) { - static config_t *cfg = NULL; - char *name; - outgoing_t *outgoing; - /* 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); } else { - for(list_node_t *i = outgoing_list->head; i; i = i->next) { - outgoing = i->data; + for list_each(outgoing_t, outgoing, outgoing_list) outgoing->timeout = -1; - } } /* Make sure there is one outgoing_t in the list for each ConnectTo. */ - for(cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + for(config_t *cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + char *name; get_config_string(cfg, &name); if(!check_id(name)) { @@ -607,8 +646,7 @@ void try_outgoing_connections(void) { bool found = false; - for(list_node_t *i = outgoing_list->head; i; i = i->next) { - outgoing = i->data; + for list_each(outgoing_t, outgoing, outgoing_list) { if(!strcmp(outgoing->name, name)) { found = true; outgoing->timeout = 0; @@ -617,7 +655,7 @@ void try_outgoing_connections(void) { } if(!found) { - outgoing = xmalloc_and_zero(sizeof *outgoing); + outgoing_t *outgoing = xmalloc_and_zero(sizeof *outgoing); outgoing->name = name; list_insert_tail(outgoing_list, outgoing); setup_outgoing_connection(outgoing); @@ -626,9 +664,7 @@ void try_outgoing_connections(void) { /* Terminate any connections whose outgoing_t is to be deleted. */ - for(list_node_t *node = connection_list->head, *next; node; node = next) { - next = node->next; - connection_t *c = node->data; + for list_each(connection_t, c, connection_list) { if(c->outgoing && c->outgoing->timeout == -1) { c->outgoing = NULL; logger(DEBUG_CONNECTIONS, LOG_INFO, "No more outgoing connection to %s", c->name); @@ -638,10 +674,7 @@ void try_outgoing_connections(void) { /* Delete outgoing_ts for which there is no ConnectTo. */ - for(list_node_t *node = outgoing_list->head, *next; node; node = next) { - next = node->next; - outgoing = node->data; + for list_each(outgoing_t, outgoing, outgoing_list) if(outgoing->timeout == -1) list_delete_node(outgoing_list, node); - } }