X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fnet_socket.c;h=982bc800a1ebf88860bce270a61ac562aaeec32c;hb=c6a15e27d934e90a1f3a26438dddb395bdc9de19;hp=a8e197b4c430f37dbb1833e31cfacc8b3dfd6ec2;hpb=6debc6c79ba385d35f646e0958f84ace5b8f4b4d;p=tinc diff --git a/src/net_socket.c b/src/net_socket.c index a8e197b4..982bc800 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -47,7 +47,7 @@ int fwmark; listen_socket_t listen_socket[MAXSOCKETS]; int listen_sockets; -#ifndef HAVE_MINGW +#ifndef HAVE_WINDOWS io_t unix_socket; #endif @@ -176,9 +176,20 @@ static bool bind_to_address(connection_t *c) { return true; } +static bool try_bind(int nfd, const sockaddr_t *sa, const char *type) { + if(!bind(nfd, &sa->sa, SALEN(sa->sa))) { + return true; + } + + closesocket(nfd); + char *addrstr = sockaddr2hostname(sa); + logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/%s: %s", addrstr, type, sockstrerror(sockerrno)); + free(addrstr); + return false; +} + int setup_listen_socket(const sockaddr_t *sa) { int nfd; - char *addrstr; int option; char *iface; @@ -237,11 +248,7 @@ int setup_listen_socket(const sockaddr_t *sa) { #endif } - if(bind(nfd, &sa->sa, SALEN(sa->sa))) { - closesocket(nfd); - addrstr = sockaddr2hostname(sa); - logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno)); - free(addrstr); + if(!try_bind(nfd, sa, "tcp")) { return -1; } @@ -282,10 +289,8 @@ static void set_udp_buffer(int nfd, int type, const char *name, int size, bool w } } - int setup_vpn_in_socket(const sockaddr_t *sa) { int nfd; - char *addrstr; int option; nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); @@ -386,11 +391,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { return -1; } - if(bind(nfd, &sa->sa, SALEN(sa->sa))) { - closesocket(nfd); - addrstr = sockaddr2hostname(sa); - logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno)); - free(addrstr); + if(!try_bind(nfd, sa, "udp")) { return -1; } @@ -425,7 +426,7 @@ void finish_connecting(connection_t *c) { } static void do_outgoing_pipe(connection_t *c, const char *command) { -#ifndef HAVE_MINGW +#ifndef HAVE_WINDOWS int fd[2]; if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { @@ -455,9 +456,12 @@ static void do_outgoing_pipe(connection_t *c, const char *command) { sockaddr2str(&c->address, &host, &port); setenv("REMOTEADDRESS", host, true); setenv("REMOTEPORT", port, true); - setenv("NODE", c->name, true); setenv("NAME", myself->name, true); + if(c->name) { + setenv("NODE", c->name, true); + } + if(netname) { setenv("NETNAME", netname, true); } @@ -647,12 +651,7 @@ begin: c->last_ping_time = time(NULL); c->status.connecting = true; c->name = xstrdup(outgoing->node->name); -#ifndef DISABLE_LEGACY - c->outcipher = myself->connection->outcipher; - c->outdigest = myself->connection->outdigest; -#endif c->outmaclength = myself->connection->outmaclength; - c->outcompression = myself->connection->outcompression; c->last_ping_time = now.tv_sec; connection_add(c); @@ -672,50 +671,26 @@ void setup_outgoing_connection(outgoing_t *outgoing, bool verbose) { n->address_cache = open_address_cache(n); } - if(n->connection) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name); - - if(!n->connection->outgoing) { - n->connection->outgoing = outgoing; - return; - } else { - goto remove; - } + if(!n->connection) { + do_outgoing_connection(outgoing); + return; } - do_outgoing_connection(outgoing); - return; - -remove: - list_delete(&outgoing_list, outgoing); -} - -/* - accept a new tcp connect and create a - new connection -*/ -void handle_new_meta_connection(void *data, int flags) { - (void)flags; - listen_socket_t *l = data; - connection_t *c; - sockaddr_t sa; - int fd; - socklen_t len = sizeof(sa); + logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name); - fd = accept(l->tcp.fd, &sa.sa, &len); - - if(fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); - return; + if(n->connection->outgoing) { + list_delete(&outgoing_list, outgoing); + } else { + n->connection->outgoing = outgoing; } +} - sockaddrunmap(&sa); - +static bool check_tarpit(const sockaddr_t *sa, int fd) { // Check if we get many connections from the same host static sockaddr_t prev_sa; - if(!sockaddrcmp_noport(&sa, &prev_sa)) { + if(!sockaddrcmp_noport(sa, &prev_sa)) { static time_t samehost_burst; static time_t samehost_burst_time; @@ -730,7 +705,7 @@ void handle_new_meta_connection(void *data, int flags) { if(samehost_burst > max_connection_burst) { tarpit(fd); - return; + return true; } } @@ -753,6 +728,34 @@ void handle_new_meta_connection(void *data, int flags) { if(connection_burst >= max_connection_burst) { connection_burst = max_connection_burst; tarpit(fd); + return true; + } + + return false; +} + +/* + accept a new tcp connect and create a + new connection +*/ +void handle_new_meta_connection(void *data, int flags) { + (void)flags; + listen_socket_t *l = data; + connection_t *c; + sockaddr_t sa; + int fd; + socklen_t len = sizeof(sa); + + fd = accept(l->tcp.fd, &sa.sa, &len); + + if(fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); + return; + } + + sockaddrunmap(&sa); + + if(!is_local_connection(&sa) && check_tarpit(&sa, fd)) { return; } @@ -760,12 +763,7 @@ void handle_new_meta_connection(void *data, int flags) { c = new_connection(); c->name = xstrdup(""); -#ifndef DISABLE_LEGACY - c->outcipher = myself->connection->outcipher; - c->outdigest = myself->connection->outdigest; -#endif c->outmaclength = myself->connection->outmaclength; - c->outcompression = myself->connection->outcompression; c->address = sa; c->hostname = sockaddr2hostname(&sa); @@ -783,7 +781,7 @@ void handle_new_meta_connection(void *data, int flags) { c->allow_request = ID; } -#ifndef HAVE_MINGW +#ifndef HAVE_WINDOWS /* accept a new UNIX socket connection */ @@ -862,17 +860,16 @@ void try_outgoing_connections(void) { node_t *n = lookup_node(name); if(!n) { - n = new_node(); - n->name = xstrdup(name); + n = new_node(name); node_add(n); } - free(name); - outgoing->node = n; list_insert_tail(&outgoing_list, outgoing); setup_outgoing_connection(outgoing, true); } + + free(name); } /* Terminate any connections whose outgoing_t is to be deleted. */