fclose(f);
}
-static char *get_my_hostname(meshlink_handle_t* mesh) {
- char *hostname = NULL;
- char *port = NULL;
- char *hostport = NULL;
- char *name = mesh->self->name;
- char filename[PATH_MAX] = "";
- char line[4096];
- FILE *f;
- // Use first Address statement in own host config file
- snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", mesh->confbase, name);
- scan_for_hostname(filename, &hostname, &port);
+static bool is_valid_hostname(const char *hostname) {
+ for(const char *p = hostname; *p; p++) {
+ if(!(isalnum(*p) || *p == '-' || *p == '.' || *p == ':'))
+ return false;
+ }
- if(hostname)
- goto done;
+ return true;
+}
+
+char *meshlink_get_external_address(meshlink_handle_t *mesh) {
+ char *hostname = NULL;
- // If that doesn't work, guess externally visible hostname
logger(mesh, MESHLINK_DEBUG, "Trying to discover externally visible hostname...\n");
struct addrinfo *ai = str2addrinfo("meshlink.io", "80", SOCK_STREAM);
struct addrinfo *aip = ai;
static const char request[] = "GET http://www.meshlink.io/host.cgi HTTP/1.0\r\n\r\n";
+ char line[256];
while(aip) {
int s = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
freeaddrinfo(ai);
// Check that the hostname is reasonable
- if(hostname) {
- for(char *p = hostname; *p; p++) {
- if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':')
- continue;
- // If not, forget it.
- free(hostname);
- hostname = NULL;
- break;
- }
+ if(hostname && !is_valid_hostname(hostname)) {
+ free(hostname);
+ hostname = NULL;
}
+ if(!hostname)
+ meshlink_errno = MESHLINK_ERESOLV;
+
+ return hostname;
+}
+
+static char *get_my_hostname(meshlink_handle_t* mesh) {
+ char *hostname = NULL;
+ char *port = NULL;
+ char *hostport = NULL;
+ char *name = mesh->self->name;
+ char filename[PATH_MAX] = "";
+ FILE *f;
+
+ // Use first Address statement in own host config file
+ snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", mesh->confbase, name);
+ scan_for_hostname(filename, &hostname, &port);
+
+ if(hostname)
+ goto done;
+
+ hostname = meshlink_get_external_address(mesh);
if(!hostname)
return NULL;
meshlink_errno = MESHLINK_EINVAL;
return false;
}
-
+
+ if(!is_valid_hostname(address)) {
+ logger(mesh, MESHLINK_DEBUG, "Invalid character in address: %s\n", address);
+ meshlink_errno = MESHLINK_EINVAL;
+ return false;
+ }
+
bool rval = false;
pthread_mutex_lock(&(mesh->mesh_mutex));
+ rval = append_config_file(mesh, mesh->self->name, "Address", address);
+ pthread_mutex_unlock(&(mesh->mesh_mutex));
- for(const char *p = address; *p; p++) {
- if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':')
- continue;
- logger(mesh, MESHLINK_DEBUG, "Invalid character in address: %s\n", address);
+ return rval;
+}
+
+bool meshlink_add_external_address(meshlink_handle_t *mesh) {
+ if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
- pthread_mutex_unlock(&(mesh->mesh_mutex));
return false;
}
+ char *address = meshlink_get_external_address(mesh);
+ if(!address)
+ return false;
+
+ bool rval = false;
+
+ pthread_mutex_lock(&(mesh->mesh_mutex));
rval = append_config_file(mesh, mesh->self->name, "Address", address);
pthread_mutex_unlock(&(mesh->mesh_mutex));
+
+ free(address);
return rval;
}