]> git.meshlink.io Git - meshlink/blobdiff - src/net_socket.c
Add meta-connection attempt callback feature
[meshlink] / src / net_socket.c
index 1e981af6b2a61e48357e32b23a83dbbfa613cacf..3047ccbd8bfedeae2debdeb717bdf441c7bb040f 100644 (file)
@@ -453,7 +453,7 @@ static bool get_next_outgoing_address(meshlink_handle_t *mesh, outgoing_t *outgo
        }
 
        if(outgoing->state == OUTGOING_CANONICAL) {
-               if(outgoing->aip || get_next_cfg(mesh, outgoing, "CanonicalAddress")) {
+               while(outgoing->aip || get_next_cfg(mesh, outgoing, "CanonicalAddress")) {
                        if(get_next_ai(mesh, outgoing)) {
                                return true;
                        } else {
@@ -467,7 +467,7 @@ static bool get_next_outgoing_address(meshlink_handle_t *mesh, outgoing_t *outgo
        }
 
        if(outgoing->state == OUTGOING_RECENT) {
-               if(outgoing->aip || get_next_cfg(mesh, outgoing, "Address")) {
+               while(outgoing->aip || get_next_cfg(mesh, outgoing, "Address")) {
                        if(get_next_ai(mesh, outgoing)) {
                                return true;
                        } else {
@@ -481,14 +481,18 @@ static bool get_next_outgoing_address(meshlink_handle_t *mesh, outgoing_t *outgo
        }
 
        if(outgoing->state == OUTGOING_KNOWN) {
-               if(outgoing->aip || get_recent(mesh, outgoing)) {
-                       if(get_next_ai(mesh, outgoing)) {
-                               return true;
-                       } else {
-                               free_known_addresses(outgoing->ai);
-                               outgoing->ai = NULL;
-                               outgoing->aip = NULL;
-                       }
+               if(!outgoing->aip) {
+                       get_recent(mesh, outgoing);
+               } else {
+                       outgoing->aip = outgoing->aip->ai_next;
+               }
+
+               if(outgoing->aip) {
+                       return true;
+               } else {
+                       free_known_addresses(outgoing->ai);
+                       outgoing->ai = NULL;
+                       outgoing->aip = NULL;
                }
 
                outgoing->state = OUTGOING_END;
@@ -633,9 +637,30 @@ void setup_outgoing_connection(meshlink_handle_t *mesh, outgoing_t *outgoing) {
                return;
        }
 
+       if(mesh->connection_try_cb) {
+               node_t *n = lookup_node(mesh, outgoing->name);
+               mesh->connection_try_cb(mesh, (struct meshlink_node *)n);
+       }
+
        do_outgoing_connection(mesh, outgoing);
 }
 
+/// Delayed close of a filedescriptor.
+static void tarpit(int fd) {
+       static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+       static int next_pit = 0;
+
+       if(pits[next_pit] != -1) {
+               closesocket(pits[next_pit]);
+       }
+
+       pits[next_pit++] = fd;
+
+       if(next_pit >= (int)(sizeof pits / sizeof pits[0])) {
+               next_pit = 0;
+       }
+}
+
 /*
   accept a new tcp connect and create a
   new connection
@@ -663,57 +688,23 @@ void handle_new_meta_connection(event_loop_t *loop, void *data, int flags) {
 
        sockaddrunmap(&sa);
 
-       // Check if we get many connections from the same host
-
-       static sockaddr_t prev_sa;
-       static int tarpit = -1;
-
-       if(tarpit >= 0) {
-               closesocket(tarpit);
-               tarpit = -1;
-       }
-
-       if(!sockaddrcmp_noport(&sa, &prev_sa)) {
-               static int samehost_burst;
-               static int samehost_burst_time;
-
-               if(mesh->loop.now.tv_sec - samehost_burst_time > samehost_burst) {
-                       samehost_burst = 0;
-               } else {
-                       samehost_burst -= mesh->loop.now.tv_sec - samehost_burst_time;
-               }
-
-               samehost_burst_time = mesh->loop.now.tv_sec;
-               samehost_burst++;
-
-               if(samehost_burst > max_connection_burst) {
-                       tarpit = fd;
-                       return;
-               }
-       }
-
-       memcpy(&prev_sa, &sa, sizeof(sa));
-
-       // Check if we get many connections from different hosts
+       /* Rate limit incoming connections to max_connection_burst/second. */
 
        static int connection_burst;
        static int connection_burst_time;
 
-       if(mesh->loop.now.tv_sec - connection_burst_time > connection_burst) {
+       if(mesh->loop.now.tv_sec != connection_burst_time) {
+               connection_burst_time = mesh->loop.now.tv_sec;
                connection_burst = 0;
-       } else {
-               connection_burst -= mesh->loop.now.tv_sec - connection_burst_time;
        }
 
-       connection_burst_time = mesh->loop.now.tv_sec;
-       connection_burst++;
-
        if(connection_burst >= max_connection_burst) {
-               connection_burst = max_connection_burst;
-               tarpit = fd;
+               tarpit(fd);
                return;
        }
 
+       connection_burst++;
+
        // Accept the new connection
 
        c = new_connection();
@@ -782,8 +773,8 @@ void try_outgoing_connections(meshlink_handle_t *mesh) {
 
                if(!check_id(name)) {
                        logger(mesh, MESHLINK_ERROR,
-                              "Invalid name for outgoing connection in %s line %d",
-                              cfg->file, cfg->line);
+                              "Invalid name for outgoing connection in line %d",
+                              cfg->line);
                        free(name);
                        continue;
                }