]> git.meshlink.io Git - meshlink/commitdiff
Feature external ip address master
authorElear Solutions Dev <38581919+elear-solutions-dev@users.noreply.github.com>
Sun, 20 Oct 2024 15:25:59 +0000 (20:55 +0530)
committerGitHub <noreply@github.com>
Sun, 20 Oct 2024 15:25:59 +0000 (20:55 +0530)
* Basic external_ip_address support

* Added support for port parsing for external IP address

* Cleanup some logging

src/meshlink.c
src/net_packet.c
src/node.c
src/node.h
src/protocol.h
src/protocol_key.c

index a1a2ec407c87477a9e77e204b700b5f944afdb52..d634989014526cef1e1a64e0dbf2efda342d4efb 100644 (file)
@@ -1656,6 +1656,19 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) {
                return NULL;
        }
 
+       if(mesh->devclass == DEV_CLASS_BACKBONE) {
+               logger(NULL, MESHLINK_DEBUG, "Resolving external IP address as we are a backbone node\n");
+
+               mesh->self->external_ip_address = meshlink_get_external_address(mesh);
+
+               // if(meshlink_errno == MESHLINK_ERESOLV) {
+               if(!mesh->self->external_ip_address) {
+                       logger(NULL, MESHLINK_WARNING, "Couldn't resolve external IP address, continuing without it...\n");
+               } else {
+                       logger(NULL, MESHLINK_INFO, "Found external IP address: %s\n", mesh->self->external_ip_address);
+               }
+       }
+
        add_local_addresses(mesh);
 
        if(!node_write_config(mesh, mesh->self, new_configuration)) {
index acc90c97497668f00e491d724d801626e2648402..183631f83c98fe1830b7110bb64c442d65dce680 100644 (file)
@@ -339,20 +339,52 @@ static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const s
                goto check_socket;
        }
 
