]> git.meshlink.io Git - meshlink-tiny/commitdiff
Remove graph, edges and communication via UDP.
authorGuus Sliepen <guus@meshlink.io>
Sun, 13 Jun 2021 21:58:54 +0000 (23:58 +0200)
committerGuus Sliepen <guus@meshlink.io>
Sat, 19 Jun 2021 13:58:03 +0000 (15:58 +0200)
42 files changed:
src/Makefile.am
src/connection.h
src/devtools.c
src/devtools.h
src/discovery.c [deleted file]
src/discovery.h [deleted file]
src/edge.c [deleted file]
src/edge.h [deleted file]
src/graph.c [deleted file]
src/graph.h [deleted file]
src/mdns.c [deleted file]
src/mdns.h [deleted file]
src/meshlink-tiny++.h
src/meshlink-tiny.h
src/meshlink.c
src/meshlink.sym
src/meshlink_internal.h
src/net.c
src/net.h
src/net_packet.c
src/net_setup.c
src/net_socket.c
src/node.c
src/node.h
src/protocol.h
src/protocol_auth.c
src/protocol_edge.c
src/protocol_key.c
test/basic.c
test/basicpp.cpp
test/channels-aio-fd.c
test/channels-fork.c
test/channels-udp.c
test/duplicate.c
test/get-all-nodes.c
test/import-export.c
test/invite-join.c
test/netns_utils.c
test/storage-policy.c
test/trio.c
test/trio2.c
test/utils.c

index 8d624923e3fd876066ec93b3b332cbd1596c1081..51a42e9688ab8824e3f24ec42ef9e0b047a12c48 100644 (file)
@@ -42,19 +42,15 @@ libmeshlink_tiny_la_SOURCES = \
        conf.c conf.h \
        connection.c connection.h \
        crypto.c crypto.h \
-       discovery.c discovery.h \
        dropin.c dropin.h \
        ecdh.h \
        ecdsa.h \
        ecdsagen.h \
-       edge.c edge.h \
        event.c event.h \
-       graph.c graph.h \
        hash.c hash.h \
        have.h \
        list.c list.h \
        logger.c logger.h \
-       mdns.c mdns.h \
        meshlink.c meshlink-tiny.h meshlink.sym \
        meshlink_internal.h \
        meshlink_queue.h \
index b5ccaed9ec46b299bcf4a89445c1ab221a7e6638..248f80674e5af5f2413412f2cdef947f0233c1c1 100644 (file)
@@ -44,7 +44,6 @@ typedef struct connection_status_t {
 } connection_status_t;
 
 #include "ecdsa.h"
-#include "edge.h"
 #include "net.h"
 #include "node.h"
 #include "submesh.h"
