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