]> git.meshlink.io Git - meshlink/blobdiff - src/protocol_key.c
Feature external ip address
[meshlink] / src / protocol_key.c
index 25dbc55e5c04b7533e9eb0f6c5eeb62214cc648e..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;
@@ -345,6 +381,10 @@ bool req_key_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
                        return true;
                }
 
+               size_t len = strlen(request);
+               from->in_forward += len + SPTPS_OVERHEAD;
+               to->out_forward += len + SPTPS_OVERHEAD;
+
                send_request(mesh, to->nexthop->connection, NULL, "%s", request);
        }
 
@@ -411,6 +451,11 @@ bool ans_key_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
                        return false;
                }
 
+               /* TODO: find a good way to avoid the use of strlen() */
+               size_t len = strlen(request);
+               from->in_forward += len + SPTPS_OVERHEAD;
+               to->out_forward += len + SPTPS_OVERHEAD;
+
                /* Append the known UDP address of the from node, if we have a confirmed one */
                if(!*address && from->status.udp_confirmed && from->address.sa.sa_family != AF_UNSPEC) {
                        char *reflexive_address, *reflexive_port;