@@ -71,7 +70,6 @@ typedef struct connection_t {
 
        struct outgoing_t *outgoing;    /* used to keep track of outgoing connections */
 
-       struct edge_t *edge;            /* edge associated with this connection */
        struct submesh_t *submesh;      /* his submesh handle if available in invitation file */
 
        // Only used during authentication
index 2a98e595054850a78fecd489058acba6914db846..d14d1d81370cdadf7d18232585b02bdcd2861003 100644 (file)
@@ -55,210 +55,6 @@ void (*devtool_set_inviter_commits_first)(bool inviter_commited_first) = inviter
 void (*devtool_adns_resolve_probe)(void) = nop_probe;
 void (*devtool_sptps_renewal_probe)(meshlink_node_t *node) = sptps_renewal_nop_probe;
 
-/* Return an array of edges in the current network graph.
- * Data captures the current state and will not be updated.
- * Caller must deallocate data when done.
- */
-devtool_edge_t *devtool_get_all_edges(meshlink_handle_t *mesh, devtool_edge_t *edges, size_t *nmemb) {
-       if(!mesh || !nmemb || (*nmemb && !edges)) {
-               meshlink_errno = MESHLINK_EINVAL;
-               return NULL;
-       }
-
-       if(pthread_mutex_lock(&mesh->mutex) != 0) {
-               abort();
-       }
-
-       devtool_edge_t *result = NULL;
-       unsigned int result_size = 0;
-
-       result_size = mesh->edges->count / 2;
-
-       // if result is smaller than edges, we have to dealloc all the excess devtool_edge_t
-       if((size_t)result_size > *nmemb) {
-               result = xrealloc(edges, result_size * sizeof(*result));
-       } else {
-               result = edges;
-       }
-
-       if(result) {
-               devtool_edge_t *p = result;
-               unsigned int n = 0;
-
-               for splay_each(edge_t, e, mesh->edges) {
-                       // skip edges that do not represent a two-directional connection
-                       if(!e->reverse || e->reverse->to != e->from) {
-                               continue;
-                       }
-
-                       // don't count edges twice
-                       if(e->to < e->from) {
-                               continue;
-                       }
-
-                       assert(n < result_size);
-
-                       p->from = (meshlink_node_t *)e->from;
-                       p->to = (meshlink_node_t *)e->to;
-                       p->address = e->address.storage;
-                       p->weight = e->weight;
-
-                       n++;
-                       p++;
-               }
-
-               // shrink result to the actual amount of memory used
-               result = xrealloc(result, n * sizeof(*result));
-               *nmemb = n;
-       } else {
-               *nmemb = 0;
-               meshlink_errno = MESHLINK_ENOMEM;
-       }
-
-       pthread_mutex_unlock(&mesh->mutex);
-
-       return result;
-}
-
-static bool fstrwrite(const char *str, FILE *stream) {
-       assert(stream);
-
-       size_t len = strlen(str);
-
-       if(fwrite((void *)str, 1, len, stream) != len) {
-               return false;
-       }
-
-       return true;
-}
-
-bool devtool_export_json_all_edges_state(meshlink_handle_t *mesh, FILE *stream) {
-       assert(stream);
-
-       bool result = true;
-
-       if(pthread_mutex_lock(&mesh->mutex) != 0) {
-               abort();
-       }
-
-       // export edges and nodes
-       size_t node_count = 0;
-       size_t edge_count = 0;
-
-       meshlink_node_t **nodes = meshlink_get_all_nodes(mesh, NULL, &node_count);
-       devtool_edge_t *edges = devtool_get_all_edges(mesh, NULL, &edge_count);
-
-       if((!nodes && node_count != 0) || (!edges && edge_count != 0)) {
-               goto fail;
-       }
-
-       // export begin
-       if(!fstrwrite("{\n", stream)) {
-               goto fail;
-       }
-
-       // export nodes
-       if(!fstrwrite("\t\"nodes\": {\n", stream)) {
-               goto fail;
-       }
-
-       char buf[16];
-
-       for(size_t i = 0; i < node_count; ++i) {
-               if(!fstrwrite("\t\t\"", stream) || !fstrwrite(((node_t *)nodes[i])->name, stream) || !fstrwrite("\": {\n", stream)) {
-                       goto fail;
-               }
-
-               if(!fstrwrite("\t\t\t\"name\": \"", stream) || !fstrwrite(((node_t *)nodes[i])->name, stream) || !fstrwrite("\",\n", stream)) {
-                       goto fail;
-               }
-
-               snprintf(buf, sizeof(buf), "%d", ((node_t *)nodes[i])->devclass);
-
-               if(!fstrwrite("\t\t\t\"devclass\": ", stream) || !fstrwrite(buf, stream) || !fstrwrite("\n", stream)) {
-                       goto fail;
-               }
-
-               if(!fstrwrite((i + 1) != node_count ? "\t\t},\n" : "\t\t}\n", stream)) {
-                       goto fail;
-               }
-       }
-
-       if(!fstrwrite("\t},\n", stream)) {
-               goto fail;
-       }
-
-       // export edges
-
-       if(!fstrwrite("\t\"edges\": {\n", stream)) {
-               goto fail;
-       }
-
-       for(size_t i = 0; i < edge_count; ++i) {
-               if(!fstrwrite("\t\t\"", stream) || !fstrwrite(edges[i].from->name, stream) || !fstrwrite("_to_", stream) || !fstrwrite(edges[i].to->name, stream) || !fstrwrite("\": {\n", stream)) {
-                       goto fail;
-               }
-
-               if(!fstrwrite("\t\t\t\"from\": \"", stream) || !fstrwrite(edges[i].from->name, stream) || !fstrwrite("\",\n", stream)) {
-                       goto fail;
-               }
-
-               if(!fstrwrite("\t\t\t\"to\": \"", stream) || !fstrwrite(edges[i].to->name, stream) || !fstrwrite("\",\n", stream)) {
-                       goto fail;
-               }
-
-               char *host = NULL, *port = NULL, *address = NULL;
-               sockaddr2str((const sockaddr_t *)&edges[i].address, &host, &port);
-
-               if(host && port) {
-                       xasprintf(&address, "{ \"host\": \"%s\", \"port\": %s }", host, port);
-               }
-
-               free(host);
-               free(port);
-
-               if(!fstrwrite("\t\t\t\"address\": ", stream) || !fstrwrite(address ? address : "null", stream) || !fstrwrite(",\n", stream)) {
-                       free(address);
-                       goto fail;
-               }
-
-               free(address);
-
-               snprintf(buf, sizeof(buf), "%d", edges[i].weight);
-
-               if(!fstrwrite("\t\t\t\"weight\": ", stream) || !fstrwrite(buf, stream) || !fstrwrite("\n", stream)) {
-                       goto fail;
-               }
-
-               if(!fstrwrite((i + 1) != edge_count ? "\t\t},\n" : "\t\t}\n", stream)) {
-                       goto fail;
-               }
-       }
-
-       if(!fstrwrite("\t}\n", stream)) {
-               goto fail;
-       }
-
-       // DONE!
-
-       if(!fstrwrite("}", stream)) {
-               goto fail;
-       }
-
-       goto done;
-
-fail:
-       result = false;
-
-done:
-       free(nodes);
-       free(edges);
-
-       pthread_mutex_unlock(&mesh->mutex);
-
-       return result;
-}
-
 void devtool_get_node_status(meshlink_handle_t *mesh, meshlink_node_t *node, devtool_node_status_t *status) {
        if(!mesh || !node || !status) {
                meshlink_errno = MESHLINK_EINVAL;
index 786e290012e6f28c13f8e60940247413d263cf0b..c9335cf5450d00ca5366d4ffaef9563dafd4f50f 100644 (file)
  *  Applications should not depend on any of these functions for their normal operation.
  */
 
-/// An edge in the MeshLink network.
-typedef struct devtool_edge devtool_edge_t;
-
-/// An edge in the MeshLink network.
-struct devtool_edge {
-       struct meshlink_node *from;     ///< Pointer to a node. Node memory is
-       //   owned by meshlink and should not be
-       //   deallocated. Node contents may be
-       //   changed by meshlink.
-       struct meshlink_node *to;       ///< Pointer to a node. Node memory is
-       //   owned by meshlink and should not be
-       //   deallocated. Node contents may be
-       //   changed by meshlink.
-       struct sockaddr_storage address;///< The address information associated
-       //   with this edge.
-       int weight;                     ///< Weight assigned to this edge.
-};
-
-/// Get a list of edges.
-/** This function returns an array with copies of all known bidirectional edges.
- *  The edges are copied to capture the mesh state at call time, since edges
- *  mutate frequently. The nodes pointed to within the devtool_edge_t type
- *  are not copies; these are the same pointers that one would get from a call
- *  to meshlink_get_all_nodes().
- *
- *  @param mesh         A handle which represents an instance of MeshLink.
- *  @param edges        A pointer to a previously allocated array of
- *                      devtool_edge_t, or NULL in which case MeshLink will
- *                      allocate a new array.
- *                      The application is allowed to call free() on the array whenever it wishes.
- *                      The pointers in the devtool_edge_t elements are valid until
- *                      meshlink_close() is called.
- *  @param nmemb        A pointer to a variable holding the number of elements that
- *                      are stored in the array. In case the @a edges @a
- *                      argument is not NULL, MeshLink might call realloc()
- *                      on the array to change its size.
- *                      The contents of this variable will be changed to reflect
- *                      the new size of the array.
- *  @return             A pointer to an array containing devtool_edge_t elements,
- *                      or NULL in case of an error.
- *                      If the @a edges @a argument was not NULL, then the
- *                      return value can be either the same value or a different
- *                      value. If the new values is NULL, then the old array
- *                      will have been freed by Meshlink.
- */
-devtool_edge_t *devtool_get_all_edges(meshlink_handle_t *mesh, devtool_edge_t *edges, size_t *nmemb);
-
-/// Export a list of edges to a file in JSON format.
-/*  @param mesh         A handle which represents an instance of MeshLink.
- *  @param FILE         An open file descriptor to which a JSON representation of the edges will be written.
- *
- *  @return             True in case of success, false otherwise.
- */
-bool devtool_export_json_all_edges_state(meshlink_handle_t *mesh, FILE *stream);
-
 /// The status of a node.
 typedef struct devtool_node_status devtool_node_status_t;
 
diff --git a/src/discovery.c b/src/discovery.c
deleted file mode 100644 (file)
index 032b559..0000000
+++ /dev/null
@@ -1,1063 +0,0 @@
-/*
-  discovery.c -- local network discovery
-  Copyright (C) 2014-2021 Guus Sliepen <guus@meshlink.io>
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License along
-  with this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#define __APPLE_USE_RFC_3542
-#include "system.h"
-
-#if defined(__APPLE__)
-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreFoundation/CFArray.h>
-#include <CoreFoundation/CFString.h>
-#include <SystemConfiguration/SystemConfiguration.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#elif defined(__unix) && !defined(__linux)
-#include <net/if.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#elif defined(__linux)
-#include <asm/types.h>
-#include <net/if.h>
-#include <linux/if_link.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#endif
-
-#include "mdns.h"
-#include "meshlink_internal.h"
-#include "event.h"
-#include "discovery.h"
-#include "sockaddr.h"
-#include "logger.h"
-#include "netutl.h"
-#include "node.h"
-#include "connection.h"
-#include "utils.h"
-#include "xalloc.h"
-
-#define MESHLINK_MDNS_SERVICE_TYPE "_%s._tcp"
-#define MESHLINK_MDNS_NAME_KEY "name"
-#define MESHLINK_MDNS_FINGERPRINT_KEY "fingerprint"
-
-#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL 0
-#endif
-
-#ifndef IPV6_ADD_MEMBERSHIP
-#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
-#endif
-
-#ifndef IPV6_DROP_MEMBERSHIP
-#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
-#endif
-
-static const sockaddr_t mdns_address_ipv4 = {
-       .in.sin_family = AF_INET,
-       .in.sin_addr.s_addr = 0xfb0000e0,
-       .in.sin_port = 0xe914,
-};
-
-static const sockaddr_t mdns_address_ipv6 = {
-       .in6.sin6_family = AF_INET6,
-       .in6.sin6_addr.s6_addr[0x0] = 0xff,
-       .in6.sin6_addr.s6_addr[0x1] = 0x02,
-       .in6.sin6_addr.s6_addr[0xf] = 0xfb,
-       .in6.sin6_port = 0xe914,
-};
-
-typedef struct discovery_address {
-       int index;
-       bool up;
-       sockaddr_t address;
-       time_t last_response_sent;
-} discovery_address_t;
-
-static int iface_compare(const void *va, const void *vb) {
-       const int *a = va;
-       const int *b = vb;
-       return *a - *b;
-}
-
-static int address_compare(const void *va, const void *vb) {
-       const discovery_address_t *a = va;
-       const discovery_address_t *b = vb;
-
-       if(a->index != b->index) {
-               return a->index - b->index;
-       }
-
-       return sockaddrcmp_noport(&a->address, &b->address);
-}
-
-static void send_mdns_packet_ipv4(meshlink_handle_t *mesh, int fd, int index, const sockaddr_t *src, const sockaddr_t *dest, void *data, size_t len) {
-#ifdef IP_MULTICAST_IF
-       struct ip_mreqn mreq = {
-               .imr_address = src->in.sin_addr,
-               .imr_ifindex = index,
-       };
-
-       if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq)) != 0) {
-               logger(mesh, MESHLINK_ERROR, "Could not set outgoing multicast interface on IPv4 socket");
-               return;
-       }
-
-#endif
-
-#ifdef IP_PKTINFO
-       struct iovec iov  = {
-               .iov_base = data,
-               .iov_len = len,
-       };
-
-       struct in_pktinfo pkti = {
-               .ipi_ifindex = index,
-               .ipi_addr = src->in.sin_addr,
-       };
-
-       union {
-               char buf[CMSG_SPACE(sizeof(pkti))];
-               struct cmsghdr align;
-       } u;
-
-       memset(&u, 0, sizeof(u));
-
-       struct msghdr msg = {
-               .msg_name = (struct sockaddr *) &dest->sa,
-               .msg_namelen = SALEN(dest->sa),
-               .msg_iov = &iov,
-               .msg_iovlen = 1,
-               .msg_control = u.buf,
-               .msg_controllen = sizeof(u.buf),
-       };
-
-       struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
-       cmsg->cmsg_level = IPPROTO_IP;
-       cmsg->cmsg_type = IP_PKTINFO;
-       cmsg->cmsg_len = CMSG_LEN(sizeof(pkti));
-       memcpy(CMSG_DATA(cmsg), &pkti, sizeof(pkti));
-
-       // Send the packet
-       ssize_t result = sendmsg(fd, &msg, MSG_DONTWAIT | MSG_NOSIGNAL);
-#else
-       (void)index;
-       (void)src;
-
-       // Send the packet
-       ssize_t result = sendto(fd, data, len, MSG_DONTWAIT | MSG_NOSIGNAL, &dest->sa, SALEN(dest->sa));
-#endif
-
-       if(result <= 0) {
-               logger(mesh, MESHLINK_ERROR, "Error sending multicast packet: %s", strerror(errno));
-       }
-}
-
-static void send_mdns_packet_ipv6(meshlink_handle_t *mesh, int fd, int index, const sockaddr_t *src, const sockaddr_t *dest, void *data, size_t len) {
-#ifdef IPV6_MULTICAST_IF
-
-       if(setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &index, sizeof(index)) != 0) {
-               logger(mesh, MESHLINK_ERROR, "Could not set outgoing multicast interface on IPv6 socket");
-               return;
-       }
-
-#endif
-
-#ifdef IPV6_PKTINFO
-       struct iovec iov  = {
-               .iov_base = data,
-               .iov_len = len,
-       };
-
-       struct in6_pktinfo pkti = {
-               .ipi6_ifindex = index,
-               .ipi6_addr = src->in6.sin6_addr,
-       };
-
-       union {
-               char buf[CMSG_SPACE(sizeof(pkti))];
-               struct cmsghdr align;
-       } u;
-
-       memset(&u, 0, sizeof u);
-
-       struct msghdr msg = {
-               .msg_name = (struct sockaddr *) &dest->sa,
-               .msg_namelen = SALEN(dest->sa),
-               .msg_iov = &iov,
-               .msg_iovlen = 1,
-               .msg_control = u.buf,
-               .msg_controllen = CMSG_LEN(sizeof(pkti)),
-       };
-
-       struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
-       cmsg->cmsg_level = IPPROTO_IPV6;
-       cmsg->cmsg_type = IPV6_PKTINFO;
-       cmsg->cmsg_len = CMSG_LEN(sizeof(pkti));
-       memcpy(CMSG_DATA(cmsg), &pkti, sizeof(pkti));
-
-       // Send the packet
-       ssize_t result = sendmsg(fd, &msg, MSG_DONTWAIT | MSG_NOSIGNAL);
-#else
-       (void)index;
-       (void)src;
-
-       // Send the packet
-       ssize_t result = sendto(fd, data, len, MSG_DONTWAIT | MSG_NOSIGNAL, &dest->sa, SALEN(dest->sa));
-#endif
-
-       if(result <= 0) {
-               logger(mesh, MESHLINK_ERROR, "Error sending multicast packet: %s", strerror(errno));
-       }
-}
-
-static void send_mdns_packet(meshlink_handle_t *mesh, discovery_address_t *addr, bool response) {
-       // Configure the socket to send the packet to the right interface
-       uint8_t msg[1024];
-       size_t msg_size;
-
-       if(response) {
-               char *fingerprint = meshlink_get_fingerprint(mesh, (meshlink_node_t *)mesh->self);
-               static const char *keys[] = {MESHLINK_MDNS_NAME_KEY, MESHLINK_MDNS_FINGERPRINT_KEY};
-               const char *values[] = {mesh->name, fingerprint};
-               msg_size = prepare_response(msg, sizeof msg, fingerprint, mesh->appname, "tcp", atoi(mesh->myport), 2, keys, values);
-               free(fingerprint);
-               addr->last_response_sent = mesh->loop.now.tv_sec;
-       } else {
-               msg_size = prepare_request(msg, sizeof msg, mesh->appname, "tcp");
-       }
-
-       switch(addr->address.sa.sa_family) {
-       case AF_INET:
-               send_mdns_packet_ipv4(mesh, mesh->discovery.sockets[0].fd, addr->index, &addr->address, &mdns_address_ipv4, msg, msg_size);
-               break;
-
-       case AF_INET6:
-               send_mdns_packet_ipv6(mesh, mesh->discovery.sockets[1].fd, addr->index, &addr->address, &mdns_address_ipv6, msg, msg_size);
-               break;
-
-       default:
-               break;
-       }
-}
-
-static void mdns_io_handler(event_loop_t *loop, void *data, int flags) {
-       (void)flags;
-       meshlink_handle_t *mesh = loop->data;
-       io_t *io = data;
-       uint8_t buf[1024];
-       sockaddr_t sa;
-       socklen_t sl = sizeof(sa);
-
-#ifdef IP_PKTINFO
-       struct iovec iov  = {
-               .iov_base = buf,
-               .iov_len = sizeof(buf),
-       };
-
-       union {
-               char buf[1024];
-               struct cmsghdr align;
-       } u;
-
-       struct msghdr msg = {
-               .msg_name = &sa,
-               .msg_namelen = sl,
-               .msg_iov = &iov,
-               .msg_iovlen = 1,
-               .msg_control = u.buf,
-               .msg_controllen = sizeof(u.buf),
-       };
-
-       ssize_t len = recvmsg(io->fd, &msg, MSG_DONTWAIT | MSG_NOSIGNAL);
-
-       sl = msg.msg_namelen;
-#else
-       ssize_t len = recvfrom(io->fd, buf, sizeof(buf), MSG_DONTWAIT, &sa.sa, &sl);
-#endif
-
-       if(len == -1) {
-               if(!sockwouldblock(errno)) {
-                       logger(mesh, MESHLINK_ERROR, "Error reading from mDNS discovery socket: %s", strerror(errno));
-                       io_set(loop, io, 0);
-               }
-
-               return;
-       }
-
-       char *name = NULL;
-       uint16_t port = 0;
-       const char *keys[2] = {MESHLINK_MDNS_NAME_KEY, MESHLINK_MDNS_FINGERPRINT_KEY};
-       char *values[2] = {NULL, NULL};
-
-       if(parse_response(buf, len, &name, mesh->appname, "tcp", &port, 2, keys, values)) {
-               node_t *n = (node_t *)meshlink_get_node(mesh, values[0]);
-
-               if(n) {
-                       if(n != mesh->self) {
-                               logger(mesh, MESHLINK_INFO, "Node %s discovered on the local network.\n", n->name);
-                       }
-
-                       switch(sa.sa.sa_family) {
-                       case AF_INET:
-                               sa.in.sin_port = htons(port);
-                               break;
-
-                       case AF_INET6:
-                               sa.in6.sin6_port = htons(port);
-                               break;
-
-                       default:
-                               logger(mesh, MESHLINK_WARNING, "Could not resolve node %s to a known address family type.\n", n->name);
-                               sa.sa.sa_family = AF_UNKNOWN;
-                               break;
-                       }
-
-                       if(sa.sa.sa_family != AF_UNKNOWN) {
-                               n->catta_address = sa;
-                               n->last_connect_try = 0;
-                               node_add_recent_address(mesh, n, &sa);
-
-                               if(n->connection) {
-                                       n->connection->last_ping_time = -3600;
-                               }
-
-                               for list_each(outgoing_t, outgoing, mesh->outgoings) {
-                                       if(outgoing->node != n) {
-                                               continue;
-                                       }
-
-                                       outgoing->timeout = 0;
-
-                                       if(outgoing->ev.cb) {
-                                               timeout_set(&mesh->loop, &outgoing->ev, &(struct timespec) {
-                                                       0, 0
-                                               });
-                                       }
-                               }
-                       }
-               }
-       } else if(parse_request(buf, len, mesh->appname, "tcp")) {
-               char *fingerprint = meshlink_get_fingerprint(mesh, (meshlink_node_t *)mesh->self);
-               const char *response_values[] = {mesh->name, fingerprint};
-               size_t size = prepare_response(buf, sizeof(buf), fingerprint, mesh->appname, "tcp", atoi(mesh->myport), 2, keys, response_values);
-
-               int index = -1;
-               int family = AF_UNSPEC;
-
-               for(struct cmsghdr *cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL; cmptr = CMSG_NXTHDR(&msg, cmptr)) {
-#ifdef IP_PKTINFO
-
-                       if(cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO) {
-                               struct in_pktinfo *pktinfo = (struct in_pktinfo *) CMSG_DATA(cmptr);
-                               index = pktinfo->ipi_ifindex;
-                               family = AF_INET;
-                               break;
-                       } else
-#endif
-#ifdef IPV6_PKTINFO
-                               if(cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == IPV6_PKTINFO) {
-                                       struct in6_pktinfo *pktinfo = (struct in6_pktinfo *) CMSG_DATA(cmptr);
-                                       index = pktinfo->ipi6_ifindex;
-                                       family = AF_INET6;
-                                       break;
-                               }
-
-#endif
-               }
-
-               if(index) {
-                       // Send a multicast response back using all addresses matching the interface
-                       for(int i = 0; i < mesh->discovery.address_count; i++) {
-                               discovery_address_t *p = &mesh->discovery.addresses[i];
-
-                               if(p->index == index && p->address.sa.sa_family == family) {
-                                       send_mdns_packet(mesh, p, true);
-                               }
-                       }
-               } else {
-                       // Send a unicast response back
-                       sendto(io->fd, buf, size, MSG_DONTWAIT | MSG_NOSIGNAL, &sa.sa, sl);
-               }
-
-               free(fingerprint);
-       }
-
-       free(name);
-
-       for(int i = 0; i < 2; i++) {
-               free(values[i]);
-       }
-}
-
-static void iface_up(meshlink_handle_t *mesh, int index) {
-       int *p = bsearch(&index, mesh->discovery.ifaces, mesh->discovery.iface_count, sizeof(*p), iface_compare);
-
-       if(p) {
-               return;
-       }
-
-       mesh->discovery.ifaces = xrealloc(mesh->discovery.ifaces, ++mesh->discovery.iface_count * sizeof(*p));
-       mesh->discovery.ifaces[mesh->discovery.iface_count - 1] = index;
-       qsort(mesh->discovery.ifaces, mesh->discovery.iface_count, sizeof(*p), iface_compare);
-
-       // Add multicast membership
-       struct ip_mreqn mreq4 = {
-               .imr_multiaddr = mdns_address_ipv4.in.sin_addr,
-               .imr_ifindex = index,
-       };
-
-       setsockopt(mesh->discovery.sockets[0].fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq4, sizeof(mreq4));
-       setsockopt(mesh->discovery.sockets[0].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq4, sizeof(mreq4));
-
-       struct ipv6_mreq mreq6 = {
-               .ipv6mr_multiaddr = mdns_address_ipv6.in6.sin6_addr,
-               .ipv6mr_interface = index,
-       };
-
-       setsockopt(mesh->discovery.sockets[1].fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6));
-       setsockopt(mesh->discovery.sockets[1].fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6));
-
-       // Send an announcement for all addresses associated with this interface
-       for(int i = 0; i < mesh->discovery.address_count; i++) {
-               if(mesh->discovery.addresses[i].index == index) {
-                       send_mdns_packet(mesh, &mesh->discovery.addresses[i], false);
-               }
-       }
-
-       handle_network_change(mesh, true);
-}
-
-static void iface_down(meshlink_handle_t *mesh, int index) {
-       int *p = bsearch(&index, mesh->discovery.ifaces, mesh->discovery.iface_count, sizeof(*p), iface_compare);
-
-       if(!p) {
-               return;
-       }
-
-       // Drop multicast membership
-       struct ip_mreqn mreq4 = {
-               .imr_multiaddr = mdns_address_ipv4.in.sin_addr,
-               .imr_ifindex = index,
-       };
-       setsockopt(mesh->discovery.sockets[0].fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq4, sizeof(mreq4));
-
-       struct ipv6_mreq mreq6 = {
-               .ipv6mr_multiaddr = mdns_address_ipv6.in6.sin6_addr,
-               .ipv6mr_interface = index,
-       };
-       setsockopt(mesh->discovery.sockets[1].fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6));
-
-       memmove(p, p + 1, (mesh->discovery.ifaces + --mesh->discovery.iface_count - p) * sizeof(*p));
-
-       handle_network_change(mesh, mesh->discovery.iface_count);
-}
-
-static void addr_add(meshlink_handle_t *mesh, const discovery_address_t *addr) {
-       discovery_address_t *p = bsearch(addr, mesh->discovery.addresses, mesh->discovery.address_count, sizeof(*p), address_compare);
-
-       if(p) {
-               return;
-       }
-
-       bool up = bsearch(&addr->index, mesh->discovery.ifaces, mesh->discovery.iface_count, sizeof(int), iface_compare);
-
-       mesh->discovery.addresses = xrealloc(mesh->discovery.addresses, ++mesh->discovery.address_count * sizeof(*p));
-       mesh->discovery.addresses[mesh->discovery.address_count - 1] = *addr;
-       mesh->discovery.addresses[mesh->discovery.address_count - 1].up = up;
-
-       if(up) {
-               send_mdns_packet(mesh, &mesh->discovery.addresses[mesh->discovery.address_count - 1], false);
-       }
-
-       qsort(mesh->discovery.addresses, mesh->discovery.address_count, sizeof(*p), address_compare);
-}
-
-static void addr_del(meshlink_handle_t *mesh, const discovery_address_t *addr) {
-       discovery_address_t *p = bsearch(addr, mesh->discovery.addresses, mesh->discovery.address_count, sizeof(*p), address_compare);
-
-       if(!p) {
-               return;
-       }
-
-       memmove(p, p + 1, (mesh->discovery.addresses + --mesh->discovery.address_count - p) * sizeof(*p));
-}
-
-void scan_ifaddrs(meshlink_handle_t *mesh) {
-#ifdef HAVE_GETIFADDRS
-       struct ifaddrs *ifa = NULL;
-
-       if(getifaddrs(&ifa) == -1) {
-               logger(mesh, MESHLINK_ERROR, "Could not get list of interface addresses: %s", strerror(errno));
-               return;
-       }
-
-       // Check for interfaces being removed
-       for(int i = 0; i < mesh->discovery.iface_count;) {
-               bool found = false;
-
-               for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) {
-                       if(!ifap->ifa_name) {
-                               continue;
-                       }
-
-                       int index = if_nametoindex(ifap->ifa_name);
-
-                       if(mesh->discovery.ifaces[i] == index) {
-                               found = true;
-                               break;
-                       }
-               }
-
-               if(!found) {
-                       iface_down(mesh, mesh->discovery.ifaces[i]);
-               } else {
-                       i++;
-               }
-       }
-
-       // Check for addresses being removed
-       for(int i = 0; i < mesh->discovery.address_count;) {
-               discovery_address_t *p = &mesh->discovery.addresses[i];
-               bool found = false;
-
-               for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) {
-                       if(!ifap->ifa_name || !ifap->ifa_addr) {
-                               continue;
-                       }
-
-                       int index = if_nametoindex(ifap->ifa_name);
-
-                       if(p->index == index && sockaddrcmp_noport(&p->address, (sockaddr_t *)ifap->ifa_addr) == 0) {
-                               found = true;
-                               break;
-                       }
-               }
-
-               if(!found) {
-                       (void)addr_del;
-                       memmove(p, p + 1, (mesh->discovery.addresses + --mesh->discovery.address_count - p) * sizeof(*p));
-               } else {
-                       i++;
-               }
-       }
-
-       // Check for interfaces state changes and addresses going up
-       for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) {
-               if(!ifap->ifa_name) {
-                       continue;
-               }
-
-               int index = if_nametoindex(ifap->ifa_name);
-
-               if(ifap->ifa_flags & IFF_UP && ifap->ifa_flags & IFF_MULTICAST && !(ifap->ifa_flags & IFF_LOOPBACK)) {
-                       iface_up(mesh, index);
-               } else {
-                       iface_down(mesh, index);
-               }
-
-               if(!ifap->ifa_addr) {
-                       continue;
-               }
-
-               discovery_address_t addr  = {
-                       .index = index,
-               };
-
-               sockaddr_t *sa = (sockaddr_t *)ifap->ifa_addr;
-
-               if(sa->sa.sa_family == AF_INET) {
-                       memcpy(&addr.address.in, &sa->in, sizeof(sa->in));
-                       addr.address.in.sin_port = ntohs(5353);
-               } else if(sa->sa.sa_family == AF_INET6) {
-                       memcpy(&addr.address.in6, &sa->in6, sizeof(sa->in6));
-                       addr.address.in6.sin6_port = ntohs(5353);
-               } else {
-                       addr.address.sa.sa_family = AF_UNKNOWN;
-               }
-
-               if(addr.address.sa.sa_family != AF_UNKNOWN) {
-                       addr_add(mesh, &addr);
-               }
-       }
-
-       freeifaddrs(ifa);
-#else
-       (void)mesh;
-#endif
-}
-
-#if defined(__linux)
-static void netlink_getlink(int fd) {
-       static const struct {
-               struct nlmsghdr nlm;
-               struct ifinfomsg ifi;
-       } msg = {
-               .nlm.nlmsg_len = NLMSG_LENGTH(sizeof(msg.ifi)),
-               .nlm.nlmsg_type = RTM_GETLINK,
-               .nlm.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
-               .nlm.nlmsg_seq = 1,
-               .ifi.ifi_family = AF_UNSPEC,
-       };
-       send(fd, &msg, msg.nlm.nlmsg_len, 0);
-}
-
-static void netlink_getaddr(int fd) {
-       static const struct {
-               struct nlmsghdr nlm;
-               struct ifaddrmsg ifa;
-       } msg = {
-               .nlm.nlmsg_len = NLMSG_LENGTH(sizeof(msg.ifa)),
-               .nlm.nlmsg_type = RTM_GETADDR,
-               .nlm.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
-               .nlm.nlmsg_seq = 2,
-               .ifa.ifa_family = AF_UNSPEC,
-       };
-       send(fd, &msg, msg.nlm.nlmsg_len, 0);
-}
-
-static void netlink_parse_link(meshlink_handle_t *mesh, const struct nlmsghdr *nlm) {
-       const struct ifinfomsg *ifi = (const struct ifinfomsg *)(nlm + 1);
-
-       if(ifi->ifi_flags & IFF_UP && ifi->ifi_flags & IFF_MULTICAST) {
-               iface_up(mesh, ifi->ifi_index);
-       } else {
-               iface_down(mesh, ifi->ifi_index);
-       }
-}
-
-static void netlink_parse_addr(meshlink_handle_t *mesh, const struct nlmsghdr *nlm) {
-       const struct ifaddrmsg *ifa = (const struct ifaddrmsg *)(nlm + 1);
-       const uint8_t *ptr = (const uint8_t *)(ifa + 1);
-       size_t len = nlm->nlmsg_len - (ptr - (const uint8_t *)nlm);
-
-       while(len >= sizeof(struct rtattr)) {
-               const struct rtattr *rta = (const struct rtattr *)ptr;
-
-               if(rta->rta_len <= 0 || rta->rta_len > len) {
-                       break;
-               }
-
-               if(rta->rta_type == IFA_ADDRESS) {
-                       discovery_address_t addr  = {
-                               .index = ifa->ifa_index,
-                       };
-
-                       if(rta->rta_len == 8) {
-                               addr.address.sa.sa_family = AF_INET;
-                               memcpy(&addr.address.in.sin_addr, ptr + 4, 4);
-                               addr.address.in.sin_port = ntohs(5353);
-                       } else if(rta->rta_len == 20) {
-                               addr.address.sa.sa_family = AF_INET6;
-                               memcpy(&addr.address.in6.sin6_addr, ptr + 4, 16);
-                               addr.address.in6.sin6_port = ntohs(5353);
-                               addr.address.in6.sin6_scope_id = ifa->ifa_index;
-                       } else {
-                               addr.address.sa.sa_family = AF_UNKNOWN;
-                       }
-
-                       if(addr.address.sa.sa_family != AF_UNKNOWN) {
-                               if(nlm->nlmsg_type == RTM_NEWADDR) {
-                                       addr_add(mesh, &addr);
-                               } else {
-                                       addr_del(mesh, &addr);
-                               }
-                       }
-               }
-
-               unsigned short rta_len = (rta->rta_len + 3) & ~3;
-               ptr += rta_len;
-               len -= rta_len;
-       }
-}
-
-static void netlink_parse(meshlink_handle_t *mesh, const void *data, size_t len) {
-       const uint8_t *ptr = data;
-
-       while(len >= sizeof(struct nlmsghdr)) {
-               const struct nlmsghdr *nlm = (const struct nlmsghdr *)ptr;
-
-               if(nlm->nlmsg_len > len) {
-                       break;
-               }
-
-               switch(nlm->nlmsg_type) {
-               case RTM_NEWLINK:
-               case RTM_DELLINK:
-                       netlink_parse_link(mesh, nlm);
-                       break;
-
-               case RTM_NEWADDR:
-               case RTM_DELADDR:
-                       netlink_parse_addr(mesh, nlm);
-               }
-
-               ptr += nlm->nlmsg_len;
-               len -= nlm->nlmsg_len;
-       }
-}
-
-static void netlink_io_handler(event_loop_t *loop, void *data, int flags) {
-       (void)flags;
-       (void)data;
-       meshlink_handle_t *mesh = loop->data;
-
-       struct {
-               struct nlmsghdr nlm;
-               char data[16384];
-       } msg;
-
-       while(true) {
-               ssize_t result = recv(mesh->discovery.pfroute_io.fd, &msg, sizeof(msg), MSG_DONTWAIT);
-
-               if(result <= 0) {
-                       if(result == 0 || errno == EAGAIN || errno == EINTR) {
-                               break;
-                       }
-
-                       logger(mesh, MESHLINK_ERROR, "Reading from Netlink socket failed: %s\n", strerror(errno));
-                       io_set(loop, &mesh->discovery.pfroute_io, 0);
-               }
-
-               if((size_t)result < sizeof(msg.nlm)) {
-                       logger(mesh, MESHLINK_ERROR, "Invalid Netlink message\n");
-                       break;
-               }
-
-               if(msg.nlm.nlmsg_type == NLMSG_DONE) {
-                       if(msg.nlm.nlmsg_seq == 1) {
-                               // We just got the result of GETLINK, now send GETADDR.
-                               netlink_getaddr(mesh->discovery.pfroute_io.fd);
-                       }
-               } else {
-                       netlink_parse(mesh, &msg, result);
-
-                       if(loop->now.tv_sec > mesh->discovery.last_update + 5) {
-                               mesh->discovery.last_update = loop->now.tv_sec;
-                               handle_network_change(mesh, true);
-                       }
-               }
-       }
-}
-#elif defined(__APPLE__)
-static void reachability_change_callback(SCNetworkReachabilityRef reachability, SCNetworkReachabilityFlags flags, void *info) {
-       (void)reachability;
-       (void)flags;
-
-       meshlink_handle_t *mesh = info;
-
-       pthread_mutex_lock(&mesh->mutex);
-
-       scan_ifaddrs(mesh);
-
-       if(mesh->loop.now.tv_sec > mesh->discovery.last_update + 5) {
-               logger(mesh, MESHLINK_INFO, "Network change detected");
-               mesh->discovery.last_update = mesh->loop.now.tv_sec;
-               handle_network_change(mesh, true);
-       }
-
-       pthread_mutex_unlock(&mesh->mutex);
-}
-
-static void *network_change_handler(void *arg) {
-       meshlink_handle_t *mesh = arg;
-
-       mesh->discovery.runloop = CFRunLoopGetCurrent();
-
-       SCNetworkReachabilityRef reach_v4 = SCNetworkReachabilityCreateWithName(NULL, "93.184.216.34");
-       SCNetworkReachabilityRef reach_v6 = SCNetworkReachabilityCreateWithName(NULL, "2606:2800:220:1:248:1893:25c8:1946");
-
-       SCNetworkReachabilityContext context;
-       memset(&context, 0, sizeof(context));
-       context.info = mesh;
-
-       if(reach_v4) {
-               SCNetworkReachabilitySetCallback(reach_v4, reachability_change_callback, &context);
-               SCNetworkReachabilityScheduleWithRunLoop(reach_v4, mesh->discovery.runloop, kCFRunLoopDefaultMode);
-       } else {
-               logger(mesh, MESHLINK_ERROR, "Could not create IPv4 network reachability watcher");
-       }
-
-       if(reach_v6) {
-               SCNetworkReachabilitySetCallback(reach_v6, reachability_change_callback, &context);
-               SCNetworkReachabilityScheduleWithRunLoop(reach_v6, mesh->discovery.runloop, kCFRunLoopDefaultMode);
-       } else {
-               logger(mesh, MESHLINK_ERROR, "Could not create IPv6 network reachability watcher");
-       }
-
-       CFRunLoopRun();
-
-       mesh->discovery.runloop = NULL;
-
-       if(reach_v4) {
-               SCNetworkReachabilityUnscheduleFromRunLoop(reach_v4, mesh->discovery.runloop, kCFRunLoopDefaultMode);
-               CFRelease(reach_v4);
-       }
-
-       if(reach_v6) {
-               SCNetworkReachabilityUnscheduleFromRunLoop(reach_v6, mesh->discovery.runloop, kCFRunLoopDefaultMode);
-               CFRelease(reach_v6);
-       }
-
-       return NULL;
-}
-#elif defined(RTM_NEWADDR)
-static void pfroute_parse_iface(meshlink_handle_t *mesh, const struct rt_msghdr *rtm) {
-       const struct if_msghdr *ifm = (const struct if_msghdr *)rtm;
-
-       if(ifm->ifm_flags & IFF_UP && ifm->ifm_flags & IFF_MULTICAST && !(ifm->ifm_flags & IFF_LOOPBACK)) {
-               iface_up(mesh, ifm->ifm_index);
-       } else {
-               iface_down(mesh, ifm->ifm_index);
-       }
-}
-
-static void pfroute_parse_addr(meshlink_handle_t *mesh, const struct rt_msghdr *rtm) {
-       const struct ifa_msghdr *ifam = (const struct ifa_msghdr *)rtm;
-       const char *p = (const char *)(ifam + 1);
-
-       for(unsigned int i = 1; i; i <<= 1) {
-               if(!(ifam->ifam_addrs & i)) {
-                       continue;
-               }
-
-               const sockaddr_t *sa = (const sockaddr_t *)p;
-
-               if(i == RTA_IFA) {
-                       discovery_address_t addr = {
-                               .index = ifam->ifam_index,
-                       };
-
-                       if(sa->sa.sa_family == AF_INET) {
-                               addr.address.in = sa->in;
-                               addr.address.in.sin_port = ntohs(5353);
-                       } else if(sa->sa.sa_family == AF_INET6) {
-                               addr.address.in6 = sa->in6;
-                               addr.address.in6.sin6_port = ntohs(5353);
-                       } else {
-                               addr.address.sa.sa_family = AF_UNKNOWN;
-                       }
-
-                       if(addr.address.sa.sa_family != AF_UNKNOWN) {
-                               if(ifam->ifam_type == RTM_NEWADDR) {
-                                       addr_add(mesh, &addr);
-                               } else {
-                                       addr_del(mesh, &addr);
-                               }
-                       }
-
-                       break;
-               }
-
-               size_t len = (sa->sa.sa_len + 3) & ~3;
-               p += len;
-       }
-}
-
-static void pfroute_io_handler(event_loop_t *loop, void *data, int flags) {
-       (void)flags;
-       (void)data;
-       meshlink_handle_t *mesh = loop->data;
-
-       struct {
-               struct rt_msghdr rtm;
-               char data[2048];
-       } msg;
-
-       while(true) {
-               msg.rtm.rtm_version = 0;
-               ssize_t result = recv(mesh->discovery.pfroute_io.fd, &msg, sizeof(msg), MSG_DONTWAIT);
-
-               if(result <= 0) {
-                       if(result == 0 || errno == EAGAIN || errno == EINTR) {
-                               break;
-                       }
-
-                       logger(mesh, MESHLINK_ERROR, "Reading from PFROUTE socket failed: %s\n", strerror(errno));
-                       io_set(loop, &mesh->discovery.pfroute_io, 0);
-               }
-
-               if(msg.rtm.rtm_version != RTM_VERSION) {
-                       logger(mesh, MESHLINK_ERROR, "Invalid PFROUTE message version\n");
-                       break;
-               }
-
-               switch(msg.rtm.rtm_type) {
-               case RTM_IFINFO:
-                       pfroute_parse_iface(mesh, &msg.rtm);
-                       break;
-
-               case RTM_NEWADDR:
-               case RTM_DELADDR:
-                       pfroute_parse_addr(mesh, &msg.rtm);
-                       break;
-
-               default:
-                       break;
-               }
-       }
-}
-#endif
-
-bool discovery_start(meshlink_handle_t *mesh) {
-       logger(mesh, MESHLINK_DEBUG, "discovery_start called\n");
-
-       assert(mesh);
-
-       // Set up multicast sockets for mDNS
-       static const int one = 1;
-       static const int ttl = 255;
-       static const uint8_t one8 = 1;
-       static const uint8_t ttl8 = 255;
-
-       int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-
-       if(fd == -1) {
-               logger(mesh, MESHLINK_ERROR, "Error creating IPv4 socket: %s", strerror(errno));
-       } else {
-
-               sockaddr_t sa4 = {
-                       .in.sin_family = AF_INET,
-                       .in.sin_port = ntohs(5353),
-               };
-               setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-#ifdef SO_REUSEPORT
-               setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
-#endif
-#ifdef IP_PKTINFO
-               setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
-#endif
-               setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one8, sizeof(one8));
-               setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl8, sizeof(ttl8));
-
-               if(bind(fd, &sa4.sa, SALEN(sa4.sa)) == -1) {
-                       logger(mesh, MESHLINK_ERROR, "Error binding to IPv4 multicast socket: %s", strerror(errno));
-               } else {
-                       io_add(&mesh->loop, &mesh->discovery.sockets[0], mdns_io_handler, &mesh->discovery.sockets[0], fd, IO_READ);
-               }
-       }
-
-       fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
-
-       if(fd == -1) {
-               logger(mesh, MESHLINK_ERROR, "Error creating IPv6 socket: %s", strerror(errno));
-       } else {
-               sockaddr_t sa6 = {
-                       .in6.sin6_family = AF_INET6,
-                       .in6.sin6_port = ntohs(5353),
-               };
-
-               setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-#ifdef SO_REUSEPORT
-               setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
-#endif
-#ifdef IPV6_RECVPKTINFO
-               setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
-#endif
-               setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
-               setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
-               setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
-               setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
-
-               if(bind(fd, &sa6.sa, SALEN(sa6.sa)) == -1) {
-                       logger(mesh, MESHLINK_ERROR, "Error binding to IPv6 multicast socket: %s", strerror(errno));
-               } else {
-                       io_add(&mesh->loop, &mesh->discovery.sockets[1], mdns_io_handler, &mesh->discovery.sockets[1], fd, IO_READ);
-               }
-       }
-
-#if defined(__linux)
-       int sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
-
-       if(sock != -1) {
-               struct sockaddr_nl sa;
-               memset(&sa, 0, sizeof(sa));
-               sa.nl_family = AF_NETLINK;
-               sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;
-
-               if(bind(sock, (struct sockaddr *)&sa, sizeof(sa)) != -1) {
-                       io_add(&mesh->loop, &mesh->discovery.pfroute_io, netlink_io_handler, NULL, sock, IO_READ);
-                       netlink_getlink(sock);
-               } else {
-                       logger(mesh, MESHLINK_WARNING, "Could not bind AF_NETLINK socket: %s", strerror(errno));
-                       scan_ifaddrs(mesh);
-               }
-       } else {
-               logger(mesh, MESHLINK_WARNING, "Could not open AF_NETLINK socket: %s", strerror(errno));
-               scan_ifaddrs(mesh);
-       }
-
-#elif defined(__APPLE__)
-       pthread_create(&mesh->discovery.thread, NULL, network_change_handler, mesh);
-       // TODO: Do we need to wait for the thread to start succesfully?
-       scan_ifaddrs(mesh);
-#elif defined(RTM_NEWADDR)
-       int sock = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
-
-       if(sock != -1) {
-               io_add(&mesh->loop, &mesh->discovery.pfroute_io, pfroute_io_handler, NULL, sock, IO_READ);
-       } else {
-               logger(mesh, MESHLINK_WARNING, "Could not open PF_ROUTE socket: %s", strerror(errno));
-       }
-
-       scan_ifaddrs(mesh);
-#endif
-
-       return true;
-}
-
-void discovery_stop(meshlink_handle_t *mesh) {
-       logger(mesh, MESHLINK_DEBUG, "discovery_stop called\n");
-
-       assert(mesh);
-
-       free(mesh->discovery.ifaces);
-       free(mesh->discovery.addresses);
-       mesh->discovery.ifaces = NULL;
-       mesh->discovery.addresses = NULL;
-       mesh->discovery.iface_count = 0;
-       mesh->discovery.address_count = 0;
-
-#if defined(__APPLE__)
-
-       if(mesh->discovery.runloop) {
-               CFRunLoopStop(mesh->discovery.runloop);
-               pthread_join(mesh->discovery.thread, NULL);
-       }
-
-#endif
-
-       if(mesh->discovery.pfroute_io.cb) {
-               close(mesh->discovery.pfroute_io.fd);
-               io_del(&mesh->loop, &mesh->discovery.pfroute_io);
-       }
-
-       for(int i = 0; i < 2; i++) {
-               if(mesh->discovery.sockets[i].cb) {
-                       close(mesh->discovery.sockets[i].fd);
-                       io_del(&mesh->loop, &mesh->discovery.sockets[i]);
-               }
-       }
-}
-
-void discovery_refresh(meshlink_handle_t *mesh) {
-       for(int i = 0; i < mesh->discovery.address_count; i++) {
-               if(mesh->discovery.addresses[i].up) {
-                       send_mdns_packet(mesh, &mesh->discovery.addresses[i], false);
-               }
-       }
-}
diff --git a/src/discovery.h b/src/discovery.h
deleted file mode 100644 (file)
index 03c4312..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef MESHLINK_DISCOVERY_H
-#define MESHLINK_DISCOVERY_H
-
-/*
-    discovery.h -- header for discovery.c
-    Copyright (C) 2014-2021 Guus Sliepen <guus@meshlink.io>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include <stdbool.h>
-
-bool discovery_start(meshlink_handle_t *mesh);
-void discovery_stop(meshlink_handle_t *mesh);
-void discovery_refresh(meshlink_handle_t *mesh);
-void scan_ifaddrs(meshlink_handle_t *mesh);
-
-#endif
diff --git a/src/edge.c b/src/edge.c
deleted file mode 100644 (file)
index afe9cfe..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
-    edge.c -- edge tree management
-    Copyright (C) 2014 Guus Sliepen <guus@meshlink.io>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include "splay_tree.h"
-#include "edge.h"
-#include "logger.h"
-#include "meshlink_internal.h"
-#include "netutl.h"
-#include "node.h"
-#include "utils.h"
-#include "xalloc.h"
-
-static int edge_compare(const edge_t *a, const edge_t *b) {
-       return strcmp(a->to->name, b->to->name);
-}
-
-static int edge_weight_compare(const edge_t *a, const edge_t *b) {
-       int result;
-
-       result = a->weight - b->weight;
-
-       if(result) {
-               return result;
-       }
-
-       result = strcmp(a->from->name, b->from->name);
-
-       if(result) {
-               return result;
-       }
-
-       return strcmp(a->to->name, b->to->name);
-}
-
-void init_edges(meshlink_handle_t *mesh) {
-       mesh->edges = splay_alloc_tree((splay_compare_t) edge_weight_compare, NULL);
-}
-
-splay_tree_t *new_edge_tree(void) {
-       return splay_alloc_tree((splay_compare_t) edge_compare, (splay_action_t) free_edge);
-}
-
-void free_edge_tree(splay_tree_t *edge_tree) {
-       splay_delete_tree(edge_tree);
-}
-
-void exit_edges(meshlink_handle_t *mesh) {
-       if(mesh->edges) {
-               splay_delete_tree(mesh->edges);
-       }
-
-       mesh->edges = NULL;
-}
-
-/* Creation and deletion of connection elements */
-
-edge_t *new_edge(void) {
-       return xzalloc(sizeof(edge_t));
-}
-
-void free_edge(edge_t *e) {
-       sockaddrfree(&e->address);
-
-       free(e);
-}
-
-void edge_add(meshlink_handle_t *mesh, edge_t *e) {
-       splay_insert(mesh->edges, e);
-       splay_insert(e->from->edge_tree, e);
-
-       e->reverse = lookup_edge(e->to, e->from);
-
-       if(e->reverse) {
-               e->reverse->reverse = e;
-       }
-}
-
-void edge_del(meshlink_handle_t *mesh, edge_t *e) {
-       if(e->reverse) {
-               e->reverse->reverse = NULL;
-       }
-
-       splay_delete(mesh->edges, e);
-       splay_delete(e->from->edge_tree, e);
-}
-
-edge_t *lookup_edge(node_t *from, node_t *to) {
-       assert(from);
-       assert(to);
-
-       edge_t v;
-
-       v.from = from;
-       v.to = to;
-
-       return splay_search(from->edge_tree, &v);
-}
diff --git a/src/edge.h b/src/edge.h
deleted file mode 100644 (file)
index d5ec117..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef MESHLINK_EDGE_H
-#define MESHLINK_EDGE_H
-
-/*
-    edge.h -- header for edge.c
-    Copyright (C) 2014, 2017 Guus Sliepen <guus@meshlink.io>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "splay_tree.h"
-#include "connection.h"
-#include "net.h"
-#include "node.h"
-
-typedef struct edge_t {
-       struct node_t *from;
-       struct node_t *to;
-       sockaddr_t address;
-
-       struct connection_t *connection;        /* connection associated with this edge, if available */
-       struct edge_t *reverse;                 /* edge in the opposite direction, if available */
-
-       int weight;                             /* weight of this edge */
-       uint32_t session_id;                     /* the session_id of the from node */
-} edge_t;
-
-void init_edges(struct meshlink_handle *mesh);
-void exit_edges(struct meshlink_handle *mesh);
-edge_t *new_edge(void) __attribute__((__malloc__));
-void free_edge(edge_t *);
-struct splay_tree_t *new_edge_tree(void) __attribute__((__malloc__));
-void free_edge_tree(struct splay_tree_t *);
-void edge_add(struct meshlink_handle *mesh, edge_t *);
-void edge_del(struct meshlink_handle *mesh, edge_t *);
-edge_t *lookup_edge(struct node_t *, struct node_t *) __attribute__((__warn_unused_result__));
-
-#endif
diff --git a/src/graph.c b/src/graph.c
deleted file mode 100644 (file)
index 9a2bfb1..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
-    graph.c -- graph algorithms
-    Copyright (C) 2014 Guus Sliepen <guus@meshlink.io>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-/* We need to generate two trees from the graph:
-
-   1. A minimum spanning tree for broadcasts,
-   2. A single-source shortest path tree for unicasts.
-
-   Actually, the first one alone would suffice but would make unicast packets
-   take longer routes than necessary.
-
-   For the MST algorithm we can choose from Prim's or Kruskal's. I personally
-   favour Kruskal's, because we make an extra AVL tree of edges sorted on
-   weights (metric). That tree only has to be updated when an edge is added or
-   removed, and during the MST algorithm we just have go linearly through that
-   tree, adding safe edges until #edges = #nodes - 1. The implementation here
-   however is not so fast, because I tried to avoid having to make a forest and
-   merge trees.
-
-   For the SSSP algorithm Dijkstra's seems to be a nice choice. Currently a
-   simple breadth-first search is presented here.
-
-   The SSSP algorithm will also be used to determine whether nodes are
-   reachable from the source. It will also set the correct destination address
-   and port of a node if possible.
-*/
-
-#include "system.h"
-
-#include "connection.h"
-#include "edge.h"
-#include "graph.h"
-#include "list.h"
-#include "logger.h"
-#include "meshlink_internal.h"
-#include "netutl.h"
-#include "node.h"
-#include "protocol.h"
-#include "utils.h"
-#include "xalloc.h"
-#include "graph.h"
-
-/* Implementation of a simple breadth-first search algorithm.
-   Running time: O(E)
-*/
-
-static void sssp_bfs(meshlink_handle_t *mesh) {
-       list_t *todo_list = list_alloc(NULL);
-
-       /* Clear visited status on nodes */
-
-       for splay_each(node_t, n, mesh->nodes) {
-               n->status.visited = false;
-               n->distance = -1;
-       }
-
-       /* Begin with mesh->self */
-
-       mesh->self->status.visited = mesh->threadstarted;
-       mesh->self->nexthop = mesh->self;
-       mesh->self->prevedge = NULL;
-       mesh->self->distance = 0;
-       list_insert_head(todo_list, mesh->self);
-
-       /* Loop while todo_list is filled */
-
-       for list_each(node_t, n, todo_list) {                   /* "n" is the node from which we start */
-               logger(mesh, MESHLINK_DEBUG, " Examining edges from %s", n->name);
-
-               if(n->distance < 0) {
-                       abort();
-               }
-
-               for splay_each(edge_t, e, n->edge_tree) {       /* "e" is the edge connected to "from" */
-                       if(!e->reverse) {
-                               continue;
-                       }
-
-                       /* Situation:
-
-                                  /
-                                 /
-                          ----->(n)---e-->(e->to)
-                                 \
-                                  \
-
-                          Where e is an edge, (n) and (e->to) are nodes.
-                          n->address is set to the e->address of the edge left of n to n.
-                          We are currently examining the edge e right of n from n:
-
-                          - If edge e provides for better reachability of e->to, update
-                            e->to and (re)add it to the todo_list to (re)examine the reachability
-                            of nodes behind it.
-                        */
-
-                       if(e->to->status.visited
-                                       && (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight)) {
-                               continue;
-                       }
-
-                       e->to->status.visited = true;
-                       e->to->nexthop = (n->nexthop == mesh->self) ? e->to : n->nexthop;
-                       e->to->prevedge = e;
-                       e->to->distance = n->distance + 1;
-
-                       if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)) {
-                               update_node_udp(mesh, e->to, &e->address);
-                       }
-
-                       list_insert_tail(todo_list, e->to);
-               }
-
-               list_next = list_node->next; /* Because the list_insert_tail() above could have added something extra for us! */
-               list_delete_node(todo_list, list_node);
-       }
-
-       list_free(todo_list);
-}
-
-static void check_reachability(meshlink_handle_t *mesh) {
-       /* Check reachability status. */
-
-       int reachable = -1; /* Don't count ourself */
-
-       for splay_each(node_t, n, mesh->nodes) {
-               if(n->status.visited) {
-                       reachable++;
-               }
-
-               /* Check for nodes that have changed session_id */
-               if(n->status.visited && n->prevedge && n->prevedge->reverse->session_id != n->session_id) {
-                       logger(mesh, MESHLINK_DEBUG, "Node %s has a new session ID", n->name);
-
-                       n->session_id = n->prevedge->reverse->session_id;
-
-                       if(n->utcp) {
-                               utcp_reset_all_connections(n->utcp);
-                       }
-
-                       n->status.validkey = false;
-                       sptps_stop(&n->sptps);
-                       n->status.waitingforkey = false;
-                       n->last_req_key = -3600;
-
-                       n->status.udp_confirmed = false;
-                       n->maxmtu = MTU;
-                       n->minmtu = 0;
-                       n->mtuprobes = 0;
-
-                       timeout_del(&mesh->loop, &n->mtutimeout);
-               }
-
-               if(n->status.visited != n->status.reachable) {
-                       n->status.reachable = !n->status.reachable;
-                       n->status.dirty = true;
-
-                       if(!n->status.blacklisted) {
-                               if(n->status.reachable) {
-                                       logger(mesh, MESHLINK_DEBUG, "Node %s became reachable", n->name);
-                                       bool first_time_reachable = !n->last_reachable;
-                                       n->last_reachable = time(NULL);
-
-                                       if(first_time_reachable) {
-                                               if(!node_write_config(mesh, n, false)) {
-                                                       logger(mesh, MESHLINK_WARNING, "Could not write host config file for node %s!\n", n->name);
-
-                                               }
-                                       }
-                               } else {
-                                       logger(mesh, MESHLINK_DEBUG, "Node %s became unreachable", n->name);
-                                       n->last_unreachable = time(NULL);
-                               }
-                       }
-
-                       n->status.udp_confirmed = false;
-                       n->maxmtu = MTU;
-                       n->minmtu = 0;
-                       n->mtuprobes = 0;
-
-                       timeout_del(&mesh->loop, &n->mtutimeout);
-
-                       if(!n->status.blacklisted) {
-                               update_node_status(mesh, n);
-                       }
-
-                       if(!n->status.reachable) {
-                               update_node_udp(mesh, n, NULL);
-                               n->status.broadcast = false;
-                       }
-
-                       if(n->utcp) {
-                               utcp_offline(n->utcp, !n->status.reachable);
-                       }
-               }
-       }
-
-       if(mesh->reachable != reachable) {
-               if(!reachable) {
-                       mesh->last_unreachable = mesh->loop.now.tv_sec;
-
-                       if(mesh->threadstarted && mesh->periodictimer.cb) {
-                               timeout_set(&mesh->loop, &mesh->periodictimer, &(struct timespec) {
-                                       0, prng(mesh, TIMER_FUDGE)
-                               });
-                       }
-               }
-
-               mesh->reachable = reachable;
-       }
-}
-
-void graph(meshlink_handle_t *mesh) {
-       sssp_bfs(mesh);
-       check_reachability(mesh);
-}
diff --git a/src/graph.h b/src/graph.h
deleted file mode 100644 (file)
index 1775732..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef MESHLINK_GRAPH_H
-#define MESHLINK_GRAPH_H
-
-/*
-    graph.h -- header for graph.c
-    Copyright (C) 2014, 2017 Guus Sliepen <guus@meshlink.io>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-void graph(struct meshlink_handle *mesh);
-
-#endif
diff --git a/src/mdns.c b/src/mdns.c
deleted file mode 100644 (file)
index e92a833..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-// SPDX-FileCopyrightText: 2020 Guus Sliepen <guus@meshlink.io>
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "system.h"
-
-#include <stddef.h>
-
-#include "mdns.h"
-#include "xalloc.h"
-
-// Creating a buffer
-
-typedef struct {
-       uint8_t *ptr;
-       ptrdiff_t len;
-} buf_t;
-
-static void buf_add(buf_t *buf, const void *data, uint32_t len) {
-       if(buf->len >= len) {
-               memcpy(buf->ptr, data, len);
-               buf->ptr += len;
-               buf->len -= len;
-       } else {
-               buf->len = -1;
-       }
-}
-
-static void buf_add_uint8(buf_t *buf, uint8_t val) {
-       if(buf->len >= 1) {
-               buf->ptr[0] = val;
-               buf->ptr++;
-               buf->len--;
-       } else {
-               buf->len = -1;
-       }
-}
-
-static void buf_add_uint16(buf_t *buf, uint16_t val) {
-       uint16_t nval = htons(val);
-       buf_add(buf, &nval, sizeof(nval));
-}
-
-static void buf_add_uint32(buf_t *buf, uint32_t val) {
-       uint32_t nval = htonl(val);
-       buf_add(buf, &nval, sizeof(nval));
-}
-
-static void buf_add_label(buf_t *buf, const char *str) {
-       size_t len = strlen(str);
-
-       if(len < 256) {
-               buf_add_uint8(buf, len);
-               buf_add(buf, str, len);
-       } else {
-               buf->len = -1;
-       }
-}
-
-static void buf_add_ulabel(buf_t *buf, const char *str) {
-       size_t len = strlen(str);
-
-       if(len + 1 < 256) {
-               buf_add_uint8(buf, len + 1);
-               buf_add_uint8(buf, '_');
-               buf_add(buf, str, len);
-       } else {
-               buf->len = -1;
-       }
-}
-
-static void buf_add_kvp(buf_t *buf, const char *key, const char *val) {
-       size_t key_len = strlen(key);
-       size_t val_len = strlen(val);
-
-       if(key_len + val_len + 1 < 256) {
-               buf_add_uint8(buf, key_len + val_len + 1);
-               buf_add(buf, key, key_len);
-               buf_add_uint8(buf, '=');
-               buf_add(buf, val, val_len);
-       } else {
-               buf->len = -1;
-       }
-}
-
-static uint8_t *buf_len_start(buf_t *buf) {
-       if(buf->len < 2) {
-               buf->len = -1;
-               return NULL;
-       } else {
-               uint8_t *ptr = buf->ptr;
-               buf->ptr += 2;
-               buf->len -= 2;
-               return ptr;
-       }
-}
-
-static void buf_len_end(buf_t *buf, uint8_t *ptr) {
-       if(buf->len < 0) {
-               return;
-       }
-
-       uint16_t len = htons(buf->ptr - ptr - 2);
-       memcpy(ptr, &len, sizeof(len));
-}
-
-// Functions reading a buffer
-
-typedef struct {
-       const uint8_t *ptr;
-       ptrdiff_t len;
-} cbuf_t;
-
-static void buf_check(cbuf_t *buf, const void *data, uint32_t len) {
-       if(buf->len >= len && !memcmp(buf->ptr, data, len)) {
-               buf->ptr += len;
-               buf->len -= len;
-       } else {
-               buf->len = -1;
-       }
-}
-
-static void buf_check_uint8(cbuf_t *buf, uint8_t val) {
-       if(buf->len >= 1 && buf->ptr[0] == val) {
-               buf->ptr++;
-               buf->len--;
-       } else {
-               buf->len = -1;
-       }
-}
-
-static void buf_check_uint16(cbuf_t *buf, uint16_t val) {
-       uint16_t nval = htons(val);
-       buf_check(buf, &nval, sizeof(nval));
-}
-
-static uint16_t buf_get_uint16(cbuf_t *buf) {
-       uint16_t nval;
-
-       if(buf->len >= 2) {
-               memcpy(&nval, buf->ptr, 2);
-               buf->ptr += 2;
-               buf->len -= 2;
-               return ntohs(nval);
-       } else {
-               buf->len = -1;
-               return 0;
-       }
-}
-
-static void buf_check_uint32(cbuf_t *buf, uint32_t val) {
-       uint32_t nval = htonl(val);
-       buf_check(buf, &nval, sizeof(nval));
-}
-
-static void buf_check_label(cbuf_t *buf, const char *str) {
-       size_t len = strlen(str);
-
-       if(len < 256) {
-               buf_check_uint8(buf, len);
-               buf_check(buf, str, len);
-       } else {
-               buf->len = -1;
-       }
-}
-
-static char *buf_get_label(cbuf_t *buf) {
-       if(buf->len < 1) {
-               buf->len = -1;
-               return NULL;
-       }
-
-       uint8_t len = buf->ptr[0];
-       buf->ptr++;
-       buf->len--;
-
-       if(buf->len < len) {
-               buf->len = -1;
-               return NULL;
-       }
-
-       char *label = xmalloc(len + 1);
-       memcpy(label, buf->ptr, len);
-       label[len] = 0;
-       buf->ptr += len;
-       buf->len -= len;
-       return label;
-}
-
-static void buf_check_ulabel(cbuf_t *buf, const char *str) {
-       size_t len = strlen(str);
-
-       if(len + 1 < 256) {
-               buf_check_uint8(buf, len + 1);
-               buf_check_uint8(buf, '_');
-               buf_check(buf, str, len);
-       } else {
-               buf->len = -1;
-       }
-}
-
-static void buf_get_kvp(cbuf_t *buf, const char *key, char **val) {
-       char *kvp = buf_get_label(buf);
-
-       if(buf->len == -1) {
-               return;
-       }
-
-       char *split = strchr(kvp, '=');
-
-       if(!split) {
-               buf->len = -1;
-               return;
-       }
-
-       *split++ = 0;
-
-       if(strcmp(kvp, key)) {
-               buf->len = -1;
-               return;
-       }
-
-       memmove(kvp, split, strlen(split) + 1);
-       *val = kvp;
-}
-
-static const uint8_t *buf_check_len_start(cbuf_t *buf) {
-       if(buf->len < 2) {
-               buf->len = -1;
-               return NULL;
-       } else {
-               const uint8_t *ptr = buf->ptr;
-               buf->ptr += 2;
-               buf->len -= 2;
-               return ptr;
-       }
-}
-
-static void buf_check_len_end(cbuf_t *buf, const uint8_t *ptr) {
-       if(buf->len < 0) {
-               return;
-       }
-
-       uint16_t len = htons(buf->ptr - ptr - 2);
-
-       if(memcmp(ptr, &len, sizeof(len))) {
-               buf->len = -1;
-       }
-}
-
-size_t prepare_request(void *vdata, size_t size, const char *protocol, const char *transport) {
-       uint8_t *data = vdata;
-       buf_t buf = {data, size};
-
-       // Header
-       buf_add_uint16(&buf, 0); // TX ID
-       buf_add_uint16(&buf, 0); // flags
-       buf_add_uint16(&buf, 1); // 1 question
-       buf_add_uint16(&buf, 0); // 0 answer RR
-       buf_add_uint16(&buf, 0); // 0 authority RRs
-       buf_add_uint16(&buf, 0); // 0 additional RR
-
-       // Question section: _protocol._transport.local PTR IN
-       buf_add_ulabel(&buf, protocol);
-       buf_add_ulabel(&buf, transport);
-       buf_add_label(&buf, "local");
-       buf_add_uint8(&buf, 0);
-       buf_add_uint16(&buf, 0xc); // PTR
-       buf_add_uint16(&buf, 0x1); // IN
-
-       // Done.
-       if(buf.len < 0) {
-               return 0;
-       } else {
-               return buf.ptr - data;
-       }
-}
-
-bool parse_request(const void *vdata, size_t size, const char *protocol, const char *transport) {
-       const uint8_t *data = vdata;
-       cbuf_t buf = {data, size};
-
-       // Header
-       buf_get_uint16(&buf); // TX ID
-       buf_check_uint16(&buf, 0); // flags
-       buf_check_uint16(&buf, 1); // 1 question
-       buf_get_uint16(&buf); // ? answer RR
-       buf_get_uint16(&buf); // ? authority RRs
-       buf_get_uint16(&buf); // ? additional RR
-
-       if(buf.len == -1) {
-               return false;
-       }
-
-       // Question section: _protocol._transport.local PTR IN
-       buf_check_ulabel(&buf, protocol);
-       buf_check_ulabel(&buf, transport);
-       buf_check_label(&buf, "local");
-       buf_check_uint8(&buf, 0);
-       buf_check_uint16(&buf, 0xc); // PTR
-       buf_check_uint16(&buf, 0x1); // IN
-
-       if(buf.len == -1) {
-               return false;
-       }
-
-       // Done.
-       return buf.len != -1;
-}
-
-size_t prepare_response(void *vdata, size_t size, const char *name, const char *protocol, const char *transport, uint16_t port, int nkeys, const char **keys, const char **values) {
-       uint8_t *data = vdata;
-       buf_t buf = {data, size};
-
-       // Header
-       buf_add_uint16(&buf, 0); // TX ID
-       buf_add_uint16(&buf, 0x8400); // flags
-       buf_add_uint16(&buf, 0); // 1 question
-       buf_add_uint16(&buf, 3); // 1 answer RR
-       buf_add_uint16(&buf, 0); // 0 authority RRs
-       buf_add_uint16(&buf, 0); // 1 additional RR
-
-       // Add the TXT record: _protocol._transport local TXT IN 3600 name._protocol._transport key=value...
-       uint16_t full_name = buf.ptr - data; // remember start of full name
-       buf_add_label(&buf, name);
-       uint16_t protocol_offset = buf.ptr - data; // remember start of _protocol
-       buf_add_ulabel(&buf, protocol);
-       buf_add_ulabel(&buf, transport);
-       uint16_t local_offset = buf.ptr - data; // remember start of local
-       buf_add_label(&buf, "local");
-       buf_add_uint8(&buf, 0);
-       buf_add_uint16(&buf, 0x10); // TXT
-       buf_add_uint16(&buf, 0x1); // IN
-       buf_add_uint32(&buf, 3600); // TTL
-
-       uint8_t *len_ptr = buf_len_start(&buf);
-
-       for(int i = 0; i < nkeys; i++) {
-               buf_add_kvp(&buf, keys[i], values[i]);
-       }
-
-       buf_len_end(&buf, len_ptr);
-
-       // Add the PTR record: _protocol._transport.local PTR IN 3600 name._protocol._transport.local
-       buf_add_uint16(&buf, 0xc000 | protocol_offset);
-       buf_add_uint16(&buf, 0xc); // PTR
-       buf_add_uint16(&buf, 0x8001); // IN (flush)
-       buf_add_uint32(&buf, 3600); // TTL
-       len_ptr = buf_len_start(&buf);
-       buf_add_uint16(&buf, 0xc000 | full_name);
-       buf_len_end(&buf, len_ptr);
-
-       // Add the SRV record: name._protocol._transport.local SRV IN 120 0 0 port name.local
-       buf_add_uint16(&buf, 0xc000 | full_name);
-       buf_add_uint16(&buf, 0x21); // SRV
-       buf_add_uint16(&buf, 0x8001); // IN (flush)
-       buf_add_uint32(&buf, 120); // TTL
-       len_ptr = buf_len_start(&buf);
-       buf_add_uint16(&buf, 0); // priority
-       buf_add_uint16(&buf, 0); // weight
-       buf_add_uint16(&buf, port); // port
-       buf_add_label(&buf, name);
-       buf_add_uint16(&buf, 0xc000 | local_offset);
-       buf_len_end(&buf, len_ptr);
-
-       // Done.
-       if(buf.len < 0) {
-               return 0;
-       } else {
-               return buf.ptr - data;
-       }
-}
-
-bool parse_response(const void *vdata, size_t size, char **name, const char *protocol, const char *transport, uint16_t *port, int nkeys, const char **keys, char **values) {
-       const uint8_t *data = vdata;
-       cbuf_t buf = {data, size};
-
-       // Header
-       buf_check_uint16(&buf, 0); // TX ID
-       buf_check_uint16(&buf, 0x8400); // flags
-       buf_check_uint16(&buf, 0); // 0 question
-       buf_check_uint16(&buf, 3); // 1 answer RR
-       buf_check_uint16(&buf, 0); // 0 authority RRs
-       buf_check_uint16(&buf, 0); // 0 checkitional RR
-
-       if(buf.len == -1) {
-               return false;
-       }
-
-       // Check the TXT record: _protocol._transport local TXT IN 3600 name._protocol._transport key=value...
-       uint16_t full_name = buf.ptr - data; // remember start of full name
-       *name = buf_get_label(&buf);
-       uint16_t protocol_offset = buf.ptr - data; // remember start of _protocol
-       buf_check_ulabel(&buf, protocol);
-       buf_check_ulabel(&buf, transport);
-       uint16_t local_offset = buf.ptr - data; // remember start of local
-       buf_check_label(&buf, "local");
-       buf_check_uint8(&buf, 0);
-       buf_check_uint16(&buf, 0x10); // TXT
-       buf_check_uint16(&buf, 0x1); // IN
-       buf_check_uint32(&buf, 3600); // TTL
-       const uint8_t *len_ptr = buf_check_len_start(&buf);
-
-       for(int i = 0; i < nkeys; i++) {
-               buf_get_kvp(&buf, keys[i], &values[i]);
-       }
-
-       buf_check_len_end(&buf, len_ptr);
-
-       if(buf.len == -1) {
-               return false;
-       }
-
-       // Check the PTR record: _protocol._transport.local PTR IN 3600 name._protocol._transport.local
-       buf_check_uint16(&buf, 0xc000 | protocol_offset);
-       buf_check_uint16(&buf, 0xc); // PTR
-       buf_check_uint16(&buf, 0x8001); // IN (flush)
-       buf_check_uint32(&buf, 3600); // TTL
-       len_ptr = buf_check_len_start(&buf);
-       buf_check_uint16(&buf, 0xc000 | full_name);
-       buf_check_len_end(&buf, len_ptr);
-
-       if(buf.len == -1) {
-               return false;
-       }
-
-       // Check the SRV record: name._protocol._transport.local SRV IN 120 0 0 port name.local
-       buf_check_uint16(&buf, 0xc000 | full_name);
-       buf_check_uint16(&buf, 0x21); // SRV
-       buf_check_uint16(&buf, 0x8001); // IN (flush)
-       buf_check_uint32(&buf, 120); // TTL
-       len_ptr = buf_check_len_start(&buf);
-       buf_check_uint16(&buf, 0); // priority
-       buf_check_uint16(&buf, 0); // weight
-       *port = buf_get_uint16(&buf); // port
-       buf_check_label(&buf, *name);
-       buf_check_uint16(&buf, 0xc000 | local_offset);
-       buf_check_len_end(&buf, len_ptr);
-
-       // Done.
-       return buf.len == 0;
-}
diff --git a/src/mdns.h b/src/mdns.h
deleted file mode 100644 (file)
index 6029158..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-// SPDX-FileCopyrightText: 2020 Guus Sliepen <guus@meshlink.io>
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <stdint.h>
-#include <unistd.h>
-
-size_t prepare_packet(void *buf, size_t size, const char *name, const char *protocol, const char *transport, uint16_t port, int nkeys, const char **keys, const char **values, bool response);
-size_t prepare_request(void *buf, size_t size, const char *protocol, const char *transport);
-size_t prepare_response(void *buf, size_t size, const char *name, const char *protocol, const char *transport, uint16_t port, int nkeys, const char **keys, const char **values);
-bool parse_response(const void *buf, size_t size, char **name, const char *protocol, const char *transport, uint16_t *port, int nkeys, const char **keys, char **values);
-bool parse_request(const void *buf, size_t size, const char *protocol, const char *transport);
-
index b9e7bb7ccb79387bdae678dc0978c911e1a89187..fbe0b297458bb8a224a68ba93a2a5b3ffc6d0aeb 100644 (file)
@@ -1017,16 +1017,6 @@ public:
                return meshlink_channel_get_mss(handle, channel);
        };
 
-       /// Enable or disable zeroconf discovery of local peers
-       /** This controls whether zeroconf discovery using the Catta library will be
-        *  enabled to search for peers on the local network. By default, it is enabled.
-        *
-        *  @param enable  Set to true to enable discovery, false to disable.
-        */
-       void enable_discovery(bool enable = true) {
-               meshlink_enable_discovery(handle, enable);
-       }
-
        /// Inform MeshLink that the local network configuration might have changed
        /** This is intended to be used when there is no way for MeshLink to get notifications of local network changes.
         *  It forces MeshLink to scan all network interfaces for changes in up/down status and new/removed addresses,
@@ -1080,17 +1070,6 @@ 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 8dbe72512a052b06e3d5a3dab39f2bb9ecd61fd4..0ee3f1ae78b132ec0bbcc401f6978ac66b8da666 100644 (file)
@@ -1544,16 +1544,6 @@ void meshlink_set_node_channel_timeout(struct meshlink_handle *mesh, struct mesh
  */
 void meshlink_hint_address(struct meshlink_handle *mesh, struct meshlink_node *node, const struct sockaddr *addr);
 