+       /* Else, if we have a external IP address, try this once every batch */
+       if(mesh->udp_choice == 1 && n->external_ip_address) {
+               logger(mesh, MESHLINK_DEBUG, "Trying the external IP address...\n");
+
+               char *host = xstrdup(n->external_ip_address);
+               char *port = strchr(host, ' ');
+
+               if(port) {
+                       *port++ = 0;
+                       logger(mesh, MESHLINK_DEBUG, "Using external IP host: %s and port %s\n", host, port);
+                       *sa_buf = str2sockaddr(host, port);
+                       *sa = sa_buf;
+
+                       if(sa_buf->sa.sa_family != AF_UNKNOWN) {
+                               free(host);
+                               goto check_socket;
+                       } else {
+                               logger(mesh, MESHLINK_DEBUG, "Couldn't create str2sockaddr, so skipping external IP address...\n");
+                       }
+               } else {
+                       logger(mesh, MESHLINK_DEBUG, "Couldn't find port, so skipping external IP address...\n");
+               }
+
+               free(host);
+       }
+
        /* Else, if we have a canonical address, try this once every batch */
        if(mesh->udp_choice == 1 && n->canonical_address) {
+               logger(mesh, MESHLINK_DEBUG, "Trying the canonical host...\n");
                char *host = xstrdup(n->canonical_address);
                char *port = strchr(host, ' ');
 
                if(port) {
                        *port++ = 0;
+                       logger(mesh, MESHLINK_DEBUG, "Using canonical host: %s and port %s\n", host, port);
                        *sa_buf = str2sockaddr_random(mesh, host, port);
                        *sa = sa_buf;
 
                        if(sa_buf->sa.sa_family != AF_UNKNOWN) {
                                free(host);
                                goto check_socket;
+                       } else {
+                               logger(mesh, MESHLINK_DEBUG, "Couldn't create str2sockaddr, so skipping canonical host...\n");
                        }
+               } else {
+                       logger(mesh, MESHLINK_DEBUG, "Couldn't find port, so skipping canonical host...\n");
                }
 
                free(host);
index b8caed6c7e06ca182f671fd046f8be4d44d76611..ae661a1b2b3c3de417a5e71fd2797137ae08aaab 100644 (file)
@@ -82,6 +82,7 @@ void free_node(node_t *n) {
 
        free(n->name);
        free(n->canonical_address);
+       free(n->external_ip_address);
 
        free(n);
 }
index 918f1cce8db0821c064ac9dad125b53d3ef3ae55..2e6d1317f45644a0e40debd14ceaabefa10c6b57 100644 (file)
@@ -88,6 +88,7 @@ typedef struct node_t {
        time_t last_successfull_connection;
 
        char *canonical_address;                /* The canonical address of this node, if known */
+       char *external_ip_address;              /* The external IP address of this node, if known */
        sockaddr_t recent[MAX_RECENT];          /* Recently seen addresses */
        sockaddr_t catta_address;               /* Latest address seen by Catta */
 
index 94f760f1e2cb0cf51b5d786b93eedb4de994e314..8a02ba382aa762875e0e13a52069a8877593fbb6 100644 (file)
@@ -49,6 +49,7 @@ typedef enum request_t {
        REQ_PUBKEY, ANS_PUBKEY,
        REQ_SPTPS,
        REQ_CANONICAL,
+       REQ_EXTERNAL,
        NUM_REQUESTS
 } request_t;
 
@@ -100,6 +101,7 @@ bool send_add_edge(struct meshlink_handle *mesh, struct connection_t *, const st
 bool send_del_edge(struct meshlink_handle *mesh, struct connection_t *, const struct edge_t *, int contradictions);
 bool send_req_key(struct meshlink_handle *mesh, struct node_t *);
 bool send_canonical_address(struct meshlink_handle *mesh, struct node_t *);
+bool send_external_ip_address(struct meshlink_handle *mesh, struct node_t *);
 bool send_raw_packet(struct meshlink_handle *mesh, struct connection_t *, const vpn_packet_t *);
 
 /* Request handlers  */
index 745845a650ebd0453660e53301a0cbc056459931..6e5c1a8f6317015b3207f415d68221afec13f625 100644 (file)
@@ -83,6 +83,14 @@ static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data
        return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_KEY, buf);
 }
 
+bool send_external_ip_address(meshlink_handle_t *mesh, node_t *to) {
+       if(!mesh->self->external_ip_address) {
+               return true;
+       }
+
+       return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %d %s %s", REQ_KEY, mesh->self->name, to->name, REQ_EXTERNAL, mesh->self->external_ip_address, mesh->myport);
+}
+
 bool send_canonical_address(meshlink_handle_t *mesh, node_t *to) {
        if(!mesh->self->canonical_address) {
                return true;
@@ -113,6 +121,9 @@ bool send_req_key(meshlink_handle_t *mesh, node_t *to) {
        /* Send our canonical address to help with UDP hole punching */
        send_canonical_address(mesh, to);
 
+       /* Send our external IP address to help with UDP hole punching */
+       send_external_ip_address(mesh, to);
+
        char label[sizeof(meshlink_udp_label) + strlen(mesh->self->name) + strlen(to->name) + 2];
        snprintf(label, sizeof(label), "%s %s %s", meshlink_udp_label, mesh->self->name, to->name);
        sptps_stop(&to->sptps);
@@ -231,6 +242,9 @@ static bool req_key_ext_h(meshlink_handle_t *mesh, connection_t *c, const char *
                /* Send our canonical address to help with UDP hole punching */
                send_canonical_address(mesh, from);
 
+               /* Send our external IP address to help with UDP hole punching */
+               send_external_ip_address(mesh, from);
+
                if(!sptps_start(&from->sptps, from, false, true, mesh->private_key, from->ecdsa, label, sizeof(label) - 1, send_sptps_data, receive_sptps_record)) {
                        logger(mesh, MESHLINK_ERROR, "Could not start SPTPS session with %s: %s", from->name, strerror(errno));
                        return true;
@@ -287,6 +301,28 @@ static bool req_key_ext_h(meshlink_handle_t *mesh, connection_t *c, const char *
                return true;
        }
 
+       case REQ_EXTERNAL: {
+               char ip[MAX_STRING_SIZE];
+               char port[MAX_STRING_SIZE];
+               logger(mesh, MESHLINK_DEBUG, "Got %s from %s with data: %s", "REQ_EXTERNAL", from->name, request);
+
+               if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING " " MAX_STRING, ip, port) != 2) {
+                       logger(mesh, MESHLINK_ERROR, "Got bad %s from %s: %s", "REQ_EXTERNAL", from->name, request);
+                       return true;
+               }
+
+               char *external_ip_address;
+               xasprintf(&external_ip_address, "%s %s", ip, port);
+
+               if(mesh->log_level <= MESHLINK_DEBUG && (!from->external_ip_address || strcmp(from->external_ip_address, external_ip_address))) {
+                       logger(mesh, MESHLINK_DEBUG, "Updating external IP address of %s to %s", from->name, external_ip_address);
+               }
+
+               free(from->external_ip_address);
+               from->external_ip_address = external_ip_address;
+               return true;
+       }
+
        default:
                logger(mesh, MESHLINK_ERROR, "Unknown extended REQ_KEY request from %s: %s", from->name, request);
                return true;