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)) {
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);
free(n->name);
free(n->canonical_address);
+ free(n->external_ip_address);
free(n);
}
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 */
REQ_PUBKEY, ANS_PUBKEY,
REQ_SPTPS,
REQ_CANONICAL,
+ REQ_EXTERNAL,
NUM_REQUESTS
} request_t;
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 */
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;
/* 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);
/* 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;
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;