-/// Enable or disable zeroconf discovery of local peers
-/** This controls whether zeroconf discovery using the Catta library will be
- *  enabled to search for peers on the local network. By default, it is enabled.
- *
- *  \memberof meshlink_handle
- *  @param mesh    A handle which represents an instance of MeshLink.
- *  @param enable  Set to true to enable discovery, false to disable.
- */
-void meshlink_enable_discovery(struct meshlink_handle *mesh, bool enable);
-
 /// Inform MeshLink that the local network configuration might have changed
 /** This is intended to be used when there is no way for MeshLink to get notifications of local network changes.
  *  It forces MeshLink to scan all network interfaces for changes in up/down status and new/removed addresses,
@@ -1630,17 +1620,6 @@ void meshlink_reset_timers(struct meshlink_handle *mesh);
  */
 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.
- */
-void meshlink_set_external_address_discovery_url(struct meshlink_handle *mesh, const char *url);
-
 /// 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
index 0d607fe2626997e86d518e4be04df38d08901e09..abec7f49994b104623a86abd2a8d8a73e3b02fb4 100644 (file)
@@ -37,9 +37,7 @@
 #include "utils.h"
 #include "xalloc.h"
 #include "ed25519/sha512.h"
-#include "discovery.h"
 #include "devtools.h"
