From b549eb9642b4b8b441b0e23cd3e0b4d7f39907ae Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 19 Jun 2021 17:47:18 +0200 Subject: [PATCH] Remove support for automatically detecting external addresses. --- src/meshlink-tiny++.h | 72 --------- src/meshlink-tiny.h | 99 ------------- src/meshlink.c | 330 ------------------------------------------ src/meshlink.sym | 5 - 4 files changed, 506 deletions(-) diff --git a/src/meshlink-tiny++.h b/src/meshlink-tiny++.h index 1a74c29..eba23aa 100644 --- a/src/meshlink-tiny++.h +++ b/src/meshlink-tiny++.h @@ -526,78 +526,6 @@ public: return meshlink_clear_canonical_address(handle, node); } - /// Add an Address for the local node. - /** This function adds an Address for the local node, which will be used for invitation URLs. - * @deprecated This function is deprecated, use set_canonical_address() and/or add_invitation_address(). - * - * @param address A string containing the address, which can be either in numeric format or a hostname. - * - * @return This function returns true if the address was added, false otherwise. - */ - bool add_address(const char *address) __attribute__((__deprecated__("use set_canonical_address() and/or add_invitation_address() instead"))) { - return meshlink_set_canonical_address(handle, get_self(), address, NULL); - } - - /** This function performs tries to discover the local node's external address - * by contacting the meshlink.io server. If a reverse lookup of the address works, - * the FQDN associated with the address will be returned. - * - * Please note that this is function only returns a single address, - * even if the local node might have more than one external address. - * In that case, there is no control over which address will be selected. - * Also note that if you have a dynamic IP address, or are behind carrier-grade NAT, - * there is no guarantee that the external address will be valid for an extended period of time. - * - * This function is blocking. It can take several seconds before it returns. - * There is no guarantee it will be able to resolve the external address. - * Failures might be because by temporary network outages. - * - * @param family The address family to check, for example AF_INET or AF_INET6. If AF_UNSPEC is given, - * this might return the external address for any working address family. - * - * @return This function returns a pointer to a C string containing the discovered external address, - * or NULL if there was an error looking up the address. - * After get_external_address() returns, the application is free to overwrite or free this string. - */ - bool get_external_address(int family = AF_UNSPEC) { - return meshlink_get_external_address_for_family(handle, family); - } - - /** This function performs tries to discover the address of the local interface used for outgoing connection. - * - * Please note that this is function only returns a single address, - * even if the local node might have more than one external address. - * In that case, there is no control over which address will be selected. - * Also note that if you have a dynamic IP address, or are behind carrier-grade NAT, - * there is no guarantee that the external address will be valid for an extended period of time. - * - * This function will fail if it couldn't find a local address for the given address family. - * If hostname resolving is requested, this function may block for a few seconds. - * - * @param family The address family to check, for example AF_INET or AF_INET6. If AF_UNSPEC is given, - * this might return the external address for any working address family. - * - * @return This function returns a pointer to a C string containing the discovered external address, - * or NULL if there was an error looking up the address. - * After get_external_address() returns, the application is free to overwrite or free this string. - */ - bool get_local_address(int family = AF_UNSPEC) { - return meshlink_get_local_address_for_family(handle, family); - } - - /// Try to discover the external address for the local node, and add it to its list of addresses. - /** This function is equivalent to: - * - * mesh->add_address(mesh->get_external_address()); - * - * Read the description of get_external_address() for the limitations of this function. - * - * @return This function returns true if the address was added, false otherwise. - */ - bool add_external_address() { - return meshlink_add_external_address(handle); - } - /// Set the scheduling granularity of the application /** This should be set to the effective scheduling granularity for the application. * This depends on the scheduling granularity of the operating system, the application's diff --git a/src/meshlink-tiny.h b/src/meshlink-tiny.h index a13e627..131dc8e 100644 --- a/src/meshlink-tiny.h +++ b/src/meshlink-tiny.h @@ -869,105 +869,6 @@ bool meshlink_set_canonical_address(struct meshlink_handle *mesh, struct meshlin */ bool meshlink_clear_canonical_address(struct meshlink_handle *mesh, struct meshlink_node *node) __attribute__((__warn_unused_result__)); -/// Add an Address for the local node. -/** This function adds an Address for the local node, which will be used for invitation URLs. - * @deprecated This function is deprecated, use meshlink_set_canonical_address() and/or meshlink_add_invitation_address(). - * - * \memberof meshlink_handle - * @param mesh A handle which represents an instance of MeshLink. - * @param address A nul-terminated C string containing the address, which can be either in numeric format or a hostname. - * - * @return This function returns true if the address was added, false otherwise. - */ -bool meshlink_add_address(struct meshlink_handle *mesh, const char *address) __attribute__((__warn_unused_result__, __deprecated__("use meshlink_set_canonical_address() and/or meshlink_add_invitation_address() instead"))); - -/// Try to discover the external address for the local node. -/** This function performs tries to discover the local node's external address - * by contacting the meshlink.io server. If a reverse lookup of the address works, - * the FQDN associated with the address will be returned. - * - * Please note that this is function only returns a single address, - * even if the local node might have more than one external address. - * In that case, there is no control over which address will be selected. - * Also note that if you have a dynamic IP address, or are behind carrier-grade NAT, - * there is no guarantee that the external address will be valid for an extended period of time. - * - * This function is blocking. It can take several seconds before it returns. - * There is no guarantee it will be able to resolve the external address. - * Failures might be because by temporary network outages. - * - * \memberof meshlink_handle - * @param mesh A handle which represents an instance of MeshLink. - * - * @return This function returns a pointer to a C string containing the discovered external address, - * or NULL if there was an error looking up the address. - * After meshlink_get_external_address() returns, the application is free to overwrite or free this string. - */ -char *meshlink_get_external_address(struct meshlink_handle *mesh) __attribute__((__warn_unused_result__)); - -/// Try to discover the external address for the local node. -/** This function performs tries to discover the local node's external address - * by contacting the meshlink.io server. If a reverse lookup of the address works, - * the FQDN associated with the address will be returned. - * - * Please note that this is function only returns a single address, - * even if the local node might have more than one external address. - * In that case, there is no control over which address will be selected. - * Also note that if you have a dynamic IP address, or are behind carrier-grade NAT, - * there is no guarantee that the external address will be valid for an extended period of time. - * - * This function is blocking. It can take several seconds before it returns. - * There is no guarantee it will be able to resolve the external address. - * Failures might be because by temporary network outages. - * - * \memberof meshlink_handle - * @param mesh A handle which represents an instance of MeshLink. - * @param address_family The address family to check, for example AF_INET or AF_INET6. If AF_UNSPEC is given, - * this might return the external address for any working address family. - * - * @return This function returns a pointer to a C string containing the discovered external address, - * or NULL if there was an error looking up the address. - * After meshlink_get_external_address_for_family() returns, the application is free to overwrite or free this string. - */ -char *meshlink_get_external_address_for_family(struct meshlink_handle *mesh, int address_family) __attribute__((__warn_unused_result__)); - -/// Try to discover the local address for the local node. -/** This function performs tries to discover the address of the local interface used for outgoing connection. - * - * Please note that this is function only returns a single address, - * even if the interface might have more than one address. - * In that case, there is no control over which address will be selected. - * Also note that if you have a dynamic IP address, - * there is no guarantee that the local address will be valid for an extended period of time. - * - * This function will fail if it couldn't find a local address for the given address family. - * If hostname resolving is requested, this function may block for a few seconds. - * - * \memberof meshlink_handle - * @param mesh A handle which represents an instance of MeshLink. - * @param address_family The address family to check, for example AF_INET or AF_INET6. If AF_UNSPEC is given, - * this might return the local address for any working address family. - * - * @return This function returns a pointer to a C string containing the discovered local address, - * or NULL if there was an error looking up the address. - * After meshlink_get_local_address_for_family() returns, the application is free to overwrite or free this string. - */ -char *meshlink_get_local_address_for_family(struct meshlink_handle *mesh, int address_family) __attribute__((__warn_unused_result__)); - -/// Try to discover the external address for the local node, and add it to its list of addresses. -/** This function is equivalent to: - * - * meshlink_set_canonical_address(mesh, meshlink_get_self(mesh), meshlink_get_external_address(mesh), NULL); - * - * Read the description of meshlink_get_external_address() for the limitations of this function. - * - * \memberof meshlink_handle - * @param mesh A handle which represents an instance of MeshLink. - * - * @return This function returns true if the address was added, false otherwise. - */ -bool meshlink_add_external_address(struct meshlink_handle *mesh) __attribute__((__warn_unused_result__)); - /** This function allows the local node to join an existing mesh using an invitation URL generated by another node. * An invitation can only be used if the local node has never connected to other nodes before. * After a successfully accepted invitation, the name of the local node may have changed. diff --git a/src/meshlink.c b/src/meshlink.c index b7379fc..59776da 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -149,285 +149,6 @@ static int socket_in_netns(int domain, int type, int protocol, int netns) { } -// Find out what local address a socket would use if we connect to the given address. -// We do this using connect() on a UDP socket, so the kernel has to resolve the address -// of both endpoints, but this will actually not send any UDP packet. -static bool getlocaladdr(const char *destaddr, sockaddr_t *sa, socklen_t *salen, int netns) { - struct addrinfo *rai = NULL; - const struct addrinfo hint = { - .ai_family = AF_UNSPEC, - .ai_socktype = SOCK_DGRAM, - .ai_protocol = IPPROTO_UDP, - .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV, - }; - - if(getaddrinfo(destaddr, "80", &hint, &rai) || !rai) { - return false; - } - - int sock = socket_in_netns(rai->ai_family, rai->ai_socktype, rai->ai_protocol, netns); - - if(sock == -1) { - freeaddrinfo(rai); - return false; - } - - if(connect(sock, rai->ai_addr, rai->ai_addrlen) && !sockwouldblock(errno)) { - closesocket(sock); - freeaddrinfo(rai); - return false; - } - - freeaddrinfo(rai); - - if(getsockname(sock, &sa->sa, salen)) { - closesocket(sock); - return false; - } - - closesocket(sock); - return true; -} - -static bool getlocaladdrname(const char *destaddr, char *host, socklen_t hostlen, int netns) { - sockaddr_t sa; - socklen_t salen = sizeof(sa); - - if(!getlocaladdr(destaddr, &sa, &salen, netns)) { - return false; - } - - if(getnameinfo(&sa.sa, salen, host, hostlen, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV)) { - return false; - } - - return true; -} - -char *meshlink_get_external_address(meshlink_handle_t *mesh) { - return meshlink_get_external_address_for_family(mesh, AF_UNSPEC); -} - -char *meshlink_get_external_address_for_family(meshlink_handle_t *mesh, int family) { - logger(mesh, MESHLINK_DEBUG, "meshlink_get_external_address_for_family(%d)", family); - 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(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) { - continue; - } - - int s = socket_in_netns(aip->ai_family, aip->ai_socktype, aip->ai_protocol, mesh->netns); - -#ifdef SO_NOSIGPIPE - int nosigpipe = 1; - setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(nosigpipe)); -#endif - - if(s >= 0) { - set_timeout(s, 5000); - - if(connect(s, aip->ai_addr, aip->ai_addrlen)) { - closesocket(s); - s = -1; - } - } - - if(s >= 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) { - line[len] = 0; - - if(line[len - 1] == '\n') { - line[--len] = 0; - } - - char *p = strrchr(line, '\n'); - - if(p && p[1]) { - hostname = xstrdup(p + 1); - } - } - - closesocket(s); - - if(hostname) { - break; - } - } - } - - if(ai) { - freeaddrinfo(ai); - } - - // Check that the hostname is reasonable - if(hostname && !is_valid_hostname(hostname)) { - free(hostname); - hostname = NULL; - } - - if(!hostname) { - meshlink_errno = MESHLINK_ERESOLV; - } - - return hostname; -} - -static bool is_localaddr(sockaddr_t *sa) { - switch(sa->sa.sa_family) { - case AF_INET: - return *(uint8_t *)(&sa->in.sin_addr.s_addr) == 127; - - case AF_INET6: { - uint16_t first = sa->in6.sin6_addr.s6_addr[0] << 8 | sa->in6.sin6_addr.s6_addr[1]; - return first == 0 || (first & 0xffc0) == 0xfe80; - } - - default: - return false; - } -} - -#ifdef HAVE_GETIFADDRS -struct getifaddrs_in_netns_params { - struct ifaddrs **ifa; - int netns; -}; - -#ifdef HAVE_SETNS -static void *getifaddrs_in_netns_thread(void *arg) { - struct getifaddrs_in_netns_params *params = arg; - - if(setns(params->netns, CLONE_NEWNET) == -1) { - meshlink_errno = MESHLINK_EINVAL; - return NULL; - } - - if(getifaddrs(params->ifa) != 0) { - *params->ifa = NULL; - } - - return NULL; -} -#endif // HAVE_SETNS - -static int getifaddrs_in_netns(struct ifaddrs **ifa, int netns) { - if(netns == -1) { - return getifaddrs(ifa); - } - -#ifdef HAVE_SETNS - struct getifaddrs_in_netns_params params = {ifa, netns}; - pthread_t thr; - - if(pthread_create(&thr, NULL, getifaddrs_in_netns_thread, ¶ms) == 0) { - if(pthread_join(thr, NULL) != 0) { - abort(); - } - } - - return *params.ifa ? 0 : -1; -#else - return -1; -#endif // HAVE_SETNS - -} -#endif - -char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int family) { - logger(mesh, MESHLINK_DEBUG, "meshlink_get_local_address_for_family(%d)", family); - - if(!mesh) { - meshlink_errno = MESHLINK_EINVAL; - return NULL; - } - - // Determine address of the local interface used for outgoing connections. - char localaddr[NI_MAXHOST]; - bool success = false; - - if(family == AF_INET) { - success = getlocaladdrname("93.184.216.34", localaddr, sizeof(localaddr), mesh->netns); - } else if(family == AF_INET6) { - success = getlocaladdrname("2606:2800:220:1:248:1893:25c8:1946", localaddr, sizeof(localaddr), mesh->netns); - } - -#ifdef HAVE_GETIFADDRS - - if(!success) { - struct ifaddrs *ifa = NULL; - getifaddrs_in_netns(&ifa, mesh->netns); - - for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) { - sockaddr_t *sa = (sockaddr_t *)ifap->ifa_addr; - - if(!sa || sa->sa.sa_family != family) { - continue; - } - - if(is_localaddr(sa)) { - continue; - } - - if(!getnameinfo(&sa->sa, SALEN(sa->sa), localaddr, sizeof(localaddr), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV)) { - success = true; - break; - } - } - - freeifaddrs(ifa); - } - -#endif - - if(!success) { - meshlink_errno = MESHLINK_ENETWORK; - return NULL; - } - - return xstrdup(localaddr); -} - static bool write_main_config_files(meshlink_handle_t *mesh) { if(!mesh->confbase) { return true; @@ -807,29 +528,6 @@ static struct timespec idle(event_loop_t *loop, void *data) { return tmin; } -// Get our local address(es) by simulating connecting to an Internet host. -static void add_local_addresses(meshlink_handle_t *mesh) { - sockaddr_t sa; - sa.storage.ss_family = AF_UNKNOWN; - socklen_t salen = sizeof(sa); - - // IPv4 example.org - - if(getlocaladdr("93.184.216.34", &sa, &salen, mesh->netns)) { - sa.in.sin_port = ntohs(atoi(mesh->myport)); - node_add_recent_address(mesh, mesh->self, &sa); - } - - // IPv6 example.org - - salen = sizeof(sa); - - if(getlocaladdr("2606:2800:220:1:248:1893:25c8:1946", &sa, &salen, mesh->netns)) { - sa.in6.sin6_port = ntohs(atoi(mesh->myport)); - node_add_recent_address(mesh, mesh->self, &sa); - } -} - static bool meshlink_setup(meshlink_handle_t *mesh) { if(!config_destroy(mesh->confbase, "new")) { logger(mesh, MESHLINK_ERROR, "Could not delete configuration in %s/new: %s\n", mesh->confbase, strerror(errno)); @@ -1405,8 +1103,6 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { return NULL; } - add_local_addresses(mesh); - if(!node_write_config(mesh, mesh->self, new_configuration)) { logger(NULL, MESHLINK_ERROR, "Cannot update configuration\n"); return NULL; @@ -2380,32 +2076,6 @@ bool meshlink_clear_canonical_address(meshlink_handle_t *mesh, meshlink_node_t * return config_sync(mesh, "current"); } -bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) { - logger(mesh, MESHLINK_DEBUG, "meshlink_add_address(%s)", address ? address : "(null)"); - - return meshlink_set_canonical_address(mesh, (meshlink_node_t *)mesh->self, address, NULL); -} - -bool meshlink_add_external_address(meshlink_handle_t *mesh) { - logger(mesh, MESHLINK_DEBUG, "meshlink_add_external_address()"); - - if(!mesh) { - meshlink_errno = MESHLINK_EINVAL; - return false; - } - - char *address = meshlink_get_external_address(mesh); - - if(!address) { - return false; - } - - bool rval = meshlink_set_canonical_address(mesh, (meshlink_node_t *)mesh->self, address, NULL); - free(address); - - return rval; -} - bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) { logger(mesh, MESHLINK_DEBUG, "meshlink_join(%s)", invitation ? invitation : "(null)"); diff --git a/src/meshlink.sym b/src/meshlink.sym index d7134a7..01149d6 100644 --- a/src/meshlink.sym +++ b/src/meshlink.sym @@ -6,8 +6,6 @@ devtool_open_in_netns devtool_set_meta_status_cb devtool_set_inviter_commits_first devtool_trybind_probe -meshlink_add_address -meshlink_add_external_address meshlink_channel_abort meshlink_channel_aio_fd_receive meshlink_channel_aio_fd_send @@ -34,10 +32,7 @@ meshlink_get_all_nodes meshlink_get_all_nodes_by_dev_class meshlink_get_all_nodes_by_last_reachable meshlink_get_all_nodes_by_submesh -meshlink_get_external_address -meshlink_get_external_address_for_family meshlink_get_fingerprint -meshlink_get_local_address_for_family meshlink_get_node meshlink_get_node_dev_class meshlink_get_node_reachability -- 2.39.2