]> git.meshlink.io Git - meshlink/blob - src/meshlink.c
Add a configurable fast connection retry period.
[meshlink] / src / meshlink.c
1 /*
2     meshlink.c -- Implementation of the MeshLink API.
3     Copyright (C) 2014-2018 Guus Sliepen <guus@meshlink.io>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "system.h"
21 #include <pthread.h>
22
23 #include "crypto.h"
24 #include "ecdsagen.h"
25 #include "logger.h"
26 #include "meshlink_internal.h"
27 #include "netutl.h"
28 #include "node.h"
29 #include "submesh.h"
30 #include "packmsg.h"
31 #include "prf.h"
32 #include "protocol.h"
33 #include "route.h"
34 #include "sockaddr.h"
35 #include "utils.h"
36 #include "xalloc.h"
37 #include "ed25519/sha512.h"
38 #include "discovery.h"
39 #include "devtools.h"
40
41 #ifndef MSG_NOSIGNAL
42 #define MSG_NOSIGNAL 0
43 #endif
44 __thread meshlink_errno_t meshlink_errno;
45 meshlink_log_cb_t global_log_cb;
46 meshlink_log_level_t global_log_level;
47
48 typedef bool (*search_node_by_condition_t)(const node_t *, const void *);
49
50 static int rstrip(char *value) {
51         int len = strlen(value);
52
53         while(len && strchr("\t\r\n ", value[len - 1])) {
54                 value[--len] = 0;
55         }
56
57         return len;
58 }
59
60 static void get_canonical_address(node_t *n, char **hostname, char **port) {
61         if(!n->canonical_address) {
62                 return;
63         }
64
65         *hostname = xstrdup(n->canonical_address);
66         char *space = strchr(*hostname, ' ');
67
68         if(space) {
69                 *space++ = 0;
70                 *port = xstrdup(space);
71         }
72 }
73
74 static bool is_valid_hostname(const char *hostname) {
75         if(!*hostname) {
76                 return false;
77         }
78
79         for(const char *p = hostname; *p; p++) {
80                 if(!(isalnum(*p) || *p == '-' || *p == '.' || *p == ':')) {
81                         return false;
82                 }
83         }
84
85         return true;
86 }
87
88 static bool is_valid_port(const char *port) {
89         if(!*port) {
90                 return false;
91         }
92
93         if(isdigit(*port)) {
94                 char *end;
95                 unsigned long int result = strtoul(port, &end, 10);
96                 return result && result < 65536 && !*end;
97         }
98
99         for(const char *p = port; *p; p++) {
100                 if(!(isalnum(*p) || *p == '-')) {
101                         return false;
102                 }
103         }
104
105         return true;
106 }
107
108 static void set_timeout(int sock, int timeout) {
109 #ifdef _WIN32
110         DWORD tv = timeout;
111 #else
112         struct timeval tv;
113         tv.tv_sec = timeout / 1000;
114         tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
115 #endif
116         setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
117         setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
118 }
119
120 struct socket_in_netns_params {
121         int domain;
122         int type;
123         int protocol;
124         int netns;
125         int fd;
126 };
127
128 #ifdef HAVE_SETNS
129 static void *socket_in_netns_thread(void *arg) {
130         struct socket_in_netns_params *params = arg;
131
132         if(setns(params->netns, CLONE_NEWNET) == -1) {
133                 meshlink_errno = MESHLINK_EINVAL;
134                 return NULL;
135         }
136
137         params->fd = socket(params->domain, params->type, params->protocol);
138
139         return NULL;
140 }
141 #endif // HAVE_SETNS
142
143 static int socket_in_netns(int domain, int type, int protocol, int netns) {
144         if(netns == -1) {
145                 return socket(domain, type, protocol);
146         }
147
148 #ifdef HAVE_SETNS
149         struct socket_in_netns_params params = {domain, type, protocol, netns, -1};
150
151         pthread_t thr;
152
153         if(pthread_create(&thr, NULL, socket_in_netns_thread, &params) == 0) {
154                 pthread_join(thr, NULL);
155         }
156
157         return params.fd;
158 #else
159         return -1;
160 #endif // HAVE_SETNS
161
162 }
163
164 // Find out what local address a socket would use if we connect to the given address.
165 // We do this using connect() on a UDP socket, so the kernel has to resolve the address
166 // of both endpoints, but this will actually not send any UDP packet.
167 static bool getlocaladdr(char *destaddr, sockaddr_t *sa, socklen_t *salen, int netns) {
168         struct addrinfo *rai = NULL;
169         const struct addrinfo hint = {
170                 .ai_family = AF_UNSPEC,
171                 .ai_socktype = SOCK_DGRAM,
172                 .ai_protocol = IPPROTO_UDP,
173         };
174
175         if(getaddrinfo(destaddr, "80", &hint, &rai) || !rai) {
176                 return false;
177         }
178
179         int sock = socket_in_netns(rai->ai_family, rai->ai_socktype, rai->ai_protocol, netns);
180
181         if(sock == -1) {
182                 freeaddrinfo(rai);
183                 return false;
184         }
185
186         if(connect(sock, rai->ai_addr, rai->ai_addrlen) && !sockwouldblock(errno)) {
187                 closesocket(sock);
188                 freeaddrinfo(rai);
189                 return false;
190         }
191
192         freeaddrinfo(rai);
193
194         if(getsockname(sock, &sa->sa, salen)) {
195                 closesocket(sock);
196                 return false;
197         }
198
199         closesocket(sock);
200         return true;
201 }
202
203 static bool getlocaladdrname(char *destaddr, char *host, socklen_t hostlen, int netns) {
204         sockaddr_t sa;
205         socklen_t salen = sizeof(sa);
206
207         if(!getlocaladdr(destaddr, &sa, &salen, netns)) {
208                 return false;
209         }
210
211         if(getnameinfo(&sa.sa, salen, host, hostlen, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV)) {
212                 return false;
213         }
214
215         return true;
216 }
217
218 char *meshlink_get_external_address(meshlink_handle_t *mesh) {
219         return meshlink_get_external_address_for_family(mesh, AF_UNSPEC);
220 }
221
222 char *meshlink_get_external_address_for_family(meshlink_handle_t *mesh, int family) {
223         char *hostname = NULL;
224
225         logger(mesh, MESHLINK_DEBUG, "Trying to discover externally visible hostname...\n");
226         struct addrinfo *ai = str2addrinfo("meshlink.io", "80", SOCK_STREAM);
227         static const char request[] = "GET http://www.meshlink.io/host.cgi HTTP/1.0\r\n\r\n";
228         char line[256];
229
230         for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
231                 if(family != AF_UNSPEC && aip->ai_family != family) {
232                         continue;
233                 }
234
235                 int s = socket_in_netns(aip->ai_family, aip->ai_socktype, aip->ai_protocol, mesh->netns);
236
237                 if(s >= 0) {
238                         set_timeout(s, 5000);
239
240                         if(connect(s, aip->ai_addr, aip->ai_addrlen)) {
241                                 closesocket(s);
242                                 s = -1;
243                         }
244                 }
245
246                 if(s >= 0) {
247                         send(s, request, sizeof(request) - 1, 0);
248                         int len = recv(s, line, sizeof(line) - 1, MSG_WAITALL);
249
250                         if(len > 0) {
251                                 line[len] = 0;
252
253                                 if(line[len - 1] == '\n') {
254                                         line[--len] = 0;
255                                 }
256
257                                 char *p = strrchr(line, '\n');
258
259                                 if(p && p[1]) {
260                                         hostname = xstrdup(p + 1);
261                                 }
262                         }
263
264                         closesocket(s);
265
266                         if(hostname) {
267                                 break;
268                         }
269                 }
270         }
271
272         if(ai) {
273                 freeaddrinfo(ai);
274         }
275
276         // Check that the hostname is reasonable
277         if(hostname && !is_valid_hostname(hostname)) {
278                 free(hostname);
279                 hostname = NULL;
280         }
281
282         if(!hostname) {
283                 meshlink_errno = MESHLINK_ERESOLV;
284         }
285
286         return hostname;
287 }
288
289 char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int family) {
290         (void)mesh;
291
292         // Determine address of the local interface used for outgoing connections.
293         char localaddr[NI_MAXHOST];
294         bool success = false;
295
296         if(family == AF_INET) {
297                 success = getlocaladdrname("93.184.216.34", localaddr, sizeof(localaddr), mesh->netns);
298         } else if(family == AF_INET6) {
299                 success = getlocaladdrname("2606:2800:220:1:248:1893:25c8:1946", localaddr, sizeof(localaddr), mesh->netns);
300         }
301
302         if(!success) {
303                 meshlink_errno = MESHLINK_ENETWORK;
304                 return NULL;
305         }
306
307         return xstrdup(localaddr);
308 }
309
310 void remove_duplicate_hostnames(char *host[], char *port[], int n) {
311         for(int i = 0; i < n; i++) {
312                 if(!host[i]) {
313                         continue;
314                 }
315
316                 // Ignore duplicate hostnames
317                 bool found = false;
318
319                 for(int j = 0; j < i; j++) {
320                         if(!host[j]) {
321                                 continue;
322                         }
323
324                         if(strcmp(host[i], host[j])) {
325                                 continue;
326                         }
327
328                         if(strcmp(port[i], port[j])) {
329                                 continue;
330                         }
331
332                         found = true;
333                         break;
334                 }
335
336                 if(found || !is_valid_hostname(host[i])) {
337                         free(host[i]);
338                         free(port[i]);
339                         host[i] = NULL;
340                         port[i] = NULL;
341                         continue;
342                 }
343         }
344 }
345
346 // This gets the hostname part for use in invitation URLs
347 static char *get_my_hostname(meshlink_handle_t *mesh, uint32_t flags) {
348         char *hostname[4] = {NULL};
349         char *port[4] = {NULL};
350         char *hostport = NULL;
351
352         if(!(flags & (MESHLINK_INVITE_LOCAL | MESHLINK_INVITE_PUBLIC))) {
353                 flags |= MESHLINK_INVITE_LOCAL | MESHLINK_INVITE_PUBLIC;
354         }
355
356         if(!(flags & (MESHLINK_INVITE_IPV4 | MESHLINK_INVITE_IPV6))) {
357                 flags |= MESHLINK_INVITE_IPV4 | MESHLINK_INVITE_IPV6;
358         }
359
360         // Add local addresses if requested
361         if(flags & MESHLINK_INVITE_LOCAL) {
362                 if(flags & MESHLINK_INVITE_IPV4) {
363                         hostname[0] = meshlink_get_local_address_for_family(mesh, AF_INET);
364                 }
365
366                 if(flags & MESHLINK_INVITE_IPV6) {
367                         hostname[1] = meshlink_get_local_address_for_family(mesh, AF_INET6);
368                 }
369         }
370
371         // Add public/canonical addresses if requested
372         if(flags & MESHLINK_INVITE_PUBLIC) {
373                 // Try the CanonicalAddress first
374                 get_canonical_address(mesh->self, &hostname[2], &port[2]);
375
376                 if(!hostname[2]) {
377                         if(flags & MESHLINK_INVITE_IPV4) {
378                                 hostname[2] = meshlink_get_external_address_for_family(mesh, AF_INET);
379                         }
380
381                         if(flags & MESHLINK_INVITE_IPV6) {
382                                 hostname[3] = meshlink_get_external_address_for_family(mesh, AF_INET6);
383                         }
384                 }
385         }
386
387         for(int i = 0; i < 4; i++) {
388                 // Ensure we always have a port number
389                 if(hostname[i] && !port[i]) {
390                         port[i] = xstrdup(mesh->myport);
391                 }
392         }
393
394         remove_duplicate_hostnames(hostname, port, 4);
395
396         // Resolve the hostnames
397         for(int i = 0; i < 4; i++) {
398                 if(!hostname[i]) {
399                         continue;
400                 }
401
402                 // Convert what we have to a sockaddr
403                 struct addrinfo *ai_in, *ai_out;
404                 struct addrinfo hint = {
405                         .ai_family = AF_UNSPEC,
406                         .ai_flags = AI_NUMERICSERV,
407                         .ai_socktype = SOCK_STREAM,
408                 };
409                 int err = getaddrinfo(hostname[i], port[i], &hint, &ai_in);
410
411                 if(err || !ai_in) {
412                         continue;
413                 }
414
415                 // Remember the address
416                 node_add_recent_address(mesh, mesh->self, (sockaddr_t *)ai_in->ai_addr);
417
418                 if(flags & MESHLINK_INVITE_NUMERIC) {
419                         // We don't need to do any further conversion
420                         freeaddrinfo(ai_in);
421                         continue;
422                 }
423
424                 // Convert it to a hostname
425                 char resolved_host[NI_MAXHOST];
426                 char resolved_port[NI_MAXSERV];
427                 err = getnameinfo(ai_in->ai_addr, ai_in->ai_addrlen, resolved_host, sizeof resolved_host, resolved_port, sizeof resolved_port, NI_NUMERICSERV);
428
429                 if(err || !is_valid_hostname(resolved_host)) {
430                         freeaddrinfo(ai_in);
431                         continue;
432                 }
433
434                 // Convert the hostname back to a sockaddr
435                 hint.ai_family = ai_in->ai_family;
436                 err = getaddrinfo(resolved_host, resolved_port, &hint, &ai_out);
437
438                 if(err || !ai_out) {
439                         freeaddrinfo(ai_in);
440                         continue;
441                 }
442
443                 // Check if it's still the same sockaddr
444                 if(ai_in->ai_addrlen != ai_out->ai_addrlen || memcmp(ai_in->ai_addr, ai_out->ai_addr, ai_in->ai_addrlen)) {
445                         freeaddrinfo(ai_in);
446                         freeaddrinfo(ai_out);
447                         continue;
448                 }
449
450                 // Yes: replace the hostname with the resolved one
451                 free(hostname[i]);
452                 hostname[i] = xstrdup(resolved_host);
453
454                 freeaddrinfo(ai_in);
455                 freeaddrinfo(ai_out);
456         }
457
458         // Remove duplicates again, since IPv4 and IPv6 addresses might map to the same hostname
459         remove_duplicate_hostnames(hostname, port, 4);
460
461         // Concatenate all unique address to the hostport string
462         for(int i = 0; i < 4; i++) {
463                 if(!hostname[i]) {
464                         continue;
465                 }
466
467                 // Append the address to the hostport string
468                 char *newhostport;
469                 xasprintf(&newhostport, (strchr(hostname[i], ':') ? "%s%s[%s]:%s" : "%s%s%s:%s"), hostport ? hostport : "", hostport ? "," : "", hostname[i], port[i]);
470                 free(hostport);
471                 hostport = newhostport;
472
473                 free(hostname[i]);
474                 free(port[i]);
475         }
476
477         return hostport;
478 }
479
480 static bool try_bind(int port) {
481         struct addrinfo *ai = NULL;
482         struct addrinfo hint = {
483                 .ai_flags = AI_PASSIVE,
484                 .ai_family = AF_UNSPEC,
485                 .ai_socktype = SOCK_STREAM,
486                 .ai_protocol = IPPROTO_TCP,
487         };
488
489         char portstr[16];
490         snprintf(portstr, sizeof(portstr), "%d", port);
491
492         if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) {
493                 return false;
494         }
495
496         //while(ai) {
497         for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
498                 int fd = socket(aip->ai_family, SOCK_STREAM, IPPROTO_TCP);
499
500                 if(!fd) {
501                         freeaddrinfo(ai);
502                         return false;
503                 }
504
505                 int result = bind(fd, aip->ai_addr, aip->ai_addrlen);
506                 closesocket(fd);
507
508                 if(result) {
509                         freeaddrinfo(ai);
510                         return false;
511                 }
512         }
513
514         freeaddrinfo(ai);
515         return true;
516 }
517
518 static int check_port(meshlink_handle_t *mesh) {
519         for(int i = 0; i < 1000; i++) {
520                 int port = 0x1000 + prng(mesh, 0x8000);
521
522                 if(try_bind(port)) {
523                         free(mesh->myport);
524                         xasprintf(&mesh->myport, "%d", port);
525                         return port;
526                 }
527         }
528
529         meshlink_errno = MESHLINK_ENETWORK;
530         logger(mesh, MESHLINK_DEBUG, "Could not find any available network port.\n");
531         return 0;
532 }
533
534 static bool write_main_config_files(meshlink_handle_t *mesh) {
535         if(!mesh->confbase) {
536                 return true;
537         }
538
539         uint8_t buf[4096];
540
541         /* Write the main config file */
542         packmsg_output_t out = {buf, sizeof buf};
543
544         packmsg_add_uint32(&out, MESHLINK_CONFIG_VERSION);
545         packmsg_add_str(&out, mesh->name);
546         packmsg_add_bin(&out, ecdsa_get_private_key(mesh->private_key), 96);
547         packmsg_add_bin(&out, ecdsa_get_private_key(mesh->invitation_key), 96);
548         packmsg_add_uint16(&out, atoi(mesh->myport));
549
550         if(!packmsg_output_ok(&out)) {
551                 return false;
552         }
553
554         config_t config = {buf, packmsg_output_size(&out, buf)};
555
556         if(!main_config_write(mesh, "current", &config, mesh->config_key)) {
557                 return false;
558         }
559
560         /* Write our own host config file */
561         if(!node_write_config(mesh, mesh->self)) {
562                 return false;
563         }
564
565         return true;
566 }
567
568 static bool finalize_join(meshlink_handle_t *mesh, const void *buf, uint16_t len) {
569         packmsg_input_t in = {buf, len};
570         uint32_t version = packmsg_get_uint32(&in);
571
572         if(version != MESHLINK_INVITATION_VERSION) {
573                 logger(mesh, MESHLINK_ERROR, "Invalid invitation version!\n");
574                 return false;
575         }
576
577         char *name = packmsg_get_str_dup(&in);
578         packmsg_skip_element(&in); /* submesh */
579         dev_class_t devclass = packmsg_get_int32(&in);
580         uint32_t count = packmsg_get_array(&in);
581
582         if(!name) {
583                 logger(mesh, MESHLINK_DEBUG, "No Name found in invitation!\n");
584                 return false;
585         }
586
587         if(!check_id(name)) {
588                 logger(mesh, MESHLINK_DEBUG, "Invalid Name found in invitation: %s!\n", name);
589                 free(name);
590                 return false;
591         }
592
593         if(!count) {
594                 logger(mesh, MESHLINK_ERROR, "Incomplete invitation file!\n");
595                 free(name);
596                 return false;
597         }
598
599         free(mesh->name);
600         free(mesh->self->name);
601         mesh->name = name;
602         mesh->self->name = xstrdup(name);
603         mesh->self->devclass = devclass == DEV_CLASS_UNKNOWN ? mesh->devclass : devclass;
604
605         // Initialize configuration directory
606         if(!config_init(mesh, "current")) {
607                 return false;
608         }
609
610         if(!write_main_config_files(mesh)) {
611                 return false;
612         }
613
614         // Write host config files
615         for(uint32_t i = 0; i < count; i++) {
616                 const void *data;
617                 uint32_t len = packmsg_get_bin_raw(&in, &data);
618
619                 if(!len) {
620                         logger(mesh, MESHLINK_ERROR, "Incomplete invitation file!\n");
621                         return false;
622                 }
623
624                 packmsg_input_t in2 = {data, len};
625                 uint32_t version = packmsg_get_uint32(&in2);
626                 char *name = packmsg_get_str_dup(&in2);
627
628                 if(!packmsg_input_ok(&in2) || version != MESHLINK_CONFIG_VERSION || !check_id(name)) {
629                         free(name);
630                         packmsg_input_invalidate(&in);
631                         break;
632                 }
633
634                 if(!check_id(name)) {
635                         free(name);
636                         break;
637                 }
638
639                 if(!strcmp(name, mesh->name)) {
640                         logger(mesh, MESHLINK_DEBUG, "Secondary chunk would overwrite our own host config file.\n");
641                         free(name);
642                         meshlink_errno = MESHLINK_EPEER;
643                         return false;
644                 }
645
646                 node_t *n = new_node();
647                 n->name = name;
648
649                 config_t config = {data, len};
650
651                 if(!node_read_from_config(mesh, n, &config)) {
652                         free_node(n);
653                         logger(mesh, MESHLINK_ERROR, "Invalid host config file in invitation file!\n");
654                         meshlink_errno = MESHLINK_EPEER;
655                         return false;
656                 }
657
658                 if(i == 0) {
659                         /* The first host config file is of the inviter itself;
660                          * remember the address we are currently using for the invitation connection.
661                          */
662                         sockaddr_t sa;
663                         socklen_t salen = sizeof(sa);
664
665                         if(getpeername(mesh->sock, &sa.sa, &salen) == 0) {
666                                 node_add_recent_address(mesh, n, &sa);
667                         }
668                 }
669
670                 if(!node_write_config(mesh, n)) {
671                         free_node(n);
672                         return false;
673                 }
674
675                 node_add(mesh, n);
676         }
677
678         /* Ensure the configuration directory metadata is on disk */
679         if(!config_sync(mesh, "current") || !sync_path(mesh->confbase)) {
680                 return false;
681         }
682
683         sptps_send_record(&mesh->sptps, 1, ecdsa_get_public_key(mesh->private_key), 32);
684
685         logger(mesh, MESHLINK_DEBUG, "Configuration stored in: %s\n", mesh->confbase);
686
687         return true;
688 }
689
690 static bool invitation_send(void *handle, uint8_t type, const void *data, size_t len) {
691         (void)type;
692         meshlink_handle_t *mesh = handle;
693         const char *ptr = data;
694
695         while(len) {
696                 int result = send(mesh->sock, ptr, len, 0);
697
698                 if(result == -1 && errno == EINTR) {
699                         continue;
700                 } else if(result <= 0) {
701                         return false;
702                 }
703
704                 ptr += result;
705                 len -= result;
706         }
707
708         return true;
709 }
710
711 static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint16_t len) {
712         meshlink_handle_t *mesh = handle;
713
714         switch(type) {
715         case SPTPS_HANDSHAKE:
716                 return sptps_send_record(&mesh->sptps, 0, mesh->cookie, sizeof(mesh)->cookie);
717
718         case 0:
719                 return finalize_join(mesh, msg, len);
720
721         case 1:
722                 logger(mesh, MESHLINK_DEBUG, "Invitation succesfully accepted.\n");
723                 shutdown(mesh->sock, SHUT_RDWR);
724                 mesh->success = true;
725                 break;
726
727         default:
728                 return false;
729         }
730
731         return true;
732 }
733
734 static bool recvline(meshlink_handle_t *mesh, size_t len) {
735         char *newline = NULL;
736
737         if(!mesh->sock) {
738                 abort();
739         }
740
741         while(!(newline = memchr(mesh->buffer, '\n', mesh->blen))) {
742                 int result = recv(mesh->sock, mesh->buffer + mesh->blen, sizeof(mesh)->buffer - mesh->blen, 0);
743
744                 if(result == -1 && errno == EINTR) {
745                         continue;
746                 } else if(result <= 0) {
747                         return false;
748                 }
749
750                 mesh->blen += result;
751         }
752
753         if((size_t)(newline - mesh->buffer) >= len) {
754                 return false;
755         }
756
757         len = newline - mesh->buffer;
758
759         memcpy(mesh->line, mesh->buffer, len);
760         mesh->line[len] = 0;
761         memmove(mesh->buffer, newline + 1, mesh->blen - len - 1);
762         mesh->blen -= len + 1;
763
764         return true;
765 }
766
767 static bool sendline(int fd, char *format, ...) {
768         char buffer[4096];
769         char *p = buffer;
770         int blen = 0;
771         va_list ap;
772
773         va_start(ap, format);
774         blen = vsnprintf(buffer, sizeof(buffer), format, ap);
775         va_end(ap);
776
777         if(blen < 1 || (size_t)blen >= sizeof(buffer)) {
778                 return false;
779         }
780
781         buffer[blen] = '\n';
782         blen++;
783
784         while(blen) {
785                 int result = send(fd, p, blen, MSG_NOSIGNAL);
786
787                 if(result == -1 && errno == EINTR) {
788                         continue;
789                 } else if(result <= 0) {
790                         return false;
791                 }
792
793                 p += result;
794                 blen -= result;
795         }
796
797         return true;
798 }
799
800 static const char *errstr[] = {
801         [MESHLINK_OK] = "No error",
802         [MESHLINK_EINVAL] = "Invalid argument",
803         [MESHLINK_ENOMEM] = "Out of memory",
804         [MESHLINK_ENOENT] = "No such node",
805         [MESHLINK_EEXIST] = "Node already exists",
806         [MESHLINK_EINTERNAL] = "Internal error",
807         [MESHLINK_ERESOLV] = "Could not resolve hostname",
808         [MESHLINK_ESTORAGE] = "Storage error",
809         [MESHLINK_ENETWORK] = "Network error",
810         [MESHLINK_EPEER] = "Error communicating with peer",
811         [MESHLINK_ENOTSUP] = "Operation not supported",
812         [MESHLINK_EBUSY] = "MeshLink instance already in use",
813         [MESHLINK_EBLACKLISTED] = "Node is blacklisted",
814 };
815
816 const char *meshlink_strerror(meshlink_errno_t err) {
817         if((int)err < 0 || err >= sizeof(errstr) / sizeof(*errstr)) {
818                 return "Invalid error code";
819         }
820
821         return errstr[err];
822 }
823
824 static bool ecdsa_keygen(meshlink_handle_t *mesh) {
825         logger(mesh, MESHLINK_DEBUG, "Generating ECDSA keypairs:\n");
826
827         mesh->private_key = ecdsa_generate();
828         mesh->invitation_key = ecdsa_generate();
829
830         if(!mesh->private_key || !mesh->invitation_key) {
831                 logger(mesh, MESHLINK_DEBUG, "Error during key generation!\n");
832                 meshlink_errno = MESHLINK_EINTERNAL;
833                 return false;
834         }
835
836         logger(mesh, MESHLINK_DEBUG, "Done.\n");
837
838         return true;
839 }
840
841 static struct timeval idle(event_loop_t *loop, void *data) {
842         (void)loop;
843         meshlink_handle_t *mesh = data;
844         struct timeval t, tmin = {3600, 0};
845
846         for splay_each(node_t, n, mesh->nodes) {
847                 if(!n->utcp) {
848                         continue;
849                 }
850
851                 t = utcp_timeout(n->utcp);
852
853                 if(timercmp(&t, &tmin, <)) {
854                         tmin = t;
855                 }
856         }
857
858         return tmin;
859 }
860
861 // Get our local address(es) by simulating connecting to an Internet host.
862 static void add_local_addresses(meshlink_handle_t *mesh) {
863         sockaddr_t sa;
864         sa.storage.ss_family = AF_UNKNOWN;
865         socklen_t salen = sizeof(sa);
866
867         // IPv4 example.org
868
869         if(getlocaladdr("93.184.216.34", &sa, &salen, mesh->netns)) {
870                 sa.in.sin_port = ntohs(atoi(mesh->myport));
871                 node_add_recent_address(mesh, mesh->self, &sa);
872         }
873
874         // IPv6 example.org
875
876         salen = sizeof(sa);
877
878         if(getlocaladdr("2606:2800:220:1:248:1893:25c8:1946", &sa, &salen, mesh->netns)) {
879                 sa.in6.sin6_port = ntohs(atoi(mesh->myport));
880                 node_add_recent_address(mesh, mesh->self, &sa);
881         }
882 }
883
884 static bool meshlink_setup(meshlink_handle_t *mesh) {
885         if(!config_destroy(mesh->confbase, "new")) {
886                 logger(mesh, MESHLINK_ERROR, "Could not delete configuration in %s/new: %s\n", mesh->confbase, strerror(errno));
887                 meshlink_errno = MESHLINK_ESTORAGE;
888                 return false;
889         }
890
891         if(!config_destroy(mesh->confbase, "old")) {
892                 logger(mesh, MESHLINK_ERROR, "Could not delete configuration in %s/old: %s\n", mesh->confbase, strerror(errno));
893                 meshlink_errno = MESHLINK_ESTORAGE;
894                 return false;
895         }
896
897         if(!config_init(mesh, "current")) {
898                 logger(mesh, MESHLINK_ERROR, "Could not set up configuration in %s/current: %s\n", mesh->confbase, strerror(errno));
899                 meshlink_errno = MESHLINK_ESTORAGE;
900                 return false;
901         }
902
903         if(!ecdsa_keygen(mesh)) {
904                 meshlink_errno = MESHLINK_EINTERNAL;
905                 return false;
906         }
907
908         if(check_port(mesh) == 0) {
909                 meshlink_errno = MESHLINK_ENETWORK;
910                 return false;
911         }
912
913         /* Create a node for ourself */
914
915         mesh->self = new_node();
916         mesh->self->name = xstrdup(mesh->name);
917         mesh->self->devclass = mesh->devclass;
918         mesh->self->ecdsa = ecdsa_set_public_key(ecdsa_get_public_key(mesh->private_key));
919         mesh->self->session_id = mesh->session_id;
920
921         if(!write_main_config_files(mesh)) {
922                 logger(mesh, MESHLINK_ERROR, "Could not write main config files into %s/current: %s\n", mesh->confbase, strerror(errno));
923                 meshlink_errno = MESHLINK_ESTORAGE;
924                 return false;
925         }
926
927         /* Ensure the configuration directory metadata is on disk */
928         if(!config_sync(mesh, "current")) {
929                 return false;
930         }
931
932         return true;
933 }
934
935 static bool meshlink_read_config(meshlink_handle_t *mesh) {
936         config_t config;
937
938         if(!main_config_read(mesh, "current", &config, mesh->config_key)) {
939                 logger(NULL, MESHLINK_ERROR, "Could not read main configuration file!");
940                 return false;
941         }
942
943         packmsg_input_t in = {config.buf, config.len};
944         const void *private_key;
945         const void *invitation_key;
946
947         uint32_t version = packmsg_get_uint32(&in);
948         char *name = packmsg_get_str_dup(&in);
949         uint32_t private_key_len = packmsg_get_bin_raw(&in, &private_key);
950         uint32_t invitation_key_len = packmsg_get_bin_raw(&in, &invitation_key);
951         uint16_t myport = packmsg_get_uint16(&in);
952
953         if(!packmsg_done(&in) || version != MESHLINK_CONFIG_VERSION || private_key_len != 96 || invitation_key_len != 96) {
954                 logger(NULL, MESHLINK_ERROR, "Error parsing main configuration file!");
955                 free(name);
956                 config_free(&config);
957                 return false;
958         }
959
960 #if 0
961
962         // TODO: check this?
963         if(mesh->name && strcmp(mesh->name, name)) {
964                 logger(NULL, MESHLINK_ERROR, "Configuration is for a different name (%s)!", name);
965                 meshlink_errno = MESHLINK_ESTORAGE;
966                 free(name);
967                 config_free(&config);
968                 return false;
969         }
970
971 #endif
972
973         free(mesh->name);
974         mesh->name = name;
975         xasprintf(&mesh->myport, "%u", myport);
976         mesh->private_key = ecdsa_set_private_key(private_key);
977         mesh->invitation_key = ecdsa_set_private_key(invitation_key);
978         config_free(&config);
979
980         /* Create a node for ourself and read our host configuration file */
981
982         mesh->self = new_node();
983         mesh->self->name = xstrdup(name);
984         mesh->self->devclass = mesh->devclass;
985         mesh->self->session_id = mesh->session_id;
986
987         if(!node_read_public_key(mesh, mesh->self)) {
988                 logger(NULL, MESHLINK_ERROR, "Could not read our host configuration file!");
989                 meshlink_errno = MESHLINK_ESTORAGE;
990                 free_node(mesh->self);
991                 mesh->self = NULL;
992                 return false;
993         }
994
995         return true;
996 }
997
998 #ifdef HAVE_SETNS
999 static void *setup_network_in_netns_thread(void *arg) {
1000         meshlink_handle_t *mesh = arg;
1001
1002         if(setns(mesh->netns, CLONE_NEWNET) != 0) {
1003                 return NULL;
1004         }
1005
1006         bool success = setup_network(mesh);
1007         add_local_addresses(mesh);
1008         return success ? arg : NULL;
1009 }
1010 #endif // HAVE_SETNS
1011
1012 meshlink_open_params_t *meshlink_open_params_init(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
1013         if(!confbase || !*confbase) {
1014                 logger(NULL, MESHLINK_ERROR, "No confbase given!\n");
1015                 meshlink_errno = MESHLINK_EINVAL;
1016                 return NULL;
1017         }
1018
1019         if(!appname || !*appname) {
1020                 logger(NULL, MESHLINK_ERROR, "No appname given!\n");
1021                 meshlink_errno = MESHLINK_EINVAL;
1022                 return NULL;
1023         }
1024
1025         if(strchr(appname, ' ')) {
1026                 logger(NULL, MESHLINK_ERROR, "Invalid appname given!\n");
1027                 meshlink_errno = MESHLINK_EINVAL;
1028                 return NULL;
1029         }
1030
1031         if(!name || !*name) {
1032                 logger(NULL, MESHLINK_ERROR, "No name given!\n");
1033                 meshlink_errno = MESHLINK_EINVAL;
1034                 return NULL;
1035         };
1036
1037         if(!check_id(name)) {
1038                 logger(NULL, MESHLINK_ERROR, "Invalid name given!\n");
1039                 meshlink_errno = MESHLINK_EINVAL;
1040                 return NULL;
1041         }
1042
1043         if(devclass < 0 || devclass >= DEV_CLASS_COUNT) {
1044                 logger(NULL, MESHLINK_ERROR, "Invalid devclass given!\n");
1045                 meshlink_errno = MESHLINK_EINVAL;
1046                 return NULL;
1047         }
1048
1049         meshlink_open_params_t *params = xzalloc(sizeof * params);
1050
1051         params->confbase = xstrdup(confbase);
1052         params->name = xstrdup(name);
1053         params->appname = xstrdup(appname);
1054         params->devclass = devclass;
1055         params->netns = -1;
1056
1057         return params;
1058 }
1059
1060 bool meshlink_open_params_set_netns(meshlink_open_params_t *params, int netns) {
1061         if(!params) {
1062                 meshlink_errno = MESHLINK_EINVAL;
1063                 return false;
1064         }
1065
1066         params->netns = netns;
1067
1068         return true;
1069 }
1070
1071 bool meshlink_open_params_set_storage_key(meshlink_open_params_t *params, const void *key, size_t keylen) {
1072         if(!params) {
1073                 meshlink_errno = MESHLINK_EINVAL;
1074                 return false;
1075         }
1076
1077         if((!key && keylen) || (key && !keylen)) {
1078                 logger(NULL, MESHLINK_ERROR, "Invalid key length!\n");
1079                 meshlink_errno = MESHLINK_EINVAL;
1080                 return false;
1081         }
1082
1083         params->key = key;
1084         params->keylen = keylen;
1085
1086         return true;
1087 }
1088
1089 bool meshlink_encrypted_key_rotate(meshlink_handle_t *mesh, const void *new_key, size_t new_keylen) {
1090         if(!mesh || !new_key || !new_keylen) {
1091                 logger(mesh, MESHLINK_ERROR, "Invalid arguments given!\n");
1092                 meshlink_errno = MESHLINK_EINVAL;
1093                 return false;
1094         }
1095
1096         pthread_mutex_lock(&mesh->mutex);
1097
1098         // Create hash for the new key
1099         void *new_config_key;
1100         new_config_key = xmalloc(CHACHA_POLY1305_KEYLEN);
1101
1102         if(!prf(new_key, new_keylen, "MeshLink configuration key", 26, new_config_key, CHACHA_POLY1305_KEYLEN)) {
1103                 logger(mesh, MESHLINK_ERROR, "Error creating new configuration key!\n");
1104                 meshlink_errno = MESHLINK_EINTERNAL;
1105                 pthread_mutex_unlock(&mesh->mutex);
1106                 return false;
1107         }
1108
1109         // Copy contents of the "current" confbase sub-directory to "new" confbase sub-directory with the new key
1110
1111         if(!config_copy(mesh, "current", mesh->config_key, "new", new_config_key)) {
1112                 logger(mesh, MESHLINK_ERROR, "Could not set up configuration in %s/old: %s\n", mesh->confbase, strerror(errno));
1113                 meshlink_errno = MESHLINK_ESTORAGE;
1114                 pthread_mutex_unlock(&mesh->mutex);
1115                 return false;
1116         }
1117
1118         devtool_keyrotate_probe(1);
1119
1120         // Rename confbase/current/ to confbase/old
1121
1122         if(!config_rename(mesh, "current", "old")) {
1123                 logger(mesh, MESHLINK_ERROR, "Cannot rename %s/current to %s/old\n", mesh->confbase, mesh->confbase);
1124                 meshlink_errno = MESHLINK_ESTORAGE;
1125                 pthread_mutex_unlock(&mesh->mutex);
1126                 return false;
1127         }
1128
1129         devtool_keyrotate_probe(2);
1130
1131         // Rename confbase/new/ to confbase/current
1132
1133         if(!config_rename(mesh, "new", "current")) {
1134                 logger(mesh, MESHLINK_ERROR, "Cannot rename %s/new to %s/current\n", mesh->confbase, mesh->confbase);
1135                 meshlink_errno = MESHLINK_ESTORAGE;
1136                 pthread_mutex_unlock(&mesh->mutex);
1137                 return false;
1138         }
1139
1140         devtool_keyrotate_probe(3);
1141
1142         // Cleanup the "old" confbase sub-directory
1143
1144         if(!config_destroy(mesh->confbase, "old")) {
1145                 pthread_mutex_unlock(&mesh->mutex);
1146                 return false;
1147         }
1148
1149         // Change the mesh handle key with new key
1150
1151         free(mesh->config_key);
1152         mesh->config_key = new_config_key;
1153
1154         pthread_mutex_unlock(&mesh->mutex);
1155
1156         return true;
1157 }
1158
1159 void meshlink_open_params_free(meshlink_open_params_t *params) {
1160         if(!params) {
1161                 meshlink_errno = MESHLINK_EINVAL;
1162                 return;
1163         }
1164
1165         free(params->confbase);
1166         free(params->name);
1167         free(params->appname);
1168
1169         free(params);
1170 }
1171
1172 /// Device class traits
1173 static const dev_class_traits_t default_class_traits[DEV_CLASS_COUNT] = {
1174         { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 10000, .edge_weight = 1 }, // DEV_CLASS_BACKBONE
1175         { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 100, .edge_weight = 3 },   // DEV_CLASS_STATIONARY
1176         { .pingtimeout = 5, .pinginterval = 60, .min_connects = 3, .max_connects = 3, .edge_weight = 6 },     // DEV_CLASS_PORTABLE
1177         { .pingtimeout = 5, .pinginterval = 60, .min_connects = 1, .max_connects = 1, .edge_weight = 9 },     // DEV_CLASS_UNKNOWN
1178 };
1179
1180 meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
1181         if(!confbase || !*confbase) {
1182                 logger(NULL, MESHLINK_ERROR, "No confbase given!\n");
1183                 meshlink_errno = MESHLINK_EINVAL;
1184                 return NULL;
1185         }
1186
1187         /* Create a temporary struct on the stack, to avoid allocating and freeing one. */
1188         meshlink_open_params_t params;
1189         memset(&params, 0, sizeof(params));
1190
1191         params.confbase = (char *)confbase;
1192         params.name = (char *)name;
1193         params.appname = (char *)appname;
1194         params.devclass = devclass;
1195         params.netns = -1;
1196
1197         return meshlink_open_ex(&params);
1198 }
1199
1200 meshlink_handle_t *meshlink_open_encrypted(const char *confbase, const char *name, const char *appname, dev_class_t devclass, const void *key, size_t keylen) {
1201         if(!confbase || !*confbase) {
1202                 logger(NULL, MESHLINK_ERROR, "No confbase given!\n");
1203                 meshlink_errno = MESHLINK_EINVAL;
1204                 return NULL;
1205         }
1206
1207         /* Create a temporary struct on the stack, to avoid allocating and freeing one. */
1208         meshlink_open_params_t params;
1209         memset(&params, 0, sizeof(params));
1210
1211         params.confbase = (char *)confbase;
1212         params.name = (char *)name;
1213         params.appname = (char *)appname;
1214         params.devclass = devclass;
1215         params.netns = -1;
1216
1217         if(!meshlink_open_params_set_storage_key(&params, key, keylen)) {
1218                 return false;
1219         }
1220
1221         return meshlink_open_ex(&params);
1222 }
1223
1224 meshlink_handle_t *meshlink_open_ephemeral(const char *name, const char *appname, dev_class_t devclass) {
1225         /* Create a temporary struct on the stack, to avoid allocating and freeing one. */
1226         meshlink_open_params_t params;
1227         memset(&params, 0, sizeof(params));
1228
1229         params.name = (char *)name;
1230         params.appname = (char *)appname;
1231         params.devclass = devclass;
1232         params.netns = -1;
1233
1234         return meshlink_open_ex(&params);
1235 }
1236
1237 meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) {
1238         // Validate arguments provided by the application
1239         bool usingname = false;
1240
1241         logger(NULL, MESHLINK_DEBUG, "meshlink_open called\n");
1242
1243         if(!params->appname || !*params->appname) {
1244                 logger(NULL, MESHLINK_ERROR, "No appname given!\n");
1245                 meshlink_errno = MESHLINK_EINVAL;
1246                 return NULL;
1247         }
1248
1249         if(strchr(params->appname, ' ')) {
1250                 logger(NULL, MESHLINK_ERROR, "Invalid appname given!\n");
1251                 meshlink_errno = MESHLINK_EINVAL;
1252                 return NULL;
1253         }
1254
1255         if(!params->name || !*params->name) {
1256                 logger(NULL, MESHLINK_ERROR, "No name given!\n");
1257                 //return NULL;
1258         } else { //check name only if there is a name != NULL
1259
1260                 if(!check_id(params->name)) {
1261                         logger(NULL, MESHLINK_ERROR, "Invalid name given!\n");
1262                         meshlink_errno = MESHLINK_EINVAL;
1263                         return NULL;
1264                 } else {
1265                         usingname = true;
1266                 }
1267         }
1268
1269         if(params->devclass < 0 || params->devclass >= DEV_CLASS_COUNT) {
1270                 logger(NULL, MESHLINK_ERROR, "Invalid devclass given!\n");
1271                 meshlink_errno = MESHLINK_EINVAL;
1272                 return NULL;
1273         }
1274
1275         if((params->key && !params->keylen) || (!params->key && params->keylen)) {
1276                 logger(NULL, MESHLINK_ERROR, "Invalid key length!\n");
1277                 meshlink_errno = MESHLINK_EINVAL;
1278                 return NULL;
1279         }
1280
1281         meshlink_handle_t *mesh = xzalloc(sizeof(meshlink_handle_t));
1282
1283         if(params->confbase) {
1284                 mesh->confbase = xstrdup(params->confbase);
1285         }
1286
1287         mesh->appname = xstrdup(params->appname);
1288         mesh->devclass = params->devclass;
1289         mesh->discovery = true;
1290         mesh->invitation_timeout = 604800; // 1 week
1291         mesh->netns = params->netns;
1292         mesh->submeshes = NULL;
1293         mesh->log_cb = global_log_cb;
1294         mesh->log_level = global_log_level;
1295
1296         randomize(&mesh->prng_state, sizeof(mesh->prng_state));
1297
1298         do {
1299                 randomize(&mesh->session_id, sizeof(mesh->session_id));
1300         } while(mesh->session_id == 0);
1301
1302         memcpy(mesh->dev_class_traits, default_class_traits, sizeof(default_class_traits));
1303
1304         if(usingname) {
1305                 mesh->name = xstrdup(params->name);
1306         }
1307
1308         // Hash the key
1309         if(params->key) {
1310                 mesh->config_key = xmalloc(CHACHA_POLY1305_KEYLEN);
1311
1312                 if(!prf(params->key, params->keylen, "MeshLink configuration key", 26, mesh->config_key, CHACHA_POLY1305_KEYLEN)) {
1313                         logger(NULL, MESHLINK_ERROR, "Error creating configuration key!\n");
1314                         meshlink_close(mesh);
1315                         meshlink_errno = MESHLINK_EINTERNAL;
1316                         return NULL;
1317                 }
1318         }
1319
1320         // initialize mutex
1321         pthread_mutexattr_t attr;
1322         pthread_mutexattr_init(&attr);
1323         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1324         pthread_mutex_init(&mesh->mutex, &attr);
1325
1326         mesh->threadstarted = false;
1327         event_loop_init(&mesh->loop);
1328         mesh->loop.data = mesh;
1329
1330         meshlink_queue_init(&mesh->outpacketqueue);
1331
1332         // Atomically lock the configuration directory.
1333         if(!main_config_lock(mesh)) {
1334                 meshlink_close(mesh);
1335                 return NULL;
1336         }
1337
1338         // If no configuration exists yet, create it.
1339
1340         if(!meshlink_confbase_exists(mesh)) {
1341                 if(!meshlink_setup(mesh)) {
1342                         logger(NULL, MESHLINK_ERROR, "Cannot create initial configuration\n");
1343                         meshlink_close(mesh);
1344                         return NULL;
1345                 }
1346         } else {
1347                 if(!meshlink_read_config(mesh)) {
1348                         logger(NULL, MESHLINK_ERROR, "Cannot read main configuration\n");
1349                         meshlink_close(mesh);
1350                         return NULL;
1351                 }
1352         }
1353
1354 #ifdef HAVE_MINGW
1355         struct WSAData wsa_state;
1356         WSAStartup(MAKEWORD(2, 2), &wsa_state);
1357 #endif
1358
1359         // Setup up everything
1360         // TODO: we should not open listening sockets yet
1361
1362         bool success = false;
1363
1364         if(mesh->netns != -1) {
1365 #ifdef HAVE_SETNS
1366                 pthread_t thr;
1367
1368                 if(pthread_create(&thr, NULL, setup_network_in_netns_thread, mesh) == 0) {
1369                         void *retval = NULL;
1370                         success = pthread_join(thr, &retval) == 0 && retval;
1371                 }
1372
1373 #else
1374                 meshlink_errno = MESHLINK_EINTERNAL;
1375                 return NULL;
1376
1377 #endif // HAVE_SETNS
1378         } else {
1379                 success = setup_network(mesh);
1380                 add_local_addresses(mesh);
1381         }
1382
1383         if(!success) {
1384                 meshlink_close(mesh);
1385                 meshlink_errno = MESHLINK_ENETWORK;
1386                 return NULL;
1387         }
1388
1389         add_local_addresses(mesh);
1390
1391         if(!node_write_config(mesh, mesh->self)) {
1392                 logger(NULL, MESHLINK_ERROR, "Cannot update configuration\n");
1393                 return NULL;
1394         }
1395
1396         idle_set(&mesh->loop, idle, mesh);
1397
1398         logger(NULL, MESHLINK_DEBUG, "meshlink_open returning\n");
1399         return mesh;
1400 }
1401
1402 meshlink_submesh_t *meshlink_submesh_open(meshlink_handle_t  *mesh, const char *submesh) {
1403         meshlink_submesh_t *s = NULL;
1404
1405         if(!mesh) {
1406                 logger(NULL, MESHLINK_ERROR, "No mesh handle given!\n");
1407                 meshlink_errno = MESHLINK_EINVAL;
1408                 return NULL;
1409         }
1410
1411         if(!submesh || !*submesh) {
1412                 logger(NULL, MESHLINK_ERROR, "No submesh name given!\n");
1413                 meshlink_errno = MESHLINK_EINVAL;
1414                 return NULL;
1415         }
1416
1417         //lock mesh->nodes
1418         pthread_mutex_lock(&mesh->mutex);
1419
1420         s = (meshlink_submesh_t *)create_submesh(mesh, submesh);
1421
1422         pthread_mutex_unlock(&mesh->mutex);
1423
1424         return s;
1425 }
1426
1427 static void *meshlink_main_loop(void *arg) {
1428         meshlink_handle_t *mesh = arg;
1429
1430         if(mesh->netns != -1) {
1431 #ifdef HAVE_SETNS
1432
1433                 if(setns(mesh->netns, CLONE_NEWNET) != 0) {
1434                         pthread_cond_signal(&mesh->cond);
1435                         return NULL;
1436                 }
1437
1438 #else
1439                 pthread_cond_signal(&mesh->cond);
1440                 return NULL;
1441 #endif // HAVE_SETNS
1442         }
1443
1444 #if HAVE_CATTA
1445
1446         if(mesh->discovery) {
1447                 discovery_start(mesh);
1448         }
1449
1450 #endif
1451
1452         pthread_mutex_lock(&mesh->mutex);
1453
1454         logger(mesh, MESHLINK_DEBUG, "Starting main_loop...\n");
1455         pthread_cond_broadcast(&mesh->cond);
1456         main_loop(mesh);
1457         logger(mesh, MESHLINK_DEBUG, "main_loop returned.\n");
1458
1459         pthread_mutex_unlock(&mesh->mutex);
1460
1461 #if HAVE_CATTA
1462
1463         // Stop discovery
1464         if(mesh->discovery) {
1465                 discovery_stop(mesh);
1466         }
1467
1468 #endif
1469
1470         return NULL;
1471 }
1472
1473 bool meshlink_start(meshlink_handle_t *mesh) {
1474         assert(mesh->self);
1475         assert(mesh->private_key);
1476
1477         if(!mesh) {
1478                 meshlink_errno = MESHLINK_EINVAL;
1479                 return false;
1480         }
1481
1482         logger(mesh, MESHLINK_DEBUG, "meshlink_start called\n");
1483
1484         pthread_mutex_lock(&mesh->mutex);
1485
1486         assert(mesh->self->ecdsa);
1487         assert(!memcmp((uint8_t *)mesh->self->ecdsa + 64, (uint8_t *)mesh->private_key + 64, 32));
1488
1489         if(mesh->threadstarted) {
1490                 logger(mesh, MESHLINK_DEBUG, "thread was already running\n");
1491                 pthread_mutex_unlock(&mesh->mutex);
1492                 return true;
1493         }
1494
1495         if(mesh->listen_socket[0].tcp.fd < 0) {
1496                 logger(mesh, MESHLINK_ERROR, "Listening socket not open\n");
1497                 meshlink_errno = MESHLINK_ENETWORK;
1498                 return false;
1499         }
1500
1501         mesh->thedatalen = 0;
1502
1503         // TODO: open listening sockets first
1504
1505         //Check that a valid name is set
1506         if(!mesh->name) {
1507                 logger(mesh, MESHLINK_DEBUG, "No name given!\n");
1508                 meshlink_errno = MESHLINK_EINVAL;
1509                 pthread_mutex_unlock(&mesh->mutex);
1510                 return false;
1511         }
1512
1513         init_outgoings(mesh);
1514
1515         // Start the main thread
1516
1517         event_loop_start(&mesh->loop);
1518
1519         if(pthread_create(&mesh->thread, NULL, meshlink_main_loop, mesh) != 0) {
1520                 logger(mesh, MESHLINK_DEBUG, "Could not start thread: %s\n", strerror(errno));
1521                 memset(&mesh->thread, 0, sizeof(mesh)->thread);
1522                 meshlink_errno = MESHLINK_EINTERNAL;
1523                 event_loop_stop(&mesh->loop);
1524                 pthread_mutex_unlock(&mesh->mutex);
1525                 return false;
1526         }
1527
1528         pthread_cond_wait(&mesh->cond, &mesh->mutex);
1529         mesh->threadstarted = true;
1530         mesh->self->last_reachable = time(NULL);
1531         mesh->self->status.dirty = true;
1532
1533         pthread_mutex_unlock(&mesh->mutex);
1534         return true;
1535 }
1536
1537 void meshlink_stop(meshlink_handle_t *mesh) {
1538         if(!mesh) {
1539                 meshlink_errno = MESHLINK_EINVAL;
1540                 return;
1541         }
1542
1543         pthread_mutex_lock(&mesh->mutex);
1544         logger(mesh, MESHLINK_DEBUG, "meshlink_stop called\n");
1545
1546         if(mesh->self) {
1547                 mesh->self->last_unreachable = time(NULL);
1548                 mesh->self->status.dirty = true;
1549         }
1550
1551         // Shut down the main thread
1552         event_loop_stop(&mesh->loop);
1553
1554         // Send ourselves a UDP packet to kick the event loop
1555         for(int i = 0; i < mesh->listen_sockets; i++) {
1556                 sockaddr_t sa;
1557                 socklen_t salen = sizeof(sa);
1558
1559                 if(getsockname(mesh->listen_socket[i].udp.fd, &sa.sa, &salen) == -1) {
1560                         logger(mesh, MESHLINK_ERROR, "System call `%s' failed: %s", "getsockname", sockstrerror(sockerrno));
1561                         continue;
1562                 }
1563
1564                 if(sendto(mesh->listen_socket[i].udp.fd, "", 1, MSG_NOSIGNAL, &sa.sa, salen) == -1) {
1565                         logger(mesh, MESHLINK_ERROR, "Could not send a UDP packet to ourself: %s", sockstrerror(sockerrno));
1566                 }
1567         }
1568
1569         if(mesh->threadstarted) {
1570                 // Wait for the main thread to finish
1571                 pthread_mutex_unlock(&mesh->mutex);
1572                 pthread_join(mesh->thread, NULL);
1573                 pthread_mutex_lock(&mesh->mutex);
1574
1575                 mesh->threadstarted = false;
1576         }
1577
1578         // Close all metaconnections
1579         if(mesh->connections) {
1580                 for(list_node_t *node = mesh->connections->head, *next; node; node = next) {
1581                         next = node->next;
1582                         connection_t *c = node->data;
1583                         c->outgoing = NULL;
1584                         terminate_connection(mesh, c, false);
1585                 }
1586         }
1587
1588         exit_outgoings(mesh);
1589
1590         // Try to write out any changed node config files, ignore errors at this point.
1591         if(mesh->nodes) {
1592                 for splay_each(node_t, n, mesh->nodes) {
1593                         if(n->status.dirty) {
1594                                 n->status.dirty = !node_write_config(mesh, n);
1595                         }
1596                 }
1597         }
1598
1599         pthread_mutex_unlock(&mesh->mutex);
1600 }
1601
1602 void meshlink_close(meshlink_handle_t *mesh) {
1603         if(!mesh) {
1604                 meshlink_errno = MESHLINK_EINVAL;
1605                 return;
1606         }
1607
1608         // stop can be called even if mesh has not been started
1609         meshlink_stop(mesh);
1610
1611         // lock is not released after this
1612         pthread_mutex_lock(&mesh->mutex);
1613
1614         // Close and free all resources used.
1615
1616         close_network_connections(mesh);
1617
1618         logger(mesh, MESHLINK_INFO, "Terminating");
1619
1620         event_loop_exit(&mesh->loop);
1621
1622 #ifdef HAVE_MINGW
1623
1624         if(mesh->confbase) {
1625                 WSACleanup();
1626         }
1627
1628 #endif
1629
1630         ecdsa_free(mesh->invitation_key);
1631
1632         if(mesh->netns != -1) {
1633                 close(mesh->netns);
1634         }
1635
1636         for(vpn_packet_t *packet; (packet = meshlink_queue_pop(&mesh->outpacketqueue));) {
1637                 free(packet);
1638         }
1639
1640         meshlink_queue_exit(&mesh->outpacketqueue);
1641
1642         free(mesh->name);
1643         free(mesh->appname);
1644         free(mesh->confbase);
1645         free(mesh->config_key);
1646         ecdsa_free(mesh->private_key);
1647
1648         main_config_unlock(mesh);
1649
1650         pthread_mutex_unlock(&mesh->mutex);
1651         pthread_mutex_destroy(&mesh->mutex);
1652
1653         memset(mesh, 0, sizeof(*mesh));
1654
1655         free(mesh);
1656 }
1657
1658 bool meshlink_destroy(const char *confbase) {
1659         if(!confbase) {
1660                 meshlink_errno = MESHLINK_EINVAL;
1661                 return false;
1662         }
1663
1664         /* Exit early if the confbase directory itself doesn't exist */
1665         if(access(confbase, F_OK) && errno == ENOENT) {
1666                 return true;
1667         }
1668
1669         /* Take the lock the same way meshlink_open() would. */
1670         char lockfilename[PATH_MAX];
1671         snprintf(lockfilename, sizeof(lockfilename), "%s" SLASH "meshlink.lock", confbase);
1672
1673         FILE *lockfile = fopen(lockfilename, "w+");
1674
1675         if(!lockfile) {
1676                 logger(NULL, MESHLINK_ERROR, "Could not open lock file %s: %s", lockfilename, strerror(errno));
1677                 meshlink_errno = MESHLINK_ESTORAGE;
1678                 return false;
1679         }
1680
1681 #ifdef FD_CLOEXEC
1682         fcntl(fileno(lockfile), F_SETFD, FD_CLOEXEC);
1683 #endif
1684
1685 #ifdef HAVE_MINGW
1686         // TODO: use _locking()?
1687 #else
1688
1689         if(flock(fileno(lockfile), LOCK_EX | LOCK_NB) != 0) {
1690                 logger(NULL, MESHLINK_ERROR, "Configuration directory %s still in use\n", lockfilename);
1691                 fclose(lockfile);
1692                 meshlink_errno = MESHLINK_EBUSY;
1693                 return false;
1694         }
1695
1696 #endif
1697
1698         if(!config_destroy(confbase, "current") || !config_destroy(confbase, "new") || !config_destroy(confbase, "old")) {
1699                 logger(NULL, MESHLINK_ERROR, "Cannot remove sub-directories in %s: %s\n", confbase, strerror(errno));
1700                 return false;
1701         }
1702
1703         if(unlink(lockfilename)) {
1704                 logger(NULL, MESHLINK_ERROR, "Cannot remove lock file %s: %s\n", lockfilename, strerror(errno));
1705                 fclose(lockfile);
1706                 meshlink_errno = MESHLINK_ESTORAGE;
1707                 return false;
1708         }
1709
1710         fclose(lockfile);
1711
1712         if(!sync_path(confbase)) {
1713                 logger(NULL, MESHLINK_ERROR, "Cannot sync directory %s: %s\n", confbase, strerror(errno));
1714                 meshlink_errno = MESHLINK_ESTORAGE;
1715                 return false;
1716         }
1717
1718         return true;
1719 }
1720
1721 void meshlink_set_receive_cb(meshlink_handle_t *mesh, meshlink_receive_cb_t cb) {
1722         if(!mesh) {
1723                 meshlink_errno = MESHLINK_EINVAL;
1724                 return;
1725         }
1726
1727         pthread_mutex_lock(&mesh->mutex);
1728         mesh->receive_cb = cb;
1729         pthread_mutex_unlock(&mesh->mutex);
1730 }
1731
1732 void meshlink_set_connection_try_cb(meshlink_handle_t *mesh, meshlink_connection_try_cb_t cb) {
1733         if(!mesh) {
1734                 meshlink_errno = MESHLINK_EINVAL;
1735                 return;
1736         }
1737
1738         pthread_mutex_lock(&mesh->mutex);
1739         mesh->connection_try_cb = cb;
1740         pthread_mutex_unlock(&mesh->mutex);
1741 }
1742
1743 void meshlink_set_node_status_cb(meshlink_handle_t *mesh, meshlink_node_status_cb_t cb) {
1744         if(!mesh) {
1745                 meshlink_errno = MESHLINK_EINVAL;
1746                 return;
1747         }
1748
1749         pthread_mutex_lock(&mesh->mutex);
1750         mesh->node_status_cb = cb;
1751         pthread_mutex_unlock(&mesh->mutex);
1752 }
1753
1754 void meshlink_set_node_pmtu_cb(meshlink_handle_t *mesh, meshlink_node_pmtu_cb_t cb) {
1755         if(!mesh) {
1756                 meshlink_errno = MESHLINK_EINVAL;
1757                 return;
1758         }
1759
1760         pthread_mutex_lock(&mesh->mutex);
1761         mesh->node_pmtu_cb = cb;
1762         pthread_mutex_unlock(&mesh->mutex);
1763 }
1764
1765 void meshlink_set_node_duplicate_cb(meshlink_handle_t *mesh, meshlink_node_duplicate_cb_t cb) {
1766         if(!mesh) {
1767                 meshlink_errno = MESHLINK_EINVAL;
1768                 return;
1769         }
1770
1771         pthread_mutex_lock(&mesh->mutex);
1772         mesh->node_duplicate_cb = cb;
1773         pthread_mutex_unlock(&mesh->mutex);
1774 }
1775
1776 void meshlink_set_log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, meshlink_log_cb_t cb) {
1777         if(mesh) {
1778                 pthread_mutex_lock(&mesh->mutex);
1779                 mesh->log_cb = cb;
1780                 mesh->log_level = cb ? level : 0;
1781                 pthread_mutex_unlock(&mesh->mutex);
1782         } else {
1783                 global_log_cb = cb;
1784                 global_log_level = cb ? level : 0;
1785         }
1786 }
1787
1788 void meshlink_set_error_cb(struct meshlink_handle *mesh, meshlink_error_cb_t cb) {
1789         if(!mesh) {
1790                 meshlink_errno = MESHLINK_EINVAL;
1791                 return;
1792         }
1793
1794         pthread_mutex_lock(&mesh->mutex);
1795         mesh->error_cb = cb;
1796         pthread_mutex_unlock(&mesh->mutex);
1797 }
1798
1799 bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
1800         meshlink_packethdr_t *hdr;
1801
1802         // Validate arguments
1803         if(!mesh || !destination || len >= MAXSIZE - sizeof(*hdr)) {
1804                 meshlink_errno = MESHLINK_EINVAL;
1805                 return false;
1806         }
1807
1808         if(!len) {
1809                 return true;
1810         }
1811
1812         if(!data) {
1813                 meshlink_errno = MESHLINK_EINVAL;
1814                 return false;
1815         }
1816
1817         node_t *n = (node_t *)destination;
1818
1819         if(n->status.blacklisted) {
1820                 logger(mesh, MESHLINK_ERROR, "Node %s blacklisted, dropping packet\n", n->name);
1821                 meshlink_errno = MESHLINK_EBLACKLISTED;
1822                 return false;
1823         }
1824
1825         // Prepare the packet
1826         vpn_packet_t *packet = malloc(sizeof(*packet));
1827
1828         if(!packet) {
1829                 meshlink_errno = MESHLINK_ENOMEM;
1830                 return false;
1831         }
1832
1833         packet->probe = false;
1834         packet->tcp = false;
1835         packet->len = len + sizeof(*hdr);
1836
1837         hdr = (meshlink_packethdr_t *)packet->data;
1838         memset(hdr, 0, sizeof(*hdr));
1839         // leave the last byte as 0 to make sure strings are always
1840         // null-terminated if they are longer than the buffer
1841         strncpy((char *)hdr->destination, destination->name, (sizeof(hdr)->destination) - 1);
1842         strncpy((char *)hdr->source, mesh->self->name, (sizeof(hdr)->source) - 1);
1843
1844         memcpy(packet->data + sizeof(*hdr), data, len);
1845
1846         // Queue it
1847         if(!meshlink_queue_push(&mesh->outpacketqueue, packet)) {
1848                 free(packet);
1849                 meshlink_errno = MESHLINK_ENOMEM;
1850                 return false;
1851         }
1852
1853         // Notify event loop
1854         signal_trigger(&mesh->loop, &mesh->datafromapp);
1855
1856         return true;
1857 }
1858
1859 void meshlink_send_from_queue(event_loop_t *loop, void *data) {
1860         (void)loop;
1861         meshlink_handle_t *mesh = data;
1862         vpn_packet_t *packet = meshlink_queue_pop(&mesh->outpacketqueue);
1863
1864         if(!packet) {
1865                 return;
1866         }
1867
1868         mesh->self->in_packets++;
1869         mesh->self->in_bytes += packet->len;
1870         route(mesh, mesh->self, packet);
1871
1872         free(packet);
1873 }
1874
1875 ssize_t meshlink_get_pmtu(meshlink_handle_t *mesh, meshlink_node_t *destination) {
1876         if(!mesh || !destination) {
1877                 meshlink_errno = MESHLINK_EINVAL;
1878                 return -1;
1879         }
1880
1881         pthread_mutex_lock(&mesh->mutex);
1882
1883         node_t *n = (node_t *)destination;
1884
1885         if(!n->status.reachable) {
1886                 pthread_mutex_unlock(&mesh->mutex);
1887                 return 0;
1888
1889         } else if(n->mtuprobes > 30 && n->minmtu) {
1890                 pthread_mutex_unlock(&mesh->mutex);
1891                 return n->minmtu;
1892         } else {
1893                 pthread_mutex_unlock(&mesh->mutex);
1894                 return MTU;
1895         }
1896 }
1897
1898 char *meshlink_get_fingerprint(meshlink_handle_t *mesh, meshlink_node_t *node) {
1899         if(!mesh || !node) {
1900                 meshlink_errno = MESHLINK_EINVAL;
1901                 return NULL;
1902         }
1903
1904         pthread_mutex_lock(&mesh->mutex);
1905
1906         node_t *n = (node_t *)node;
1907
1908         if(!node_read_public_key(mesh, n) || !n->ecdsa) {
1909                 meshlink_errno = MESHLINK_EINTERNAL;
1910                 pthread_mutex_unlock(&mesh->mutex);
1911                 return false;
1912         }
1913
1914         char *fingerprint = ecdsa_get_base64_public_key(n->ecdsa);
1915
1916         if(!fingerprint) {
1917                 meshlink_errno = MESHLINK_EINTERNAL;
1918         }
1919
1920         pthread_mutex_unlock(&mesh->mutex);
1921         return fingerprint;
1922 }
1923
1924 meshlink_node_t *meshlink_get_self(meshlink_handle_t *mesh) {
1925         if(!mesh) {
1926                 meshlink_errno = MESHLINK_EINVAL;
1927                 return NULL;
1928         }
1929
1930         return (meshlink_node_t *)mesh->self;
1931 }
1932
1933 meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) {
1934         if(!mesh || !name) {
1935                 meshlink_errno = MESHLINK_EINVAL;
1936                 return NULL;
1937         }
1938
1939         node_t *n = NULL;
1940
1941         pthread_mutex_lock(&mesh->mutex);
1942         n = lookup_node(mesh, (char *)name); // TODO: make lookup_node() use const
1943         pthread_mutex_unlock(&mesh->mutex);
1944
1945         if(!n) {
1946                 meshlink_errno = MESHLINK_ENOENT;
1947         }
1948
1949         return (meshlink_node_t *)n;
1950 }
1951
1952 meshlink_submesh_t *meshlink_get_submesh(meshlink_handle_t *mesh, const char *name) {
1953         if(!mesh || !name) {
1954                 meshlink_errno = MESHLINK_EINVAL;
1955                 return NULL;
1956         }
1957
1958         meshlink_submesh_t *submesh = NULL;
1959
1960         pthread_mutex_lock(&mesh->mutex);
1961         submesh = (meshlink_submesh_t *)lookup_submesh(mesh, name);
1962         pthread_mutex_unlock(&mesh->mutex);
1963
1964         if(!submesh) {
1965                 meshlink_errno = MESHLINK_ENOENT;
1966         }
1967
1968         return submesh;
1969 }
1970
1971 meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t *nmemb) {
1972         if(!mesh || !nmemb || (*nmemb && !nodes)) {
1973                 meshlink_errno = MESHLINK_EINVAL;
1974                 return NULL;
1975         }
1976
1977         meshlink_node_t **result;
1978
1979         //lock mesh->nodes
1980         pthread_mutex_lock(&mesh->mutex);
1981
1982         *nmemb = mesh->nodes->count;
1983         result = realloc(nodes, *nmemb * sizeof(*nodes));
1984
1985         if(result) {
1986                 meshlink_node_t **p = result;
1987
1988                 for splay_each(node_t, n, mesh->nodes) {
1989                         *p++ = (meshlink_node_t *)n;
1990                 }
1991         } else {
1992                 *nmemb = 0;
1993                 free(nodes);
1994                 meshlink_errno = MESHLINK_ENOMEM;
1995         }
1996
1997         pthread_mutex_unlock(&mesh->mutex);
1998
1999         return result;
2000 }
2001
2002 static meshlink_node_t **meshlink_get_all_nodes_by_condition(meshlink_handle_t *mesh, const void *condition, meshlink_node_t **nodes, size_t *nmemb, search_node_by_condition_t search_node) {
2003         meshlink_node_t **result;
2004
2005         pthread_mutex_lock(&mesh->mutex);
2006
2007         *nmemb = 0;
2008
2009         for splay_each(node_t, n, mesh->nodes) {
2010                 if(search_node(n, condition)) {
2011                         ++*nmemb;
2012                 }
2013         }
2014
2015         if(*nmemb == 0) {
2016                 free(nodes);
2017                 pthread_mutex_unlock(&mesh->mutex);
2018                 return NULL;
2019         }
2020
2021         result = realloc(nodes, *nmemb * sizeof(*nodes));
2022
2023         if(result) {
2024                 meshlink_node_t **p = result;
2025
2026                 for splay_each(node_t, n, mesh->nodes) {
2027                         if(search_node(n, condition)) {
2028                                 *p++ = (meshlink_node_t *)n;
2029                         }
2030                 }
2031         } else {
2032                 *nmemb = 0;
2033                 free(nodes);
2034                 meshlink_errno = MESHLINK_ENOMEM;
2035         }
2036
2037         pthread_mutex_unlock(&mesh->mutex);
2038
2039         return result;
2040 }
2041
2042 static bool search_node_by_dev_class(const node_t *node, const void *condition) {
2043         dev_class_t *devclass = (dev_class_t *)condition;
2044
2045         if(*devclass == (dev_class_t)node->devclass) {
2046                 return true;
2047         }
2048
2049         return false;
2050 }
2051
2052 static bool search_node_by_submesh(const node_t *node, const void *condition) {
2053         if(condition == node->submesh) {
2054                 return true;
2055         }
2056
2057         return false;
2058 }
2059
2060 struct time_range {
2061         time_t start;
2062         time_t end;
2063 };
2064
2065 static bool search_node_by_last_reachable(const node_t *node, const void *condition) {
2066         const struct time_range *range = condition;
2067         time_t start = node->last_reachable;
2068         time_t end = node->last_unreachable;
2069
2070         if(end < start) {
2071                 end = time(NULL);
2072
2073                 if(end < start) {
2074                         start = end;
2075                 }
2076         }
2077
2078         if(range->end >= range->start) {
2079                 return start <= range->end && end >= range->start;
2080         } else {
2081                 return start > range->start || end < range->end;
2082         }
2083 }
2084
2085 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) {
2086         if(!mesh || devclass < 0 || devclass >= DEV_CLASS_COUNT || !nmemb) {
2087                 meshlink_errno = MESHLINK_EINVAL;
2088                 return NULL;
2089         }
2090
2091         return meshlink_get_all_nodes_by_condition(mesh, &devclass, nodes, nmemb, search_node_by_dev_class);
2092 }
2093
2094 meshlink_node_t **meshlink_get_all_nodes_by_submesh(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, meshlink_node_t **nodes, size_t *nmemb) {
2095         if(!mesh || !submesh || !nmemb) {
2096                 meshlink_errno = MESHLINK_EINVAL;
2097                 return NULL;
2098         }
2099
2100         return meshlink_get_all_nodes_by_condition(mesh, submesh, nodes, nmemb, search_node_by_submesh);
2101 }
2102
2103 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) {
2104         if(!mesh || !nmemb) {
2105                 meshlink_errno = MESHLINK_EINVAL;
2106                 return NULL;
2107         }
2108
2109         struct time_range range = {start, end};
2110
2111         return meshlink_get_all_nodes_by_condition(mesh, &range, nodes, nmemb, search_node_by_last_reachable);
2112 }
2113
2114 dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t *node) {
2115         if(!mesh || !node) {
2116                 meshlink_errno = MESHLINK_EINVAL;
2117                 return -1;
2118         }
2119
2120         dev_class_t devclass;
2121
2122         pthread_mutex_lock(&mesh->mutex);
2123
2124         devclass = ((node_t *)node)->devclass;
2125
2126         pthread_mutex_unlock(&mesh->mutex);
2127
2128         return devclass;
2129 }
2130
2131 meshlink_submesh_t *meshlink_get_node_submesh(meshlink_handle_t *mesh, meshlink_node_t *node) {
2132         if(!mesh || !node) {
2133                 meshlink_errno = MESHLINK_EINVAL;
2134                 return NULL;
2135         }
2136
2137         node_t *n = (node_t *)node;
2138
2139         meshlink_submesh_t *s;
2140
2141         s = (meshlink_submesh_t *)n->submesh;
2142
2143         return s;
2144 }
2145
2146 bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void *signature, size_t *siglen) {
2147         if(!mesh || !data || !len || !signature || !siglen) {
2148                 meshlink_errno = MESHLINK_EINVAL;
2149                 return false;
2150         }
2151
2152         if(*siglen < MESHLINK_SIGLEN) {
2153                 meshlink_errno = MESHLINK_EINVAL;
2154                 return false;
2155         }
2156
2157         pthread_mutex_lock(&mesh->mutex);
2158
2159         if(!ecdsa_sign(mesh->private_key, data, len, signature)) {
2160                 meshlink_errno = MESHLINK_EINTERNAL;
2161                 pthread_mutex_unlock(&mesh->mutex);
2162                 return false;
2163         }
2164
2165         *siglen = MESHLINK_SIGLEN;
2166         pthread_mutex_unlock(&mesh->mutex);
2167         return true;
2168 }
2169
2170 bool meshlink_verify(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len, const void *signature, size_t siglen) {
2171         if(!mesh || !data || !len || !signature) {
2172                 meshlink_errno = MESHLINK_EINVAL;
2173                 return false;
2174         }
2175
2176         if(siglen != MESHLINK_SIGLEN) {
2177                 meshlink_errno = MESHLINK_EINVAL;
2178                 return false;
2179         }
2180
2181         pthread_mutex_lock(&mesh->mutex);
2182
2183         bool rval = false;
2184
2185         struct node_t *n = (struct node_t *)source;
2186
2187         if(!node_read_public_key(mesh, n)) {
2188                 meshlink_errno = MESHLINK_EINTERNAL;
2189                 rval = false;
2190         } else {
2191                 rval = ecdsa_verify(((struct node_t *)source)->ecdsa, data, len, signature);
2192         }
2193
2194         pthread_mutex_unlock(&mesh->mutex);
2195         return rval;
2196 }
2197
2198 static bool refresh_invitation_key(meshlink_handle_t *mesh) {
2199         pthread_mutex_lock(&mesh->mutex);
2200
2201         size_t count = invitation_purge_old(mesh, time(NULL) - mesh->invitation_timeout);
2202
2203         if(!count) {
2204                 // TODO: Update invitation key if necessary?
2205         }
2206
2207         pthread_mutex_unlock(&mesh->mutex);
2208
2209         return mesh->invitation_key;
2210 }
2211
2212 bool meshlink_set_canonical_address(meshlink_handle_t *mesh, meshlink_node_t *node, const char *address, const char *port) {
2213         if(!mesh || !node || !address) {
2214                 meshlink_errno = MESHLINK_EINVAL;
2215                 return false;
2216         }
2217
2218         if(!is_valid_hostname(address)) {
2219                 logger(mesh, MESHLINK_DEBUG, "Invalid character in address: %s\n", address);
2220                 meshlink_errno = MESHLINK_EINVAL;
2221                 return false;
2222         }
2223
2224         if(port && !is_valid_port(port)) {
2225                 logger(mesh, MESHLINK_DEBUG, "Invalid character in port: %s\n", address);
2226                 meshlink_errno = MESHLINK_EINVAL;
2227                 return false;
2228         }
2229
2230         char *canonical_address;
2231
2232         if(port) {
2233                 xasprintf(&canonical_address, "%s %s", address, port);
2234         } else {
2235                 canonical_address = xstrdup(address);
2236         }
2237
2238         pthread_mutex_lock(&mesh->mutex);
2239
2240         node_t *n = (node_t *)node;
2241         free(n->canonical_address);
2242         n->canonical_address = canonical_address;
2243
2244         if(!node_write_config(mesh, n)) {
2245                 pthread_mutex_unlock(&mesh->mutex);
2246                 return false;
2247         }
2248
2249         pthread_mutex_unlock(&mesh->mutex);
2250
2251         return config_sync(mesh, "current");
2252 }
2253
2254 bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) {
2255         return meshlink_set_canonical_address(mesh, (meshlink_node_t *)mesh->self, address, NULL);
2256 }
2257
2258 bool meshlink_add_external_address(meshlink_handle_t *mesh) {
2259         if(!mesh) {
2260                 meshlink_errno = MESHLINK_EINVAL;
2261                 return false;
2262         }
2263
2264         char *address = meshlink_get_external_address(mesh);
2265
2266         if(!address) {
2267                 return false;
2268         }
2269
2270         bool rval = meshlink_add_address(mesh, address);
2271         free(address);
2272
2273         return rval;
2274 }
2275
2276 int meshlink_get_port(meshlink_handle_t *mesh) {
2277         if(!mesh) {
2278                 meshlink_errno = MESHLINK_EINVAL;
2279                 return -1;
2280         }
2281
2282         if(!mesh->myport) {
2283                 meshlink_errno = MESHLINK_EINTERNAL;
2284                 return -1;
2285         }
2286
2287         int port;
2288
2289         pthread_mutex_lock(&mesh->mutex);
2290         port = atoi(mesh->myport);
2291         pthread_mutex_unlock(&mesh->mutex);
2292
2293         return port;
2294 }
2295
2296 bool meshlink_set_port(meshlink_handle_t *mesh, int port) {
2297         if(!mesh || port < 0 || port >= 65536 || mesh->threadstarted) {
2298                 meshlink_errno = MESHLINK_EINVAL;
2299                 return false;
2300         }
2301
2302         if(mesh->myport && port == atoi(mesh->myport)) {
2303                 return true;
2304         }
2305
2306         if(!try_bind(port)) {
2307                 meshlink_errno = MESHLINK_ENETWORK;
2308                 return false;
2309         }
2310
2311         devtool_trybind_probe();
2312
2313         bool rval = false;
2314
2315         pthread_mutex_lock(&mesh->mutex);
2316
2317         if(mesh->threadstarted) {
2318                 meshlink_errno = MESHLINK_EINVAL;
2319                 goto done;
2320         }
2321
2322         free(mesh->myport);
2323         xasprintf(&mesh->myport, "%d", port);
2324
2325         /* Close down the network. This also deletes mesh->self. */
2326         close_network_connections(mesh);
2327
2328         /* Recreate mesh->self. */
2329         mesh->self = new_node();
2330         mesh->self->name = xstrdup(mesh->name);
2331         mesh->self->devclass = mesh->devclass;
2332         mesh->self->session_id = mesh->session_id;
2333         xasprintf(&mesh->myport, "%d", port);
2334
2335         if(!node_read_public_key(mesh, mesh->self)) {
2336                 logger(NULL, MESHLINK_ERROR, "Could not read our host configuration file!");
2337                 meshlink_errno = MESHLINK_ESTORAGE;
2338                 free_node(mesh->self);
2339                 mesh->self = NULL;
2340                 goto done;
2341         } else if(!setup_network(mesh)) {
2342                 meshlink_errno = MESHLINK_ENETWORK;
2343                 goto done;
2344         }
2345
2346         /* Rebuild our own list of recent addresses */
2347         memset(mesh->self->recent, 0, sizeof(mesh->self->recent));
2348         add_local_addresses(mesh);
2349
2350         /* Write meshlink.conf with the updated port number */
2351         write_main_config_files(mesh);
2352
2353         rval = config_sync(mesh, "current");
2354
2355 done:
2356         pthread_mutex_unlock(&mesh->mutex);
2357
2358         return rval && meshlink_get_port(mesh) == port;
2359 }
2360
2361 void meshlink_set_invitation_timeout(meshlink_handle_t *mesh, int timeout) {
2362         mesh->invitation_timeout = timeout;
2363 }
2364
2365 char *meshlink_invite_ex(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, const char *name, uint32_t flags) {
2366         meshlink_submesh_t *s = NULL;
2367
2368         if(!mesh) {
2369                 meshlink_errno = MESHLINK_EINVAL;
2370                 return NULL;
2371         }
2372
2373         if(submesh) {
2374                 s = (meshlink_submesh_t *)lookup_submesh(mesh, submesh->name);
2375
2376                 if(s != submesh) {
2377                         logger(mesh, MESHLINK_DEBUG, "Invalid SubMesh Handle.\n");
2378                         meshlink_errno = MESHLINK_EINVAL;
2379                         return NULL;
2380                 }
2381         } else {
2382                 s = (meshlink_submesh_t *)mesh->self->submesh;
2383         }
2384
2385         pthread_mutex_lock(&mesh->mutex);
2386
2387         // Check validity of the new node's name
2388         if(!check_id(name)) {
2389                 logger(mesh, MESHLINK_ERROR, "Invalid name for node.\n");
2390                 meshlink_errno = MESHLINK_EINVAL;
2391                 pthread_mutex_unlock(&mesh->mutex);
2392                 return NULL;
2393         }
2394
2395         // Ensure no host configuration file with that name exists
2396         if(config_exists(mesh, "current", name)) {
2397                 logger(mesh, MESHLINK_ERROR, "A host config file for %s already exists!\n", name);
2398                 meshlink_errno = MESHLINK_EEXIST;
2399                 pthread_mutex_unlock(&mesh->mutex);
2400                 return NULL;
2401         }
2402
2403         // Ensure no other nodes know about this name
2404         if(meshlink_get_node(mesh, name)) {
2405                 logger(mesh, MESHLINK_ERROR, "A node with name %s is already known!\n", name);
2406                 meshlink_errno = MESHLINK_EEXIST;
2407                 pthread_mutex_unlock(&mesh->mutex);
2408                 return NULL;
2409         }
2410
2411         // Get the local address
2412         char *address = get_my_hostname(mesh, flags);
2413
2414         if(!address) {
2415                 logger(mesh, MESHLINK_ERROR, "No Address known for ourselves!\n");
2416                 meshlink_errno = MESHLINK_ERESOLV;
2417                 pthread_mutex_unlock(&mesh->mutex);
2418                 return NULL;
2419         }
2420
2421         if(!refresh_invitation_key(mesh)) {
2422                 meshlink_errno = MESHLINK_EINTERNAL;
2423                 pthread_mutex_unlock(&mesh->mutex);
2424                 return NULL;
2425         }
2426
2427         // If we changed our own host config file, write it out now
2428         if(mesh->self->status.dirty) {
2429                 if(!node_write_config(mesh, mesh->self)) {
2430                         logger(mesh, MESHLINK_ERROR, "Could not write our own host conifg file!\n");
2431                         pthread_mutex_unlock(&mesh->mutex);
2432                         return NULL;
2433                 }
2434         }
2435
2436         char hash[64];
2437
2438         // Create a hash of the key.
2439         char *fingerprint = ecdsa_get_base64_public_key(mesh->invitation_key);
2440         sha512(fingerprint, strlen(fingerprint), hash);
2441         b64encode_urlsafe(hash, hash, 18);
2442
2443         // Create a random cookie for this invitation.
2444         char cookie[25];
2445         randomize(cookie, 18);
2446
2447         // Create a filename that doesn't reveal the cookie itself
2448         char buf[18 + strlen(fingerprint)];
2449         char cookiehash[64];
2450         memcpy(buf, cookie, 18);
2451         memcpy(buf + 18, fingerprint, sizeof(buf) - 18);
2452         sha512(buf, sizeof(buf), cookiehash);
2453         b64encode_urlsafe(cookiehash, cookiehash, 18);
2454
2455         b64encode_urlsafe(cookie, cookie, 18);
2456
2457         free(fingerprint);
2458
2459         /* Construct the invitation file */
2460         uint8_t outbuf[4096];
2461         packmsg_output_t inv = {outbuf, sizeof(outbuf)};
2462
2463         packmsg_add_uint32(&inv, MESHLINK_INVITATION_VERSION);
2464         packmsg_add_str(&inv, name);
2465         packmsg_add_str(&inv, s ? s->name : CORE_MESH);
2466         packmsg_add_int32(&inv, DEV_CLASS_UNKNOWN); /* TODO: allow this to be set by inviter? */
2467
2468         /* TODO: Add several host config files to bootstrap connections.
2469          * Note: make sure we only add config files of nodes that are in the core mesh or the same submesh,
2470          * and are not blacklisted.
2471          */
2472         config_t configs[5];
2473         memset(configs, 0, sizeof(configs));
2474         int count = 0;
2475
2476         if(config_read(mesh, "current", mesh->self->name, &configs[count], mesh->config_key)) {
2477                 count++;
2478         }
2479
2480         /* Append host config files to the invitation file */
2481         packmsg_add_array(&inv, count);
2482
2483         for(int i = 0; i < count; i++) {
2484                 packmsg_add_bin(&inv, configs[i].buf, configs[i].len);
2485                 config_free(&configs[i]);
2486         }
2487
2488         config_t config = {outbuf, packmsg_output_size(&inv, outbuf)};
2489
2490         if(!invitation_write(mesh, "current", cookiehash, &config, mesh->config_key)) {
2491                 logger(mesh, MESHLINK_DEBUG, "Could not create invitation file %s: %s\n", cookiehash, strerror(errno));
2492                 meshlink_errno = MESHLINK_ESTORAGE;
2493                 pthread_mutex_unlock(&mesh->mutex);
2494                 return NULL;
2495         }
2496
2497         // Create an URL from the local address, key hash and cookie
2498         char *url;
2499         xasprintf(&url, "%s/%s%s", address, hash, cookie);
2500         free(address);
2501
2502         pthread_mutex_unlock(&mesh->mutex);
2503         return url;
2504 }
2505
2506 char *meshlink_invite(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, const char *name) {
2507         return meshlink_invite_ex(mesh, submesh, name, 0);
2508 }
2509
2510 bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) {
2511         if(!mesh || !invitation) {
2512                 meshlink_errno = MESHLINK_EINVAL;
2513                 return false;
2514         }
2515
2516         pthread_mutex_lock(&mesh->mutex);
2517
2518         //Before doing meshlink_join make sure we are not connected to another mesh
2519         if(mesh->threadstarted) {
2520                 logger(mesh, MESHLINK_ERROR, "Cannot join while started\n");
2521                 meshlink_errno = MESHLINK_EINVAL;
2522                 pthread_mutex_unlock(&mesh->mutex);
2523                 return false;
2524         }
2525
2526         // Refuse to join a mesh if we are already part of one. We are part of one if we know at least one other node.
2527         if(mesh->nodes->count > 1) {
2528                 logger(mesh, MESHLINK_ERROR, "Already part of an existing mesh\n");
2529                 meshlink_errno = MESHLINK_EINVAL;
2530                 pthread_mutex_unlock(&mesh->mutex);
2531                 return false;
2532         }
2533
2534         //TODO: think of a better name for this variable, or of a different way to tokenize the invitation URL.
2535         char copy[strlen(invitation) + 1];
2536         strcpy(copy, invitation);
2537
2538         // Split the invitation URL into a list of hostname/port tuples, a key hash and a cookie.
2539
2540         char *slash = strchr(copy, '/');
2541
2542         if(!slash) {
2543                 goto invalid;
2544         }
2545
2546         *slash++ = 0;
2547
2548         if(strlen(slash) != 48) {
2549                 goto invalid;
2550         }
2551
2552         char *address = copy;
2553         char *port = NULL;
2554
2555         if(!b64decode(slash, mesh->hash, 18) || !b64decode(slash + 24, mesh->cookie, 18)) {
2556                 goto invalid;
2557         }
2558
2559         // Generate a throw-away key for the invitation.
2560         ecdsa_t *key = ecdsa_generate();
2561
2562         if(!key) {
2563                 meshlink_errno = MESHLINK_EINTERNAL;
2564                 pthread_mutex_unlock(&mesh->mutex);
2565                 return false;
2566         }
2567
2568         char *b64key = ecdsa_get_base64_public_key(key);
2569         char *comma;
2570         mesh->sock = -1;
2571
2572         while(address && *address) {
2573                 // We allow commas in the address part to support multiple addresses in one invitation URL.
2574                 comma = strchr(address, ',');
2575
2576                 if(comma) {
2577                         *comma++ = 0;
2578                 }
2579
2580                 // Split of the port
2581                 port = strrchr(address, ':');
2582
2583                 if(!port) {
2584                         goto invalid;
2585                 }
2586
2587                 *port++ = 0;
2588
2589                 // IPv6 address are enclosed in brackets, per RFC 3986
2590                 if(*address == '[') {
2591                         address++;
2592                         char *bracket = strchr(address, ']');
2593
2594                         if(!bracket) {
2595                                 goto invalid;
2596                         }
2597
2598                         *bracket++ = 0;
2599
2600                         if(*bracket) {
2601                                 goto invalid;
2602                         }
2603                 }
2604
2605                 // Connect to the meshlink daemon mentioned in the URL.
2606                 struct addrinfo *ai = str2addrinfo(address, port, SOCK_STREAM);
2607
2608                 if(ai) {
2609                         for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
2610                                 mesh->sock = socket_in_netns(aip->ai_family, aip->ai_socktype, aip->ai_protocol, mesh->netns);
2611
2612                                 if(mesh->sock == -1) {
2613                                         logger(mesh, MESHLINK_DEBUG, "Could not open socket: %s\n", strerror(errno));
2614                                         meshlink_errno = MESHLINK_ENETWORK;
2615                                         continue;
2616                                 }
2617
2618                                 set_timeout(mesh->sock, 5000);
2619
2620                                 if(connect(mesh->sock, aip->ai_addr, aip->ai_addrlen)) {
2621                                         logger(mesh, MESHLINK_DEBUG, "Could not connect to %s port %s: %s\n", address, port, strerror(errno));
2622                                         meshlink_errno = MESHLINK_ENETWORK;
2623                                         closesocket(mesh->sock);
2624                                         mesh->sock = -1;
2625                                         continue;
2626                                 }
2627                         }
2628
2629                         freeaddrinfo(ai);
2630                 } else {
2631                         meshlink_errno = MESHLINK_ERESOLV;
2632                 }
2633
2634                 if(mesh->sock != -1 || !comma) {
2635                         break;
2636                 }
2637
2638                 address = comma;
2639         }
2640
2641         if(mesh->sock == -1) {
2642                 pthread_mutex_unlock(&mesh->mutex);
2643                 return false;
2644         }
2645
2646         logger(mesh, MESHLINK_DEBUG, "Connected to %s port %s...\n", address, port);
2647
2648         // Tell him we have an invitation, and give him our throw-away key.
2649
2650         mesh->blen = 0;
2651
2652         if(!sendline(mesh->sock, "0 ?%s %d.%d %s", b64key, PROT_MAJOR, PROT_MINOR, mesh->appname)) {
2653                 logger(mesh, MESHLINK_DEBUG, "Error sending request to %s port %s: %s\n", address, port, strerror(errno));
2654                 closesocket(mesh->sock);
2655                 meshlink_errno = MESHLINK_ENETWORK;
2656                 pthread_mutex_unlock(&mesh->mutex);
2657                 return false;
2658         }
2659
2660         free(b64key);
2661
2662         char hisname[4096] = "";
2663         int code, hismajor, hisminor = 0;
2664
2665         if(!recvline(mesh, sizeof(mesh)->line) || sscanf(mesh->line, "%d %s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(mesh, sizeof(mesh)->line) || !rstrip(mesh->line) || sscanf(mesh->line, "%d ", &code) != 1 || code != ACK || strlen(mesh->line) < 3) {
2666                 logger(mesh, MESHLINK_DEBUG, "Cannot read greeting from peer\n");
2667                 closesocket(mesh->sock);
2668                 meshlink_errno = MESHLINK_ENETWORK;
2669                 pthread_mutex_unlock(&mesh->mutex);
2670                 return false;
2671         }
2672
2673         // Check if the hash of the key he gave us matches the hash in the URL.
2674         char *fingerprint = mesh->line + 2;
2675         char hishash[64];
2676
2677         if(sha512(fingerprint, strlen(fingerprint), hishash)) {
2678                 logger(mesh, MESHLINK_DEBUG, "Could not create hash\n%s\n", mesh->line + 2);
2679                 meshlink_errno = MESHLINK_EINTERNAL;
2680                 pthread_mutex_unlock(&mesh->mutex);
2681                 return false;
2682         }
2683
2684         if(memcmp(hishash, mesh->hash, 18)) {
2685                 logger(mesh, MESHLINK_DEBUG, "Peer has an invalid key!\n%s\n", mesh->line + 2);
2686                 meshlink_errno = MESHLINK_EPEER;
2687                 pthread_mutex_unlock(&mesh->mutex);
2688                 return false;
2689
2690         }
2691
2692         ecdsa_t *hiskey = ecdsa_set_base64_public_key(fingerprint);
2693
2694         if(!hiskey) {
2695                 meshlink_errno = MESHLINK_EINTERNAL;
2696                 pthread_mutex_unlock(&mesh->mutex);
2697                 return false;
2698         }
2699
2700         // Start an SPTPS session
2701         if(!sptps_start(&mesh->sptps, mesh, true, false, key, hiskey, meshlink_invitation_label, sizeof(meshlink_invitation_label), invitation_send, invitation_receive)) {
2702                 meshlink_errno = MESHLINK_EINTERNAL;
2703                 pthread_mutex_unlock(&mesh->mutex);
2704                 return false;
2705         }
2706
2707         // Feed rest of input buffer to SPTPS
2708         if(!sptps_receive_data(&mesh->sptps, mesh->buffer, mesh->blen)) {
2709                 meshlink_errno = MESHLINK_EPEER;
2710                 pthread_mutex_unlock(&mesh->mutex);
2711                 return false;
2712         }
2713
2714         int len;
2715
2716         while((len = recv(mesh->sock, mesh->line, sizeof(mesh)->line, 0))) {
2717                 if(len < 0) {
2718                         if(errno == EINTR) {
2719                                 continue;
2720                         }
2721
2722                         logger(mesh, MESHLINK_DEBUG, "Error reading data from %s port %s: %s\n", address, port, strerror(errno));
2723                         meshlink_errno = MESHLINK_ENETWORK;
2724                         pthread_mutex_unlock(&mesh->mutex);
2725                         return false;
2726                 }
2727
2728                 if(!sptps_receive_data(&mesh->sptps, mesh->line, len)) {
2729                         meshlink_errno = MESHLINK_EPEER;
2730                         pthread_mutex_unlock(&mesh->mutex);
2731                         return false;
2732                 }
2733         }
2734
2735         sptps_stop(&mesh->sptps);
2736         ecdsa_free(hiskey);
2737         ecdsa_free(key);
2738         closesocket(mesh->sock);
2739
2740         if(!mesh->success) {
2741                 logger(mesh, MESHLINK_DEBUG, "Connection closed by peer, invitation cancelled.\n");
2742                 meshlink_errno = MESHLINK_EPEER;
2743                 pthread_mutex_unlock(&mesh->mutex);
2744                 return false;
2745         }
2746
2747         pthread_mutex_unlock(&mesh->mutex);
2748         return true;
2749
2750 invalid:
2751         logger(mesh, MESHLINK_DEBUG, "Invalid invitation URL\n");
2752         meshlink_errno = MESHLINK_EINVAL;
2753         pthread_mutex_unlock(&mesh->mutex);
2754         return false;
2755 }
2756
2757 char *meshlink_export(meshlink_handle_t *mesh) {
2758         if(!mesh) {
2759                 meshlink_errno = MESHLINK_EINVAL;
2760                 return NULL;
2761         }
2762
2763         // Create a config file on the fly.
2764
2765         uint8_t buf[4096];
2766         packmsg_output_t out = {buf, sizeof(buf)};
2767         packmsg_add_uint32(&out, MESHLINK_CONFIG_VERSION);
2768         packmsg_add_str(&out, mesh->name);
2769         packmsg_add_str(&out, CORE_MESH);
2770
2771         pthread_mutex_lock(&mesh->mutex);
2772
2773         packmsg_add_int32(&out, mesh->self->devclass);
2774         packmsg_add_bool(&out, mesh->self->status.blacklisted);
2775         packmsg_add_bin(&out, ecdsa_get_public_key(mesh->private_key), 32);
2776         packmsg_add_str(&out, mesh->self->canonical_address ? mesh->self->canonical_address : "");
2777
2778         uint32_t count = 0;
2779
2780         for(uint32_t i = 0; i < MAX_RECENT; i++) {
2781                 if(mesh->self->recent[i].sa.sa_family) {
2782                         count++;
2783                 } else {
2784                         break;
2785                 }
2786         }
2787
2788         packmsg_add_array(&out, count);
2789
2790         for(uint32_t i = 0; i < count; i++) {
2791                 packmsg_add_sockaddr(&out, &mesh->self->recent[i]);
2792         }
2793
2794         packmsg_add_int64(&out, 0);
2795         packmsg_add_int64(&out, 0);
2796
2797         pthread_mutex_unlock(&mesh->mutex);
2798
2799         if(!packmsg_output_ok(&out)) {
2800                 logger(mesh, MESHLINK_DEBUG, "Error creating export data\n");
2801                 meshlink_errno = MESHLINK_EINTERNAL;
2802                 return NULL;
2803         }
2804
2805         // Prepare a base64-encoded packmsg array containing our config file
2806
2807         uint32_t len = packmsg_output_size(&out, buf);
2808         uint32_t len2 = ((len + 4) * 4) / 3 + 4;
2809         uint8_t *buf2 = xmalloc(len2);
2810         packmsg_output_t out2 = {buf2, len2};
2811         packmsg_add_array(&out2, 1);
2812         packmsg_add_bin(&out2, buf, packmsg_output_size(&out, buf));
2813
2814         if(!packmsg_output_ok(&out2)) {
2815                 logger(mesh, MESHLINK_DEBUG, "Error creating export data\n");
2816                 meshlink_errno = MESHLINK_EINTERNAL;
2817                 free(buf2);
2818                 return NULL;
2819         }
2820
2821         b64encode_urlsafe(buf2, (char *)buf2, packmsg_output_size(&out2, buf2));
2822
2823         return (char *)buf2;
2824 }
2825
2826 bool meshlink_import(meshlink_handle_t *mesh, const char *data) {
2827         if(!mesh || !data) {
2828                 meshlink_errno = MESHLINK_EINVAL;
2829                 return false;
2830         }
2831
2832         size_t datalen = strlen(data);
2833         uint8_t *buf = xmalloc(datalen);
2834         int buflen = b64decode(data, buf, datalen);
2835
2836         if(!buflen) {
2837                 logger(mesh, MESHLINK_DEBUG, "Invalid data\n");
2838                 meshlink_errno = MESHLINK_EPEER;
2839                 return false;
2840         }
2841
2842         packmsg_input_t in = {buf, buflen};
2843         uint32_t count = packmsg_get_array(&in);
2844
2845         if(!count) {
2846                 logger(mesh, MESHLINK_DEBUG, "Invalid data\n");
2847                 meshlink_errno = MESHLINK_EPEER;
2848                 return false;
2849         }
2850
2851         pthread_mutex_lock(&mesh->mutex);
2852
2853         while(count--) {
2854                 const void *data;
2855                 uint32_t len = packmsg_get_bin_raw(&in, &data);
2856
2857                 if(!len) {
2858                         break;
2859                 }
2860
2861                 packmsg_input_t in2 = {data, len};
2862                 uint32_t version = packmsg_get_uint32(&in2);
2863                 char *name = packmsg_get_str_dup(&in2);
2864
2865                 if(!packmsg_input_ok(&in2) || version != MESHLINK_CONFIG_VERSION || !check_id(name)) {
2866                         free(name);
2867                         packmsg_input_invalidate(&in);
2868                         break;
2869                 }
2870
2871                 if(!check_id(name)) {
2872                         free(name);
2873                         break;
2874                 }
2875
2876                 node_t *n = lookup_node(mesh, name);
2877
2878                 if(n) {
2879                         logger(mesh, MESHLINK_DEBUG, "Node %s already exists, not importing\n", name);
2880                         free(name);
2881                         continue;
2882                 }
2883
2884                 n = new_node();
2885                 n->name = name;
2886
2887                 config_t config = {data, len};
2888
2889                 if(!node_read_from_config(mesh, n, &config)) {
2890                         free_node(n);
2891                         packmsg_input_invalidate(&in);
2892                         break;
2893                 }
2894
2895                 if(!config_write(mesh, "current", n->name, &config, mesh->config_key)) {
2896                         free_node(n);
2897                         return false;
2898                 }
2899
2900                 node_add(mesh, n);
2901         }
2902
2903         pthread_mutex_unlock(&mesh->mutex);
2904
2905         free(buf);
2906
2907         if(!packmsg_done(&in)) {
2908                 logger(mesh, MESHLINK_ERROR, "Invalid data\n");
2909                 meshlink_errno = MESHLINK_EPEER;
2910                 return false;
2911         }
2912
2913         if(!config_sync(mesh, "current")) {
2914                 return false;
2915         }
2916
2917         return true;
2918 }
2919
2920 static bool blacklist(meshlink_handle_t *mesh, node_t *n) {
2921         if(n == mesh->self) {
2922                 logger(mesh, MESHLINK_ERROR, "%s blacklisting itself?\n", n->name);
2923                 meshlink_errno = MESHLINK_EINVAL;
2924                 return false;
2925         }
2926
2927         if(n->status.blacklisted) {
2928                 logger(mesh, MESHLINK_DEBUG, "Node %s already blacklisted\n", n->name);
2929                 return true;
2930         }
2931
2932         n->status.blacklisted = true;
2933
2934         /* Immediately shut down any connections we have with the blacklisted node.
2935          * We can't call terminate_connection(), because we might be called from a callback function.
2936          */
2937         for list_each(connection_t, c, mesh->connections) {
2938                 if(c->node == n) {
2939                         shutdown(c->socket, SHUT_RDWR);
2940                 }
2941         }
2942
2943         utcp_abort_all_connections(n->utcp);
2944
2945         n->mtu = 0;
2946         n->minmtu = 0;
2947         n->maxmtu = MTU;
2948         n->mtuprobes = 0;
2949         n->status.udp_confirmed = false;
2950
2951         /* Graph updates will suppress status updates for blacklisted nodes, so we need to
2952          * manually call the status callback if necessary.
2953          */
2954         if(n->status.reachable && mesh->node_status_cb) {
2955                 mesh->node_status_cb(mesh, (meshlink_node_t *)n, false);
2956         }
2957
2958         return node_write_config(mesh, n) && config_sync(mesh, "current");
2959 }
2960
2961 bool meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node) {
2962         if(!mesh || !node) {
2963                 meshlink_errno = MESHLINK_EINVAL;
2964                 return false;
2965         }
2966
2967         pthread_mutex_lock(&mesh->mutex);
2968
2969         if(!blacklist(mesh, (node_t *)node)) {
2970                 pthread_mutex_unlock(&mesh->mutex);
2971                 return false;
2972         }
2973
2974         pthread_mutex_unlock(&mesh->mutex);
2975
2976         logger(mesh, MESHLINK_DEBUG, "Blacklisted %s.\n", node->name);
2977         return true;
2978 }
2979
2980 bool meshlink_blacklist_by_name(meshlink_handle_t *mesh, const char *name) {
2981         if(!mesh || !name) {
2982                 meshlink_errno = MESHLINK_EINVAL;
2983                 return false;
2984         }
2985
2986         pthread_mutex_lock(&mesh->mutex);
2987
2988         node_t *n = lookup_node(mesh, (char *)name);
2989
2990         if(!n) {
2991                 n = new_node();
2992                 n->name = xstrdup(name);
2993                 node_add(mesh, n);
2994         }
2995
2996         if(!blacklist(mesh, (node_t *)n)) {
2997                 pthread_mutex_unlock(&mesh->mutex);
2998                 return false;
2999         }
3000
3001         pthread_mutex_unlock(&mesh->mutex);
3002
3003         logger(mesh, MESHLINK_DEBUG, "Blacklisted %s.\n", name);
3004         return true;
3005 }
3006
3007 static bool whitelist(meshlink_handle_t *mesh, node_t *n) {
3008         if(n == mesh->self) {
3009                 logger(mesh, MESHLINK_ERROR, "%s whitelisting itself?\n", n->name);
3010                 meshlink_errno = MESHLINK_EINVAL;
3011                 return false;
3012         }
3013
3014         if(!n->status.blacklisted) {
3015                 logger(mesh, MESHLINK_DEBUG, "Node %s was already whitelisted\n", n->name);
3016                 return true;
3017         }
3018
3019         n->status.blacklisted = false;
3020
3021         if(n->status.reachable) {
3022                 update_node_status(mesh, n);
3023         }
3024
3025         return node_write_config(mesh, n) && config_sync(mesh, "current");
3026 }
3027
3028 bool meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) {
3029         if(!mesh || !node) {
3030                 meshlink_errno = MESHLINK_EINVAL;
3031                 return false;
3032         }
3033
3034         pthread_mutex_lock(&mesh->mutex);
3035
3036         if(!whitelist(mesh, (node_t *)node)) {
3037                 pthread_mutex_unlock(&mesh->mutex);
3038                 return false;
3039         }
3040
3041         pthread_mutex_unlock(&mesh->mutex);
3042
3043         logger(mesh, MESHLINK_DEBUG, "Whitelisted %s.\n", node->name);
3044         return true;
3045 }
3046
3047 bool meshlink_whitelist_by_name(meshlink_handle_t *mesh, const char *name) {
3048         if(!mesh || !name) {
3049                 meshlink_errno = MESHLINK_EINVAL;
3050                 return false;
3051         }
3052
3053         pthread_mutex_lock(&mesh->mutex);
3054
3055         node_t *n = lookup_node(mesh, (char *)name);
3056
3057         if(!n) {
3058                 n = new_node();
3059                 n->name = xstrdup(name);
3060                 node_add(mesh, n);
3061         }
3062
3063         if(!whitelist(mesh, (node_t *)n)) {
3064                 pthread_mutex_unlock(&mesh->mutex);
3065                 return false;
3066         }
3067
3068         pthread_mutex_unlock(&mesh->mutex);
3069
3070         logger(mesh, MESHLINK_DEBUG, "Whitelisted %s.\n", name);
3071         return true;
3072 }
3073
3074 void meshlink_set_default_blacklist(meshlink_handle_t *mesh, bool blacklist) {
3075         mesh->default_blacklist = blacklist;
3076 }
3077
3078 bool meshlink_forget_node(meshlink_handle_t *mesh, meshlink_node_t *node) {
3079         if(!mesh || !node) {
3080                 meshlink_errno = MESHLINK_EINVAL;
3081                 return false;
3082         }
3083
3084         node_t *n = (node_t *)node;
3085
3086         pthread_mutex_lock(&mesh->mutex);
3087
3088         /* Check that the node is not reachable */
3089         if(n->status.reachable || n->connection) {
3090                 pthread_mutex_unlock(&mesh->mutex);
3091                 logger(mesh, MESHLINK_WARNING, "Could not forget %s: still reachable", n->name);
3092                 return false;
3093         }
3094
3095         /* Check that we don't have any active UTCP connections */
3096         if(n->utcp && utcp_is_active(n->utcp)) {
3097                 pthread_mutex_unlock(&mesh->mutex);
3098                 logger(mesh, MESHLINK_WARNING, "Could not forget %s: active UTCP connections", n->name);
3099                 return false;
3100         }
3101
3102         /* Check that we have no active connections to this node */
3103         for list_each(connection_t, c, mesh->connections) {
3104                 if(c->node == n) {
3105                         pthread_mutex_unlock(&mesh->mutex);
3106                         logger(mesh, MESHLINK_WARNING, "Could not forget %s: active connection", n->name);
3107                         return false;
3108                 }
3109         }
3110
3111         /* Remove any pending outgoings to this node */
3112         if(mesh->outgoings) {
3113                 for list_each(outgoing_t, outgoing, mesh->outgoings) {
3114                         if(outgoing->node == n) {
3115                                 list_delete_node(mesh->outgoings, node);
3116                         }
3117                 }
3118         }
3119
3120         /* Delete the config file for this node */
3121         if(!config_delete(mesh, "current", n->name)) {
3122                 pthread_mutex_unlock(&mesh->mutex);
3123                 return false;
3124         }
3125
3126         /* Delete the node struct and any remaining edges referencing this node */
3127         node_del(mesh, n);
3128
3129         pthread_mutex_unlock(&mesh->mutex);
3130
3131         return config_sync(mesh, "current");
3132 }
3133
3134 /* Hint that a hostname may be found at an address
3135  * See header file for detailed comment.
3136  */
3137 void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const struct sockaddr *addr) {
3138         if(!mesh || !node || !addr) {
3139                 meshlink_errno = EINVAL;
3140                 return;
3141         }
3142
3143         pthread_mutex_lock(&mesh->mutex);
3144
3145         node_t *n = (node_t *)node;
3146
3147         if(node_add_recent_address(mesh, n, (sockaddr_t *)addr)) {
3148                 if(!node_write_config(mesh, n)) {
3149                         logger(mesh, MESHLINK_DEBUG, "Could not update %s\n", n->name);
3150                 }
3151         }
3152
3153         pthread_mutex_unlock(&mesh->mutex);
3154         // @TODO do we want to fire off a connection attempt right away?
3155 }
3156
3157 static bool channel_pre_accept(struct utcp *utcp, uint16_t port) {
3158         (void)port;
3159         node_t *n = utcp->priv;
3160         meshlink_handle_t *mesh = n->mesh;
3161         return mesh->channel_accept_cb;
3162 }
3163
3164 static void aio_signal(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_aio_buffer_t *aio) {
3165         if(aio->data) {
3166                 if(aio->cb.buffer) {
3167                         aio->cb.buffer(mesh, channel, aio->data, aio->len, aio->priv);
3168                 }
3169         } else {
3170                 if(aio->cb.fd) {
3171                         aio->cb.fd(mesh, channel, aio->fd, aio->done, aio->priv);
3172                 }
3173         }
3174 }
3175
3176 static ssize_t channel_recv(struct utcp_connection *connection, const void *data, size_t len) {
3177         meshlink_channel_t *channel = connection->priv;
3178
3179         if(!channel) {
3180                 abort();
3181         }
3182
3183         node_t *n = channel->node;
3184         meshlink_handle_t *mesh = n->mesh;
3185
3186         if(n->status.destroyed) {
3187                 meshlink_channel_close(mesh, channel);
3188                 return len;
3189         }
3190
3191         const char *p = data;
3192         size_t left = len;
3193
3194         while(channel->aio_receive) {
3195                 meshlink_aio_buffer_t *aio = channel->aio_receive;
3196                 size_t todo = aio->len - aio->done;
3197
3198                 if(todo > left) {
3199                         todo = left;
3200                 }
3201
3202                 if(aio->data) {
3203                         memcpy((char *)aio->data + aio->done, p, todo);
3204                 } else {
3205                         ssize_t result = write(aio->fd, p, todo);
3206
3207                         if(result > 0) {
3208                                 todo = result;
3209                         }
3210                 }
3211
3212                 aio->done += todo;
3213
3214                 if(aio->done == aio->len) {
3215                         channel->aio_receive = aio->next;
3216                         aio_signal(mesh, channel, aio);
3217                         free(aio);
3218                 }
3219
3220                 p += todo;
3221                 left -= todo;
3222
3223                 if(!left && len) {
3224                         return len;
3225                 }
3226         }
3227
3228         if(channel->receive_cb) {
3229                 channel->receive_cb(mesh, channel, p, left);
3230         }
3231
3232         return len;
3233 }
3234
3235 static void channel_accept(struct utcp_connection *utcp_connection, uint16_t port) {
3236         node_t *n = utcp_connection->utcp->priv;
3237
3238         if(!n) {
3239                 abort();
3240         }
3241
3242         meshlink_handle_t *mesh = n->mesh;
3243
3244         if(!mesh->channel_accept_cb) {
3245                 return;
3246         }
3247
3248         meshlink_channel_t *channel = xzalloc(sizeof(*channel));
3249         channel->node = n;
3250         channel->c = utcp_connection;
3251
3252         if(mesh->channel_accept_cb(mesh, channel, port, NULL, 0)) {
3253                 utcp_accept(utcp_connection, channel_recv, channel);
3254         } else {
3255                 free(channel);
3256         }
3257 }
3258
3259 static ssize_t channel_send(struct utcp *utcp, const void *data, size_t len) {
3260         node_t *n = utcp->priv;
3261
3262         if(n->status.destroyed) {
3263                 return -1;
3264         }
3265
3266         meshlink_handle_t *mesh = n->mesh;
3267         return meshlink_send(mesh, (meshlink_node_t *)n, data, len) ? (ssize_t)len : -1;
3268 }
3269
3270 void meshlink_set_channel_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_receive_cb_t cb) {
3271         if(!mesh || !channel) {
3272                 meshlink_errno = MESHLINK_EINVAL;
3273                 return;
3274         }
3275
3276         channel->receive_cb = cb;
3277 }
3278
3279 static void channel_receive(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
3280         (void)mesh;
3281         node_t *n = (node_t *)source;
3282
3283         if(!n->utcp) {
3284                 abort();
3285         }
3286
3287         utcp_recv(n->utcp, data, len);
3288 }
3289
3290 static void channel_poll(struct utcp_connection *connection, size_t len) {
3291         meshlink_channel_t *channel = connection->priv;
3292
3293         if(!channel) {
3294                 abort();
3295         }
3296
3297         node_t *n = channel->node;
3298         meshlink_handle_t *mesh = n->mesh;
3299         meshlink_aio_buffer_t *aio = channel->aio_send;
3300
3301         if(aio) {
3302                 /* We at least one AIO buffer. Send as much as possible form the first buffer. */
3303                 size_t left = aio->len - aio->done;
3304                 ssize_t sent;
3305
3306                 if(len > left) {
3307                         len = left;
3308                 }
3309
3310                 if(aio->data) {
3311                         sent = utcp_send(connection, (char *)aio->data + aio->done, len);
3312                 } else {
3313                         char buf[65536];
3314                         size_t todo = utcp_get_sndbuf_free(connection);
3315
3316                         if(todo > left) {
3317                                 todo = left;
3318                         }
3319
3320                         if(todo > sizeof(buf)) {
3321                                 todo = sizeof(buf);
3322                         }
3323
3324                         ssize_t result = read(aio->fd, buf, todo);
3325
3326                         if(result > 0) {
3327                                 sent = utcp_send(connection, buf, result);
3328                         } else {
3329                                 sent = result;
3330                         }
3331                 }
3332
3333                 if(sent >= 0) {
3334                         aio->done += sent;
3335                 }
3336
3337                 /* If the buffer is now completely sent, call the callback and dispose of it. */
3338                 if(aio->done >= aio->len) {
3339                         channel->aio_send = aio->next;
3340                         aio_signal(mesh, channel, aio);
3341                         free(aio);
3342                 }
3343         } else {
3344                 if(channel->poll_cb) {
3345                         channel->poll_cb(mesh, channel, len);
3346                 } else {
3347                         utcp_set_poll_cb(connection, NULL);
3348                 }
3349         }
3350 }
3351
3352 void meshlink_set_channel_poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_poll_cb_t cb) {
3353         if(!mesh || !channel) {
3354                 meshlink_errno = MESHLINK_EINVAL;
3355                 return;
3356         }
3357
3358         pthread_mutex_lock(&mesh->mutex);
3359         channel->poll_cb = cb;
3360         utcp_set_poll_cb(channel->c, (cb || channel->aio_send) ? channel_poll : NULL);
3361         pthread_mutex_unlock(&mesh->mutex);
3362 }
3363
3364 void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_accept_cb_t cb) {
3365         if(!mesh) {
3366                 meshlink_errno = MESHLINK_EINVAL;
3367                 return;
3368         }
3369
3370         pthread_mutex_lock(&mesh->mutex);
3371         mesh->channel_accept_cb = cb;
3372         mesh->receive_cb = channel_receive;
3373
3374         for splay_each(node_t, n, mesh->nodes) {
3375                 if(!n->utcp && n != mesh->self) {
3376                         n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
3377                 }
3378         }
3379
3380         pthread_mutex_unlock(&mesh->mutex);
3381 }
3382
3383 void meshlink_set_channel_sndbuf(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t size) {
3384         (void)mesh;
3385
3386         if(!channel) {
3387                 meshlink_errno = MESHLINK_EINVAL;
3388                 return;
3389         }
3390
3391         pthread_mutex_lock(&mesh->mutex);
3392         utcp_set_sndbuf(channel->c, size);
3393         pthread_mutex_unlock(&mesh->mutex);
3394 }
3395
3396 void meshlink_set_channel_rcvbuf(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t size) {
3397         (void)mesh;
3398
3399         if(!channel) {
3400                 meshlink_errno = MESHLINK_EINVAL;
3401                 return;
3402         }
3403
3404         pthread_mutex_lock(&mesh->mutex);
3405         utcp_set_rcvbuf(channel->c, size);
3406         pthread_mutex_unlock(&mesh->mutex);
3407 }
3408
3409 meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len, uint32_t flags) {
3410         if(data && len) {
3411                 abort();        // TODO: handle non-NULL data
3412         }
3413
3414         if(!mesh || !node) {
3415                 meshlink_errno = MESHLINK_EINVAL;
3416                 return NULL;
3417         }
3418
3419         pthread_mutex_lock(&mesh->mutex);
3420
3421         node_t *n = (node_t *)node;
3422
3423         if(!n->utcp) {
3424                 n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
3425                 mesh->receive_cb = channel_receive;
3426
3427                 if(!n->utcp) {
3428                         meshlink_errno = errno == ENOMEM ? MESHLINK_ENOMEM : MESHLINK_EINTERNAL;
3429                         pthread_mutex_unlock(&mesh->mutex);
3430                         return NULL;
3431                 }
3432         }
3433
3434         if(n->status.blacklisted) {
3435                 logger(mesh, MESHLINK_ERROR, "Cannot open a channel with blacklisted node\n");
3436                 meshlink_errno = MESHLINK_EBLACKLISTED;
3437                 pthread_mutex_unlock(&mesh->mutex);
3438                 return NULL;
3439         }
3440
3441         meshlink_channel_t *channel = xzalloc(sizeof(*channel));
3442         channel->node = n;
3443         channel->receive_cb = cb;
3444
3445         if(data && !len) {
3446                 channel->priv = (void *)data;
3447         }
3448
3449         channel->c = utcp_connect_ex(n->utcp, port, channel_recv, channel, flags);
3450
3451         pthread_mutex_unlock(&mesh->mutex);
3452
3453         if(!channel->c) {
3454                 meshlink_errno = errno == ENOMEM ? MESHLINK_ENOMEM : MESHLINK_EINTERNAL;
3455                 free(channel);
3456                 return NULL;
3457         }
3458
3459         return channel;
3460 }
3461
3462 meshlink_channel_t *meshlink_channel_open(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len) {
3463         return meshlink_channel_open_ex(mesh, node, port, cb, data, len, MESHLINK_CHANNEL_TCP);
3464 }
3465
3466 void meshlink_channel_shutdown(meshlink_handle_t *mesh, meshlink_channel_t *channel, int direction) {
3467         if(!mesh || !channel) {
3468                 meshlink_errno = MESHLINK_EINVAL;
3469                 return;
3470         }
3471
3472         pthread_mutex_lock(&mesh->mutex);
3473         utcp_shutdown(channel->c, direction);
3474         pthread_mutex_unlock(&mesh->mutex);
3475 }
3476
3477 void meshlink_channel_close(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
3478         if(!mesh || !channel) {
3479                 meshlink_errno = MESHLINK_EINVAL;
3480                 return;
3481         }
3482
3483         pthread_mutex_lock(&mesh->mutex);
3484
3485         utcp_close(channel->c);
3486
3487         /* Clean up any outstanding AIO buffers. */
3488         for(meshlink_aio_buffer_t *aio = channel->aio_send, *next; aio; aio = next) {
3489                 next = aio->next;
3490                 aio_signal(mesh, channel, aio);
3491                 free(aio);
3492         }
3493
3494         for(meshlink_aio_buffer_t *aio = channel->aio_receive, *next; aio; aio = next) {
3495                 next = aio->next;
3496                 aio_signal(mesh, channel, aio);
3497                 free(aio);
3498         }
3499
3500         pthread_mutex_unlock(&mesh->mutex);
3501
3502         free(channel);
3503 }
3504
3505 ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
3506         if(!mesh || !channel) {
3507                 meshlink_errno = MESHLINK_EINVAL;
3508                 return -1;
3509         }
3510
3511         if(!len) {
3512                 return 0;
3513         }
3514
3515         if(!data) {
3516                 meshlink_errno = MESHLINK_EINVAL;
3517                 return -1;
3518         }
3519
3520         // TODO: more finegrained locking.
3521         // Ideally we want to put the data into the UTCP connection's send buffer.
3522         // Then, preferably only if there is room in the receiver window,
3523         // kick the meshlink thread to go send packets.
3524
3525         ssize_t retval;
3526
3527         pthread_mutex_lock(&mesh->mutex);
3528
3529         /* Disallow direct calls to utcp_send() while we still have AIO active. */
3530         if(channel->aio_send) {
3531                 retval = 0;
3532         } else {
3533                 retval = utcp_send(channel->c, data, len);
3534         }
3535
3536         pthread_mutex_unlock(&mesh->mutex);
3537
3538         if(retval < 0) {
3539                 meshlink_errno = MESHLINK_ENETWORK;
3540         }
3541
3542         return retval;
3543 }
3544
3545 bool meshlink_channel_aio_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, meshlink_aio_cb_t cb, void *priv) {
3546         if(!mesh || !channel) {
3547                 meshlink_errno = MESHLINK_EINVAL;
3548                 return false;
3549         }
3550
3551         if(!len || !data) {
3552                 meshlink_errno = MESHLINK_EINVAL;
3553                 return false;
3554         }
3555
3556         meshlink_aio_buffer_t *aio = xzalloc(sizeof(*aio));
3557         aio->data = data;
3558         aio->len = len;
3559         aio->cb.buffer = cb;
3560         aio->priv = priv;
3561
3562         pthread_mutex_lock(&mesh->mutex);
3563
3564         /* Append the AIO buffer descriptor to the end of the chain */
3565         meshlink_aio_buffer_t **p = &channel->aio_send;
3566
3567         while(*p) {
3568                 p = &(*p)->next;
3569         }
3570
3571         *p = aio;
3572
3573         /* Ensure the poll callback is set, and call it right now to push data if possible */
3574         utcp_set_poll_cb(channel->c, channel_poll);
3575         channel_poll(channel->c, len);
3576
3577         pthread_mutex_unlock(&mesh->mutex);
3578
3579         return true;
3580 }
3581
3582 bool meshlink_channel_aio_fd_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, int fd, size_t len, meshlink_aio_fd_cb_t cb, void *priv) {
3583         if(!mesh || !channel) {
3584                 meshlink_errno = MESHLINK_EINVAL;
3585                 return false;
3586         }
3587
3588         if(!len || fd == -1) {
3589                 meshlink_errno = MESHLINK_EINVAL;
3590                 return false;
3591         }
3592
3593         meshlink_aio_buffer_t *aio = xzalloc(sizeof(*aio));
3594         aio->fd = fd;
3595         aio->len = len;
3596         aio->cb.fd = cb;
3597         aio->priv = priv;
3598
3599         pthread_mutex_lock(&mesh->mutex);
3600
3601         /* Append the AIO buffer descriptor to the end of the chain */
3602         meshlink_aio_buffer_t **p = &channel->aio_send;
3603
3604         while(*p) {
3605                 p = &(*p)->next;
3606         }
3607
3608         *p = aio;
3609
3610         /* Ensure the poll callback is set, and call it right now to push data if possible */
3611         utcp_set_poll_cb(channel->c, channel_poll);
3612         channel_poll(channel->c, len);
3613
3614         pthread_mutex_unlock(&mesh->mutex);
3615
3616         return true;
3617 }
3618
3619 bool meshlink_channel_aio_receive(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, meshlink_aio_cb_t cb, void *priv) {
3620         if(!mesh || !channel) {
3621                 meshlink_errno = MESHLINK_EINVAL;
3622                 return false;
3623         }
3624
3625         if(!len || !data) {
3626                 meshlink_errno = MESHLINK_EINVAL;
3627                 return false;
3628         }
3629
3630         meshlink_aio_buffer_t *aio = xzalloc(sizeof(*aio));
3631         aio->data = data;
3632         aio->len = len;
3633         aio->cb.buffer = cb;
3634         aio->priv = priv;
3635
3636         pthread_mutex_lock(&mesh->mutex);
3637
3638         /* Append the AIO buffer descriptor to the end of the chain */
3639         meshlink_aio_buffer_t **p = &channel->aio_receive;
3640
3641         while(*p) {
3642                 p = &(*p)->next;
3643         }
3644
3645         *p = aio;
3646
3647         pthread_mutex_unlock(&mesh->mutex);
3648
3649         return true;
3650 }
3651
3652 bool meshlink_channel_aio_fd_receive(meshlink_handle_t *mesh, meshlink_channel_t *channel, int fd, size_t len, meshlink_aio_fd_cb_t cb, void *priv) {
3653         if(!mesh || !channel) {
3654                 meshlink_errno = MESHLINK_EINVAL;
3655                 return false;
3656         }
3657
3658         if(!len || fd == -1) {
3659                 meshlink_errno = MESHLINK_EINVAL;
3660                 return false;
3661         }
3662
3663         meshlink_aio_buffer_t *aio = xzalloc(sizeof(*aio));
3664         aio->fd = fd;
3665         aio->len = len;
3666         aio->cb.fd = cb;
3667         aio->priv = priv;
3668
3669         pthread_mutex_lock(&mesh->mutex);
3670
3671         /* Append the AIO buffer descriptor to the end of the chain */
3672         meshlink_aio_buffer_t **p = &channel->aio_receive;
3673
3674         while(*p) {
3675                 p = &(*p)->next;
3676         }
3677
3678         *p = aio;
3679
3680         pthread_mutex_unlock(&mesh->mutex);
3681
3682         return true;
3683 }
3684
3685 uint32_t meshlink_channel_get_flags(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
3686         if(!mesh || !channel) {
3687                 meshlink_errno = MESHLINK_EINVAL;
3688                 return -1;
3689         }
3690
3691         return channel->c->flags;
3692 }
3693
3694 size_t meshlink_channel_get_sendq(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
3695         if(!mesh || !channel) {
3696                 meshlink_errno = MESHLINK_EINVAL;
3697                 return -1;
3698         }
3699
3700         return utcp_get_sendq(channel->c);
3701 }
3702
3703 size_t meshlink_channel_get_recvq(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
3704         if(!mesh || !channel) {
3705                 meshlink_errno = MESHLINK_EINVAL;
3706                 return -1;
3707         }
3708
3709         return utcp_get_recvq(channel->c);
3710 }
3711
3712 void meshlink_set_node_channel_timeout(meshlink_handle_t *mesh, meshlink_node_t *node, int timeout) {
3713         if(!mesh || !node) {
3714                 meshlink_errno = MESHLINK_EINVAL;
3715                 return;
3716         }
3717
3718         node_t *n = (node_t *)node;
3719
3720         pthread_mutex_lock(&mesh->mutex);
3721
3722         if(!n->utcp) {
3723                 n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
3724         }
3725
3726         utcp_set_user_timeout(n->utcp, timeout);
3727
3728         pthread_mutex_unlock(&mesh->mutex);
3729 }
3730
3731 void update_node_status(meshlink_handle_t *mesh, node_t *n) {
3732         if(n->status.reachable && mesh->channel_accept_cb && !n->utcp) {
3733                 n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
3734         }
3735
3736         if(mesh->node_status_cb) {
3737                 mesh->node_status_cb(mesh, (meshlink_node_t *)n, n->status.reachable && !n->status.blacklisted);
3738         }
3739
3740         if(mesh->node_pmtu_cb) {
3741                 mesh->node_pmtu_cb(mesh, (meshlink_node_t *)n, n->minmtu);
3742         }
3743 }
3744
3745 void update_node_pmtu(meshlink_handle_t *mesh, node_t *n) {
3746         if(mesh->node_pmtu_cb && !n->status.blacklisted) {
3747                 mesh->node_pmtu_cb(mesh, (meshlink_node_t *)n, n->minmtu);
3748         }
3749 }
3750
3751 void handle_duplicate_node(meshlink_handle_t *mesh, node_t *n) {
3752         if(!mesh->node_duplicate_cb || n->status.duplicate) {
3753                 return;
3754         }
3755
3756         n->status.duplicate = true;
3757         mesh->node_duplicate_cb(mesh, (meshlink_node_t *)n);
3758 }
3759
3760 void meshlink_enable_discovery(meshlink_handle_t *mesh, bool enable) {
3761 #if HAVE_CATTA
3762
3763         if(!mesh) {
3764                 meshlink_errno = MESHLINK_EINVAL;
3765                 return;
3766         }
3767
3768         pthread_mutex_lock(&mesh->mutex);
3769
3770         if(mesh->discovery == enable) {
3771                 goto end;
3772         }
3773
3774         if(mesh->threadstarted) {
3775                 if(enable) {
3776                         discovery_start(mesh);
3777                 } else {
3778                         discovery_stop(mesh);
3779                 }
3780         }
3781
3782         mesh->discovery = enable;
3783
3784 end:
3785         pthread_mutex_unlock(&mesh->mutex);
3786 #else
3787         (void)mesh;
3788         (void)enable;
3789         meshlink_errno = MESHLINK_ENOTSUP;
3790 #endif
3791 }
3792
3793 void meshlink_set_dev_class_timeouts(meshlink_handle_t *mesh, dev_class_t devclass, int pinginterval, int pingtimeout) {
3794         if(!mesh || devclass < 0 || devclass >= DEV_CLASS_COUNT) {
3795                 meshlink_errno = EINVAL;
3796                 return;
3797         }
3798
3799         if(pinginterval < 1 || pingtimeout < 1 || pingtimeout > pinginterval) {
3800                 meshlink_errno = EINVAL;
3801                 return;
3802         }
3803
3804         pthread_mutex_lock(&mesh->mutex);
3805         mesh->dev_class_traits[devclass].pinginterval = pinginterval;
3806         mesh->dev_class_traits[devclass].pingtimeout = pingtimeout;
3807         pthread_mutex_unlock(&mesh->mutex);
3808 }
3809
3810 void meshlink_set_dev_class_fast_retry_period(meshlink_handle_t *mesh, dev_class_t devclass, int fast_retry_period) {
3811         if(!mesh || devclass < 0 || devclass >= DEV_CLASS_COUNT) {
3812                 meshlink_errno = EINVAL;
3813                 return;
3814         }
3815
3816         if(fast_retry_period < 0) {
3817                 meshlink_errno = EINVAL;
3818                 return;
3819         }
3820
3821         pthread_mutex_lock(&mesh->mutex);
3822         mesh->dev_class_traits[devclass].fast_retry_period = fast_retry_period;
3823         pthread_mutex_unlock(&mesh->mutex);
3824 }
3825
3826 void handle_network_change(meshlink_handle_t *mesh, bool online) {
3827         (void)online;
3828
3829         if(!mesh->connections || !mesh->loop.running) {
3830                 return;
3831         }
3832
3833         retry(mesh);
3834 }
3835
3836 void call_error_cb(meshlink_handle_t *mesh, meshlink_errno_t meshlink_errno) {
3837         // We should only call the callback function if we are in the background thread.
3838         if(!mesh->error_cb) {
3839                 return;
3840         }
3841
3842         if(!mesh->threadstarted) {
3843                 return;
3844         }
3845
3846         if(mesh->thread == pthread_self()) {
3847                 mesh->error_cb(mesh, meshlink_errno);
3848         }
3849 }
3850
3851
3852 static void __attribute__((constructor)) meshlink_init(void) {
3853         crypto_init();
3854 }
3855
3856 static void __attribute__((destructor)) meshlink_exit(void) {
3857         crypto_exit();
3858 }