-#include "graph.h"
 
 #ifndef MSG_NOSIGNAL
 #define MSG_NOSIGNAL 0
@@ -464,18 +462,7 @@ static bool try_bind(meshlink_handle_t *mesh, int port) {
                        }
                }
 
-               /* If TCP worked, then we require that UDP works as well. */
-
-               int udp_fd = setup_udp_listen_socket(mesh, aip);
-
-               if(udp_fd == -1) {
-                       closesocket(tcp_fd);
-                       success = false;
-                       break;
-               }
-
                closesocket(tcp_fd);
-               closesocket(udp_fd);
                success = true;
        }
 
@@ -656,10 +643,6 @@ static bool finalize_join(join_state_t *state, const void *buf, uint16_t len) {
                        }
                }
 
-               /* Clear the reachability times, since we ourself have never seen these nodes yet */
-               n->last_reachable = 0;
-               n->last_unreachable = 0;
-
                if(!node_write_config(mesh, n, true)) {
                        free_node(n);
                        return false;
@@ -1369,7 +1352,6 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) {
 
        mesh->appname = xstrdup(params->appname);
        mesh->devclass = params->devclass;
-       mesh->discovery.enabled = true;
        mesh->netns = params->netns;
        mesh->submeshes = NULL;
        mesh->log_cb = global_log_cb;
@@ -1545,10 +1527,6 @@ static void *meshlink_main_loop(void *arg) {
 #endif // HAVE_SETNS
        }
 
-       if(mesh->discovery.enabled) {
-               discovery_start(mesh);
-       }
-
        if(pthread_mutex_lock(&mesh->mutex) != 0) {
                abort();
        }
@@ -1560,11 +1538,6 @@ static void *meshlink_main_loop(void *arg) {
 
        pthread_mutex_unlock(&mesh->mutex);
 
-       // Stop discovery
-       if(mesh->discovery.enabled) {
-               discovery_stop(mesh);
-       }
-
        return NULL;
 }
 
@@ -1636,9 +1609,6 @@ bool meshlink_start(meshlink_handle_t *mesh) {
        pthread_cond_wait(&mesh->cond, &mesh->mutex);
        mesh->threadstarted = true;
 
-       // Ensure we are considered reachable
-       graph(mesh);
-
        pthread_mutex_unlock(&mesh->mutex);
        return true;
 }
@@ -1658,20 +1628,7 @@ void meshlink_stop(meshlink_handle_t *mesh) {
        // Shut down the main thread
        event_loop_stop(&mesh->loop);
 
-       // Send ourselves a UDP packet to kick the event loop
-       for(int i = 0; i < mesh->listen_sockets; i++) {
-               sockaddr_t sa;
-               socklen_t salen = sizeof(sa);
-
-               if(getsockname(mesh->listen_socket[i].udp.fd, &sa.sa, &salen) == -1) {
-                       logger(mesh, MESHLINK_ERROR, "System call `%s' failed: %s", "getsockname", sockstrerror(sockerrno));
-                       continue;
-               }
-
-               if(sendto(mesh->listen_socket[i].udp.fd, "", 1, MSG_NOSIGNAL, &sa.sa, salen) == -1) {
-                       logger(mesh, MESHLINK_ERROR, "Could not send a UDP packet to ourself: %s", sockstrerror(sockerrno));
-               }
-       }
+       // TODO: send something to a local socket to kick the event loop
 
        if(mesh->threadstarted) {
                // Wait for the main thread to finish
@@ -1701,11 +1658,6 @@ void meshlink_stop(meshlink_handle_t *mesh) {
        exit_adns(mesh);
        exit_outgoings(mesh);
 
-       // Ensure we are considered unreachable
-       if(mesh->nodes) {
-               graph(mesh);
-       }
-
        // Try to write out any changed node config files, ignore errors at this point.
        if(mesh->nodes) {
                for splay_each(node_t, n, mesh->nodes) {
@@ -2289,26 +2241,6 @@ struct time_range {
        time_t end;
 };
 
-static bool search_node_by_last_reachable(const node_t *node, const void *condition) {
-       const struct time_range *range = condition;
-       time_t start = node->last_reachable;
-       time_t end = node->last_unreachable;
-
-       if(end < start) {
-               end = time(NULL);
-
-               if(end < start) {
-                       start = end;
-               }
-       }
-
-       if(range->end >= range->start) {
-               return start <= range->end && end >= range->start;
-       } else {
-               return start > range->start || end < range->end;
-       }
-}
-
 meshlink_node_t **meshlink_get_all_nodes_by_dev_class(meshlink_handle_t *mesh, dev_class_t devclass, meshlink_node_t **nodes, size_t *nmemb) {
        if(!mesh || devclass < 0 || devclass >= DEV_CLASS_COUNT || !nmemb) {
                meshlink_errno = MESHLINK_EINVAL;
@@ -2327,17 +2259,6 @@ meshlink_node_t **meshlink_get_all_nodes_by_submesh(meshlink_handle_t *mesh, mes
        return meshlink_get_all_nodes_by_condition(mesh, submesh, nodes, nmemb, search_node_by_submesh);
 }
 
-meshlink_node_t **meshlink_get_all_nodes_by_last_reachable(meshlink_handle_t *mesh, time_t start, time_t end, meshlink_node_t **nodes, size_t *nmemb) {
-       if(!mesh || !nmemb) {
-               meshlink_errno = MESHLINK_EINVAL;
-               return NULL;
-       }
-
-       struct time_range range = {start, end};
-
-       return meshlink_get_all_nodes_by_condition(mesh, &range, nodes, nmemb, search_node_by_last_reachable);
-}
-
 dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t *node) {
        if(!mesh || !node) {
                meshlink_errno = MESHLINK_EINVAL;
@@ -2387,13 +2308,9 @@ bool meshlink_get_node_reachability(struct meshlink_handle *mesh, struct meshlin
 
        reachable = n->status.reachable && !n->status.blacklisted;
 
-       if(last_reachable) {
-               *last_reachable = n->last_reachable;
-       }
-
-       if(last_unreachable) {
-               *last_unreachable = n->last_unreachable;
-       }
+       // TODO: handle reachable times?
+       (void)last_reachable;
+       (void)last_unreachable;
 
        pthread_mutex_unlock(&mesh->mutex);
 
@@ -3075,10 +2992,6 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) {
                        break;
                }
 
-               /* Clear the reachability times, since we ourself have never seen these nodes yet */
-               n->last_reachable = 0;
-               n->last_unreachable = 0;
-
                if(!node_write_config(mesh, n, true)) {
                        free_node(n);
                        free(buf);
@@ -4049,36 +3962,6 @@ void handle_duplicate_node(meshlink_handle_t *mesh, node_t *n) {
        mesh->node_duplicate_cb(mesh, (meshlink_node_t *)n);
 }
 
-void meshlink_enable_discovery(meshlink_handle_t *mesh, bool enable) {
-       logger(mesh, MESHLINK_DEBUG, "meshlink_enable_discovery(%d)", enable);
-
-       if(!mesh) {
-               meshlink_errno = MESHLINK_EINVAL;
-               return;
-       }
-
-       if(pthread_mutex_lock(&mesh->mutex) != 0) {
-               abort();
-       }
-
-       if(mesh->discovery.enabled == enable) {
-               goto end;
-       }
-
-       if(mesh->threadstarted) {
-               if(enable) {
-                       discovery_start(mesh);
-               } else {
-                       discovery_stop(mesh);
-               }
-       }
-
-       mesh->discovery.enabled = enable;
-
-end:
-       pthread_mutex_unlock(&mesh->mutex);
-}
-
 void meshlink_hint_network_change(struct meshlink_handle *mesh) {
        logger(mesh, MESHLINK_DEBUG, "meshlink_hint_network_change()");
 
@@ -4091,15 +3974,6 @@ void meshlink_hint_network_change(struct meshlink_handle *mesh) {
                abort();
        }
 
-       if(mesh->discovery.enabled) {
-               scan_ifaddrs(mesh);
-       }
-
-       if(mesh->loop.now.tv_sec > mesh->discovery.last_update + 5) {
-               mesh->discovery.last_update = mesh->loop.now.tv_sec;
-               handle_network_change(mesh, 1);
-       }
-
        pthread_mutex_unlock(&mesh->mutex);
 }
 
@@ -4180,10 +4054,6 @@ void meshlink_reset_timers(struct meshlink_handle *mesh) {
 
        handle_network_change(mesh, true);
 
-       if(mesh->discovery.enabled) {
-               discovery_refresh(mesh);
-       }
-
        pthread_mutex_unlock(&mesh->mutex);
 }
 
@@ -4203,28 +4073,6 @@ void meshlink_set_inviter_commits_first(struct meshlink_handle *mesh, bool invit
        pthread_mutex_unlock(&mesh->mutex);
 }
 
-void meshlink_set_external_address_discovery_url(struct meshlink_handle *mesh, const char *url) {
-       logger(mesh, MESHLINK_DEBUG, "meshlink_set_external_address_discovery_url(%s)", url ? url : "(null)");
-
-       if(!mesh) {
-               meshlink_errno = EINVAL;
-               return;
-       }
-
-       if(url && (strncmp(url, "http://", 7) || strchr(url, ' '))) {
-               meshlink_errno = EINVAL;
-               return;
-       }
-
-       if(pthread_mutex_lock(&mesh->mutex) != 0) {
-               abort();
-       }
-
-       free(mesh->external_address_url);
-       mesh->external_address_url = url ? xstrdup(url) : NULL;
-       pthread_mutex_unlock(&mesh->mutex);
-}
-
 void meshlink_set_scheduling_granularity(struct meshlink_handle *mesh, long granularity) {
        logger(mesh, MESHLINK_DEBUG, "meshlink_set_scheduling_granularity(%ld)", granularity);
 
index acb8525cad7f0ba0977ace989503563360448985..f6cd014bd798200c1c27b2ad02dbb5bfbd09b54c 100644 (file)
@@ -1,6 +1,4 @@
 __emutls_v.meshlink_errno
-devtool_export_json_all_edges_state
-devtool_get_all_edges
 devtool_get_all_submeshes
 devtool_get_node_status
 devtool_keyrotate_probe
@@ -28,7 +26,6 @@ meshlink_clear_canonical_address
 meshlink_close
 meshlink_destroy
 meshlink_destroy_ex
-meshlink_enable_discovery
 meshlink_encrypted_key_rotate
 meshlink_errno
 meshlink_export
@@ -81,7 +78,6 @@ meshlink_set_dev_class_fast_retry_period
 meshlink_set_dev_class_maxtimeout
 meshlink_set_dev_class_timeouts
 meshlink_set_error_cb
-meshlink_set_external_address_discovery_url
 meshlink_set_inviter_commits_first
 meshlink_set_log_cb
 meshlink_set_node_channel_timeout
index af3a2501a646e37bc6d8c321f62ae4e998ada872..10849117c2d45ddf3d4bd88044d317c51fa0ebf7 100644 (file)
@@ -47,7 +47,6 @@ static const char meshlink_udp_label[] = "MeshLink UDP";
 
 typedef struct listen_socket_t {
        struct io_t tcp;
-       struct io_t udp;
        sockaddr_t sa;
        sockaddr_t broadcast_sa;
 } listen_socket_t;
@@ -100,10 +99,7 @@ struct meshlink_handle {
        meshlink_queue_t outpacketqueue;
        signal_t datafromapp;
 
-       hash_t *node_udp_cache;
-
        struct splay_tree_t *nodes;
-       struct splay_tree_t *edges;
 
        struct list_t *connections;
        struct list_t *outgoings;
@@ -148,8 +144,6 @@ struct meshlink_handle {
 
        dev_class_t devclass;
 
-       int udp_choice;
-
        dev_class_traits_t dev_class_traits[DEV_CLASS_COUNT];
 
        int netns;
@@ -168,22 +162,6 @@ struct meshlink_handle {
        pthread_cond_t cond;
        bool threadstarted;
 
-       // mDNS discovery
-       struct {
-               bool enabled;
-               io_t pfroute_io;
-               int *ifaces;
-               struct discovery_address *addresses;
-               int iface_count;
-               int address_count;
-               io_t sockets[2];
-               time_t last_update;
-#ifdef __APPLE__
-               pthread_t thread;
-               void *runloop;
-#endif
-       } discovery;
-
        // ADNS
        pthread_t adns_thread;
        pthread_cond_t adns_cond;
index 35cfc6502a6b12091fd36ed8d9353aa38765b3ce..60c16cb9fadc8b9ca3ac2127b180927c0ffe20e0 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -23,7 +23,6 @@
 #include "conf.h"
 #include "connection.h"
 #include "devtools.h"
-#include "graph.h"
 #include "logger.h"
 #include "meshlink_internal.h"
 #include "meta.h"
@@ -47,11 +46,12 @@ static const int default_interval = 60;
 /*
   Terminate a connection:
   - Mark it as inactive
-  - Remove the edge representing this connection
   - Kill it with fire
   - Check if we need to retry making an outgoing connection
 */
 void terminate_connection(meshlink_handle_t *mesh, connection_t *c, bool report) {
+       (void)report;
+
        if(c->status.active) {
                logger(mesh, MESHLINK_INFO, "Closing connection with %s", c->name);
        }
@@ -66,31 +66,6 @@ void terminate_connection(meshlink_handle_t *mesh, connection_t *c, bool report)
 
        c->status.active = false;
 
-       if(c->edge) {
-               if(report) {
-                       send_del_edge(mesh, mesh->everyone, c->edge, 0);
-               }
-
-               edge_del(mesh, c->edge);
-               c->edge = NULL;
-
-               /* Run MST and SSSP algorithms */
-
-               graph(mesh);
-
-               /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
-
-               if(report && c->node && !c->node->status.reachable) {
-                       edge_t *e;
-                       e = lookup_edge(c->node, mesh->self);
-
-                       if(e) {
-                               send_del_edge(mesh, mesh->everyone, e, 0);
-                               edge_del(mesh, e);
-                       }
-               }
-       }
-
        outgoing_t *outgoing = c->outgoing;
        connection_del(mesh, c);
 
index 9994fac6fe700bbeca2750205aeb168a2bf0d5e4..34bb54c95b30d1050a4d793e0369a1879f836094 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -89,7 +89,6 @@ void finish_connecting(struct meshlink_handle *mesh, struct connection_t *);
 void do_outgoing_connection(struct meshlink_handle *mesh, struct outgoing_t *);
 void handle_new_meta_connection(struct event_loop_t *loop, void *, int);
 int setup_tcp_listen_socket(struct meshlink_handle *mesh, const struct addrinfo *aip) __attribute__((__warn_unused_result__));
-int setup_udp_listen_socket(struct meshlink_handle *mesh, const struct addrinfo *aip) __attribute__((__warn_unused_result__));
 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len);
 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) __attribute__((__warn_unused_result__));
 void send_packet(struct meshlink_handle *mesh, struct node_t *, struct vpn_packet_t *);
index 02a617d1922bfae065a41539b14ddedec707964e..b6478e44a7c47f438c7bbfd4f1a419c1ba599ff0 100644 (file)
@@ -22,7 +22,6 @@
 #include "conf.h"
 #include "connection.h"
 #include "crypto.h"
-#include "graph.h"
 #include "logger.h"
 #include "meshlink_internal.h"
 #include "net.h"
 
 int keylifetime = 0;
 
-static void send_udppacket(meshlink_handle_t *mesh, node_t *, vpn_packet_t *);
-
-#define MAX_SEQNO 1073741824
-
-/* mtuprobes == 1..30: initial discovery, send bursts with 1 second interval
-   mtuprobes ==    31: sleep pinginterval seconds
-   mtuprobes ==    32: send 1 burst, sleep pingtimeout second
-   mtuprobes ==    33: no response from other side, restart PMTU discovery process
-
-   Probes are sent in batches of at least three, with random sizes between the
-   lower and upper boundaries for the MTU thus far discovered.
-
-   After the initial discovery, a fourth packet is added to each batch with a
-   size larger than the currently known PMTU, to test if the PMTU has increased.
-
-   In case local discovery is enabled, another packet is added to each batch,
-   which will be broadcast to the local network.
-
-*/
-
-static void send_mtu_probe_handler(event_loop_t *loop, void *data) {
-       meshlink_handle_t *mesh = loop->data;
-       node_t *n = data;
-       int timeout = 1;
-
-       n->mtuprobes++;
-
-       if(!n->status.reachable || !n->status.validkey) {
-               logger(mesh, MESHLINK_INFO, "Trying to send MTU probe to unreachable or rekeying node %s", n->name);
-               n->mtuprobes = 0;
-               return;
-       }
-
-       if(n->mtuprobes > 32) {
-               if(!n->minmtu) {
-                       n->mtuprobes = 31;
-                       timeout = mesh->dev_class_traits[n->devclass].pinginterval;
-                       goto end;
-               }
-
-               logger(mesh, MESHLINK_INFO, "%s did not respond to UDP ping, restarting PMTU discovery", n->name);
-               n->status.udp_confirmed = false;
-               n->mtuprobes = 1;
-               n->minmtu = 0;
-               n->maxmtu = MTU;
-
-               update_node_pmtu(mesh, n);
-       }
-
-       if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) {
-               logger(mesh, MESHLINK_INFO, "No response to MTU probes from %s", n->name);
-               n->mtuprobes = 31;
-       }
-
-       if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) {
-               if(n->minmtu > n->maxmtu) {
-                       n->minmtu = n->maxmtu;
-                       update_node_pmtu(mesh, n);
-               } else {
-                       n->maxmtu = n->minmtu;
-               }
-
-               n->mtu = n->minmtu;
-               logger(mesh, MESHLINK_INFO, "Fixing MTU of %s to %d after %d probes", n->name, n->mtu, n->mtuprobes);
-               n->mtuprobes = 31;
-       }
-
-       if(n->mtuprobes == 31) {
-               if(!n->minmtu && n->status.want_udp && n->nexthop && n->nexthop->connection) {
-                       /* Send a dummy ANS_KEY to try to update the reflexive UDP address */
-                       send_request(mesh, n->nexthop->connection, NULL, "%d %s %s . -1 -1 -1 0", ANS_KEY, mesh->self->name, n->name);
-                       n->status.want_udp = false;
-               }
-
-               timeout = mesh->dev_class_traits[n->devclass].pinginterval;
-               goto end;
-       } else if(n->mtuprobes == 32) {
-               timeout = mesh->dev_class_traits[n->devclass].pingtimeout;
-       }
-
-       for(int i = 0; i < 5; i++) {
-               int len;
-
-               if(i == 0) {
-                       if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU) {
-                               continue;
-                       }
-
-                       len = n->maxmtu + 8;
-               } else if(n->maxmtu <= n->minmtu) {
-                       len = n->maxmtu;
-               } else {
-                       len = n->minmtu + 1 + prng(mesh, n->maxmtu - n->minmtu);
-               }
-
-               if(len < 64) {
-                       len = 64;
-               }
-
-               vpn_packet_t packet;
-               packet.probe = true;
-               memset(packet.data, 0, 14);
-               randomize(packet.data + 14, len - 14);
-               packet.len = len;
-               n->status.broadcast = i >= 4 && n->mtuprobes <= 10 && n->prevedge;
-
-               logger(mesh, MESHLINK_DEBUG, "Sending MTU probe length %d to %s", len, n->name);
-
-               send_udppacket(mesh, n, &packet);
-       }
-
-       n->status.broadcast = false;
-
-end:
-       timeout_set(&mesh->loop, &n->mtutimeout, &(struct timespec) {
-               timeout, prng(mesh, TIMER_FUDGE)
-       });
-}
-
-void send_mtu_probe(meshlink_handle_t *mesh, node_t *n) {
-       timeout_add(&mesh->loop, &n->mtutimeout, send_mtu_probe_handler, n, &(struct timespec) {
-               1, 0
-       });
-       send_mtu_probe_handler(&mesh->loop, n);
-}
-
-static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
-       if(len < 64) {
-               logger(mesh, MESHLINK_WARNING, "Got too short MTU probe length %d from %s", packet->len, n->name);
-               return;
-       }
-
-       logger(mesh, MESHLINK_DEBUG, "Got MTU probe length %d from %s", packet->len, n->name);
-
-       if(!packet->data[0]) {
-               /* It's a probe request, send back a reply */
-
-               packet->data[0] = 1;
-
-               /* Temporarily set udp_confirmed, so that the reply is sent
-                  back exactly the way it came in. */
-
-               bool udp_confirmed = n->status.udp_confirmed;
-               n->status.udp_confirmed = true;
-               send_udppacket(mesh, n, packet);
-               n->status.udp_confirmed = udp_confirmed;
-       } else {
-               /* It's a valid reply: now we know bidirectional communication
-                  is possible using the address and socket that the reply
-                  packet used. */
-
-               if(!n->status.udp_confirmed) {
-                       char *address, *port;
-                       sockaddr2str(&n->address, &address, &port);
-
-                       if(n->nexthop && n->nexthop->connection) {
-                               send_request(mesh, n->nexthop->connection, NULL, "%d %s %s . -1 -1 -1 0 %s %s", ANS_KEY, n->name, n->name, address, port);
-                       } else {
-                               logger(mesh, MESHLINK_WARNING, "Cannot send reflexive address to %s via %s", n->name, n->nexthop ? n->nexthop->name : n->name);
-                       }
-
-                       free(address);
-                       free(port);
-                       n->status.udp_confirmed = true;
-               }
-
-               /* If we haven't established the PMTU yet, restart the discovery process. */
-
-               if(n->mtuprobes > 30) {
-                       if(len == n->maxmtu + 8) {
-                               logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s detected, restarting PMTU discovery", n->name);
-                               n->maxmtu = MTU;
-                               n->mtuprobes = 10;
-                               return;
-                       }
-
-                       if(n->minmtu) {
-                               n->mtuprobes = 30;
-                       } else {
-                               n->mtuprobes = 1;
-                       }
-               }
-
-               /* If applicable, raise the minimum supported MTU */
-
-               if(len > n->maxmtu) {
-                       len = n->maxmtu;
-               }
-
-               if(n->minmtu < len) {
-                       n->minmtu = len;
-                       update_node_pmtu(mesh, n);
-               }
-       }
-}
-
 /* VPN packet I/O */
 
 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
@@ -245,33 +48,6 @@ static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *pac
        }
 }
 
-static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
-       (void)mesh;
-       return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
-}
-
-static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
-       if(!n->status.reachable) {
-               logger(mesh, MESHLINK_ERROR, "Got SPTPS data from unreachable node %s", n->name);
-               return;
-       }
-
-       if(!n->sptps.state) {
-               if(!n->status.waitingforkey) {
-                       logger(mesh, MESHLINK_DEBUG, "Got packet from %s but we haven't exchanged keys yet", n->name);
-                       send_req_key(mesh, n);
-               } else {
-                       logger(mesh, MESHLINK_DEBUG, "Got packet from %s but he hasn't got our key yet", n->name);
-               }
-
-               return;
-       }
-
-       if(!sptps_receive_data(&n->sptps, inpkt->data, inpkt->len)) {
-               logger(mesh, MESHLINK_ERROR, "Could not process SPTPS data from %s: %s", n->name, strerror(errno));
-       }
-}
-
 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
        if(!n->status.reachable) {
                logger(mesh, MESHLINK_ERROR, "Trying to send SPTPS data to unreachable node %s", n->name);
@@ -305,107 +81,6 @@ static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *
        return;
 }
 
-static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock, sockaddr_t *sa_buf) {
-       /* Latest guess */
-       *sa = &n->address;
-       *sock = n->sock;
-
-       /* If the UDP address is confirmed, use it. */
-       if(n->status.udp_confirmed) {
-               return;
-       }
-
-       /* Send every third packet to n->address; that could be set
-          to the node's reflexive UDP address discovered during key
-          exchange. */
-
-       if(++mesh->udp_choice >= 3) {
-               mesh->udp_choice = 0;
-               return;
-       }
-
-       /* If we have learned an address via Catta, try this once every batch */
-       if(mesh->udp_choice == 1 && n->catta_address.sa.sa_family != AF_UNSPEC) {
-               *sa = &n->catta_address;
-               goto check_socket;
-       }
-
-       /* Else, if we have a canonical address, try this once every batch */
-       if(mesh->udp_choice == 1 && n->canonical_address) {
-               char *host = xstrdup(n->canonical_address);
-               char *port = strchr(host, ' ');
-
-               if(port) {
-                       *port++ = 0;
-                       *sa_buf = str2sockaddr_random(mesh, host, port);
-                       *sa = sa_buf;
-
-                       if(sa_buf->sa.sa_family != AF_UNKNOWN) {
-                               free(host);
-                               goto check_socket;
-                       }
-               }
-
-               free(host);
-       }
-
-       /* Otherwise, address are found in edges to this node.
-          So we pick a random edge and a random socket. */
-
-       edge_t *candidate = NULL;
-
-       {
-               int i = 0;
-               int j = prng(mesh, n->edge_tree->count);
-
-               for splay_each(edge_t, e, n->edge_tree) {
-                       if(i++ == j) {
-                               candidate = e->reverse;
-                               break;
-                       }
-               }
-       }
-
-       if(candidate) {
-               *sa = &candidate->address;
-               *sock = prng(mesh, mesh->listen_sockets);
-       }
-
-check_socket:
-
-       /* Make sure we have a suitable socket for the chosen address */
-       if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
-               for(int i = 0; i < mesh->listen_sockets; i++) {
-                       if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
-                               *sock = i;
-                               break;
-                       }
-               }
-       }
-}
-
-static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
-       *sock = prng(mesh, mesh->listen_sockets);
-       sockaddr_t *broadcast_sa = &mesh->listen_socket[*sock].broadcast_sa;
-
-       if(broadcast_sa->sa.sa_family == AF_INET6) {
-               broadcast_sa->in6.sin6_port = n->prevedge->address.in.sin_port;
-       } else {
-               broadcast_sa->in.sin_port = n->prevedge->address.in.sin_port;
-       }
-
-       *sa = broadcast_sa;
-}
-
-static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
-       if(!n->status.reachable) {
-               logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s", n->name);
-               return;
-       }
-
-       send_sptps_packet(mesh, n, origpkt);
-}
-
 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
        assert(handle);
        assert(data);
