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