Add tests for network commands
[tinc] / src / net_socket.c
index dfee573..4c76c30 100644 (file)
@@ -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;
        }
 
@@ -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);
@@ -690,32 +689,12 @@ 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);
-
-       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);
-
+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 +709,7 @@ void handle_new_meta_connection(void *data, int flags) {
 
                if(samehost_burst > max_connection_burst) {
                        tarpit(fd);
-                       return;
+                       return true;
                }
        }
 
@@ -753,6 +732,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 +767,7 @@ void handle_new_meta_connection(void *data, int flags) {
 
        c = new_connection();
        c->name = xstrdup("<unknown>");
-#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);
@@ -867,12 +869,12 @@ void try_outgoing_connections(void) {
                                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. */