@@ -419,54 +94,29 @@ bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
                return false;
        }
 
-       /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
-
-       if(type >= SPTPS_HANDSHAKE || (type != PKT_PROBE && (len - 21) > to->minmtu)) {
-               char buf[len * 4 / 3 + 5];
-               b64encode(data, buf, len);
 
-               if(!to->nexthop || !to->nexthop->connection) {
-                       logger(mesh, MESHLINK_WARNING, "Unable to forward SPTPS packet to %s via %s", to->name, to->nexthop ? to->nexthop->name : to->name);
-                       return false;
-               }
-
-               /* If no valid key is known yet, send the packets using ANS_KEY requests,
-                  to ensure we get to learn the reflexive UDP address. */
-               if(!to->status.validkey) {
-                       return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, mesh->self->name, to->name, buf, 0);
-               } else {
-                       return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
-               }
+       if(type == PKT_PROBE) {
+               /* Probe packets are not supported. */
+               return false;
        }
 
-       /* Otherwise, send the packet via UDP */
+       /* Send it via TCP. */
 
-       sockaddr_t sa_buf;
-       const sockaddr_t *sa;
-       int sock;
+       char buf[len * 4 / 3 + 5];
+       b64encode(data, buf, len);
 
-       if(to->status.broadcast) {
-               choose_broadcast_address(mesh, to, &sa, &sock);
-       } else {
-               choose_udp_address(mesh, to, &sa, &sock, &sa_buf);
+       if(!to->nexthop || !to->nexthop->connection) {
+               logger(mesh, MESHLINK_WARNING, "Unable to forward SPTPS packet to %s via %s", to->name, to->nexthop ? to->nexthop->name : to->name);
+               return false;
        }
 
-       if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
-               if(sockmsgsize(sockerrno)) {
-                       if(to->maxmtu >= len) {
-                               to->maxmtu = len - 1;
-                       }
-
-                       if(to->mtu >= len) {
-                               to->mtu = len - 1;
-                       }
-               } else {
-                       logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s: %s", to->name, sockstrerror(sockerrno));
-                       return false;
-               }
+       /* If no valid key is known yet, send the packets using ANS_KEY requests,
+          to ensure we get to learn the reflexive UDP address. */
+       if(!to->status.validkey) {
+               return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, mesh->self->name, to->name, buf, 0);
+       } else {
+               return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
        }
