X-Git-Url: http://git.meshlink.io/?p=meshlink;a=blobdiff_plain;f=src%2Fmeshlink.c;h=f6121a1ea67f589335f271a7b3edd39568ca8435;hp=1de54e916dab53abaa5f85a3db8739783fa3d3f1;hb=5c7be85686db219955e1af592b32d0d4108625cb;hpb=13ef38b7a24efc84122b4d2bfc86cddbc359b94f diff --git a/src/meshlink.c b/src/meshlink.c index 1de54e91..f6121a1e 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -59,6 +59,7 @@ const var_t variables[] = { {"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE}, {"Name", VAR_SERVER}, /* Host configuration */ + {"CanonicalAddress", VAR_HOST}, {"Address", VAR_HOST | VAR_MULTIPLE}, {"ECDSAPublicKey", VAR_HOST}, {"Port", VAR_HOST}, @@ -96,6 +97,7 @@ static int rstrip(char *value) { static void scan_for_hostname(const char *filename, char **hostname, char **port) { char line[4096]; + bool canonical = false; if(!filename || (*hostname && *port)) { return; @@ -135,25 +137,33 @@ static void scan_for_hostname(const char *filename, char **hostname, char **port p += strspn(p, "\t "); p[strcspn(p, "\t ")] = 0; - // p is now pointing to the port - - // Check that the hostname is a symbolic name (it's not a numeric IPv4 or IPv6 address) - if(!q[strspn(q, "0123456789.")] || strchr(q, ':')) { - continue; - } + // p is now pointing to the port, if present if(!*port && !strcasecmp(line, "Port")) { *port = xstrdup(q); - } else if(!*hostname && !strcasecmp(line, "Address")) { + } else if(!canonical && !*hostname && !strcasecmp(line, "Address")) { + // Check that the hostname is a symbolic name (it's not a numeric IPv4 or IPv6 address) + if(!q[strspn(q, "0123456789.")] || strchr(q, ':')) { + continue; + } + *hostname = xstrdup(q); + if(*p) { + free(*port); + *port = xstrdup(p); + } + } else if(!strcasecmp(line, "CanonicalAddress")) { + *hostname = xstrdup(q); + canonical = true; + if(*p) { free(*port); *port = xstrdup(p); } } - if(*hostname && *port) { + if(canonical && *hostname && *port) { break; } } @@ -162,6 +172,10 @@ static void scan_for_hostname(const char *filename, char **hostname, char **port } static bool is_valid_hostname(const char *hostname) { + if(!*hostname) { + return false; + } + for(const char *p = hostname; *p; p++) { if(!(isalnum(*p) || *p == '-' || *p == '.' || *p == ':')) { return false; @@ -171,6 +185,26 @@ static bool is_valid_hostname(const char *hostname) { return true; } +static bool is_valid_port(const char *port) { + if(!*port) { + return false; + } + + if(isdigit(*port)) { + char *end; + unsigned long int result = strtoul(port, &end, 10); + return result && result < 65536 && !*end; + } + + for(const char *p = port; *p; p++) { + if(!(isalnum(*p) || *p == '-')) { + return false; + } + } + + return true; +} + static void set_timeout(int sock, int timeout) { #ifdef _WIN32 DWORD tv = timeout; @@ -1675,8 +1709,8 @@ static bool refresh_invitation_key(meshlink_handle_t *mesh) { return mesh->invitation_key; } -bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) { - if(!mesh || !address) { +bool meshlink_set_canonical_address(meshlink_handle_t *mesh, meshlink_node_t *node, const char *address, const char *port) { + if(!mesh || !node || !address) { meshlink_errno = MESHLINK_EINVAL; return false; } @@ -1687,15 +1721,32 @@ bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) { return false; } - bool rval = false; + if(port && !is_valid_port(port)) { + logger(mesh, MESHLINK_DEBUG, "Invalid character in port: %s\n", address); + meshlink_errno = MESHLINK_EINVAL; + return false; + } + + char *canonical_address; + + if(port) { + xasprintf(&canonical_address, "%s %s", address, port); + } else { + canonical_address = xstrdup(address); + } pthread_mutex_lock(&(mesh->mesh_mutex)); - rval = append_config_file(mesh, mesh->self->name, "Address", address); + bool rval = modify_config_file(mesh, node->name, "CanonicalAddress", canonical_address, 1); pthread_mutex_unlock(&(mesh->mesh_mutex)); + free(canonical_address); return rval; } +bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) { + return meshlink_set_canonical_address(mesh, mesh->self, address, NULL); +} + bool meshlink_add_external_address(meshlink_handle_t *mesh) { if(!mesh) { meshlink_errno = MESHLINK_EINVAL;