Improve recently seen address cache
[tinc] / src / net_socket.c
index 5d72471..982bc80 100644 (file)
@@ -671,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);
-
-       fd = accept(l->tcp.fd, &sa.sa, &len);
+       logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name);
 
-       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;
 
@@ -729,7 +705,7 @@ void handle_new_meta_connection(void *data, int flags) {
 
                if(samehost_burst > max_connection_burst) {
                        tarpit(fd);
-                       return;
+                       return true;
                }
        }
 
@@ -752,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;
        }
 
@@ -856,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. */