-
-       return true;
 }
 
 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
@@ -498,11 +148,8 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t
        vpn_packet_t inpkt;
 
        if(type == PKT_PROBE) {
-               inpkt.len = len;
-               inpkt.probe = true;
-               memcpy(inpkt.data, data, len);
-               mtu_probe_h(mesh, from, &inpkt, len);
-               return true;
+               /* We shouldn't receive any UDP probe packets. */
+               return false;
        } else {
                inpkt.probe = false;
        }
@@ -549,89 +196,3 @@ void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
        send_sptps_packet(mesh, n, packet);
        return;
 }
-
-static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
-       node_t *n = NULL;
-       bool hard = false;
-
-       for splay_each(edge_t, e, mesh->edges) {
-               if(!e->to->status.reachable || e->to == mesh->self) {
-                       continue;
-               }
-
-               if(sockaddrcmp_noport(from, &e->address)) {
-                       if(mesh->last_hard_try == mesh->loop.now.tv_sec) {
-                               continue;
-                       }
-
-                       hard = true;
-               }
-
-               if(!try_mac(mesh, e->to, pkt)) {
-                       continue;
-               }
-
-               n = e->to;
-               break;
-       }
-
-       if(hard) {
-               mesh->last_hard_try = mesh->loop.now.tv_sec;
-       }
-
-       return n;
-}
-
-void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
-       (void)flags;
-       meshlink_handle_t *mesh = loop->data;
-       listen_socket_t *ls = data;
-       vpn_packet_t pkt;
-       char *hostname;
-       sockaddr_t from;
-       socklen_t fromlen = sizeof(from);
-       node_t *n;
-       int len;
-
-       memset(&from, 0, sizeof(from));
-
-       len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
-
-       if(len <= 0 || len > MAXSIZE) {
-               if(!sockwouldblock(sockerrno)) {
-                       logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
-               }
-
-               return;
-       }
-
-       pkt.len = len;
-
-       sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
-
-       n = lookup_node_udp(mesh, &from);
-
-       if(!n) {
-               n = try_harder(mesh, &from, &pkt);
-
-               if(n) {
-                       update_node_udp(mesh, n, &from);
-               } else if(mesh->log_level <= MESHLINK_WARNING) {
-                       hostname = sockaddr2hostname(&from);
-                       logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
-                       free(hostname);
-                       return;
-               } else {
-                       return;
-               }
-       }
-
-       if(n->status.blacklisted) {
-               logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
-               return;
-       }
-
-       n->sock = ls - mesh->listen_socket;
-
-       receive_udppacket(mesh, n, &pkt);
-}
index a7a538f01c75d1b4ed66fa77114391bbce123ce1..7fd760b472f77fe591809b276a3bdaa158d52d0b 100644 (file)
@@ -22,7 +22,6 @@
 #include "conf.h"
 #include "connection.h"
 #include "ecdsa.h"
-#include "graph.h"
 #include "logger.h"
 #include "meshlink_internal.h"
 #include "net.h"
@@ -121,16 +120,8 @@ bool node_read_public_key(meshlink_handle_t *mesh, node_t *n) {
                }
        }
 
-       time_t last_reachable = packmsg_get_int64(&in);
-       time_t last_unreachable = packmsg_get_int64(&in);
-
-       if(!n->last_reachable) {
-               n->last_reachable = last_reachable;
-       }
-
-       if(!n->last_unreachable) {
-               n->last_unreachable = last_unreachable;
-       }
+       packmsg_skip_element(&in); // last_reachable
+       packmsg_skip_element(&in); // last_unreachable
 
        config_free(&config);
        return true;
@@ -212,8 +203,8 @@ bool node_read_from_config(meshlink_handle_t *mesh, node_t *n, const config_t *c
                }
        }
 
