]> git.meshlink.io Git - meshlink/blob - src/meshlink.c
Added meshlink_submesh_open
[meshlink] / src / meshlink.c
1 /*
2     meshlink.c -- Implementation of the MeshLink API.
3     Copyright (C) 2014-2018 Guus Sliepen <guus@meshlink.io>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 #define VAR_SERVER 1    /* Should be in meshlink.conf */
20 #define VAR_HOST 2      /* Can be in host config file */
21 #define VAR_MULTIPLE 4  /* Multiple statements allowed */
22 #define VAR_OBSOLETE 8  /* Should not be used anymore */
23 #define VAR_SAFE 16     /* Variable is safe when accepting invitations */
24 #define MAX_ADDRESS_LENGTH 45 /* Max length of an (IPv6) address */
25 #define MAX_PORT_LENGTH 5 /* 0-65535 */
26 typedef struct {
27         const char *name;
28         int type;
29 } var_t;
30
31 #include "system.h"
32 #include <pthread.h>
33
34 #include "crypto.h"
35 #include "ecdsagen.h"
36 #include "logger.h"
37 #include "meshlink_internal.h"
38 #include "netutl.h"
39 #include "node.h"
40 #include "submesh.h"
41 #include "protocol.h"
42 #include "route.h"
43 #include "sockaddr.h"
44 #include "utils.h"
45 #include "xalloc.h"
46 #include "ed25519/sha512.h"
47 #include "discovery.h"
48
49 #ifndef MSG_NOSIGNAL
50 #define MSG_NOSIGNAL 0
51 #endif
52
53 __thread meshlink_errno_t meshlink_errno;
54 meshlink_log_cb_t global_log_cb;
55 meshlink_log_level_t global_log_level;
56
57 //TODO: this can go away completely
58 const var_t variables[] = {
59         /* Server configuration */
60         {"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE},
61         {"Name", VAR_SERVER},
62         /* Host configuration */
63         {"CanonicalAddress", VAR_HOST},
64         {"Address", VAR_HOST | VAR_MULTIPLE},
65         {"ECDSAPublicKey", VAR_HOST},
66         {"Port", VAR_HOST},
67         {NULL, 0}
68 };
69
70 static bool fcopy(FILE *out, const char *filename) {
71         FILE *in = fopen(filename, "r");
72
73         if(!in) {
74                 logger(NULL, MESHLINK_ERROR, "Could not open %s: %s\n", filename, strerror(errno));
75                 return false;
76         }
77
78         char buf[1024];
79         size_t len;
80
81         while((len = fread(buf, 1, sizeof(buf), in))) {
82                 fwrite(buf, len, 1, out);
83         }
84
85         fclose(in);
86         return true;
87 }
88
89 static int rstrip(char *value) {
90         int len = strlen(value);
91
92         while(len && strchr("\t\r\n ", value[len - 1])) {
93                 value[--len] = 0;
94         }
95
96         return len;
97 }
98
99 static void scan_for_canonical_address(const char *filename, char **hostname, char **port) {
100         char line[4096];
101
102         if(!filename || (*hostname && *port)) {
103                 return;
104         }
105
106         FILE *f = fopen(filename, "r");
107
108         if(!f) {
109                 return;
110         }
111
112         while(fgets(line, sizeof(line), f)) {
113                 if(!rstrip(line)) {
114                         continue;
115                 }
116
117                 char *p = line, *q;
118                 p += strcspn(p, "\t =");
119
120                 if(!*p) {
121                         continue;
122                 }
123
124                 q = p + strspn(p, "\t ");
125
126                 if(*q == '=') {
127                         q += 1 + strspn(q + 1, "\t ");
128                 }
129
130                 // q is now pointing to the hostname
131                 *p = 0;
132                 p = q + strcspn(q, "\t ");
133
134                 if(*p) {
135                         *p++ = 0;
136                 }
137
138                 p += strspn(p, "\t ");
139                 p[strcspn(p, "\t ")] = 0;
140                 // p is now pointing to the port, if present
141
142                 if(!*port && !strcasecmp(line, "Port")) {
143                         *port = xstrdup(q);
144                 } else if(!strcasecmp(line, "CanonicalAddress")) {
145                         *hostname = xstrdup(q);
146
147                         if(*p) {
148                                 free(*port);
149                                 *port = xstrdup(p);
150                         }
151                 }
152
153                 if(*hostname && *port) {
154                         break;
155                 }
156         }
157
158         fclose(f);
159 }
160
161 static bool is_valid_hostname(const char *hostname) {
162         if(!*hostname) {
163                 return false;
164         }
165
166         for(const char *p = hostname; *p; p++) {
167                 if(!(isalnum(*p) || *p == '-' || *p == '.' || *p == ':')) {
168                         return false;
169                 }
170         }
171
172         return true;
173 }
174
175 static bool is_valid_port(const char *port) {
176         if(!*port) {
177                 return false;
178         }
179
180         if(isdigit(*port)) {
181                 char *end;
182                 unsigned long int result = strtoul(port, &end, 10);
183                 return result && result < 65536 && !*end;
184         }
185
186         for(const char *p = port; *p; p++) {
187                 if(!(isalnum(*p) || *p == '-')) {
188                         return false;
189                 }
190         }
191
192         return true;
193 }
194
195 static void set_timeout(int sock, int timeout) {
196 #ifdef _WIN32
197         DWORD tv = timeout;
198 #else
199         struct timeval tv;
200         tv.tv_sec = timeout / 1000;
201         tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
202 #endif
203         setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
204         setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
205 }
206
207 struct socket_in_netns_params {
208         int domain;
209         int type;
210         int protocol;
211         int netns;
212         int fd;
213 };
214
215 static void *socket_in_netns_thread(void *arg) {
216         struct socket_in_netns_params *params = arg;
217
218         if(setns(params->netns, CLONE_NEWNET) == -1) {
219                 meshlink_errno = MESHLINK_EINVAL;
220         } else {
221                 params->fd = socket(params->domain, params->type, params->protocol);
222         }
223
224         return NULL;
225 }
226
227 static int socket_in_netns(int domain, int type, int protocol, int netns) {
228         if(netns == -1) {
229                 return socket(domain, type, protocol);
230         }
231
232         struct socket_in_netns_params params = {domain, type, protocol, netns, -1};
233
234         pthread_t thr;
235
236         if(pthread_create(&thr, NULL, socket_in_netns_thread, &params) == 0) {
237                 pthread_join(thr, NULL);
238         }
239
240         return params.fd;
241 }
242
243 // Find out what local address a socket would use if we connect to the given address.
244 // We do this using connect() on a UDP socket, so the kernel has to resolve the address
245 // of both endpoints, but this will actually not send any UDP packet.
246 static bool getlocaladdrname(char *destaddr, char *host, socklen_t hostlen, int netns) {
247         struct addrinfo *rai = NULL;
248         const struct addrinfo hint = {
249                 .ai_family = AF_UNSPEC,
250                 .ai_socktype = SOCK_DGRAM,
251                 .ai_protocol = IPPROTO_UDP,
252         };
253
254         if(getaddrinfo(destaddr, "80", &hint, &rai) || !rai) {
255                 return false;
256         }
257
258         int sock = socket_in_netns(rai->ai_family, rai->ai_socktype, rai->ai_protocol, netns);
259
260         if(sock == -1) {
261                 freeaddrinfo(rai);
262                 return false;
263         }
264
265         if(connect(sock, rai->ai_addr, rai->ai_addrlen) && !sockwouldblock(errno)) {
266                 closesocket(sock);
267                 freeaddrinfo(rai);
268                 return false;
269         }
270
271         freeaddrinfo(rai);
272
273         struct sockaddr_storage sn;
274         socklen_t sl = sizeof(sn);
275
276         if(getsockname(sock, (struct sockaddr *)&sn, &sl)) {
277                 closesocket(sock);
278                 return false;
279         }
280
281         closesocket(sock);
282
283         if(getnameinfo((struct sockaddr *)&sn, sl, host, hostlen, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV)) {
284                 return false;
285         }
286
287         return true;
288 }
289
290 char *meshlink_get_external_address(meshlink_handle_t *mesh) {
291         return meshlink_get_external_address_for_family(mesh, AF_UNSPEC);
292 }
293
294 char *meshlink_get_external_address_for_family(meshlink_handle_t *mesh, int family) {
295         char *hostname = NULL;
296
297         logger(mesh, MESHLINK_DEBUG, "Trying to discover externally visible hostname...\n");
298         struct addrinfo *ai = str2addrinfo("meshlink.io", "80", SOCK_STREAM);
299         static const char request[] = "GET http://www.meshlink.io/host.cgi HTTP/1.0\r\n\r\n";
300         char line[256];
301
302         for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
303                 if(family != AF_UNSPEC && aip->ai_family != family) {
304                         continue;
305                 }
306
307                 int s = socket_in_netns(aip->ai_family, aip->ai_socktype, aip->ai_protocol, mesh->netns);
308
309                 if(s >= 0) {
310                         set_timeout(s, 5000);
311
312                         if(connect(s, aip->ai_addr, aip->ai_addrlen)) {
313                                 closesocket(s);
314                                 s = -1;
315                         }
316                 }
317
318                 if(s >= 0) {
319                         send(s, request, sizeof(request) - 1, 0);
320                         int len = recv(s, line, sizeof(line) - 1, MSG_WAITALL);
321
322                         if(len > 0) {
323                                 line[len] = 0;
324
325                                 if(line[len - 1] == '\n') {
326                                         line[--len] = 0;
327                                 }
328
329                                 char *p = strrchr(line, '\n');
330
331                                 if(p && p[1]) {
332                                         hostname = xstrdup(p + 1);
333                                 }
334                         }
335
336                         closesocket(s);
337
338                         if(hostname) {
339                                 break;
340                         }
341                 }
342         }
343
344         if(ai) {
345                 freeaddrinfo(ai);
346         }
347
348         // Check that the hostname is reasonable
349         if(hostname && !is_valid_hostname(hostname)) {
350                 free(hostname);
351                 hostname = NULL;
352         }
353
354         if(!hostname) {
355                 meshlink_errno = MESHLINK_ERESOLV;
356         }
357
358         return hostname;
359 }
360
361 char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int family) {
362         (void)mesh;
363
364         // Determine address of the local interface used for outgoing connections.
365         char localaddr[NI_MAXHOST];
366         bool success = false;
367
368         if(family == AF_INET) {
369                 success = getlocaladdrname("93.184.216.34", localaddr, sizeof(localaddr), mesh->netns);
370         } else if(family == AF_INET6) {
371                 success = getlocaladdrname("2606:2800:220:1:248:1893:25c8:1946", localaddr, sizeof(localaddr), mesh->netns);
372         }
373
374         if(!success) {
375                 meshlink_errno = MESHLINK_ENETWORK;
376                 return NULL;
377         }
378
379         return xstrdup(localaddr);
380 }
381
382 void remove_duplicate_hostnames(char *host[], char *port[], int n) {
383         for(int i = 0; i < n; i++) {
384                 if(!host[i]) {
385                         continue;
386                 }
387
388                 // Ignore duplicate hostnames
389                 bool found = false;
390
391                 for(int j = 0; j < i; j++) {
392                         if(!host[j]) {
393                                 continue;
394                         }
395
396                         if(strcmp(host[i], host[j])) {
397                                 continue;
398                         }
399
400                         if(strcmp(port[i], port[j])) {
401                                 continue;
402                         }
403
404                         found = true;
405                         break;
406                 }
407
408                 if(found) {
409                         free(host[i]);
410                         free(port[i]);
411                         host[i] = NULL;
412                         port[i] = NULL;
413                         continue;
414                 }
415         }
416 }
417
418 // This gets the hostname part for use in invitation URLs
419 static char *get_my_hostname(meshlink_handle_t *mesh, uint32_t flags) {
420         char *hostname[4] = {NULL};
421         char *port[4] = {NULL};
422         char *hostport = NULL;
423
424         if(!(flags & (MESHLINK_INVITE_LOCAL | MESHLINK_INVITE_PUBLIC))) {
425                 flags |= MESHLINK_INVITE_LOCAL | MESHLINK_INVITE_PUBLIC;
426         }
427
428         if(!(flags & (MESHLINK_INVITE_IPV4 | MESHLINK_INVITE_IPV6))) {
429                 flags |= MESHLINK_INVITE_IPV4 | MESHLINK_INVITE_IPV6;
430         }
431
432         // Add local addresses if requested
433         if(flags & MESHLINK_INVITE_LOCAL) {
434                 if(flags & MESHLINK_INVITE_IPV4) {
435                         hostname[0] = meshlink_get_local_address_for_family(mesh, AF_INET);
436                 }
437
438                 if(flags & MESHLINK_INVITE_IPV6) {
439                         hostname[1] = meshlink_get_local_address_for_family(mesh, AF_INET6);
440                 }
441         }
442
443         // Add public/canonical addresses if requested
444         if(flags & MESHLINK_INVITE_PUBLIC) {
445                 // Try the CanonicalAddress first
446                 char filename[PATH_MAX] = "";
447                 snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", mesh->confbase, mesh->self->name);
448                 scan_for_canonical_address(filename, &hostname[2], &port[2]);
449
450                 if(!hostname[2]) {
451                         if(flags & MESHLINK_INVITE_IPV4) {
452                                 hostname[2] = meshlink_get_external_address_for_family(mesh, AF_INET);
453                         }
454
455                         if(flags & MESHLINK_INVITE_IPV6) {
456                                 hostname[3] = meshlink_get_external_address_for_family(mesh, AF_INET6);
457                         }
458                 }
459         }
460
461         for(int i = 0; i < 4; i++) {
462                 // Ensure we always have a port number
463                 if(hostname[i] && !port[i]) {
464                         port[i] = xstrdup(mesh->myport);
465                 }
466         }
467
468         remove_duplicate_hostnames(hostname, port, 4);
469
470         if(!(flags & MESHLINK_INVITE_NUMERIC)) {
471                 for(int i = 0; i < 4; i++) {
472                         if(!hostname[i]) {
473                                 continue;
474                         }
475
476                         // Convert what we have to a sockaddr
477                         struct addrinfo *ai_in, *ai_out;
478                         struct addrinfo hint = {
479                                 .ai_family = AF_UNSPEC,
480                                 .ai_flags = AI_NUMERICSERV,
481                                 .ai_socktype = SOCK_STREAM,
482                         };
483                         int err = getaddrinfo(hostname[i], port[i], &hint, &ai_in);
484
485                         if(err || !ai_in) {
486                                 continue;
487                         }
488
489                         // Convert it to a hostname
490                         char resolved_host[NI_MAXHOST];
491                         char resolved_port[NI_MAXSERV];
492                         err = getnameinfo(ai_in->ai_addr, ai_in->ai_addrlen, resolved_host, sizeof resolved_host, resolved_port, sizeof resolved_port, NI_NUMERICSERV);
493
494                         if(err) {
495                                 freeaddrinfo(ai_in);
496                                 continue;
497                         }
498
499                         // Convert the hostname back to a sockaddr
500                         hint.ai_family = ai_in->ai_family;
501                         err = getaddrinfo(resolved_host, resolved_port, &hint, &ai_out);
502
503                         if(err || !ai_out) {
504                                 freeaddrinfo(ai_in);
505                                 continue;
506                         }
507
508                         // Check if it's still the same sockaddr
509                         if(ai_in->ai_addrlen != ai_out->ai_addrlen || memcmp(ai_in->ai_addr, ai_out->ai_addr, ai_in->ai_addrlen)) {
510                                 freeaddrinfo(ai_in);
511                                 freeaddrinfo(ai_out);
512                                 continue;
513                         }
514
515                         // Yes: replace the hostname with the resolved one
516                         free(hostname[i]);
517                         hostname[i] = xstrdup(resolved_host);
518
519                         freeaddrinfo(ai_in);
520                         freeaddrinfo(ai_out);
521                 }
522         }
523
524         // Remove duplicates again, since IPv4 and IPv6 addresses might map to the same hostname
525         remove_duplicate_hostnames(hostname, port, 4);
526
527         // Concatenate all unique address to the hostport string
528         for(int i = 0; i < 4; i++) {
529                 if(!hostname[i]) {
530                         continue;
531                 }
532
533                 // Ensure we have the same addresses in our own host config file.
534                 char *tmphostport;
535                 xasprintf(&tmphostport, "%s %s", hostname[i], port[i]);
536                 append_config_file(mesh, mesh->self->name, "Address", tmphostport);
537                 free(tmphostport);
538
539                 // Append the address to the hostport string
540                 char *newhostport;
541                 xasprintf(&newhostport, (strchr(hostname[i], ':') ? "%s%s[%s]:%s" : "%s%s%s:%s"), hostport ? hostport : "", hostport ? "," : "", hostname[i], port[i]);
542                 free(hostport);
543                 hostport = newhostport;
544
545                 free(hostname[i]);
546                 free(port[i]);
547         }
548
549         return hostport;
550 }
551
552 static char *get_line(const char **data) {
553         if(!data || !*data) {
554                 return NULL;
555         }
556
557         if(! **data) {
558                 *data = NULL;
559                 return NULL;
560         }
561
562         static char line[1024];
563         const char *end = strchr(*data, '\n');
564         size_t len = end ? (size_t)(end - *data) : strlen(*data);
565
566         if(len >= sizeof(line)) {
567                 logger(NULL, MESHLINK_ERROR, "Maximum line length exceeded!\n");
568                 return NULL;
569         }
570
571         if(len && !isprint(**data)) {
572                 abort();
573         }
574
575         memcpy(line, *data, len);
576         line[len] = 0;
577
578         if(end) {
579                 *data = end + 1;
580         } else {
581                 *data = NULL;
582         }
583
584         return line;
585 }
586
587 static char *get_value(const char *data, const char *var) {
588         char *line = get_line(&data);
589
590         if(!line) {
591                 return NULL;
592         }
593
594         char *sep = line + strcspn(line, " \t=");
595         char *val = sep + strspn(sep, " \t");
596
597         if(*val == '=') {
598                 val += 1 + strspn(val + 1, " \t");
599         }
600
601         *sep = 0;
602
603         if(strcasecmp(line, var)) {
604                 return NULL;
605         }
606
607         return val;
608 }
609
610 static bool try_bind(int port) {
611         struct addrinfo *ai = NULL;
612         struct addrinfo hint = {
613                 .ai_flags = AI_PASSIVE,
614                 .ai_family = AF_UNSPEC,
615                 .ai_socktype = SOCK_STREAM,
616                 .ai_protocol = IPPROTO_TCP,
617         };
618
619         char portstr[16];
620         snprintf(portstr, sizeof(portstr), "%d", port);
621
622         if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) {
623                 return false;
624         }
625
626         while(ai) {
627                 int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
628
629                 if(!fd) {
630                         freeaddrinfo(ai);
631                         return false;
632                 }
633
634                 int result = bind(fd, ai->ai_addr, ai->ai_addrlen);
635                 closesocket(fd);
636
637                 if(result) {
638                         freeaddrinfo(ai);
639                         return false;
640                 }
641
642                 ai = ai->ai_next;
643         }
644
645         freeaddrinfo(ai);
646         return true;
647 }
648
649 int check_port(meshlink_handle_t *mesh) {
650         for(int i = 0; i < 1000; i++) {
651                 int port = 0x1000 + (rand() & 0x7fff);
652
653                 if(try_bind(port)) {
654                         char filename[PATH_MAX];
655                         snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", mesh->confbase, mesh->name);
656                         FILE *f = fopen(filename, "a");
657
658                         if(!f) {
659                                 meshlink_errno = MESHLINK_ESTORAGE;
660                                 logger(mesh, MESHLINK_DEBUG, "Could not store Port.\n");
661                                 return 0;
662                         }
663
664                         fprintf(f, "Port = %d\n", port);
665                         fclose(f);
666                         return port;
667                 }
668         }
669
670         meshlink_errno = MESHLINK_ENETWORK;
671         logger(mesh, MESHLINK_DEBUG, "Could not find any available network port.\n");
672         return 0;
673 }
674
675 static void deltree(const char *dirname) {
676         DIR *d = opendir(dirname);
677
678         if(d) {
679                 struct dirent *ent;
680
681                 while((ent = readdir(d))) {
682                         if(ent->d_name[0] == '.') {
683                                 continue;
684                         }
685
686                         char filename[PATH_MAX];
687                         snprintf(filename, sizeof(filename), "%s" SLASH "%s", dirname, ent->d_name);
688
689                         if(unlink(filename)) {
690                                 deltree(filename);
691                         }
692                 }
693
694                 closedir(d);
695         }
696
697         rmdir(dirname);
698 }
699
700 static bool finalize_join(meshlink_handle_t *mesh) {
701         char *name = xstrdup(get_value(mesh->data, "Name"));
702
703         if(!name) {
704                 logger(mesh, MESHLINK_DEBUG, "No Name found in invitation!\n");
705                 return false;
706         }
707
708         if(!check_id(name)) {
709                 logger(mesh, MESHLINK_DEBUG, "Invalid Name found in invitation: %s!\n", name);
710                 return false;
711         }
712
713         char filename[PATH_MAX];
714         snprintf(filename, sizeof(filename), "%s" SLASH "meshlink.conf", mesh->confbase);
715
716         FILE *f = fopen(filename, "w");
717
718         if(!f) {
719                 logger(mesh, MESHLINK_DEBUG, "Could not create file %s: %s\n", filename, strerror(errno));
720                 return false;
721         }
722
723         fprintf(f, "Name = %s\n", name);
724
725         // Wipe all old host config files and invitations
726         snprintf(filename, sizeof(filename), "%s" SLASH "hosts", mesh->confbase);
727         deltree(filename);
728
729         if(mkdir(filename, 0777) && errno != EEXIST) {
730                 logger(mesh, MESHLINK_DEBUG, "Could not create directory %s: %s\n", filename, strerror(errno));
731                 return false;
732         }
733
734         snprintf(filename, sizeof(filename), "%s" SLASH "invitations", mesh->confbase);
735         deltree(filename);
736
737         // Create a new host config file for ourself
738         snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", mesh->confbase, name);
739         FILE *fh = fopen(filename, "w");
740
741         if(!fh) {
742                 logger(mesh, MESHLINK_DEBUG, "Could not create file %s: %s\n", filename, strerror(errno));
743                 fclose(f);
744                 return false;
745         }
746
747         // Filter first chunk on approved keywords, split between meshlink.conf and hosts/Name
748         // Other chunks go unfiltered to their respective host config files
749         const char *p = mesh->data;
750         char *l, *value;
751
752         while((l = get_line(&p))) {
753                 // Ignore comments
754                 if(*l == '#') {
755                         continue;
756                 }
757
758                 // Split line into variable and value
759                 int len = strcspn(l, "\t =");
760                 value = l + len;
761                 value += strspn(value, "\t ");
762
763                 if(*value == '=') {
764                         value++;
765                         value += strspn(value, "\t ");
766                 }
767
768                 l[len] = 0;
769
770                 // Is it a Name?
771                 if(!strcasecmp(l, "Name"))
772                         if(strcmp(value, name)) {
773                                 break;
774                         } else {
775                                 continue;
776                         } else if(!strcasecmp(l, "NetName")) {
777                         continue;
778                 }
779
780                 // Check the list of known variables
781                 bool found = false;
782                 int i;
783
784                 for(i = 0; variables[i].name; i++) {
785                         if(strcasecmp(l, variables[i].name)) {
786                                 continue;
787                         }
788
789                         found = true;
790                         break;
791                 }
792
793                 // Ignore unknown and unsafe variables
794                 if(!found) {
795                         logger(mesh, MESHLINK_DEBUG, "Ignoring unknown variable '%s' in invitation.\n", l);
796                         continue;
797                 } else if(!(variables[i].type & VAR_SAFE)) {
798                         logger(mesh, MESHLINK_DEBUG, "Ignoring unsafe variable '%s' in invitation.\n", l);
799                         continue;
800                 }
801
802                 // Copy the safe variable to the right config file
803                 fprintf(variables[i].type & VAR_HOST ? fh : f, "%s = %s\n", l, value);
804         }
805
806         fclose(f);
807
808         while(l && !strcasecmp(l, "Name")) {
809                 if(!check_id(value)) {
810                         logger(mesh, MESHLINK_DEBUG, "Invalid Name found in invitation.\n");
811                         return false;
812                 }
813
814                 if(!strcmp(value, name)) {
815                         logger(mesh, MESHLINK_DEBUG, "Secondary chunk would overwrite our own host config file.\n");
816                         return false;
817                 }
818
819                 snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", mesh->confbase, value);
820                 f = fopen(filename, "w");
821
822                 if(!f) {
823                         logger(mesh, MESHLINK_DEBUG, "Could not create file %s: %s\n", filename, strerror(errno));
824                         return false;
825                 }
826
827                 while((l = get_line(&p))) {
828                         if(!strcmp(l, "#---------------------------------------------------------------#")) {
829                                 continue;
830                         }
831
832                         int len = strcspn(l, "\t =");
833
834                         if(len == 4 && !strncasecmp(l, "Name", 4)) {
835                                 value = l + len;
836                                 value += strspn(value, "\t ");
837
838                                 if(*value == '=') {
839                                         value++;
840                                         value += strspn(value, "\t ");
841                                 }
842
843                                 l[len] = 0;
844                                 break;
845                         }
846
847                         fputs(l, f);
848                         fputc('\n', f);
849                 }
850
851                 fclose(f);
852         }
853
854         char *b64key = ecdsa_get_base64_public_key(mesh->self->connection->ecdsa);
855
856         if(!b64key) {
857                 fclose(fh);
858                 return false;
859         }
860
861         fprintf(fh, "ECDSAPublicKey = %s\n", b64key);
862         fprintf(fh, "Port = %s\n", mesh->myport);
863
864         fclose(fh);
865
866         sptps_send_record(&(mesh->sptps), 1, b64key, strlen(b64key));
867         free(b64key);
868
869         free(mesh->name);
870         free(mesh->self->name);
871         free(mesh->self->connection->name);
872         mesh->name = xstrdup(name);
873         mesh->self->name = xstrdup(name);
874         mesh->self->connection->name = name;
875
876         logger(mesh, MESHLINK_DEBUG, "Configuration stored in: %s\n", mesh->confbase);
877
878         load_all_nodes(mesh);
879
880         return true;
881 }
882
883 static bool invitation_send(void *handle, uint8_t type, const void *data, size_t len) {
884         (void)type;
885         meshlink_handle_t *mesh = handle;
886         const char *ptr = data;
887
888         while(len) {
889                 int result = send(mesh->sock, ptr, len, 0);
890
891                 if(result == -1 && errno == EINTR) {
892                         continue;
893                 } else if(result <= 0) {
894                         return false;
895                 }
896
897                 ptr += result;
898                 len -= result;
899         }
900
901         return true;
902 }
903
904 static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint16_t len) {
905         meshlink_handle_t *mesh = handle;
906
907         switch(type) {
908         case SPTPS_HANDSHAKE:
909                 return sptps_send_record(&(mesh->sptps), 0, mesh->cookie, sizeof(mesh)->cookie);
910
911         case 0:
912                 mesh->data = xrealloc(mesh->data, mesh->thedatalen + len + 1);
913                 memcpy(mesh->data + mesh->thedatalen, msg, len);
914                 mesh->thedatalen += len;
915                 mesh->data[mesh->thedatalen] = 0;
916                 break;
917
918         case 1:
919                 mesh->thedatalen = 0;
920                 return finalize_join(mesh);
921
922         case 2:
923                 logger(mesh, MESHLINK_DEBUG, "Invitation succesfully accepted.\n");
924                 shutdown(mesh->sock, SHUT_RDWR);
925                 mesh->success = true;
926                 break;
927
928         default:
929                 return false;
930         }
931
932         return true;
933 }
934
935 static bool recvline(meshlink_handle_t *mesh, size_t len) {
936         char *newline = NULL;
937
938         if(!mesh->sock) {
939                 abort();
940         }
941
942         while(!(newline = memchr(mesh->buffer, '\n', mesh->blen))) {
943                 int result = recv(mesh->sock, mesh->buffer + mesh->blen, sizeof(mesh)->buffer - mesh->blen, 0);
944
945                 if(result == -1 && errno == EINTR) {
946                         continue;
947                 } else if(result <= 0) {
948                         return false;
949                 }
950
951                 mesh->blen += result;
952         }
953
954         if((size_t)(newline - mesh->buffer) >= len) {
955                 return false;
956         }
957
958         len = newline - mesh->buffer;
959
960         memcpy(mesh->line, mesh->buffer, len);
961         mesh->line[len] = 0;
962         memmove(mesh->buffer, newline + 1, mesh->blen - len - 1);
963         mesh->blen -= len + 1;
964
965         return true;
966 }
967 static bool sendline(int fd, char *format, ...) {
968         static char buffer[4096];
969         char *p = buffer;
970         int blen = 0;
971         va_list ap;
972
973         va_start(ap, format);
974         blen = vsnprintf(buffer, sizeof(buffer), format, ap);
975         va_end(ap);
976
977         if(blen < 1 || (size_t)blen >= sizeof(buffer)) {
978                 return false;
979         }
980
981         buffer[blen] = '\n';
982         blen++;
983
984         while(blen) {
985                 int result = send(fd, p, blen, MSG_NOSIGNAL);
986
987                 if(result == -1 && errno == EINTR) {
988                         continue;
989                 } else if(result <= 0) {
990                         return false;
991                 }
992
993                 p += result;
994                 blen -= result;
995         }
996
997         return true;
998 }
999
1000 static const char *errstr[] = {
1001         [MESHLINK_OK] = "No error",
1002         [MESHLINK_EINVAL] = "Invalid argument",
1003         [MESHLINK_ENOMEM] = "Out of memory",
1004         [MESHLINK_ENOENT] = "No such node",
1005         [MESHLINK_EEXIST] = "Node already exists",
1006         [MESHLINK_EINTERNAL] = "Internal error",
1007         [MESHLINK_ERESOLV] = "Could not resolve hostname",
1008         [MESHLINK_ESTORAGE] = "Storage error",
1009         [MESHLINK_ENETWORK] = "Network error",
1010         [MESHLINK_EPEER] = "Error communicating with peer",
1011         [MESHLINK_ENOTSUP] = "Operation not supported",
1012         [MESHLINK_EBUSY] = "MeshLink instance already in use",
1013 };
1014
1015 const char *meshlink_strerror(meshlink_errno_t err) {
1016         if((int)err < 0 || err >= sizeof(errstr) / sizeof(*errstr)) {
1017                 return "Invalid error code";
1018         }
1019
1020         return errstr[err];
1021 }
1022
1023 static bool ecdsa_keygen(meshlink_handle_t *mesh) {
1024         ecdsa_t *key;
1025         FILE *f;
1026         char pubname[PATH_MAX], privname[PATH_MAX];
1027
1028         logger(mesh, MESHLINK_DEBUG, "Generating ECDSA keypair:\n");
1029
1030         if(!(key = ecdsa_generate())) {
1031                 logger(mesh, MESHLINK_DEBUG, "Error during key generation!\n");
1032                 meshlink_errno = MESHLINK_EINTERNAL;
1033                 return false;
1034         } else {
1035                 logger(mesh, MESHLINK_DEBUG, "Done.\n");
1036         }
1037
1038         if(snprintf(privname, sizeof(privname), "%s" SLASH "ecdsa_key.priv", mesh->confbase) >= PATH_MAX) {
1039                 logger(mesh, MESHLINK_DEBUG, "Filename too long: %s" SLASH "ecdsa_key.priv\n", mesh->confbase);
1040                 meshlink_errno = MESHLINK_ESTORAGE;
1041                 return false;
1042         }
1043
1044         f = fopen(privname, "wb");
1045
1046         if(!f) {
1047                 meshlink_errno = MESHLINK_ESTORAGE;
1048                 return false;
1049         }
1050
1051 #ifdef HAVE_FCHMOD
1052         fchmod(fileno(f), 0600);
1053 #endif
1054
1055         if(!ecdsa_write_pem_private_key(key, f)) {
1056                 logger(mesh, MESHLINK_DEBUG, "Error writing private key!\n");
1057                 ecdsa_free(key);
1058                 fclose(f);
1059                 meshlink_errno = MESHLINK_EINTERNAL;
1060                 return false;
1061         }
1062
1063         fclose(f);
1064
1065         snprintf(pubname, sizeof(pubname), "%s" SLASH "hosts" SLASH "%s", mesh->confbase, mesh->name);
1066         f = fopen(pubname, "a");
1067
1068         if(!f) {
1069                 meshlink_errno = MESHLINK_ESTORAGE;
1070                 return false;
1071         }
1072
1073         char *pubkey = ecdsa_get_base64_public_key(key);
1074         fprintf(f, "ECDSAPublicKey = %s\n", pubkey);
1075         free(pubkey);
1076
1077         fclose(f);
1078         ecdsa_free(key);
1079
1080         return true;
1081 }
1082
1083 static struct timeval idle(event_loop_t *loop, void *data) {
1084         (void)loop;
1085         meshlink_handle_t *mesh = data;
1086         struct timeval t, tmin = {3600, 0};
1087
1088         for splay_each(node_t, n, mesh->nodes) {
1089                 if(!n->utcp) {
1090                         continue;
1091                 }
1092
1093                 t = utcp_timeout(n->utcp);
1094
1095                 if(timercmp(&t, &tmin, <)) {
1096                         tmin = t;
1097                 }
1098         }
1099
1100         return tmin;
1101 }
1102
1103 // Get our local address(es) by simulating connecting to an Internet host.
1104 static void add_local_addresses(meshlink_handle_t *mesh) {
1105         char host[NI_MAXHOST];
1106         char entry[MAX_STRING_SIZE];
1107
1108         // IPv4 example.org
1109
1110         if(getlocaladdrname("93.184.216.34", host, sizeof(host), mesh->netns)) {
1111                 snprintf(entry, sizeof(entry), "%s %s", host, mesh->myport);
1112                 append_config_file(mesh, mesh->name, "Address", entry);
1113         }
1114
1115         // IPv6 example.org
1116
1117         if(getlocaladdrname("2606:2800:220:1:248:1893:25c8:1946", host, sizeof(host), mesh->netns)) {
1118                 snprintf(entry, sizeof(entry), "%s %s", host, mesh->myport);
1119                 append_config_file(mesh, mesh->name, "Address", entry);
1120         }
1121 }
1122
1123 static bool meshlink_setup(meshlink_handle_t *mesh) {
1124         if(mkdir(mesh->confbase, 0777) && errno != EEXIST) {
1125                 logger(mesh, MESHLINK_DEBUG, "Could not create directory %s: %s\n", mesh->confbase, strerror(errno));
1126                 meshlink_errno = MESHLINK_ESTORAGE;
1127                 return false;
1128         }
1129
1130         char filename[PATH_MAX];
1131         snprintf(filename, sizeof(filename), "%s" SLASH "hosts", mesh->confbase);
1132
1133         if(mkdir(filename, 0777) && errno != EEXIST) {
1134                 logger(mesh, MESHLINK_DEBUG, "Could not create directory %s: %s\n", filename, strerror(errno));
1135                 meshlink_errno = MESHLINK_ESTORAGE;
1136                 return false;
1137         }
1138
1139         snprintf(filename, sizeof(filename), "%s" SLASH "meshlink.conf", mesh->confbase);
1140
1141         if(!access(filename, F_OK)) {
1142                 logger(mesh, MESHLINK_DEBUG, "Configuration file %s already exists!\n", filename);
1143                 meshlink_errno = MESHLINK_EEXIST;
1144                 return false;
1145         }
1146
1147         FILE *f = fopen(filename, "w");
1148
1149         if(!f) {
1150                 logger(mesh, MESHLINK_DEBUG, "Could not create file %s: %s\n", filename, strerror(errno));
1151                 meshlink_errno = MESHLINK_ESTORAGE;
1152                 return false;
1153         }
1154
1155         fprintf(f, "Name = %s\n", mesh->name);
1156         fclose(f);
1157
1158         if(!ecdsa_keygen(mesh)) {
1159                 meshlink_errno = MESHLINK_EINTERNAL;
1160                 unlink(filename);
1161                 return false;
1162         }
1163
1164         if(check_port(mesh) == 0) {
1165                 meshlink_errno = MESHLINK_ENETWORK;
1166                 unlink(filename);
1167                 return false;
1168         }
1169
1170         return true;
1171 }
1172
1173 static void *setup_network_in_netns_thread(void *arg) {
1174         meshlink_handle_t *mesh = arg;
1175
1176         if(setns(mesh->netns, CLONE_NEWNET) != 0) {
1177                 return NULL;
1178         }
1179
1180         bool success = setup_network(mesh);
1181         add_local_addresses(mesh);
1182         return success ? arg : NULL;
1183 }
1184
1185 meshlink_open_params_t *meshlink_open_params_init(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
1186         if(!confbase || !*confbase) {
1187                 logger(NULL, MESHLINK_ERROR, "No confbase given!\n");
1188                 meshlink_errno = MESHLINK_EINVAL;
1189                 return NULL;
1190         }
1191
1192         if(!appname || !*appname) {
1193                 logger(NULL, MESHLINK_ERROR, "No appname given!\n");
1194                 meshlink_errno = MESHLINK_EINVAL;
1195                 return NULL;
1196         }
1197
1198         if(strchr(appname, ' ')) {
1199                 logger(NULL, MESHLINK_ERROR, "Invalid appname given!\n");
1200                 meshlink_errno = MESHLINK_EINVAL;
1201                 return NULL;
1202         }
1203
1204         if(!name || !*name) {
1205                 logger(NULL, MESHLINK_ERROR, "No name given!\n");
1206                 //return NULL;
1207         } else { //check name only if there is a name != NULL
1208                 if(!check_id(name)) {
1209                         logger(NULL, MESHLINK_ERROR, "Invalid name given!\n");
1210                         meshlink_errno = MESHLINK_EINVAL;
1211                         return NULL;
1212                 }
1213         }
1214
1215         if((int)devclass < 0 || devclass > _DEV_CLASS_MAX) {
1216                 logger(NULL, MESHLINK_ERROR, "Invalid devclass given!\n");
1217                 meshlink_errno = MESHLINK_EINVAL;
1218                 return NULL;
1219         }
1220
1221         meshlink_open_params_t *params = xzalloc(sizeof * params);
1222
1223         params->confbase = xstrdup(confbase);
1224         params->name = xstrdup(name);
1225         params->appname = xstrdup(appname);
1226         params->devclass = devclass;
1227         params->netns = -1;
1228
1229         return params;
1230 }
1231
1232 void meshlink_open_params_free(meshlink_open_params_t *params) {
1233         if(!params) {
1234                 meshlink_errno = MESHLINK_EINVAL;
1235                 return;
1236         }
1237
1238         free(params->confbase);
1239         free(params->name);
1240         free(params->appname);
1241
1242         free(params);
1243 }
1244
1245 meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
1246         /* Create a temporary struct on the stack, to avoid allocating and freeing one. */
1247         meshlink_open_params_t params = {NULL};
1248
1249         params.confbase = (char *)confbase;
1250         params.name = (char *)name;
1251         params.appname = (char *)appname;
1252         params.devclass = devclass;
1253         params.netns = -1;
1254
1255         return meshlink_open_ex(&params);
1256 }
1257 meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) {
1258         // Validate arguments provided by the application
1259         bool usingname = false;
1260
1261         logger(NULL, MESHLINK_DEBUG, "meshlink_open called\n");
1262
1263         if(!params->confbase || !*params->confbase) {
1264                 logger(NULL, MESHLINK_ERROR, "No confbase given!\n");
1265                 meshlink_errno = MESHLINK_EINVAL;
1266                 return NULL;
1267         }
1268
1269         if(!params->appname || !*params->appname) {
1270                 logger(NULL, MESHLINK_ERROR, "No appname given!\n");
1271                 meshlink_errno = MESHLINK_EINVAL;
1272                 return NULL;
1273         }
1274
1275         if(strchr(params->appname, ' ')) {
1276                 logger(NULL, MESHLINK_ERROR, "Invalid appname given!\n");
1277                 meshlink_errno = MESHLINK_EINVAL;
1278                 return NULL;
1279         }
1280
1281         if(!params->name || !*params->name) {
1282                 logger(NULL, MESHLINK_ERROR, "No name given!\n");
1283                 //return NULL;
1284         } else { //check name only if there is a name != NULL
1285
1286                 if(!check_id(params->name)) {
1287                         logger(NULL, MESHLINK_ERROR, "Invalid name given!\n");
1288                         meshlink_errno = MESHLINK_EINVAL;
1289                         return NULL;
1290                 } else {
1291                         usingname = true;
1292                 }
1293         }
1294
1295         if((int)params->devclass < 0 || params->devclass > _DEV_CLASS_MAX) {
1296                 logger(NULL, MESHLINK_ERROR, "Invalid devclass given!\n");
1297                 meshlink_errno = MESHLINK_EINVAL;
1298                 return NULL;
1299         }
1300
1301         meshlink_handle_t *mesh = xzalloc(sizeof(meshlink_handle_t));
1302         mesh->confbase = xstrdup(params->confbase);
1303         mesh->appname = xstrdup(params->appname);
1304         mesh->devclass = params->devclass;
1305         mesh->discovery = true;
1306         mesh->invitation_timeout = 604800; // 1 week
1307         mesh->netns = params->netns;
1308
1309         if(usingname) {
1310                 mesh->name = xstrdup(params->name);
1311         }
1312
1313         // initialize mutex
1314         pthread_mutexattr_t attr;
1315         pthread_mutexattr_init(&attr);
1316         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1317         pthread_mutex_init(&(mesh->mesh_mutex), &attr);
1318
1319         mesh->threadstarted = false;
1320         event_loop_init(&mesh->loop);
1321         mesh->loop.data = mesh;
1322
1323         meshlink_queue_init(&mesh->outpacketqueue);
1324
1325         // Check whether meshlink.conf already exists
1326
1327         char filename[PATH_MAX];
1328         snprintf(filename, sizeof(filename), "%s" SLASH "meshlink.conf", params->confbase);
1329
1330         if(access(filename, R_OK)) {
1331                 if(errno == ENOENT) {
1332                         // If not, create it
1333                         if(!meshlink_setup(mesh)) {
1334                                 // meshlink_errno is set by meshlink_setup()
1335                                 return NULL;
1336                         }
1337                 } else {
1338                         logger(NULL, MESHLINK_ERROR, "Cannot not read from %s: %s\n", filename, strerror(errno));
1339                         meshlink_close(mesh);
1340                         meshlink_errno = MESHLINK_ESTORAGE;
1341                         return NULL;
1342                 }
1343         }
1344
1345         // Open the configuration file and lock it
1346
1347         mesh->conffile = fopen(filename, "r");
1348
1349         if(!mesh->conffile) {
1350                 logger(NULL, MESHLINK_ERROR, "Cannot not open %s: %s\n", filename, strerror(errno));
1351                 meshlink_close(mesh);
1352                 meshlink_errno = MESHLINK_ESTORAGE;
1353                 return NULL;
1354         }
1355
1356 #ifdef FD_CLOEXEC
1357         fcntl(fileno(mesh->conffile), F_SETFD, FD_CLOEXEC);
1358 #endif
1359
1360 #ifdef HAVE_MINGW
1361         // TODO: use _locking()?
1362 #else
1363
1364         if(flock(fileno(mesh->conffile), LOCK_EX | LOCK_NB) != 0) {
1365                 logger(NULL, MESHLINK_ERROR, "Cannot lock %s: %s\n", filename, strerror(errno));
1366                 meshlink_close(mesh);
1367                 meshlink_errno = MESHLINK_EBUSY;
1368                 return NULL;
1369         }
1370
1371 #endif
1372
1373         // Read the configuration
1374
1375         init_configuration(&mesh->config);
1376
1377         if(!read_server_config(mesh)) {
1378                 meshlink_close(mesh);
1379                 meshlink_errno = MESHLINK_ESTORAGE;
1380                 return NULL;
1381         };
1382
1383 #ifdef HAVE_MINGW
1384         struct WSAData wsa_state;
1385
1386         WSAStartup(MAKEWORD(2, 2), &wsa_state);
1387
1388 #endif
1389
1390         // Setup up everything
1391         // TODO: we should not open listening sockets yet
1392
1393         bool success = false;
1394
1395         if(mesh->netns != -1) {
1396                 pthread_t thr;
1397
1398                 if(pthread_create(&thr, NULL, setup_network_in_netns_thread, mesh) == 0) {
1399                         void *retval = NULL;
1400                         success = pthread_join(thr, &retval) == 0 && retval;
1401                 }
1402         } else {
1403                 success = setup_network(mesh);
1404                 add_local_addresses(mesh);
1405         }
1406
1407         if(!success) {
1408                 meshlink_close(mesh);
1409                 meshlink_errno = MESHLINK_ENETWORK;
1410                 return NULL;
1411         }
1412
1413         idle_set(&mesh->loop, idle, mesh);
1414
1415         logger(NULL, MESHLINK_DEBUG, "meshlink_open returning\n");
1416         return mesh;
1417 }
1418
1419 meshlink_submesh_t *meshlink_submesh_open(meshlink_handle_t  *mesh, const char *submesh) {
1420         meshlink_submesh_t *s = NULL;
1421         if(!mesh) {
1422                 logger(NULL, MESHLINK_ERROR, "No mesh handle given!\n");
1423                 meshlink_errno = MESHLINK_EINVAL;
1424                 return NULL;
1425         }
1426
1427         if(!submesh || !*submesh) {
1428                 logger(NULL, MESHLINK_ERROR, "No submesh name given!\n");
1429                 meshlink_errno = MESHLINK_EINVAL;
1430                 return NULL;
1431         }
1432
1433         s = (meshlink_submesh_t *)lookup_submesh(mesh, submesh);
1434
1435         if (s) {
1436                 logger(NULL, MESHLINK_ERROR, "SubMesh Already exists!\n");
1437                 meshlink_errno = MESHLINK_EEXIST;
1438                 return NULL;
1439         }
1440
1441         s = (meshlink_submesh_t *)new_submesh();
1442         s->name = xstrdup(submesh);
1443
1444         submesh_add(mesh, (submesh_t *)s);
1445
1446         meshlink_errno = MESHLINK_OK;
1447         return s;
1448 }
1449
1450 static void *meshlink_main_loop(void *arg) {
1451         meshlink_handle_t *mesh = arg;
1452
1453         if(mesh->netns != -1) {
1454                 if(setns(mesh->netns, CLONE_NEWNET) != 0) {
1455                         return NULL;
1456                 }
1457         }
1458
1459         pthread_mutex_lock(&(mesh->mesh_mutex));
1460
1461         try_outgoing_connections(mesh);
1462
1463         logger(mesh, MESHLINK_DEBUG, "Starting main_loop...\n");
1464         main_loop(mesh);
1465         logger(mesh, MESHLINK_DEBUG, "main_loop returned.\n");
1466
1467         pthread_mutex_unlock(&(mesh->mesh_mutex));
1468         return NULL;
1469 }
1470
1471 bool meshlink_start(meshlink_handle_t *mesh) {
1472         if(!mesh) {
1473                 meshlink_errno = MESHLINK_EINVAL;
1474                 return false;
1475         }
1476
1477         logger(mesh, MESHLINK_DEBUG, "meshlink_start called\n");
1478
1479         pthread_mutex_lock(&(mesh->mesh_mutex));
1480
1481         if(mesh->threadstarted) {
1482                 logger(mesh, MESHLINK_DEBUG, "thread was already running\n");
1483                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1484                 return true;
1485         }
1486
1487         if(mesh->listen_socket[0].tcp.fd < 0) {
1488                 logger(mesh, MESHLINK_ERROR, "Listening socket not open\n");
1489                 meshlink_errno = MESHLINK_ENETWORK;
1490                 return false;
1491         }
1492
1493         mesh->thedatalen = 0;
1494
1495         // TODO: open listening sockets first
1496
1497         //Check that a valid name is set
1498         if(!mesh->name) {
1499                 logger(mesh, MESHLINK_DEBUG, "No name given!\n");
1500                 meshlink_errno = MESHLINK_EINVAL;
1501                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1502                 return false;
1503         }
1504
1505         // Start the main thread
1506
1507         event_loop_start(&mesh->loop);
1508
1509         if(pthread_create(&mesh->thread, NULL, meshlink_main_loop, mesh) != 0) {
1510                 logger(mesh, MESHLINK_DEBUG, "Could not start thread: %s\n", strerror(errno));
1511                 memset(&mesh->thread, 0, sizeof(mesh)->thread);
1512                 meshlink_errno = MESHLINK_EINTERNAL;
1513                 event_loop_stop(&mesh->loop);
1514                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1515                 return false;
1516         }
1517
1518         mesh->threadstarted = true;
1519
1520 #if HAVE_CATTA
1521
1522         if(mesh->discovery) {
1523                 discovery_start(mesh);
1524         }
1525
1526 #endif
1527
1528         pthread_mutex_unlock(&(mesh->mesh_mutex));
1529         return true;
1530 }
1531
1532 void meshlink_stop(meshlink_handle_t *mesh) {
1533         if(!mesh) {
1534                 meshlink_errno = MESHLINK_EINVAL;
1535                 return;
1536         }
1537
1538         pthread_mutex_lock(&(mesh->mesh_mutex));
1539         logger(mesh, MESHLINK_DEBUG, "meshlink_stop called\n");
1540
1541 #if HAVE_CATTA
1542
1543         // Stop discovery
1544         if(mesh->discovery) {
1545                 discovery_stop(mesh);
1546         }
1547
1548 #endif
1549
1550         // Shut down the main thread
1551         event_loop_stop(&mesh->loop);
1552
1553         // Send ourselves a UDP packet to kick the event loop
1554         for(int i = 0; i < mesh->listen_sockets; i++) {
1555                 sockaddr_t sa;
1556                 socklen_t salen = sizeof(sa.sa);
1557
1558                 if(getsockname(mesh->listen_socket[i].udp.fd, &sa.sa, &salen) == -1) {
1559                         logger(mesh, MESHLINK_ERROR, "System call `%s' failed: %s", "getsockname", sockstrerror(sockerrno));
1560                         continue;
1561                 }
1562
1563                 if(sendto(mesh->listen_socket[i].udp.fd, "", 1, MSG_NOSIGNAL, &sa.sa, salen) == -1) {
1564                         logger(mesh, MESHLINK_ERROR, "Could not send a UDP packet to ourself: %s", sockstrerror(sockerrno));
1565                 }
1566         }
1567
1568         if(mesh->threadstarted) {
1569                 // Wait for the main thread to finish
1570                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1571                 pthread_join(mesh->thread, NULL);
1572                 pthread_mutex_lock(&(mesh->mesh_mutex));
1573
1574                 mesh->threadstarted = false;
1575         }
1576
1577         // Close all metaconnections
1578         if(mesh->connections) {
1579                 for(list_node_t *node = mesh->connections->head, *next; node; node = next) {
1580                         next = node->next;
1581                         connection_t *c = node->data;
1582                         c->outgoing = NULL;
1583                         terminate_connection(mesh, c, false);
1584                 }
1585         }
1586
1587         if(mesh->outgoings) {
1588                 list_delete_list(mesh->outgoings);
1589                 mesh->outgoings = NULL;
1590         }
1591
1592         pthread_mutex_unlock(&(mesh->mesh_mutex));
1593 }
1594
1595 void meshlink_close(meshlink_handle_t *mesh) {
1596         if(!mesh || !mesh->confbase) {
1597                 meshlink_errno = MESHLINK_EINVAL;
1598                 return;
1599         }
1600
1601         // stop can be called even if mesh has not been started
1602         meshlink_stop(mesh);
1603
1604         // lock is not released after this
1605         pthread_mutex_lock(&(mesh->mesh_mutex));
1606
1607         // Close and free all resources used.
1608
1609         close_network_connections(mesh);
1610
1611         logger(mesh, MESHLINK_INFO, "Terminating");
1612
1613         exit_configuration(&mesh->config);
1614         event_loop_exit(&mesh->loop);
1615
1616 #ifdef HAVE_MINGW
1617
1618         if(mesh->confbase) {
1619                 WSACleanup();
1620         }
1621
1622 #endif
1623
1624         ecdsa_free(mesh->invitation_key);
1625
1626         if(mesh->netns != -1) {
1627                 close(mesh->netns);
1628         }
1629
1630         free(mesh->name);
1631         free(mesh->appname);
1632         free(mesh->confbase);
1633         pthread_mutex_destroy(&(mesh->mesh_mutex));
1634
1635         if(mesh->conffile) {
1636                 fclose(mesh->conffile);
1637         }
1638
1639         memset(mesh, 0, sizeof(*mesh));
1640
1641         free(mesh);
1642 }
1643
1644 bool meshlink_destroy(const char *confbase) {
1645         if(!confbase) {
1646                 meshlink_errno = MESHLINK_EINVAL;
1647                 return false;
1648         }
1649
1650         char filename[PATH_MAX];
1651         snprintf(filename, sizeof(filename), "%s" SLASH "meshlink.conf", confbase);
1652
1653         if(unlink(filename)) {
1654                 if(errno == ENOENT) {
1655                         meshlink_errno = MESHLINK_ENOENT;
1656                         return false;
1657                 } else {
1658                         logger(NULL, MESHLINK_ERROR, "Cannot delete %s: %s\n", filename, strerror(errno));
1659                         meshlink_errno = MESHLINK_ESTORAGE;
1660                         return false;
1661                 }
1662         }
1663
1664         deltree(confbase);
1665
1666         return true;
1667 }
1668
1669 void meshlink_set_receive_cb(meshlink_handle_t *mesh, meshlink_receive_cb_t cb) {
1670         if(!mesh) {
1671                 meshlink_errno = MESHLINK_EINVAL;
1672                 return;
1673         }
1674
1675         pthread_mutex_lock(&(mesh->mesh_mutex));
1676         mesh->receive_cb = cb;
1677         pthread_mutex_unlock(&(mesh->mesh_mutex));
1678 }
1679
1680 void meshlink_set_node_status_cb(meshlink_handle_t *mesh, meshlink_node_status_cb_t cb) {
1681         if(!mesh) {
1682                 meshlink_errno = MESHLINK_EINVAL;
1683                 return;
1684         }
1685
1686         pthread_mutex_lock(&(mesh->mesh_mutex));
1687         mesh->node_status_cb = cb;
1688         pthread_mutex_unlock(&(mesh->mesh_mutex));
1689 }
1690
1691 void meshlink_set_node_duplicate_cb(meshlink_handle_t *mesh, meshlink_node_duplicate_cb_t cb) {
1692         if(!mesh) {
1693                 meshlink_errno = MESHLINK_EINVAL;
1694                 return;
1695         }
1696
1697         pthread_mutex_lock(&(mesh->mesh_mutex));
1698         mesh->node_duplicate_cb = cb;
1699         pthread_mutex_unlock(&(mesh->mesh_mutex));
1700 }
1701
1702 void meshlink_set_log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, meshlink_log_cb_t cb) {
1703         if(mesh) {
1704                 pthread_mutex_lock(&(mesh->mesh_mutex));
1705                 mesh->log_cb = cb;
1706                 mesh->log_level = cb ? level : 0;
1707                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1708         } else {
1709                 global_log_cb = cb;
1710                 global_log_level = cb ? level : 0;
1711         }
1712 }
1713
1714 bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
1715         meshlink_packethdr_t *hdr;
1716
1717         // Validate arguments
1718         if(!mesh || !destination || len >= MAXSIZE - sizeof(*hdr)) {
1719                 meshlink_errno = MESHLINK_EINVAL;
1720                 return false;
1721         }
1722
1723         if(!len) {
1724                 return true;
1725         }
1726
1727         if(!data) {
1728                 meshlink_errno = MESHLINK_EINVAL;
1729                 return false;
1730         }
1731
1732         // Prepare the packet
1733         vpn_packet_t *packet = malloc(sizeof(*packet));
1734
1735         if(!packet) {
1736                 meshlink_errno = MESHLINK_ENOMEM;
1737                 return false;
1738         }
1739
1740         packet->probe = false;
1741         packet->tcp = false;
1742         packet->len = len + sizeof(*hdr);
1743
1744         hdr = (meshlink_packethdr_t *)packet->data;
1745         memset(hdr, 0, sizeof(*hdr));
1746         // leave the last byte as 0 to make sure strings are always
1747         // null-terminated if they are longer than the buffer
1748         strncpy((char *)hdr->destination, destination->name, (sizeof(hdr)->destination) - 1);
1749         strncpy((char *)hdr->source, mesh->self->name, (sizeof(hdr)->source) - 1);
1750
1751         memcpy(packet->data + sizeof(*hdr), data, len);
1752
1753         // Queue it
1754         if(!meshlink_queue_push(&mesh->outpacketqueue, packet)) {
1755                 free(packet);
1756                 meshlink_errno = MESHLINK_ENOMEM;
1757                 return false;
1758         }
1759
1760         // Notify event loop
1761         signal_trigger(&(mesh->loop), &(mesh->datafromapp));
1762
1763         return true;
1764 }
1765
1766 void meshlink_send_from_queue(event_loop_t *loop, meshlink_handle_t *mesh) {
1767         (void)loop;
1768         vpn_packet_t *packet = meshlink_queue_pop(&mesh->outpacketqueue);
1769
1770         if(!packet) {
1771                 return;
1772         }
1773
1774         mesh->self->in_packets++;
1775         mesh->self->in_bytes += packet->len;
1776         route(mesh, mesh->self, packet);
1777 }
1778
1779 ssize_t meshlink_get_pmtu(meshlink_handle_t *mesh, meshlink_node_t *destination) {
1780         if(!mesh || !destination) {
1781                 meshlink_errno = MESHLINK_EINVAL;
1782                 return -1;
1783         }
1784
1785         pthread_mutex_lock(&(mesh->mesh_mutex));
1786
1787         node_t *n = (node_t *)destination;
1788
1789         if(!n->status.reachable) {
1790                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1791                 return 0;
1792
1793         } else if(n->mtuprobes > 30 && n->minmtu) {
1794                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1795                 return n->minmtu;
1796         } else {
1797                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1798                 return MTU;
1799         }
1800 }
1801
1802 char *meshlink_get_fingerprint(meshlink_handle_t *mesh, meshlink_node_t *node) {
1803         if(!mesh || !node) {
1804                 meshlink_errno = MESHLINK_EINVAL;
1805                 return NULL;
1806         }
1807
1808         pthread_mutex_lock(&(mesh->mesh_mutex));
1809
1810         node_t *n = (node_t *)node;
1811
1812         if(!node_read_ecdsa_public_key(mesh, n) || !n->ecdsa) {
1813                 meshlink_errno = MESHLINK_EINTERNAL;
1814                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1815                 return false;
1816         }
1817
1818         char *fingerprint = ecdsa_get_base64_public_key(n->ecdsa);
1819
1820         if(!fingerprint) {
1821                 meshlink_errno = MESHLINK_EINTERNAL;
1822         }
1823
1824         pthread_mutex_unlock(&(mesh->mesh_mutex));
1825         return fingerprint;
1826 }
1827
1828 meshlink_node_t *meshlink_get_self(meshlink_handle_t *mesh) {
1829         if(!mesh) {
1830                 meshlink_errno = MESHLINK_EINVAL;
1831                 return NULL;
1832         }
1833
1834         return (meshlink_node_t *)mesh->self;
1835 }
1836
1837 meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) {
1838         if(!mesh || !name) {
1839                 meshlink_errno = MESHLINK_EINVAL;
1840                 return NULL;
1841         }
1842
1843         meshlink_node_t *node = NULL;
1844
1845         pthread_mutex_lock(&(mesh->mesh_mutex));
1846         node = (meshlink_node_t *)lookup_node(mesh, (char *)name); // TODO: make lookup_node() use const
1847         pthread_mutex_unlock(&(mesh->mesh_mutex));
1848         return node;
1849 }
1850
1851 meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t *nmemb) {
1852         if(!mesh || !nmemb || (*nmemb && !nodes)) {
1853                 meshlink_errno = MESHLINK_EINVAL;
1854                 return NULL;
1855         }
1856
1857         meshlink_node_t **result;
1858
1859         //lock mesh->nodes
1860         pthread_mutex_lock(&(mesh->mesh_mutex));
1861
1862         *nmemb = mesh->nodes->count;
1863         result = realloc(nodes, *nmemb * sizeof(*nodes));
1864
1865         if(result) {
1866                 meshlink_node_t **p = result;
1867
1868                 for splay_each(node_t, n, mesh->nodes) {
1869                         *p++ = (meshlink_node_t *)n;
1870                 }
1871         } else {
1872                 *nmemb = 0;
1873                 free(nodes);
1874                 meshlink_errno = MESHLINK_ENOMEM;
1875         }
1876
1877         pthread_mutex_unlock(&(mesh->mesh_mutex));
1878
1879         return result;
1880 }
1881
1882 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) {
1883         if(!mesh || ((int)devclass < 0) || (devclass > _DEV_CLASS_MAX) || !nmemb) {
1884                 meshlink_errno = MESHLINK_EINVAL;
1885                 return NULL;
1886         }
1887
1888         meshlink_node_t **result;
1889
1890         pthread_mutex_lock(&(mesh->mesh_mutex));
1891
1892         *nmemb = 0;
1893
1894         for splay_each(node_t, n, mesh->nodes) {
1895                 if(n->devclass == devclass) {
1896                         *nmemb = *nmemb + 1;
1897                 }
1898         }
1899
1900         if(*nmemb == 0) {
1901                 free(nodes);
1902                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1903                 return NULL;
1904         }
1905
1906         result = realloc(nodes, *nmemb * sizeof(*nodes));
1907
1908         if(result) {
1909                 meshlink_node_t **p = result;
1910
1911                 for splay_each(node_t, n, mesh->nodes) {
1912                         if(n->devclass == devclass) {
1913                                 *p++ = (meshlink_node_t *)n;
1914                         }
1915                 }
1916         } else {
1917                 *nmemb = 0;
1918                 free(nodes);
1919                 meshlink_errno = MESHLINK_ENOMEM;
1920         }
1921
1922         pthread_mutex_unlock(&(mesh->mesh_mutex));
1923
1924         return result;
1925 }
1926
1927 dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t *node) {
1928         if(!mesh || !node) {
1929                 meshlink_errno = MESHLINK_EINVAL;
1930                 return -1;
1931         }
1932
1933         dev_class_t devclass;
1934
1935         pthread_mutex_lock(&(mesh->mesh_mutex));
1936
1937         devclass = ((node_t *)node)->devclass;
1938
1939         pthread_mutex_unlock(&(mesh->mesh_mutex));
1940
1941         return devclass;
1942 }
1943
1944 bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void *signature, size_t *siglen) {
1945         if(!mesh || !data || !len || !signature || !siglen) {
1946                 meshlink_errno = MESHLINK_EINVAL;
1947                 return false;
1948         }
1949
1950         if(*siglen < MESHLINK_SIGLEN) {
1951                 meshlink_errno = MESHLINK_EINVAL;
1952                 return false;
1953         }
1954
1955         pthread_mutex_lock(&(mesh->mesh_mutex));
1956
1957         if(!ecdsa_sign(mesh->self->connection->ecdsa, data, len, signature)) {
1958                 meshlink_errno = MESHLINK_EINTERNAL;
1959                 pthread_mutex_unlock(&(mesh->mesh_mutex));
1960                 return false;
1961         }
1962
1963         *siglen = MESHLINK_SIGLEN;
1964         pthread_mutex_unlock(&(mesh->mesh_mutex));
1965         return true;
1966 }
1967
1968 bool meshlink_verify(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len, const void *signature, size_t siglen) {
1969         if(!mesh || !data || !len || !signature) {
1970                 meshlink_errno = MESHLINK_EINVAL;
1971                 return false;
1972         }
1973
1974         if(siglen != MESHLINK_SIGLEN) {
1975                 meshlink_errno = MESHLINK_EINVAL;
1976                 return false;
1977         }
1978
1979         pthread_mutex_lock(&(mesh->mesh_mutex));
1980
1981         bool rval = false;
1982
1983         struct node_t *n = (struct node_t *)source;
1984         node_read_ecdsa_public_key(mesh, n);
1985
1986         if(!n->ecdsa) {
1987                 meshlink_errno = MESHLINK_EINTERNAL;
1988                 rval = false;
1989         } else {
1990                 rval = ecdsa_verify(((struct node_t *)source)->ecdsa, data, len, signature);
1991         }
1992
1993         pthread_mutex_unlock(&(mesh->mesh_mutex));
1994         return rval;
1995 }
1996
1997 static bool refresh_invitation_key(meshlink_handle_t *mesh) {
1998         char filename[PATH_MAX];
1999
2000         pthread_mutex_lock(&(mesh->mesh_mutex));
2001
2002         snprintf(filename, sizeof(filename), "%s" SLASH "invitations", mesh->confbase);
2003
2004         if(mkdir(filename, 0700) && errno != EEXIST) {
2005                 logger(mesh, MESHLINK_DEBUG, "Could not create directory %s: %s\n", filename, strerror(errno));
2006                 meshlink_errno = MESHLINK_ESTORAGE;
2007                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2008                 return false;
2009         }
2010
2011         // Count the number of valid invitations, clean up old ones
2012         DIR *dir = opendir(filename);
2013
2014         if(!dir) {
2015                 logger(mesh, MESHLINK_DEBUG, "Could not read directory %s: %s\n", filename, strerror(errno));
2016                 meshlink_errno = MESHLINK_ESTORAGE;
2017                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2018                 return false;
2019         }
2020
2021         errno = 0;
2022         int count = 0;
2023         struct dirent *ent;
2024         time_t deadline = time(NULL) - 604800; // 1 week in the past
2025
2026         while((ent = readdir(dir))) {
2027                 if(strlen(ent->d_name) != 24) {
2028                         continue;
2029                 }
2030
2031                 char invname[PATH_MAX];
2032                 struct stat st;
2033
2034                 if(snprintf(invname, sizeof(invname), "%s" SLASH "%s", filename, ent->d_name) >= PATH_MAX) {
2035                         logger(mesh, MESHLINK_DEBUG, "Filename too long: %s" SLASH "%s", filename, ent->d_name);
2036                         continue;
2037                 }
2038
2039                 if(!stat(invname, &st)) {
2040                         if(mesh->invitation_key && deadline < st.st_mtime) {
2041                                 count++;
2042                         } else {
2043                                 unlink(invname);
2044                         }
2045                 } else {
2046                         logger(mesh, MESHLINK_DEBUG, "Could not stat %s: %s\n", invname, strerror(errno));
2047                         errno = 0;
2048                 }
2049         }
2050
2051         if(errno) {
2052                 logger(mesh, MESHLINK_DEBUG, "Error while reading directory %s: %s\n", filename, strerror(errno));
2053                 closedir(dir);
2054                 meshlink_errno = MESHLINK_ESTORAGE;
2055                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2056                 return false;
2057         }
2058
2059         closedir(dir);
2060
2061         snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "ecdsa_key.priv", mesh->confbase);
2062
2063         // Remove the key if there are no outstanding invitations.
2064         if(!count) {
2065                 unlink(filename);
2066
2067                 if(mesh->invitation_key) {
2068                         ecdsa_free(mesh->invitation_key);
2069                         mesh->invitation_key = NULL;
2070                 }
2071         }
2072
2073         if(mesh->invitation_key) {
2074                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2075                 return true;
2076         }
2077
2078         // Create a new key if necessary.
2079         FILE *f = fopen(filename, "rb");
2080
2081         if(!f) {
2082                 if(errno != ENOENT) {
2083                         logger(mesh, MESHLINK_DEBUG, "Could not read %s: %s\n", filename, strerror(errno));
2084                         meshlink_errno = MESHLINK_ESTORAGE;
2085                         pthread_mutex_unlock(&(mesh->mesh_mutex));
2086                         return false;
2087                 }
2088
2089                 mesh->invitation_key = ecdsa_generate();
2090
2091                 if(!mesh->invitation_key) {
2092                         logger(mesh, MESHLINK_DEBUG, "Could not generate a new key!\n");
2093                         meshlink_errno = MESHLINK_EINTERNAL;
2094                         pthread_mutex_unlock(&(mesh->mesh_mutex));
2095                         return false;
2096                 }
2097
2098                 f = fopen(filename, "wb");
2099
2100                 if(!f) {
2101                         logger(mesh, MESHLINK_DEBUG, "Could not write %s: %s\n", filename, strerror(errno));
2102                         meshlink_errno = MESHLINK_ESTORAGE;
2103                         pthread_mutex_unlock(&(mesh->mesh_mutex));
2104                         return false;
2105                 }
2106
2107                 chmod(filename, 0600);
2108                 ecdsa_write_pem_private_key(mesh->invitation_key, f);
2109                 fclose(f);
2110         } else {
2111                 mesh->invitation_key = ecdsa_read_pem_private_key(f);
2112                 fclose(f);
2113
2114                 if(!mesh->invitation_key) {
2115                         logger(mesh, MESHLINK_DEBUG, "Could not read private key from %s\n", filename);
2116                         meshlink_errno = MESHLINK_ESTORAGE;
2117                 }
2118         }
2119
2120         pthread_mutex_unlock(&(mesh->mesh_mutex));
2121         return mesh->invitation_key;
2122 }
2123
2124 bool meshlink_set_canonical_address(meshlink_handle_t *mesh, meshlink_node_t *node, const char *address, const char *port) {
2125         if(!mesh || !node || !address) {
2126                 meshlink_errno = MESHLINK_EINVAL;
2127                 return false;
2128         }
2129
2130         if(!is_valid_hostname(address)) {
2131                 logger(mesh, MESHLINK_DEBUG, "Invalid character in address: %s\n", address);
2132                 meshlink_errno = MESHLINK_EINVAL;
2133                 return false;
2134         }
2135
2136         if(port && !is_valid_port(port)) {
2137                 logger(mesh, MESHLINK_DEBUG, "Invalid character in port: %s\n", address);
2138                 meshlink_errno = MESHLINK_EINVAL;
2139                 return false;
2140         }
2141
2142         char *canonical_address;
2143
2144         if(port) {
2145                 xasprintf(&canonical_address, "%s %s", address, port);
2146         } else {
2147                 canonical_address = xstrdup(address);
2148         }
2149
2150         pthread_mutex_lock(&(mesh->mesh_mutex));
2151         bool rval = modify_config_file(mesh, node->name, "CanonicalAddress", canonical_address, 1);
2152         pthread_mutex_unlock(&(mesh->mesh_mutex));
2153
2154         free(canonical_address);
2155         return rval;
2156 }
2157
2158 bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) {
2159         return meshlink_set_canonical_address(mesh, (meshlink_node_t *)mesh->self, address, NULL);
2160 }
2161
2162 bool meshlink_add_external_address(meshlink_handle_t *mesh) {
2163         if(!mesh) {
2164                 meshlink_errno = MESHLINK_EINVAL;
2165                 return false;
2166         }
2167
2168         char *address = meshlink_get_external_address(mesh);
2169
2170         if(!address) {
2171                 return false;
2172         }
2173
2174         bool rval = false;
2175
2176         pthread_mutex_lock(&(mesh->mesh_mutex));
2177         rval = append_config_file(mesh, mesh->self->name, "Address", address);
2178         pthread_mutex_unlock(&(mesh->mesh_mutex));
2179
2180         free(address);
2181         return rval;
2182 }
2183
2184 int meshlink_get_port(meshlink_handle_t *mesh) {
2185         if(!mesh) {
2186                 meshlink_errno = MESHLINK_EINVAL;
2187                 return -1;
2188         }
2189
2190         if(!mesh->myport) {
2191                 meshlink_errno = MESHLINK_EINTERNAL;
2192                 return -1;
2193         }
2194
2195         return atoi(mesh->myport);
2196 }
2197
2198 bool meshlink_set_port(meshlink_handle_t *mesh, int port) {
2199         if(!mesh || port < 0 || port >= 65536 || mesh->threadstarted) {
2200                 meshlink_errno = MESHLINK_EINVAL;
2201                 return false;
2202         }
2203
2204         if(mesh->myport && port == atoi(mesh->myport)) {
2205                 return true;
2206         }
2207
2208         if(!try_bind(port)) {
2209                 meshlink_errno = MESHLINK_ENETWORK;
2210                 return false;
2211         }
2212
2213         bool rval = false;
2214
2215         pthread_mutex_lock(&(mesh->mesh_mutex));
2216
2217         if(mesh->threadstarted) {
2218                 meshlink_errno = MESHLINK_EINVAL;
2219                 goto done;
2220         }
2221
2222         close_network_connections(mesh);
2223         exit_configuration(&mesh->config);
2224
2225         char portstr[10];
2226         snprintf(portstr, sizeof(portstr), "%d", port);
2227         portstr[sizeof(portstr) - 1] = 0;
2228
2229         modify_config_file(mesh, mesh->name, "Port", portstr, true);
2230
2231         init_configuration(&mesh->config);
2232
2233         if(!read_server_config(mesh)) {
2234                 meshlink_errno = MESHLINK_ESTORAGE;
2235         } else if(!setup_network(mesh)) {
2236                 meshlink_errno = MESHLINK_ENETWORK;
2237         } else {
2238                 rval = true;
2239         }
2240
2241 done:
2242         pthread_mutex_unlock(&(mesh->mesh_mutex));
2243
2244         return rval;
2245 }
2246
2247 void meshlink_set_invitation_timeout(meshlink_handle_t *mesh, int timeout) {
2248         mesh->invitation_timeout = timeout;
2249 }
2250
2251 char *meshlink_invite_ex(meshlink_handle_t *mesh, const char *name, uint32_t flags) {
2252         if(!mesh) {
2253                 meshlink_errno = MESHLINK_EINVAL;
2254                 return NULL;
2255         }
2256
2257         pthread_mutex_lock(&(mesh->mesh_mutex));
2258
2259         // Check validity of the new node's name
2260         if(!check_id(name)) {
2261                 logger(mesh, MESHLINK_DEBUG, "Invalid name for node.\n");
2262                 meshlink_errno = MESHLINK_EINVAL;
2263                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2264                 return NULL;
2265         }
2266
2267         // Ensure no host configuration file with that name exists
2268         char filename[PATH_MAX];
2269         snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", mesh->confbase, name);
2270
2271         if(!access(filename, F_OK)) {
2272                 logger(mesh, MESHLINK_DEBUG, "A host config file for %s already exists!\n", name);
2273                 meshlink_errno = MESHLINK_EEXIST;
2274                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2275                 return NULL;
2276         }
2277
2278         // Ensure no other nodes know about this name
2279         if(meshlink_get_node(mesh, name)) {
2280                 logger(mesh, MESHLINK_DEBUG, "A node with name %s is already known!\n", name);
2281                 meshlink_errno = MESHLINK_EEXIST;
2282                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2283                 return NULL;
2284         }
2285
2286         // Get the local address
2287         char *address = get_my_hostname(mesh, flags);
2288
2289         if(!address) {
2290                 logger(mesh, MESHLINK_DEBUG, "No Address known for ourselves!\n");
2291                 meshlink_errno = MESHLINK_ERESOLV;
2292                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2293                 return NULL;
2294         }
2295
2296         if(!refresh_invitation_key(mesh)) {
2297                 meshlink_errno = MESHLINK_EINTERNAL;
2298                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2299                 return NULL;
2300         }
2301
2302         char hash[64];
2303
2304         // Create a hash of the key.
2305         char *fingerprint = ecdsa_get_base64_public_key(mesh->invitation_key);
2306         sha512(fingerprint, strlen(fingerprint), hash);
2307         b64encode_urlsafe(hash, hash, 18);
2308
2309         // Create a random cookie for this invitation.
2310         char cookie[25];
2311         randomize(cookie, 18);
2312
2313         // Create a filename that doesn't reveal the cookie itself
2314         char buf[18 + strlen(fingerprint)];
2315         char cookiehash[64];
2316         memcpy(buf, cookie, 18);
2317         memcpy(buf + 18, fingerprint, sizeof(buf) - 18);
2318         sha512(buf, sizeof(buf), cookiehash);
2319         b64encode_urlsafe(cookiehash, cookiehash, 18);
2320
2321         b64encode_urlsafe(cookie, cookie, 18);
2322
2323         free(fingerprint);
2324
2325         // Create a file containing the details of the invitation.
2326         snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "%s", mesh->confbase, cookiehash);
2327         int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
2328
2329         if(!ifd) {
2330                 logger(mesh, MESHLINK_DEBUG, "Could not create invitation file %s: %s\n", filename, strerror(errno));
2331                 meshlink_errno = MESHLINK_ESTORAGE;
2332                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2333                 return NULL;
2334         }
2335
2336         FILE *f = fdopen(ifd, "w");
2337
2338         if(!f) {
2339                 abort();
2340         }
2341
2342         // Fill in the details.
2343         fprintf(f, "Name = %s\n", name);
2344         fprintf(f, "ConnectTo = %s\n", mesh->self->name);
2345
2346         // Copy Broadcast and Mode
2347         snprintf(filename, sizeof(filename), "%s" SLASH "meshlink.conf", mesh->confbase);
2348         FILE *tc = fopen(filename,  "r");
2349
2350         if(tc) {
2351                 char buf[1024];
2352
2353                 while(fgets(buf, sizeof(buf), tc)) {
2354                         if((!strncasecmp(buf, "Mode", 4) && strchr(" \t=", buf[4]))
2355                                         || (!strncasecmp(buf, "Broadcast", 9) && strchr(" \t=", buf[9]))) {
2356                                 fputs(buf, f);
2357
2358                                 // Make sure there is a newline character.
2359                                 if(!strchr(buf, '\n')) {
2360                                         fputc('\n', f);
2361                                 }
2362                         }
2363                 }
2364
2365                 fclose(tc);
2366         } else {
2367                 logger(mesh, MESHLINK_DEBUG, "Could not create %s: %s\n", filename, strerror(errno));
2368                 meshlink_errno = MESHLINK_ESTORAGE;
2369                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2370                 return NULL;
2371         }
2372
2373         fprintf(f, "#---------------------------------------------------------------#\n");
2374         fprintf(f, "Name = %s\n", mesh->self->name);
2375
2376         snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", mesh->confbase, mesh->self->name);
2377         fcopy(f, filename);
2378         fclose(f);
2379
2380         // Create an URL from the local address, key hash and cookie
2381         char *url;
2382         xasprintf(&url, "%s/%s%s", address, hash, cookie);
2383         free(address);
2384
2385         pthread_mutex_unlock(&(mesh->mesh_mutex));
2386         return url;
2387 }
2388
2389 char *meshlink_invite(meshlink_handle_t *mesh, const char *name) {
2390         return meshlink_invite_ex(mesh, name, 0);
2391 }
2392
2393 bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) {
2394         if(!mesh || !invitation) {
2395                 meshlink_errno = MESHLINK_EINVAL;
2396                 return false;
2397         }
2398
2399         pthread_mutex_lock(&(mesh->mesh_mutex));
2400
2401         //Before doing meshlink_join make sure we are not connected to another mesh
2402         if(mesh->threadstarted) {
2403                 logger(mesh, MESHLINK_DEBUG, "Already connected to a mesh\n");
2404                 meshlink_errno = MESHLINK_EINVAL;
2405                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2406                 return false;
2407         }
2408
2409         //TODO: think of a better name for this variable, or of a different way to tokenize the invitation URL.
2410         char copy[strlen(invitation) + 1];
2411         strcpy(copy, invitation);
2412
2413         // Split the invitation URL into a list of hostname/port tuples, a key hash and a cookie.
2414
2415         char *slash = strchr(copy, '/');
2416
2417         if(!slash) {
2418                 goto invalid;
2419         }
2420
2421         *slash++ = 0;
2422
2423         if(strlen(slash) != 48) {
2424                 goto invalid;
2425         }
2426
2427         char *address = copy;
2428         char *port = NULL;
2429
2430         if(!b64decode(slash, mesh->hash, 18) || !b64decode(slash + 24, mesh->cookie, 18)) {
2431                 goto invalid;
2432         }
2433
2434         // Generate a throw-away key for the invitation.
2435         ecdsa_t *key = ecdsa_generate();
2436
2437         if(!key) {
2438                 meshlink_errno = MESHLINK_EINTERNAL;
2439                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2440                 return false;
2441         }
2442
2443         char *b64key = ecdsa_get_base64_public_key(key);
2444         char *comma;
2445         mesh->sock = -1;
2446
2447         while(address && *address) {
2448                 // We allow commas in the address part to support multiple addresses in one invitation URL.
2449                 comma = strchr(address, ',');
2450
2451                 if(comma) {
2452                         *comma++ = 0;
2453                 }
2454
2455                 // Split of the port
2456                 port = strrchr(address, ':');
2457
2458                 if(!port) {
2459                         goto invalid;
2460                 }
2461
2462                 *port++ = 0;
2463
2464                 // IPv6 address are enclosed in brackets, per RFC 3986
2465                 if(*address == '[') {
2466                         address++;
2467                         char *bracket = strchr(address, ']');
2468
2469                         if(!bracket) {
2470                                 goto invalid;
2471                         }
2472
2473                         *bracket++ = 0;
2474
2475                         if(*bracket) {
2476                                 goto invalid;
2477                         }
2478                 }
2479
2480                 // Connect to the meshlink daemon mentioned in the URL.
2481                 struct addrinfo *ai = str2addrinfo(address, port, SOCK_STREAM);
2482
2483                 if(ai) {
2484                         for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
2485                                 mesh->sock = socket_in_netns(aip->ai_family, aip->ai_socktype, aip->ai_protocol, mesh->netns);
2486
2487                                 if(mesh->sock == -1) {
2488                                         logger(mesh, MESHLINK_DEBUG, "Could not open socket: %s\n", strerror(errno));
2489                                         meshlink_errno = MESHLINK_ENETWORK;
2490                                         continue;
2491                                 }
2492
2493                                 set_timeout(mesh->sock, 5000);
2494
2495                                 if(connect(mesh->sock, aip->ai_addr, aip->ai_addrlen)) {
2496                                         logger(mesh, MESHLINK_DEBUG, "Could not connect to %s port %s: %s\n", address, port, strerror(errno));
2497                                         meshlink_errno = MESHLINK_ENETWORK;
2498                                         closesocket(mesh->sock);
2499                                         mesh->sock = -1;
2500                                         continue;
2501                                 }
2502                         }
2503
2504                         freeaddrinfo(ai);
2505                 } else {
2506                         meshlink_errno = MESHLINK_ERESOLV;
2507                 }
2508
2509                 if(mesh->sock != -1 || !comma) {
2510                         break;
2511                 }
2512
2513                 address = comma;
2514         }
2515
2516         if(mesh->sock == -1) {
2517                 pthread_mutex_unlock(&mesh->mesh_mutex);
2518                 return false;
2519         }
2520
2521         logger(mesh, MESHLINK_DEBUG, "Connected to %s port %s...\n", address, port);
2522
2523         // Tell him we have an invitation, and give him our throw-away key.
2524
2525         mesh->blen = 0;
2526
2527         if(!sendline(mesh->sock, "0 ?%s %d.%d %s", b64key, PROT_MAJOR, 1, mesh->appname)) {
2528                 logger(mesh, MESHLINK_DEBUG, "Error sending request to %s port %s: %s\n", address, port, strerror(errno));
2529                 closesocket(mesh->sock);
2530                 meshlink_errno = MESHLINK_ENETWORK;
2531                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2532                 return false;
2533         }
2534
2535         free(b64key);
2536
2537         char hisname[4096] = "";
2538         int code, hismajor, hisminor = 0;
2539
2540         if(!recvline(mesh, sizeof(mesh)->line) || sscanf(mesh->line, "%d %s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(mesh, sizeof(mesh)->line) || !rstrip(mesh->line) || sscanf(mesh->line, "%d ", &code) != 1 || code != ACK || strlen(mesh->line) < 3) {
2541                 logger(mesh, MESHLINK_DEBUG, "Cannot read greeting from peer\n");
2542                 closesocket(mesh->sock);
2543                 meshlink_errno = MESHLINK_ENETWORK;
2544                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2545                 return false;
2546         }
2547
2548         // Check if the hash of the key he gave us matches the hash in the URL.
2549         char *fingerprint = mesh->line + 2;
2550         char hishash[64];
2551
2552         if(sha512(fingerprint, strlen(fingerprint), hishash)) {
2553                 logger(mesh, MESHLINK_DEBUG, "Could not create hash\n%s\n", mesh->line + 2);
2554                 meshlink_errno = MESHLINK_EINTERNAL;
2555                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2556                 return false;
2557         }
2558
2559         if(memcmp(hishash, mesh->hash, 18)) {
2560                 logger(mesh, MESHLINK_DEBUG, "Peer has an invalid key!\n%s\n", mesh->line + 2);
2561                 meshlink_errno = MESHLINK_EPEER;
2562                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2563                 return false;
2564
2565         }
2566
2567         ecdsa_t *hiskey = ecdsa_set_base64_public_key(fingerprint);
2568
2569         if(!hiskey) {
2570                 meshlink_errno = MESHLINK_EINTERNAL;
2571                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2572                 return false;
2573         }
2574
2575         // Start an SPTPS session
2576         if(!sptps_start(&mesh->sptps, mesh, true, false, key, hiskey, meshlink_invitation_label, sizeof(meshlink_invitation_label), invitation_send, invitation_receive)) {
2577                 meshlink_errno = MESHLINK_EINTERNAL;
2578                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2579                 return false;
2580         }
2581
2582         // Feed rest of input buffer to SPTPS
2583         if(!sptps_receive_data(&mesh->sptps, mesh->buffer, mesh->blen)) {
2584                 meshlink_errno = MESHLINK_EPEER;
2585                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2586                 return false;
2587         }
2588
2589         int len;
2590
2591         while((len = recv(mesh->sock, mesh->line, sizeof(mesh)->line, 0))) {
2592                 if(len < 0) {
2593                         if(errno == EINTR) {
2594                                 continue;
2595                         }
2596
2597                         logger(mesh, MESHLINK_DEBUG, "Error reading data from %s port %s: %s\n", address, port, strerror(errno));
2598                         meshlink_errno = MESHLINK_ENETWORK;
2599                         pthread_mutex_unlock(&(mesh->mesh_mutex));
2600                         return false;
2601                 }
2602
2603                 if(!sptps_receive_data(&mesh->sptps, mesh->line, len)) {
2604                         meshlink_errno = MESHLINK_EPEER;
2605                         pthread_mutex_unlock(&(mesh->mesh_mutex));
2606                         return false;
2607                 }
2608         }
2609
2610         sptps_stop(&mesh->sptps);
2611         ecdsa_free(hiskey);
2612         ecdsa_free(key);
2613         closesocket(mesh->sock);
2614
2615         if(!mesh->success) {
2616                 logger(mesh, MESHLINK_DEBUG, "Connection closed by peer, invitation cancelled.\n");
2617                 meshlink_errno = MESHLINK_EPEER;
2618                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2619                 return false;
2620         }
2621
2622         pthread_mutex_unlock(&(mesh->mesh_mutex));
2623         return true;
2624
2625 invalid:
2626         logger(mesh, MESHLINK_DEBUG, "Invalid invitation URL\n");
2627         meshlink_errno = MESHLINK_EINVAL;
2628         pthread_mutex_unlock(&(mesh->mesh_mutex));
2629         return false;
2630 }
2631
2632 char *meshlink_export(meshlink_handle_t *mesh) {
2633         if(!mesh) {
2634                 meshlink_errno = MESHLINK_EINVAL;
2635                 return NULL;
2636         }
2637
2638         pthread_mutex_lock(&(mesh->mesh_mutex));
2639
2640         char filename[PATH_MAX];
2641         snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", mesh->confbase, mesh->self->name);
2642         FILE *f = fopen(filename, "r");
2643
2644         if(!f) {
2645                 logger(mesh, MESHLINK_DEBUG, "Could not open %s: %s\n", filename, strerror(errno));
2646                 meshlink_errno = MESHLINK_ESTORAGE;
2647                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2648                 return NULL;
2649         }
2650
2651         fseek(f, 0, SEEK_END);
2652         int fsize = ftell(f);
2653         rewind(f);
2654
2655         size_t len = fsize + 9 + strlen(mesh->self->name);
2656         char *buf = xmalloc(len);
2657         snprintf(buf, len, "Name = %s\n", mesh->self->name);
2658
2659         if(fread(buf + len - fsize - 1, fsize, 1, f) != 1) {
2660                 logger(mesh, MESHLINK_DEBUG, "Error reading from %s: %s\n", filename, strerror(errno));
2661                 fclose(f);
2662                 free(buf);
2663                 meshlink_errno = MESHLINK_ESTORAGE;
2664                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2665                 return NULL;
2666         }
2667
2668         fclose(f);
2669         buf[len - 1] = 0;
2670
2671         pthread_mutex_unlock(&(mesh->mesh_mutex));
2672         return buf;
2673 }
2674
2675 bool meshlink_import(meshlink_handle_t *mesh, const char *data) {
2676         if(!mesh || !data) {
2677                 meshlink_errno = MESHLINK_EINVAL;
2678                 return false;
2679         }
2680
2681         pthread_mutex_lock(&(mesh->mesh_mutex));
2682
2683         if(strncmp(data, "Name = ", 7)) {
2684                 logger(mesh, MESHLINK_DEBUG, "Invalid data\n");
2685                 meshlink_errno = MESHLINK_EPEER;
2686                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2687                 return false;
2688         }
2689
2690         char *end = strchr(data + 7, '\n');
2691
2692         if(!end) {
2693                 logger(mesh, MESHLINK_DEBUG, "Invalid data\n");
2694                 meshlink_errno = MESHLINK_EPEER;
2695                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2696                 return false;
2697         }
2698
2699         int len = end - (data + 7);
2700         char name[len + 1];
2701         memcpy(name, data + 7, len);
2702         name[len] = 0;
2703
2704         if(!check_id(name)) {
2705                 logger(mesh, MESHLINK_DEBUG, "Invalid Name\n");
2706                 meshlink_errno = MESHLINK_EPEER;
2707                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2708                 return false;
2709         }
2710
2711         char filename[PATH_MAX];
2712         snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", mesh->confbase, name);
2713
2714         if(!access(filename, F_OK)) {
2715                 logger(mesh, MESHLINK_DEBUG, "File %s already exists, not importing\n", filename);
2716                 meshlink_errno = MESHLINK_EEXIST;
2717                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2718                 return false;
2719         }
2720
2721         if(errno != ENOENT) {
2722                 logger(mesh, MESHLINK_DEBUG, "Error accessing %s: %s\n", filename, strerror(errno));
2723                 meshlink_errno = MESHLINK_ESTORAGE;
2724                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2725                 return false;
2726         }
2727
2728         FILE *f = fopen(filename, "w");
2729
2730         if(!f) {
2731                 logger(mesh, MESHLINK_DEBUG, "Could not create %s: %s\n", filename, strerror(errno));
2732                 meshlink_errno = MESHLINK_ESTORAGE;
2733                 pthread_mutex_unlock(&(mesh->mesh_mutex));
2734                 return false;
2735         }
2736
2737         fwrite(end + 1, strlen(end + 1), 1, f);
2738         fclose(f);
2739
2740         load_all_nodes(mesh);
2741
2742         pthread_mutex_unlock(&(mesh->mesh_mutex));
2743         return true;
2744 }
2745
2746 void meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node) {
2747         if(!mesh || !node) {
2748                 meshlink_errno = MESHLINK_EINVAL;
2749                 return;
2750         }
2751
2752         pthread_mutex_lock(&(mesh->mesh_mutex));
2753
2754         node_t *n;
2755         n = (node_t *)node;
2756         n->status.blacklisted = true;
2757         logger(mesh, MESHLINK_DEBUG, "Blacklisted %s.\n", node->name);
2758
2759         //Make blacklisting persistent in the config file
2760         append_config_file(mesh, n->name, "blacklisted", "yes");
2761
2762         //Immediately terminate any connections we have with the blacklisted node
2763         for list_each(connection_t, c, mesh->connections) {
2764                 if(c->node == n) {
2765                         terminate_connection(mesh, c, c->status.active);
2766                 }
2767         }
2768
2769         pthread_mutex_unlock(&(mesh->mesh_mutex));
2770 }
2771
2772 void meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) {
2773         if(!mesh || !node) {
2774                 meshlink_errno = MESHLINK_EINVAL;
2775                 return;
2776         }
2777
2778         pthread_mutex_lock(&(mesh->mesh_mutex));
2779
2780         node_t *n = (node_t *)node;
2781         n->status.blacklisted = false;
2782
2783         //TODO: remove blacklisted = yes from the config file
2784
2785         pthread_mutex_unlock(&(mesh->mesh_mutex));
2786         return;
2787 }
2788
2789 void meshlink_set_default_blacklist(meshlink_handle_t *mesh, bool blacklist) {
2790         mesh->default_blacklist = blacklist;
2791 }
2792
2793 /* Hint that a hostname may be found at an address
2794  * See header file for detailed comment.
2795  */
2796 void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const struct sockaddr *addr) {
2797         if(!mesh || !node || !addr) {
2798                 return;
2799         }
2800
2801         // Ignore hints about ourself.
2802         if((node_t *)node == mesh->self) {
2803                 return;
2804         }
2805
2806         pthread_mutex_lock(&(mesh->mesh_mutex));
2807
2808         char *host = NULL, *port = NULL, *str = NULL;
2809         sockaddr2str((const sockaddr_t *)addr, &host, &port);
2810
2811         if(host && port) {
2812                 xasprintf(&str, "%s %s", host, port);
2813
2814                 if((strncmp("fe80", host, 4) != 0) && (strncmp("127.", host, 4) != 0) && (strcmp("localhost", host) != 0)) {
2815                         modify_config_file(mesh, node->name, "Address", str, 5);
2816                 } else {
2817                         logger(mesh, MESHLINK_DEBUG, "Not adding Link Local IPv6 Address to config\n");
2818                 }
2819         }
2820
2821         free(str);
2822         free(host);
2823         free(port);
2824
2825         pthread_mutex_unlock(&(mesh->mesh_mutex));
2826         // @TODO do we want to fire off a connection attempt right away?
2827 }
2828
2829 static bool channel_pre_accept(struct utcp *utcp, uint16_t port) {
2830         (void)port;
2831         node_t *n = utcp->priv;
2832         meshlink_handle_t *mesh = n->mesh;
2833         return mesh->channel_accept_cb;
2834 }
2835
2836 static ssize_t channel_recv(struct utcp_connection *connection, const void *data, size_t len) {
2837         meshlink_channel_t *channel = connection->priv;
2838
2839         if(!channel) {
2840                 abort();
2841         }
2842
2843         node_t *n = channel->node;
2844         meshlink_handle_t *mesh = n->mesh;
2845
2846         if(n->status.destroyed) {
2847                 meshlink_channel_close(mesh, channel);
2848         } else if(channel->receive_cb) {
2849                 channel->receive_cb(mesh, channel, data, len);
2850         }
2851
2852         return len;
2853 }
2854
2855 static void channel_accept(struct utcp_connection *utcp_connection, uint16_t port) {
2856         node_t *n = utcp_connection->utcp->priv;
2857
2858         if(!n) {
2859                 abort();
2860         }
2861
2862         meshlink_handle_t *mesh = n->mesh;
2863
2864         if(!mesh->channel_accept_cb) {
2865                 return;
2866         }
2867
2868         meshlink_channel_t *channel = xzalloc(sizeof(*channel));
2869         channel->node = n;
2870         channel->c = utcp_connection;
2871
2872         if(mesh->channel_accept_cb(mesh, channel, port, NULL, 0)) {
2873                 utcp_accept(utcp_connection, channel_recv, channel);
2874         } else {
2875                 free(channel);
2876         }
2877 }
2878
2879 static ssize_t channel_send(struct utcp *utcp, const void *data, size_t len) {
2880         node_t *n = utcp->priv;
2881
2882         if(n->status.destroyed) {
2883                 return -1;
2884         }
2885
2886         meshlink_handle_t *mesh = n->mesh;
2887         return meshlink_send(mesh, (meshlink_node_t *)n, data, len) ? (ssize_t)len : -1;
2888 }
2889
2890 void meshlink_set_channel_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_receive_cb_t cb) {
2891         if(!mesh || !channel) {
2892                 meshlink_errno = MESHLINK_EINVAL;
2893                 return;
2894         }
2895
2896         channel->receive_cb = cb;
2897 }
2898
2899 static void channel_receive(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
2900         (void)mesh;
2901         node_t *n = (node_t *)source;
2902
2903         if(!n->utcp) {
2904                 abort();
2905         }
2906
2907         utcp_recv(n->utcp, data, len);
2908 }
2909
2910 static void channel_poll(struct utcp_connection *connection, size_t len) {
2911         meshlink_channel_t *channel = connection->priv;
2912
2913         if(!channel) {
2914                 abort();
2915         }
2916
2917         node_t *n = channel->node;
2918         meshlink_handle_t *mesh = n->mesh;
2919
2920         if(channel->poll_cb) {
2921                 channel->poll_cb(mesh, channel, len);
2922         }
2923 }
2924
2925 void meshlink_set_channel_poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_poll_cb_t cb) {
2926         (void)mesh;
2927         channel->poll_cb = cb;
2928         utcp_set_poll_cb(channel->c, cb ? channel_poll : NULL);
2929 }
2930
2931 void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_accept_cb_t cb) {
2932         if(!mesh) {
2933                 meshlink_errno = MESHLINK_EINVAL;
2934                 return;
2935         }
2936
2937         pthread_mutex_lock(&mesh->mesh_mutex);
2938         mesh->channel_accept_cb = cb;
2939         mesh->receive_cb = channel_receive;
2940
2941         for splay_each(node_t, n, mesh->nodes) {
2942                 if(!n->utcp && n != mesh->self) {
2943                         n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
2944                 }
2945         }
2946
2947         pthread_mutex_unlock(&mesh->mesh_mutex);
2948 }
2949
2950 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) {
2951         if(data || len) {
2952                 abort();        // TODO: handle non-NULL data
2953         }
2954
2955         if(!mesh || !node) {
2956                 meshlink_errno = MESHLINK_EINVAL;
2957                 return NULL;
2958         }
2959
2960         node_t *n = (node_t *)node;
2961
2962         if(!n->utcp) {
2963                 n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
2964                 mesh->receive_cb = channel_receive;
2965
2966                 if(!n->utcp) {
2967                         meshlink_errno = errno == ENOMEM ? MESHLINK_ENOMEM : MESHLINK_EINTERNAL;
2968                         return NULL;
2969                 }
2970         }
2971
2972         meshlink_channel_t *channel = xzalloc(sizeof(*channel));
2973         channel->node = n;
2974         channel->receive_cb = cb;
2975         channel->c = utcp_connect_ex(n->utcp, port, channel_recv, channel, flags);
2976
2977         if(!channel->c) {
2978                 meshlink_errno = errno == ENOMEM ? MESHLINK_ENOMEM : MESHLINK_EINTERNAL;
2979                 free(channel);
2980                 return NULL;
2981         }
2982
2983         return channel;
2984 }
2985
2986 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) {
2987         return meshlink_channel_open_ex(mesh, node, port, cb, data, len, MESHLINK_CHANNEL_TCP);
2988 }
2989
2990 void meshlink_channel_shutdown(meshlink_handle_t *mesh, meshlink_channel_t *channel, int direction) {
2991         if(!mesh || !channel) {
2992                 meshlink_errno = MESHLINK_EINVAL;
2993                 return;
2994         }
2995
2996         utcp_shutdown(channel->c, direction);
2997 }
2998
2999 void meshlink_channel_close(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
3000         if(!mesh || !channel) {
3001                 meshlink_errno = MESHLINK_EINVAL;
3002                 return;
3003         }
3004
3005         utcp_close(channel->c);
3006         free(channel);
3007 }
3008
3009 ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
3010         if(!mesh || !channel) {
3011                 meshlink_errno = MESHLINK_EINVAL;
3012                 return -1;
3013         }
3014
3015         if(!len) {
3016                 return 0;
3017         }
3018
3019         if(!data) {
3020                 meshlink_errno = MESHLINK_EINVAL;
3021                 return -1;
3022         }
3023
3024         // TODO: more finegrained locking.
3025         // Ideally we want to put the data into the UTCP connection's send buffer.
3026         // Then, preferrably only if there is room in the receiver window,
3027         // kick the meshlink thread to go send packets.
3028
3029         pthread_mutex_lock(&mesh->mesh_mutex);
3030         ssize_t retval = utcp_send(channel->c, data, len);
3031         pthread_mutex_unlock(&mesh->mesh_mutex);
3032
3033         if(retval < 0) {
3034                 meshlink_errno = MESHLINK_ENETWORK;
3035         }
3036
3037         return retval;
3038 }
3039
3040 uint32_t meshlink_channel_get_flags(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
3041         if(!mesh || !channel) {
3042                 meshlink_errno = MESHLINK_EINVAL;
3043                 return -1;
3044         }
3045
3046         return channel->c->flags;
3047 }
3048
3049 void update_node_status(meshlink_handle_t *mesh, node_t *n) {
3050         if(n->status.reachable && mesh->channel_accept_cb && !n->utcp) {
3051                 n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
3052         }
3053
3054         if(mesh->node_status_cb) {
3055                 mesh->node_status_cb(mesh, (meshlink_node_t *)n, n->status.reachable);
3056         }
3057 }
3058
3059 void handle_duplicate_node(meshlink_handle_t *mesh, node_t *n) {
3060         if(!mesh->node_duplicate_cb || n->status.duplicate) {
3061                 return;
3062         }
3063
3064         n->status.duplicate = true;
3065         mesh->node_duplicate_cb(mesh, (meshlink_node_t *)n);
3066 }
3067
3068 void meshlink_enable_discovery(meshlink_handle_t *mesh, bool enable) {
3069 #if HAVE_CATTA
3070
3071         if(!mesh) {
3072                 meshlink_errno = MESHLINK_EINVAL;
3073                 return;
3074         }
3075
3076         pthread_mutex_lock(&mesh->mesh_mutex);
3077
3078         if(mesh->discovery == enable) {
3079                 goto end;
3080         }
3081
3082         if(mesh->threadstarted) {
3083                 if(enable) {
3084                         discovery_start(mesh);
3085                 } else {
3086                         discovery_stop(mesh);
3087                 }
3088         }
3089
3090         mesh->discovery = enable;
3091
3092 end:
3093         pthread_mutex_unlock(&mesh->mesh_mutex);
3094 #else
3095         (void)mesh;
3096         (void)enable;
3097         meshlink_errno = MESHLINK_ENOTSUP;
3098 #endif
3099 }
3100
3101 static void __attribute__((constructor)) meshlink_init(void) {
3102         crypto_init();
3103         unsigned int seed;
3104         randomize(&seed, sizeof(seed));
3105         srand(seed);
3106 }
3107
3108 static void __attribute__((destructor)) meshlink_exit(void) {
3109         crypto_exit();
3110 }
3111
3112 /// Device class traits
3113 dev_class_traits_t dev_class_traits[_DEV_CLASS_MAX + 1] = {
3114         { .min_connects = 3, .max_connects = 10000, .edge_weight = 1 }, // DEV_CLASS_BACKBONE
3115         { .min_connects = 3, .max_connects = 100, .edge_weight = 3 },   // DEV_CLASS_STATIONARY
3116         { .min_connects = 3, .max_connects = 3, .edge_weight = 6 },             // DEV_CLASS_PORTABLE
3117         { .min_connects = 1, .max_connects = 1, .edge_weight = 9 },             // DEV_CLASS_UNKNOWN
3118 };