]> git.meshlink.io Git - meshlink/commitdiff
Add meshlink_set_external_address_discovery_url().
authorGuus Sliepen <guus@meshlink.io>
Sat, 29 Feb 2020 15:19:44 +0000 (16:19 +0100)
committerGuus Sliepen <guus@meshlink.io>
Fri, 6 Mar 2020 21:04:02 +0000 (22:04 +0100)
This function can be used to override the default meshlink.io service to
query a host's own externally visible address.

src/meshlink++.h
src/meshlink.c
src/meshlink.h
src/meshlink.sym
src/meshlink_internal.h

index 4d900448baae145a0b91616190d09c8e5766328e..11e7eabb99d71dc260acfd9c413dd00a21a71b5b 100644 (file)
@@ -1030,6 +1030,17 @@ public:
                meshlink_set_inviter_commits_first(handle, inviter_commits_first);
        }
 
+       /// Set the URL used to discover the host's external address
+       /** For generating invitation URLs, MeshLink can look up the externally visible address of the local node.
+        *  It does so by querying an external service. By default, this is http://meshlink.io/host.cgi.
+        *  Only URLs starting with http:// are supported.
+        *
+        *  @param url   The URL to use for external address queries, or NULL to revert back to the default URL.
+        */
+       void set_external_address_discovery_url(const char *url) {
+               meshlink_set_external_address_discovery_url(handle, url);
+       }
+
 private:
        // non-copyable:
        mesh(const mesh &) /* TODO: C++11: = delete */;
index def3e6efc9557a7d83d7b4d587b223eb1e256ba1..3ebaee01da441aa589279e2ecd4076dd75cc7f1b 100644 (file)
@@ -221,12 +221,42 @@ char *meshlink_get_external_address(meshlink_handle_t *mesh) {
 }
 
 char *meshlink_get_external_address_for_family(meshlink_handle_t *mesh, int family) {
-       char *hostname = NULL;
+       const char *url = mesh->external_address_url;
+
+       if(!url) {
+               url = "http://meshlink.io/host.cgi";
+       }
+
+       /* Find the hostname part between the slashes */
+       if(strncmp(url, "http://", 7)) {
+               abort();
+               meshlink_errno = MESHLINK_EINTERNAL;
+               return NULL;
+       }
+
+       const char *begin = url + 7;
+
+       const char *end = strchr(begin, '/');
+
+       if(!end) {
+               end = begin + strlen(begin);
+       }
+
+       /* Make a copy */
+       char host[end - begin + 1];
+       strncpy(host, begin, end - begin);
+       host[end - begin] = 0;
+
+       char *port = strchr(host, ':');
+
+       if(port) {
+               *port++ = 0;
+       }
 
        logger(mesh, MESHLINK_DEBUG, "Trying to discover externally visible hostname...\n");
-       struct addrinfo *ai = str2addrinfo("meshlink.io", "80", SOCK_STREAM);
-       static const char request[] = "GET http://www.meshlink.io/host.cgi HTTP/1.0\r\n\r\n";
+       struct addrinfo *ai = str2addrinfo(host, port ? port : "80", SOCK_STREAM);
        char line[256];
+       char *hostname = NULL;
 
        for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
                if(family != AF_UNSPEC && aip->ai_family != family) {
@@ -245,7 +275,9 @@ char *meshlink_get_external_address_for_family(meshlink_handle_t *mesh, int fami
                }
 
                if(s >= 0) {
-                       send(s, request, sizeof(request) - 1, 0);
+                       send(s, "GET ", 4, 0);
+                       send(s, url, strlen(url), 0);
+                       send(s, " HTTP/1.0\r\n\r\n", 13, 0);
                        int len = recv(s, line, sizeof(line) - 1, MSG_WAITALL);
 
                        if(len > 0) {
@@ -1754,6 +1786,7 @@ void meshlink_close(meshlink_handle_t *mesh) {
        free(mesh->appname);
        free(mesh->confbase);
        free(mesh->config_key);
+       free(mesh->external_address_url);
        ecdsa_free(mesh->private_key);
 
        main_config_unlock(mesh);
@@ -3986,6 +4019,23 @@ extern void meshlink_set_inviter_commits_first(struct meshlink_handle *mesh, boo
        pthread_mutex_unlock(&mesh->mutex);
 }
 
+void meshlink_set_external_address_discovery_url(struct meshlink_handle *mesh, const char *url) {
+       if(!mesh) {
+               meshlink_errno = EINVAL;
+               return;
+       }
+
+       if(url && (strncmp(url, "http://", 7) || strchr(url, ' '))) {
+               meshlink_errno = EINVAL;
+               return;
+       }
+
+       pthread_mutex_lock(&mesh->mutex);
+       free(mesh->external_address_url);
+       mesh->external_address_url = url ? xstrdup(url) : NULL;
+       pthread_mutex_unlock(&mesh->mutex);
+}
+
 void handle_network_change(meshlink_handle_t *mesh, bool online) {
        (void)online;
 
index 385c12cec44b17f5a5609e62d5ad42b6607ba507..2877c64e6e1f1a3c4730cb1572566edd8de229e6 100644 (file)
@@ -1562,6 +1562,17 @@ extern void meshlink_set_dev_class_fast_retry_period(struct meshlink_handle *mes
  */
 extern void meshlink_set_inviter_commits_first(struct meshlink_handle *mesh, bool inviter_commits_first);
 
+/// Set the URL used to discover the host's external address
+/** For generating invitation URLs, MeshLink can look up the externally visible address of the local node.
+ *  It does so by querying an external service. By default, this is http://meshlink.io/host.cgi.
+ *  Only URLs starting with http:// are supported.
+ *
+ *  \memberof meshlink_handle
+ *  @param mesh  A handle which represents an instance of MeshLink.
+ *  @param url   The URL to use for external address queries, or NULL to revert back to the default URL.
+ */
+extern void meshlink_set_external_address_discovery_url(struct meshlink_handle *mesh, const char *url);
+
 #ifdef __cplusplus
 }
 #endif
index de640c0c7069cac8c4e21f7dc11bd54043c34766..6c4dd5729de6e3cf77c049367fa8a6aa0c604ff5 100644 (file)
@@ -70,6 +70,7 @@ meshlink_set_default_blacklist
 meshlink_set_dev_class_fast_retry_period
 meshlink_set_dev_class_timeouts
 meshlink_set_error_cb
+meshlink_set_external_address_discovery_url
 meshlink_set_invitation_timeout
 meshlink_set_inviter_commits_first
 meshlink_set_log_cb
index f895e02f6b50dffebc28e80232fd0f3ef8141eaa..8c67aa3e4daf3c2adc0aaa93f74e4eaa3c7d0223 100644 (file)
@@ -174,6 +174,7 @@ struct meshlink_handle {
        char *confbase;
        FILE *lockfile;
        void *config_key;
+       char *external_address_url;
 
        // Thread management
        pthread_t thread;