-       n->last_reachable = packmsg_get_int64(&in);
-       n->last_unreachable = packmsg_get_int64(&in);
+       packmsg_skip_element(&in); // last_reachable
+       packmsg_skip_element(&in); // last_unreachable
 
        return packmsg_done(&in);
 }
@@ -271,8 +262,8 @@ bool node_write_config(meshlink_handle_t *mesh, node_t *n, bool new_key) {
                packmsg_add_sockaddr(&out, &n->recent[i]);
        }
 
-       packmsg_add_int64(&out, n->last_reachable);
-       packmsg_add_int64(&out, n->last_unreachable);
+       packmsg_add_int64(&out, 0); // last_reachable
+       packmsg_add_int64(&out, 0); // last_unreachable
 
        if(!packmsg_output_ok(&out)) {
                meshlink_errno = MESHLINK_EINTERNAL;
@@ -394,79 +385,6 @@ int setup_tcp_listen_socket(meshlink_handle_t *mesh, const struct addrinfo *aip)
        return nfd;
 }
 
-int setup_udp_listen_socket(meshlink_handle_t *mesh, const struct addrinfo *aip) {
-       int nfd = socket(aip->ai_family, SOCK_DGRAM, IPPROTO_UDP);
-
-       if(nfd == -1) {
-               return -1;
-       }
-
-#ifdef FD_CLOEXEC
-       fcntl(nfd, F_SETFD, FD_CLOEXEC);
-#endif
-
-#ifdef O_NONBLOCK
-       int flags = fcntl(nfd, F_GETFL);
-
-       if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
-               closesocket(nfd);
-               logger(mesh, MESHLINK_ERROR, "System call `%s' failed: %s", "fcntl", strerror(errno));
-               return -1;
-       }
-
-#elif defined(WIN32)
-       unsigned long arg = 1;
-
-       if(ioctlsocket(nfd, FIONBIO, &arg) != 0) {
-               closesocket(nfd);
-               logger(mesh, MESHLINK_ERROR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno));
-               return -1;
-       }
-
-#endif
-
-       int option = 1;
-       setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option));
-       setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option));
-
-#if defined(IPV6_V6ONLY)
-
-       if(aip->ai_family == AF_INET6) {
-               setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option));
-       }
-
-#endif
-
-#if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT)
-#define IP_DONTFRAGMENT IP_DONTFRAG
-#endif
-
-#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
-       option = IP_PMTUDISC_DO;
-       setsockopt(nfd, IPPROTO_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option));
-#elif defined(IP_DONTFRAGMENT)
-       option = 1;
-       setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, (void *)&option, sizeof(option));
-#endif
-
-       if(aip->ai_family == AF_INET6) {
-#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
-               option = IPV6_PMTUDISC_DO;
-               setsockopt(nfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option));
-#elif defined(IPV6_DONTFRAG)
-               option = 1;
-               setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option));
-#endif
-       }
-
-       if(bind(nfd, aip->ai_addr, aip->ai_addrlen)) {
-               closesocket(nfd);
-               return -1;
-       }
-
-       return nfd;
-}
-
 /*
   Add listening sockets.
 */
@@ -523,18 +441,7 @@ static bool add_listen_sockets(meshlink_handle_t *mesh) {
                        }
                }
 
-               /* If TCP worked, then we require that UDP works as well. */
-
-               int udp_fd = setup_udp_listen_socket(mesh, aip);
-
-               if(udp_fd == -1) {
-                       closesocket(tcp_fd);
-                       success = false;
-                       break;
-               }
-
                io_add(&mesh->loop, &mesh->listen_socket[mesh->listen_sockets].tcp, handle_new_meta_connection, &mesh->listen_socket[mesh->listen_sockets], tcp_fd, IO_READ);
-               io_add(&mesh->loop, &mesh->listen_socket[mesh->listen_sockets].udp, handle_incoming_vpn_data, &mesh->listen_socket[mesh->listen_sockets], udp_fd, IO_READ);
 
                if(mesh->log_level <= MESHLINK_INFO) {
                        char *hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
@@ -562,9 +469,7 @@ static bool add_listen_sockets(meshlink_handle_t *mesh) {
        if(!success) {
                for(int i = 0; i < mesh->listen_sockets; i++) {
                        io_del(&mesh->loop, &mesh->listen_socket[i].tcp);
-                       io_del(&mesh->loop, &mesh->listen_socket[i].udp);
                        closesocket(mesh->listen_socket[i].tcp.fd);
-                       closesocket(mesh->listen_socket[i].udp.fd);
                }
 
                mesh->listen_sockets = 0;
@@ -626,7 +531,6 @@ bool setup_network(meshlink_handle_t *mesh) {
        init_connections(mesh);
        init_submeshes(mesh);
        init_nodes(mesh);
-       init_edges(mesh);
        init_requests(mesh);
 
        if(!setup_myself(mesh)) {
@@ -651,13 +555,10 @@ void close_network_connections(meshlink_handle_t *mesh) {
 
        for(int i = 0; i < mesh->listen_sockets; i++) {
                io_del(&mesh->loop, &mesh->listen_socket[i].tcp);
-               io_del(&mesh->loop, &mesh->listen_socket[i].udp);
                closesocket(mesh->listen_socket[i].tcp.fd);
-               closesocket(mesh->listen_socket[i].udp.fd);
        }
 
        exit_requests(mesh);
-       exit_edges(mesh);
        exit_nodes(mesh);
        exit_submeshes(mesh);
        exit_connections(mesh);
index 4989b6cf0578a0471a868cdfc8a1a09a633bdd32..29e37254986b2ab96b2f79ec09b2393f481951fe 100644 (file)
@@ -174,44 +174,6 @@ static void handle_meta_io(event_loop_t *loop, void *data, int flags) {
        }
 }
 
-// Find edges pointing to this node, and use them to build a list of unique, known addresses.
-static struct addrinfo *get_known_addresses(node_t *n) {
-       struct addrinfo *ai = NULL;
-
-       for splay_each(edge_t, e, n->edge_tree) {
-               if(!e->reverse) {
-                       continue;
-               }
-
-               bool found = false;
-
-               for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
-                       if(!sockaddrcmp(&e->reverse->address, (sockaddr_t *)aip->ai_addr)) {
-                               found = true;
-                               break;
-                       }
-               }
-
-               if(found) {
-                       continue;
-               }
-
-               // Create a new struct addrinfo, and put it at the head of the list.
-               struct addrinfo *nai = xzalloc(sizeof(*nai) + SALEN(e->reverse->address.sa));
-               nai->ai_next = ai;
-               ai = nai;
-
-               ai->ai_family = e->reverse->address.sa.sa_family;
-               ai->ai_socktype = SOCK_STREAM;
-               ai->ai_protocol = IPPROTO_TCP;
-               ai->ai_addrlen = SALEN(e->reverse->address.sa);
-               ai->ai_addr = (struct sockaddr *)(nai + 1);
-               memcpy(ai->ai_addr, &e->reverse->address, ai->ai_addrlen);
-       }
-
-       return ai;
-}
-
 // Build a list of recently seen addresses.
 static struct addrinfo *get_recent_addresses(node_t *n) {
        struct addrinfo *ai = NULL;
@@ -339,24 +301,6 @@ static bool get_next_outgoing_address(meshlink_handle_t *mesh, outgoing_t *outgo
                        return true;
                }
 
-               free_known_addresses(outgoing->ai);
-               outgoing->ai = NULL;
-               outgoing->aip = NULL;
-               outgoing->state = OUTGOING_KNOWN;
-       }
-
-       if(outgoing->state == OUTGOING_KNOWN) {
-               if(!outgoing->aip) {
-                       outgoing->ai = get_known_addresses(outgoing->node);
-                       outgoing->aip = outgoing->ai;
-               } else {
-                       outgoing->aip = outgoing->aip->ai_next;
-               }
-
-               if(outgoing->aip) {
-                       return true;
-               }
-
                free_known_addresses(outgoing->ai);
                outgoing->ai = NULL;
                outgoing->aip = NULL;
index b8caed6c7e06ca182f671fd046f8be4d44d76611..160bcb38248805e0724930632186c24391c2dfb1 100644 (file)
@@ -35,26 +35,19 @@ static int node_compare(const node_t *a, const node_t *b) {
 
 void init_nodes(meshlink_handle_t *mesh) {
        mesh->nodes = splay_alloc_tree((splay_compare_t) node_compare, (splay_action_t) free_node);
-       mesh->node_udp_cache = hash_alloc(0x100, sizeof(sockaddr_t));
 }
 
 void exit_nodes(meshlink_handle_t *mesh) {
-       if(mesh->node_udp_cache) {
-               hash_free(mesh->node_udp_cache);
-       }
-
        if(mesh->nodes) {
                splay_delete_tree(mesh->nodes);
        }
 
-       mesh->node_udp_cache = NULL;
        mesh->nodes = NULL;
 }
 
 node_t *new_node(void) {
        node_t *n = xzalloc(sizeof(*n));
 
-       n->edge_tree = new_edge_tree();
        n->mtu = MTU;
        n->maxmtu = MTU;
        n->devclass = DEV_CLASS_UNKNOWN;
@@ -67,10 +60,6 @@ void free_node(node_t *n) {
 
        utcp_exit(n->utcp);
 
-       if(n->edge_tree) {
-               free_edge_tree(n->edge_tree);
-       }
-
        sockaddrfree(&n->address);
 
        ecdsa_free(n->ecdsa);
@@ -93,11 +82,6 @@ void node_add(meshlink_handle_t *mesh, node_t *n) {
 
 void node_del(meshlink_handle_t *mesh, node_t *n) {
        timeout_del(&mesh->loop, &n->mtutimeout);
-
-       for splay_each(edge_t, e, n->edge_tree) {
-               edge_del(mesh, e);
-       }
-
        splay_delete(mesh->nodes, n);
 }
 
@@ -110,41 +94,6 @@ node_t *lookup_node(meshlink_handle_t *mesh, const char *name) {
        return result;
 }
 
-node_t *lookup_node_udp(meshlink_handle_t *mesh, const sockaddr_t *sa) {
-       return hash_search(mesh->node_udp_cache, sa);
-}
-
-void update_node_udp(meshlink_handle_t *mesh, node_t *n, const sockaddr_t *sa) {
-       if(n == mesh->self) {
-               logger(mesh, MESHLINK_WARNING, "Trying to update UDP address of mesh->self!");
-               return;
-       }
-
-       hash_insert(mesh->node_udp_cache, &n->address, NULL);
-
-       if(sa) {
-               n->address = *sa;
-               n->sock = 0;
-
-               for(int i = 0; i < mesh->listen_sockets; i++) {
-                       if(mesh->listen_socket[i].sa.sa.sa_family == sa->sa.sa_family) {
-                               n->sock = i;
-                               break;
-                       }
-               }
-
-               hash_insert(mesh->node_udp_cache, sa, n);
-
-               node_add_recent_address(mesh, n, sa);
-
-               if(mesh->log_level <= MESHLINK_DEBUG) {
-                       char *hostname = sockaddr2hostname(&n->address);
-                       logger(mesh, MESHLINK_DEBUG, "UDP address of %s set to %s", n->name, hostname);
-                       free(hostname);
-               }
-       }
-}
-
 bool node_add_recent_address(meshlink_handle_t *mesh, node_t *n, const sockaddr_t *sa) {
        (void)mesh;
        bool found = false;
index 63f3c2c8bad55132aa694981c702d760777d2b1e..26d868dd185f3c635677f9dd22b70dfe424f68a2 100644 (file)
@@ -88,15 +88,7 @@ typedef struct node_t {
        sockaddr_t recent[MAX_RECENT];          /* Recently seen addresses */
        sockaddr_t catta_address;               /* Latest address seen by Catta */
 
-       // Graph-related member variables
-       time_t last_reachable;
-       time_t last_unreachable;
-
-       int distance;
        struct node_t *nexthop;                 /* nearest node from us to him */
-       struct edge_t *prevedge;                /* nearest node from him to us */
-
-       struct splay_tree_t *edge_tree;         /* Edges with this node as one of the endpoints */
 } node_t;
 
 void init_nodes(struct meshlink_handle *mesh);
@@ -106,8 +98,6 @@ void free_node(node_t *n);
 void node_add(struct meshlink_handle *mesh, node_t *n);
 void node_del(struct meshlink_handle *mesh, node_t *n);
 node_t *lookup_node(struct meshlink_handle *mesh, const char *name) __attribute__((__warn_unused_result__));
-node_t *lookup_node_udp(struct meshlink_handle *mesh, const sockaddr_t *sa) __attribute__((__warn_unused_result__));
-void update_node_udp(struct meshlink_handle *mesh, node_t *n, const sockaddr_t *sa);
 bool node_add_recent_address(struct meshlink_handle *mesh, node_t *n, const sockaddr_t *addr);
 
 #endif
index fb1e10960cc25539971a4250f8c9f358a1e87556..5882513d4947be821741ac3f55b6de36b1d011cf 100644 (file)
@@ -70,7 +70,6 @@ typedef struct past_request_t {
 #define MAX_STRING_SIZE 2049
 #define MAX_STRING "%2048s"
 
-#include "edge.h"
 #include "net.h"
 #include "node.h"
 
@@ -92,8 +91,6 @@ bool send_ack(struct meshlink_handle *mesh, struct connection_t *);
 bool send_error(struct meshlink_handle *mesh, struct connection_t *, request_error_t, const char *);
 bool send_ping(struct meshlink_handle *mesh, struct connection_t *);
 bool send_pong(struct meshlink_handle *mesh, struct connection_t *);
-bool send_add_edge(struct meshlink_handle *mesh, struct connection_t *, const struct edge_t *, int contradictions);
-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 *);
 
index 943040e9fd528d4c6894ce135997564ff28cd18b..e292d58c61b44c74cf985ac2eaa2eadb831d7efe 100644 (file)
@@ -23,8 +23,6 @@
 #include "connection.h"
 #include "devtools.h"
 #include "ecdsa.h"
-#include "edge.h"
-#include "graph.h"
 #include "logger.h"
 #include "meshlink_internal.h"
 #include "meta.h"
@@ -148,16 +146,6 @@ bool send_ack(meshlink_handle_t *mesh, connection_t *c) {
        return send_request(mesh, c, NULL, "%d %s %d %x", ACK, mesh->myport, mesh->devclass, OPTION_PMTU_DISCOVERY | (PROT_MINOR << 24));
 }
 
-static void send_everything(meshlink_handle_t *mesh, connection_t *c) {
-       /* Send all known subnets and edges */
-
-       for splay_each(node_t, n, mesh->nodes) {
-               for inner_splay_each(edge_t, e, n->edge_tree) {
-                       send_add_edge(mesh, c, e, 0);
-               }
-       }
-}
-
 bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
        assert(request);
        assert(*request);
@@ -200,10 +188,6 @@ bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
                                n->connection->outgoing = NULL;
                        }
 
-                       /* Remove the edge before terminating the connection, to prevent a graph update. */
-                       edge_del(mesh, n->connection->edge);
-                       n->connection->edge = NULL;
-
                        terminate_connection(mesh, n->connection, false);
                }
        }
@@ -248,31 +232,7 @@ bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
                }
        }
 
-       /* Send him everything we know */
-
-       send_everything(mesh, c);
-
-       /* Create an edge_t for this connection */
-
-       assert(devclass >= 0 && devclass < DEV_CLASS_COUNT);
-
-       c->edge = new_edge();
-       c->edge->from = mesh->self;
-       c->edge->to = n;
-       sockaddrcpy_setport(&c->edge->address, &c->address, atoi(hisport));
-       c->edge->weight = mesh->dev_class_traits[devclass].edge_weight;
-       c->edge->connection = c;
-
-       node_add_recent_address(mesh, n, &c->address);
-       edge_add(mesh, c->edge);
-
-       /* Notify everyone of the new edge */
-
-       send_add_edge(mesh, mesh->everyone, c->edge, 0);
-
-       /* Run MST and SSSP algorithms */
-
-       graph(mesh);
+       /* TODO: Create an edge_t for this connection, send it */
 
        /* Request a session key to jump start UDP traffic */
 
index aa1a648ec5360ef60d066d3c16d2bfb45a31ec01..16ebfd5fb425fd6c94fab8e7139052ac2b363cb6 100644 (file)
@@ -21,8 +21,6 @@
 
 #include "conf.h"
 #include "connection.h"
-#include "edge.h"
-#include "graph.h"
 #include "logger.h"
 #include "meshlink_internal.h"
 #include "meta.h"
@@ -34,6 +32,7 @@
 #include "xalloc.h"
 #include "submesh.h"
 
+#if 0
 bool send_add_edge(meshlink_handle_t *mesh, connection_t *c, const edge_t *e, int contradictions) {
        bool x;
        char *address, *port;
@@ -82,11 +81,15 @@ bool send_add_edge(meshlink_handle_t *mesh, connection_t *c, const edge_t *e, in
 
        return x;
 }
+#endif
 
 bool add_edge_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
        assert(request);
        assert(*request);
 
+       (void)mesh;
+       (void)c;
+#if 0
        edge_t *e;
        node_t *from, *to;
        char from_name[MAX_STRING_SIZE];
@@ -255,10 +258,13 @@ bool add_edge_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
        /* Tell the rest about the new edge */
 
        forward_request(mesh, c, s, request);
+#endif
 
+       /* TODO: Check if this is an edge we would own */
        return true;
 }
 
+#if 0
 bool send_del_edge(meshlink_handle_t *mesh, connection_t *c, const edge_t *e, int contradictions) {
        submesh_t *s = NULL;
 
@@ -286,11 +292,15 @@ bool send_del_edge(meshlink_handle_t *mesh, connection_t *c, const edge_t *e, in
        return send_request(mesh, c, s, "%d %x %s %s %d %x", DEL_EDGE, prng(mesh, UINT_MAX),
                            e->from->name, e->to->name, contradictions, e->session_id);
 }
+#endif
 
 bool del_edge_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
        assert(request);
        assert(*request);
 
+       (void)mesh;
+       (void)c;
+#if 0
        edge_t *e;
        char from_name[MAX_STRING_SIZE];
        char to_name[MAX_STRING_SIZE];
@@ -380,5 +390,8 @@ bool del_edge_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
                }
        }
 
+#endif
+
+       /* TODO: Check if this is an edge we would own. */
        return true;
 }
index 25dbc55e5c04b7533e9eb0f6c5eeb62214cc648e..bd27b01b6aacc6a5efa3f9db3630f63bdb766c93 100644 (file)
@@ -411,17 +411,6 @@ bool ans_key_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
                        return false;
                }
 
-               /* Append the known UDP address of the from node, if we have a confirmed one */
-               if(!*address && from->status.udp_confirmed && from->address.sa.sa_family != AF_UNSPEC) {
-                       char *reflexive_address, *reflexive_port;
-                       logger(mesh, MESHLINK_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
-                       sockaddr2str(&from->address, &reflexive_address, &reflexive_port);
-                       send_request(mesh, to->nexthop->connection, NULL, "%s %s %s", request, reflexive_address, reflexive_port);
-                       free(reflexive_address);
-                       free(reflexive_port);
-                       return true;
-               }
-
                return send_request(mesh, to->nexthop->connection, NULL, "%s", request);
        }
 
@@ -429,29 +418,7 @@ bool ans_key_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
 
        if(from == mesh->self) {
                if(*key == '.' && *address && *port) {
-                       logger(mesh, MESHLINK_DEBUG, "Learned our own reflexive UDP address from %s: %s port %s", c->name, address, port);
-
-                       /* Inform all other nodes we want to communicate with and which are reachable via this connection */
-                       for splay_each(node_t, n, mesh->nodes) {
-                               if(n->nexthop != c->node) {
-                                       continue;
-                               }
-
-                               if(n->status.udp_confirmed) {
-                                       continue;
-                               }
-
-                               if(!n->status.waitingforkey && !n->status.validkey) {
-                                       continue;
-                               }
-
-                               if(!n->nexthop->connection) {
-                                       continue;
-                               }
-
-                               logger(mesh, MESHLINK_DEBUG, "Forwarding our own reflexive UDP address to %s", n->name);
-                               send_request(mesh, c, NULL, "%d %s %s . -1 -1 -1 0 %s %s", ANS_KEY, mesh->self->name, n->name, address, port);
-                       }
+                       /* Ignore reflexive UDP address */
                } else {
                        logger(mesh, MESHLINK_WARNING, "Got %s from %s from %s to %s",
                               "ANS_KEY", c->name, from_name, to_name);
@@ -482,12 +449,8 @@ bool ans_key_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
 
        if(from->status.validkey) {
                if(*address && *port) {
-                       logger(mesh, MESHLINK_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
-                       sockaddr_t sa = str2sockaddr(address, port);
-                       update_node_udp(mesh, from, &sa);
+                       /* Ignore reflexive UDP address */
                }
-
-               send_mtu_probe(mesh, from);
        }
 
        return true;
index e848efd369f92143ec0fb1694d94f36de3c9fae9..1fd39ecdd9b0e17b2dd3f841570583026c3839e6 100644 (file)
@@ -43,32 +43,12 @@ int main(void) {
        assert(self);
        assert(!strcmp(self->name, "foo"));
 
-       // Check that we are not reachable.
-
-       time_t last_reachable;
-       time_t last_unreachable;
-       assert(!meshlink_get_node_reachability(mesh, self, &last_reachable, &last_unreachable));
-       assert(!last_reachable);
-       assert(!last_unreachable);
-
        // Start and stop the mesh.
 
        assert(meshlink_start(mesh));
 
-       // Check that we are now reachable
-
-       assert(meshlink_get_node_reachability(mesh, self, &last_reachable, &last_unreachable));
-       assert(last_reachable);
-       assert(!last_unreachable);
-
        meshlink_stop(mesh);
 
-       // Check that we are no longer reachable.
-
-       assert(!meshlink_get_node_reachability(mesh, self, &last_reachable, &last_unreachable));
-       assert(last_reachable);
-       assert(last_unreachable);
-
        // Make sure we can start and stop the mesh again.
 
        assert(meshlink_start(mesh));
@@ -92,12 +72,6 @@ int main(void) {
        assert(!strcmp(mesh->name, "foo"));
        assert(!strcmp(self->name, "foo"));
 
-       // Check that we remembered we were reachable
-
-       assert(!meshlink_get_node_reachability(mesh, self, &last_reachable, &last_unreachable));
-       assert(last_reachable);
-       assert(last_unreachable);
-
        // Check that the name is ignored now, and that we still are "foo".
 
        assert(!meshlink_get_node(mesh, "bar"));
index bed69461166f025e837c58428b14cf828bdca48b..06e732ce2bdd686aceafd5a53f5e4206da85d838 100644 (file)
@@ -24,10 +24,6 @@ int main(void) {
                assert(self);
                assert(!strcmp(self->name, "foo"));
 
-               // Disable local discovery.
-
-               mesh.enable_discovery(false);
-
                // Start and stop the mesh.
 
                assert(mesh.start());
@@ -55,8 +51,6 @@ int main(void) {
 
                // Start and stop the mesh.
 
-               mesh.enable_discovery(false);
-
                assert(mesh.start());
                mesh.stop();
        }
index dbfdde6b6cb46aeabbabebb557439dbcf7e80f17..0917fa82ddc6c2421737a4ad629b43ec9aaeadcf 100644 (file)
@@ -102,9 +102,6 @@ int main(void) {
 
        mesh_b->priv = in_infos;
 
-       meshlink_enable_discovery(mesh_a, false);
-       meshlink_enable_discovery(mesh_b, false);
-
        // Set the callbacks.
 
        meshlink_set_channel_accept_cb(mesh_b, accept_cb);
index a1089b533dc0c063ede6394fe7adc2ed4a7bb633..329d1310d46ee670fa9fcca1bd3f0278bf9bdb31 100644 (file)
@@ -84,8 +84,6 @@ static int main1(int rfd, int wfd) {
        meshlink_handle_t *mesh = meshlink_open("channels_fork_conf.1", "foo", "channels-fork", DEV_CLASS_BACKBONE);
        assert(mesh);
 
-       meshlink_enable_discovery(mesh, false);
-
        assert(meshlink_set_canonical_address(mesh, meshlink_get_self(mesh), "localhost", NULL));
 
        char *data = meshlink_export(mesh);
@@ -138,8 +136,6 @@ static int main2(int rfd, int wfd) {
        meshlink_handle_t *mesh = meshlink_open("channels_fork_conf.2", "bar", "channels-fork", DEV_CLASS_BACKBONE);
        assert(mesh);
 
-       meshlink_enable_discovery(mesh, false);
-
        assert(meshlink_set_canonical_address(mesh, meshlink_get_self(mesh), "localhost", NULL));
 
        char *data = meshlink_export(mesh);
index c2687274af71f851343f7fb034dcb8c354c19bb5..820eb5433ee2ce3a7b759c451fe6ce18264c0436 100644 (file)
@@ -97,7 +97,6 @@ int main(void) {
        assert(meshlink_destroy("channels_udp_conf.0"));
        meshlink_handle_t *server = meshlink_open("channels_udp_conf.0", "server", "channels-udp", DEV_CLASS_BACKBONE);
        assert(server);
-       meshlink_enable_discovery(server, false);
        server->priv = channels;
        meshlink_set_channel_accept_cb(server, accept_cb);
        assert(meshlink_start(server));
@@ -110,7 +109,6 @@ int main(void) {
                clients[i].mesh = meshlink_open(dir, names[i], "channels-udp", DEV_CLASS_STATIONARY);
                assert(clients[i].mesh);
                clients[i].mesh->priv = &clients[i];
-               meshlink_enable_discovery(clients[i].mesh, false);
                link_meshlink_pair(server, clients[i].mesh);
                meshlink_set_node_status_cb(clients[i].mesh, status_cb);
                assert(meshlink_start(clients[i].mesh));
index 6e7607cba94e79a42126c38ccdad15f4b37cc885..0dba67f4569a3140d419d763cf0bb697853b1654 100644 (file)
@@ -36,7 +36,6 @@ int main(void) {
                assert(mesh[i]);
 
                assert(meshlink_set_canonical_address(mesh[i], meshlink_get_self(mesh[i]), "localhost", NULL));
-               meshlink_enable_discovery(mesh[i], false);
 
                meshlink_set_node_duplicate_cb(mesh[i], handle_duplicate);
        }
index 2d68c42e78b15973cb195b74d7753ee3ff6798e1..1945058fb72a4340e3a1928c7ab6c9fc791c0ec6 100644 (file)
@@ -53,19 +53,9 @@ int main(void) {
        assert(nnodes == 1);
        assert(nodes[0] == meshlink_get_self(mesh[0]));
 
-       // We should never have been online.
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
-       assert(nnodes == 0);
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
-       assert(nnodes == 1);
-       assert(nodes[0] == meshlink_get_self(mesh[0]));
-
        // Let nodes know about each other.
 
        for(int i = 0; i < 3; i++) {
-               meshlink_enable_discovery(mesh[i], false);
                assert(meshlink_set_canonical_address(mesh[i], meshlink_get_self(mesh[i]), "localhost", NULL));
                char *data = meshlink_export(mesh[i]);
                assert(data);
@@ -93,37 +83,11 @@ int main(void) {
        nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_STATIONARY, nodes, &nnodes);
        assert(nnodes == 2);
 
-       // But no node should have been online.
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
-       assert(nnodes == 0);
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
-       assert(nnodes == 3);
-
        // Start foo.
 
        time_t foo_started = time(NULL);
        assert(meshlink_start(mesh[0]));
 
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
-       assert(nnodes == 1);
-       assert(nodes[0] == meshlink_get_self(mesh[0]));
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
-       assert(nnodes == 2);
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], foo_started - 1, -1, nodes, &nnodes);
-       assert(nnodes == 1);
-       assert(nodes[0] == meshlink_get_self(mesh[0]));
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started - 1, nodes, &nnodes);
-       assert(nnodes == 0);
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
-       assert(nnodes == 1);
-       assert(nodes[0] == meshlink_get_self(mesh[0]));
-
        // Start bar and wait for it to connect.
 
        meshlink_set_node_status_cb(mesh[0], status_cb);
@@ -133,46 +97,15 @@ int main(void) {
        assert(wait_sync_flag(&bar_reachable, 20));
        time_t bar_started = time(NULL);
 
-       // Validate time ranges.
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
-       assert(nnodes == 2);
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
-       assert(nnodes == 1);
-       assert(nodes[0] == meshlink_get_node(mesh[0], "baz"));
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
-       assert(nnodes == 1);
-       assert(nodes[0] == meshlink_get_self(mesh[0]));
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
-       assert(nnodes == 2);
-       assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
-       assert(nodes[1] == meshlink_get_self(mesh[0]));
-
        // Stop bar.
 
        meshlink_stop(mesh[1]);
        sleep(2);
-       time_t bar_stopped = time(NULL);
-
-       // Validate we can see when bar was reachable.
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_stopped, bar_stopped, nodes, &nnodes);
-       assert(nnodes == 1);
-       assert(nodes[0] == meshlink_get_self(mesh[0]));
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
-       assert(nnodes == 2);
-       assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
-       assert(nodes[1] == meshlink_get_self(mesh[0]));
 
        // Close and restart foo, check that it remembers correctly.
 
        meshlink_close(mesh[0]);
        sleep(2);
-       time_t foo_stopped = time(NULL);
        mesh[0] = meshlink_open("get_all_nodes_conf.1", "foo", "get-all_nodes", DEV_CLASS_BACKBONE);
        assert(mesh[0]);
 
@@ -186,32 +119,6 @@ int main(void) {
        nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_STATIONARY, nodes, &nnodes);
        assert(nnodes == 2);
 
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
-       assert(nnodes == 1);
-       assert(nodes[0] == meshlink_get_node(mesh[0], "baz"));
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
-       assert(nnodes == 2);
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started - 1, nodes, &nnodes);
-       assert(nnodes == 0);
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
-       assert(nnodes == 1);
-       assert(nodes[0] == meshlink_get_self(mesh[0]));
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
-       assert(nnodes == 2);
-       assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
-       assert(nodes[1] == meshlink_get_self(mesh[0]));
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_stopped, bar_stopped, nodes, &nnodes);
-       assert(nnodes == 1);
-       assert(nodes[0] == meshlink_get_self(mesh[0]));
-
-       nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], foo_stopped, -1, nodes, &nnodes);
-       assert(nnodes == 0);
-
        // Clean up.
 
        for(int i = 0; i < 3; i++) {
index 08343d0fc32329e7bec63dd30474a336ce2487d2..3382fee4dea5a3a387726cb51b8bd7488d14d17e 100644 (file)
@@ -48,11 +48,6 @@ int main(void) {
        meshlink_handle_t *mesh2 = meshlink_open("import_export_conf.2", "bar", "import-export", DEV_CLASS_BACKBONE);
        assert(mesh2);
 
-       // Disable local discovery
-
-       meshlink_enable_discovery(mesh1, false);
-       meshlink_enable_discovery(mesh2, false);
-
        // Import and export both side's data
 
        assert(meshlink_set_canonical_address(mesh1, meshlink_get_self(mesh1), "localhost", NULL));
index 9ae831e29bd197ed695b1cbf0731c5f373e888fa..e84ddd83634e32ce69da0f90aa0a4096287b0afb 100644 (file)
@@ -72,12 +72,6 @@ int main(void) {
        meshlink_handle_t *mesh3 = meshlink_open("invite_join_conf.3", "quux", "invite-join", DEV_CLASS_BACKBONE);
        assert(mesh3);
 
-       // Disable local discovery.
-
-       meshlink_enable_discovery(mesh1, false);
-       meshlink_enable_discovery(mesh2, false);
-       meshlink_enable_discovery(mesh3, false);
-
        // Have the first instance generate invitations.
 
        meshlink_set_node_status_cb(mesh1, status_cb);
index 50f7be8f369a8c1c9c1b45167e800a98c7c9f24b..5e0ed2157f6ca50fd9ebe071f5381fab6d63c12b 100644 (file)
@@ -55,8 +55,6 @@ static void create_peers(peer_config_t *peers, int npeers, const char *prefix) {
                assert(peers[i].mesh);
                free(params);
                free(conf_path);
-
-               meshlink_enable_discovery(peers[i].mesh, false);
        }
 }
 
index 7f757a3099fd0d6176f6664dcc755a0a1201eb92..6885406a4a5638296e719e92f4cf7ae29516000f 100644 (file)
@@ -25,8 +25,6 @@ int main(void) {
        mesh2 = meshlink_open("storage-policy_conf.2", "bar", "storage-policy", DEV_CLASS_BACKBONE);
        assert(mesh1);
        assert(mesh2);
-       meshlink_enable_discovery(mesh1, false);
-       meshlink_enable_discovery(mesh2, false);
        meshlink_set_storage_policy(mesh1, MESHLINK_STORAGE_DISABLED);
        meshlink_set_storage_policy(mesh2, MESHLINK_STORAGE_DISABLED);
 
@@ -56,8 +54,6 @@ int main(void) {
        mesh2 = meshlink_open("storage-policy_conf.2", "bar", "storage-policy", DEV_CLASS_BACKBONE);
        assert(mesh1);
        assert(mesh2);
-       meshlink_enable_discovery(mesh1, false);
-       meshlink_enable_discovery(mesh2, false);
        meshlink_set_storage_policy(mesh1, MESHLINK_STORAGE_KEYS_ONLY);
        meshlink_set_storage_policy(mesh2, MESHLINK_STORAGE_KEYS_ONLY);
 
@@ -82,8 +78,6 @@ int main(void) {
        mesh2 = meshlink_open("storage-policy_conf.2", "bar", "storage-policy", DEV_CLASS_BACKBONE);
        assert(mesh1);
        assert(mesh2);
-       meshlink_enable_discovery(mesh1, false);
-       meshlink_enable_discovery(mesh2, false);
        meshlink_set_storage_policy(mesh1, MESHLINK_STORAGE_KEYS_ONLY);
        meshlink_set_storage_policy(mesh2, MESHLINK_STORAGE_KEYS_ONLY);
 
@@ -115,8 +109,6 @@ int main(void) {
        mesh2 = meshlink_open("storage-policy_conf.2", "bar", "storage-policy", DEV_CLASS_BACKBONE);
        assert(mesh1);
        assert(mesh2);
-       meshlink_enable_discovery(mesh1, false);
-       meshlink_enable_discovery(mesh2, false);
        meshlink_set_storage_policy(mesh1, MESHLINK_STORAGE_KEYS_ONLY);
        meshlink_set_storage_policy(mesh2, MESHLINK_STORAGE_KEYS_ONLY);
 
@@ -141,8 +133,6 @@ int main(void) {
        mesh2 = meshlink_open("storage-policy_conf.2", "bar", "storage-policy", DEV_CLASS_BACKBONE);
        assert(mesh1);
        assert(mesh2);
-       meshlink_enable_discovery(mesh1, false);
-       meshlink_enable_discovery(mesh2, false);
 
        assert(!meshlink_get_node_reachability(mesh1, meshlink_get_node(mesh1, "bar"), &last_reachable, &last_unreachable));
        assert(last_reachable);
@@ -156,8 +146,6 @@ int main(void) {
        mesh2 = meshlink_open("storage-policy_conf.2", "bar", "storage-policy", DEV_CLASS_BACKBONE);
        assert(mesh1);
        assert(mesh2);
-       meshlink_enable_discovery(mesh1, false);
-       meshlink_enable_discovery(mesh2, false);
        meshlink_set_storage_policy(mesh1, MESHLINK_STORAGE_KEYS_ONLY);
        meshlink_set_storage_policy(mesh2, MESHLINK_STORAGE_KEYS_ONLY);
 
index 292a1a5440533021d1d7bb66af2c6254970319f1..5b5a612f2c354c44ea02c35f60bc121ab11a74b6 100644 (file)
@@ -119,13 +119,6 @@ int main(void) {
 
        assert(wait_sync_flag(&received, 15));
 
-       // Check that the second and third node have autoconnected to each other
-
-       devtool_edge_t *edges = NULL;
-       size_t nedges = 0;
-       assert_after((edges = devtool_get_all_edges(mesh[1], edges, &nedges), nedges == 3), 15);
-       free(edges);
-
        // Stop the first node
 
        meshlink_stop(mesh[0]);
index cc1ce87fa90df88f79fb5a34866cb05b0238e607..c59aa64be6d625363a092a7d66ea955221dbbe60 100644 (file)
@@ -105,13 +105,6 @@ int main(void) {
        assert(wait_sync_flag(&bar_learned_baz, 5));
        assert(wait_sync_flag(&baz_learned_bar, 5));
 
-       // Check that the second and third node autoconnect to each other
-
-       devtool_edge_t *edges = NULL;
-       size_t nedges = 0;
-       assert_after((edges = devtool_get_all_edges(mesh[1], edges, &nedges), nedges == 3), 15);
-       free(edges);
-
        // Stop the nodes nodes
 
        for(int i = 0; i < 3; i++) {
index 872060b1035a1076f5fb2205b76fdea12e4ebfa0..27582ad286fa27376881a322687cd380d589e0ab 100644 (file)
@@ -100,9 +100,6 @@ void open_meshlink_pair(meshlink_handle_t **pa, meshlink_handle_t **pb, const ch
        free(a_name);
        free(b_name);
 
-       meshlink_enable_discovery(a, false);
-       meshlink_enable_discovery(b, false);
-
        link_meshlink_pair(a, b);
 
        *pa = a;
@@ -120,9 +117,6 @@ void open_meshlink_pair_ephemeral(meshlink_handle_t **pa, meshlink_handle_t **pb
        assert(a);
        assert(b);
 
-       meshlink_enable_discovery(a, false);
-       meshlink_enable_discovery(b, false);
-
        link_meshlink_pair(a, b);
 
        *pa = a;