14 MaxWeight = 0x7fffffff,
19 EtherType = 2*Eaddrlen,
20 EtherHdr = EtherType+2,
27 /* worst case: UDPv6 over 6in4 over PPPoE */
28 DefPMTU = 1500-8-Ip4Hdr-Ip6Hdr-UdpHdr-4-AESbsize-MAClen,
55 typedef struct Snet Snet;
56 typedef struct Edge Edge;
57 typedef struct Ciph Ciph;
58 typedef struct Host Host;
59 typedef struct Conn Conn;
65 Snet *next; /* next subnet on owner */
67 uchar mask[IPaddrlen];
78 Edge *next; /* next edge on src */
79 Edge *rev; /* reverse drection edge */
92 void (*crypt)(uchar*, int, AESstate*);
94 uchar key[AESkeylen+AESbsize];
119 uvlong ooo; /* out of order replay window */
144 char buf[MaxPacket+16];
161 Conn *bcast = (void*)-1;
165 char *outside = "/net";
166 char *inside = "/net";
170 uchar localip[IPaddrlen];
171 uchar localmask[IPaddrlen];
175 void delsubnet(Snet*);
176 void netrecalc(void);
178 int consend(Conn *c, char *fmt, ...);
179 #pragma varargck argpos consend 2
180 int sendudp(Host *h, int fd, uchar *p, int n);
181 void routepkt(Host *s, uchar *p, int n);
182 void needkey(Host *from);
183 void clearkey(Host *from);
188 void *v = malloc(len);
190 sysfatal("malloc: %r");
191 setmalloctag(v, getcallerpc(&len));
196 erealloc(void *v, ulong len)
198 if((v = realloc(v, len)) == nil && len != 0)
199 sysfatal("realloc: %r");
200 setrealloctag(v, getcallerpc(&v));
206 if((s = strdup(s)) == nil)
207 sysfatal("strdup: %r");
208 setmalloctag(s, getcallerpc(&s));
213 fd2dir(int fd, char *dir, int len)
218 if(fd2path(fd, dir, len) < 0)
220 p = strrchr(dir, '/');
221 if(p == nil || p == dir)
228 dir2ipport(char *dir, uchar ip[IPaddrlen])
233 if((nci = getnetconninfo(dir, -1)) == nil)
235 if(parseip(ip, nci->rsys) != -1)
236 port = atoi(nci->rserv);
237 freenetconninfo(nci);
246 if(fd < 0 || fd2dir(fd, buf, sizeof(buf)-5) == nil)
249 if((fd = open(buf, OWRITE)) >= 0){
260 assert(lconn == nil);
264 assert(lconn == nil);
276 assert(lconn == nil);
282 edgecmp(Edge *a, Edge *b)
286 if((c = a->deleted - b->deleted) != 0)
288 return a->weight - b->weight;
291 edgepcmp(void *a, void *b)
293 return edgecmp(*(Edge**)a, *(Edge**)b);
297 subnetcmp(Snet *a, Snet *b)
301 if((c = a->deleted - b->deleted) != 0)
303 if((c = ipcmp(b->mask, a->mask)) != 0)
305 if((c = ipcmp(a->ip, b->ip)) != 0)
307 return a->weight - b->weight;
310 subnetpcmp(void *a, void *b)
312 return subnetcmp(*(Snet**)a, *(Snet**)b);
316 lookupnet(uchar ip[IPaddrlen])
322 for(i=0; i<nsnet; i++){
324 maskip(ip, t->mask, x);
325 if(ipcmp(x, t->ip) == 0)
332 reportsubnet(Conn *c, Snet *t)
334 if(c == nil || !(t->deleted || t->owner->connected))
339 if(t->deleted != t->reported)
341 t->reported = !t->deleted;
342 for(x = myhost->link; x != nil; x = x->next)
343 if(x->dst->conn != lconn && x->dst->from == myhost)
344 reportsubnet(x->dst->conn, t);
347 if(t->owner == c->host)
350 consend(c, "%d %x %s %I/%d#%d", DEL_SUBNET, rand(),
351 t->owner->name, t->ip, t->prefixlen, t->weight);
353 consend(c, "%d %x %s %I/%d#%d", ADD_SUBNET, rand(), t->owner->name,
354 t->ip, t->prefixlen, t->weight);
357 reportedge(Conn *c, Edge *e)
359 if(c == nil || !(e->deleted || e->src->connected && e->dst->connected))
364 if(e->deleted != e->reported)
366 e->reported = !e->deleted;
367 for(x = myhost->link; x != nil; x = x->next)
368 if(x->dst->conn != lconn && x->dst->from == myhost)
369 reportedge(x->dst->conn, e);
372 if(e->src == c->host)
375 if(e->dst == c->host)
377 consend(c, "%d %x %s %s", DEL_EDGE, rand(),
378 e->src->name, e->dst->name);
380 consend(c, "%d %x %s %s %I %d %x %d", ADD_EDGE, rand(),
381 e->src->name, e->dst->name,
382 e->ip, e->port, e->options, e->weight);
388 static int hostup = 0;
397 qsort(edges, nedges, sizeof(edges[0]), edgepcmp);
398 while(nedges > 0 && edges[nedges-1]->deleted){
399 reportedge(bcast, edges[--nedges]);
403 for(h = hosts; h != nil; h = h->next) h->from = nil;
405 myhost->from = myhost;
406 myhost->connected = 1;
409 for(i=0; i<nedges; i++){
411 if(e->src->from == nil || (h = e->dst)->from != nil)
413 memmove(h->ip, e->ip, IPaddrlen);
415 h->options = e->options;
417 if(h->connected == 0){
419 for(t = h->snet; t != nil; t = t->next)
423 fprint(rcfd, "NAME=%s NODE=%s DEVICE=%s INTERFACE=%I"
424 " REMOTENET=%s REMOTEADDRESS=%I REMOTEPORT=%d"
426 myname, h->name, device, localip,
427 outside, h->ip, h->port,
433 for(h = hosts; h != nil; h = h->next){
434 if(h->from == nil && h->connected){
438 fprint(rcfd, "NAME=%s NODE=%s DEVICE=%s INTERFACE=%I"
439 " REMOTENET=%s REMOTEADDRESS=%I REMOTEPORT=%d"
440 " ./hosts/%s-down\n",
441 myname, h->name, device, localip,
442 outside, h->ip, h->port,
445 while(h->link != nil) {
446 deledge(h->link->rev);
449 while(h->snet != nil) delsubnet(h->snet);
453 i = myhost->link != nil;
457 fprint(rcfd, "NAME=%s NODE=%s DEVICE=%s INTERFACE=%I"
458 " REMOTENET=%s REMOTEADDRESS=%I REMOTEPORT=%d"
460 myname, myhost->name, device, localip,
461 outside, myhost->ip, myhost->port,
462 hostup ? "up" : "down");
466 qsort(snet, nsnet, sizeof(snet[0]), subnetpcmp);
467 for(i = nsnet-1; i >= 0; i--){
470 if(t->owner != myhost && (t->deleted || t->reported == 0))
471 fprint(rcfd, "NAME=%s NODE=%s DEVICE=%s INTERFACE=%I"
472 " REMOTENET=%s REMOTEADDRESS=%I REMOTEPORT=%d"
473 " SUBNET=(%I %M) WEIGHT=%d"
475 myname, t->owner->name, device, localip,
476 outside, t->owner->ip, t->owner->port,
477 t->ip, t->mask, t->weight,
478 t->deleted ? "down" : "up");
480 reportsubnet(bcast, t);
482 assert(i == nsnet-1);
489 qsort(edges, nedges, sizeof(edges[0]), edgepcmp);
490 for(i = nedges-1; i >= 0; i--){
491 reportedge(bcast, edges[i]);
492 if(edges[i]->deleted){
493 assert(i == nedges-1);
502 getsubnet(Host *h, char *s, int new)
504 uchar ip[IPaddrlen], mask[IPaddrlen];
505 int weight, prefixlen;
508 if(parseipandmask(ip, mask, s, strchr(s, '/')) == -1)
511 for(prefixlen = 0; prefixlen < 128; prefixlen++)
512 if((mask[prefixlen/8] & (0x80 >> (prefixlen%8))) == 0)
517 maskip(ip, mask, ip);
520 if((s = strchr(s, '#')) != nil)
523 for(t = h->snet; t != nil; t = t->next)
524 if(ipcmp(t->ip, ip) == 0 && ipcmp(t->mask, mask) == 0){
533 t = emalloc(sizeof(Snet));
535 ipmove(t->mask, mask);
536 t->prefixlen = prefixlen;
541 if((nsnet % 16) == 0)
542 snet = erealloc(snet, sizeof(snet[0])*(nsnet+16));
552 if(t == nil || t->deleted)
554 for(tp = &t->owner->snet; *tp != nil; tp = &(*tp)->next){
565 getedge(Host *src, Host *dst, int new)
569 for(e = src->link; e != nil; e = e->next)
574 e = emalloc(sizeof(Edge));
575 e->weight = MaxWeight;
580 if((e->rev = getedge(dst, src, 0)) != nil)
582 if((nedges % 16) == 0)
583 edges = erealloc(edges, sizeof(edges[0])*(nedges+16));
593 if(e == nil || e->deleted)
596 if(e->rev->rev != nil){
597 assert(e->rev->rev == e);
602 for(ep = &e->src->link; *ep != nil; ep = &((*ep)->next))
609 e->weight = MaxWeight;
611 memset(e->ip, 0, IPaddrlen);
616 gethost(char *name, int new)
618 char buf[8*1024], *s, *e, *x;
622 if(*name == 0 || *name == '.' || strchr(name, '/') != nil)
625 for(h = hosts; h != nil; h = h->next)
626 if(strcmp(h->name, name) == 0)
630 snprint(buf, sizeof(buf), "hosts/%s", name);
631 if((fd = open(buf, OREAD)) >= 0){
632 n = read(fd, buf, sizeof(buf)-1);
642 h = emalloc(sizeof(Host));
643 h->name = estrdup(name);
644 h->addr = estrdup(name);
647 h->options = OptClampMss|OptPmtuDiscov;
653 if((s = (char*)decodePEM(buf, "RSA PUBLIC KEY", &n, nil)) != nil){
654 h->rsapub = asn1toRSApub((uchar*)s, n);
657 for(s = buf; s != nil; s = e){
660 if((e = strchr(s, '\n')) != nil)
662 if(*s == '#' || (x = strchr(s, '=')) == nil)
665 if((n = tokenize(s, f, 2)) != 2)
667 if(cistrcmp(f[0], "Address") == 0){
668 if(tokenize(f[1], f, 2) > 1)
669 h->port = atoi(f[1]);
671 h->addr = estrdup(f[0]);
674 if(cistrcmp(f[0], "IndirectData") == 0){
675 h->options |= OptIndirect*(cistrcmp(f[1], "yes") == 0);
678 if(cistrcmp(f[0], "TCPonly") == 0){
679 h->options |= OptTcpOnly*(cistrcmp(f[1], "yes") == 0);
682 if(cistrcmp(f[0], "ClampMSS") == 0){
683 h->options &= ~(OptClampMss*(cistrcmp(f[1], "no") == 0));
686 if(cistrcmp(f[0], "PMTUDiscovery") == 0){
687 h->options &= ~(OptPmtuDiscov*(cistrcmp(f[1], "no") == 0));
690 if(cistrcmp(f[0], "PMTU") == 0){
691 h->pmtu = atoi(f[1]);
692 if(h->pmtu > MaxPacket)
694 else if(h->pmtu < 512)
698 if(cistrcmp(f[0], "Port") == 0){
699 h->port = atoi(f[1]);
702 if(cistrcmp(f[0], "Subnet") == 0){
704 getsubnet(h, f[1], 1);
708 parseip(h->ip, h->addr);
715 findhost(uchar ip[IPaddrlen], int port)
720 for(h = hosts; h != nil; h = h->next){
721 if(ipcmp(ip, h->ip) == 0 && (port == -1 || port == h->port))
736 if(myhost->rsapub == nil){
737 werrstr("no RSA public key");
740 if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
742 if((rpc = auth_allocrpc(afd)) == nil){
747 s = smprint("proto=rsa service=tinc role=client host=%q", myhost->name);
748 r = auth_rpc(rpc, "start", s, strlen(s));
753 werrstr("no key found");
754 while(auth_rpc(rpc, "read", nil, 0) == ARok){
756 if(strtomp(s, &s, 16, m) == nil)
758 if(mpcmp(m, myhost->rsapub->n) != 0)
770 putrsarpc(AuthRpc *rpc)
785 memmove(c->buf, c->rp, c->wp - c->rp);
786 c->wp -= (c->rp - c->buf);
789 if((n = read(c->fd, c->wp, &c->buf[sizeof(c->buf)] - c->wp)) <= 0)
791 if(c->cin->crypt != nil)
792 (*c->cin->crypt)((uchar*)c->wp, n, c->cin->cs);
797 conwrite(Conn *c, char *s, int n)
799 if(c->cout->crypt != nil)
800 (*c->cout->crypt)((uchar*)s, n, c->cout->cs);
801 if(write(c->fd, s, n) != n)
807 conrecv(Conn *c, char **f, int nf)
812 if(c->wp > c->rp && (e = memchr(s = c->rp, '\n', c->wp - c->rp)) != nil){
815 if(debug) fprint(2, "<-%s %s\n", c->host != nil ? c->host->name : "???", s);
816 return tokenize(s, f, nf);
818 } while(conread(c) > 0);
822 consend(Conn *c, char *fmt, ...)
832 n = vsnprint(buf, sizeof(buf)-2, fmt, a);
839 if(debug) fprint(2, "->%s %s", c->host != nil ? c->host->name : "???", buf);
840 n = conwrite(c, buf, n);
847 recvudp(Host *h, int fd)
849 uchar buf[4+MaxPacket+AESbsize+MAClen], mac[SHA2_256dlen];
854 if((n = read(fd, buf, sizeof(buf))) <= 0)
857 if(h->cin->crypt == nil || (n -= MAClen) < AESbsize){
861 hmac_sha2_256(buf, n, h->cin->key, sizeof(h->cin->key), mac, nil);
862 if(tsmemcmp(mac, buf+n, MAClen) != 0){
866 memmove(cs, h->cin->cs, sizeof(cs));
867 (*h->cin->crypt)(buf, n, cs);
868 if((n -= buf[n-1]) < 4){
878 if((o = (int)(seq - h->cin->seq)) > 0){
880 h->ooo = o < 64 ? h->ooo<<o | 1ULL : 0ULL;
883 if(o >= 64 || (h->ooo & 1ULL<<o) != 0){
893 if(n >= 4+14 && buf[4+12] == 0 && buf[4+13] == 0){
896 sendudp(h, fd, buf+4, n-4);
901 routepkt(h, buf+4, n-4);
905 sendudp(Host *h, int fd, uchar *p, int n)
907 uchar buf[4+MaxPacket+AESbsize+SHA2_256dlen];
912 if(fd < 0 || n > MaxPacket)
915 if(h->cout->crypt == nil){
921 seq = ++h->cout->seq;
927 memmove(buf+4, p, n), n += 4;
928 pad = AESbsize - ((uint)n % AESbsize);
929 memset(buf+n, pad, pad), n += pad;
930 memmove(cs, h->cout->cs, sizeof(cs));
931 (*h->cout->crypt)(buf, n, cs);
932 hmac_sha2_256(buf, n, h->cout->key, sizeof(h->cout->key), buf+n, nil);
935 if(write(fd, buf, n) != n)
937 if((seq & 0xFFFFF) == 0) needkey(h);
942 sendtcp(Host *h, uchar *p, int n)
948 if((c = h->conn) == nil)
950 m = snprint(buf, sizeof(buf), "17 %d\n", n);
952 if(conwrite(c, buf, m) < 0
953 || conwrite(c, (char*)p, n) < 0)
962 forward(Host *s, Host *d, uchar *p, int n)
966 while(d != s && d != myhost){
967 if(n <= d->pmtu && sendudp(d, d->udpfd, p, n) == 0)
969 if(sendtcp(d, p, n) == 0)
976 updatebyte(int csum, uchar *b, uchar *p, int v)
983 if(((p - b) & 1) == 0){
989 while(v = csum >> 16)
990 csum = (csum & 0xFFFF) + v;
995 clampmss(Host *d, uchar *p, int n, int o)
997 int oldmss, newmss, csum;
1000 if(n <= TcpHdr || (p[13]&2) == 0 || (d->options & OptClampMss) == 0)
1002 if((e = p+(p[12]>>4)*4) > p+n)
1004 for(h = p+TcpHdr; h < e;){
1012 if(h[1] < 2 || h[1] > e - h)
1014 if(h[0] == 2 && h[1] == 4)
1020 oldmss = h[2]<<8 | h[3];
1021 newmss = myhost->pmtu;
1022 if(d->pmtu < newmss)
1024 newmss -= o + TcpHdr;
1025 if(oldmss <= newmss)
1027 if(debug) fprint(2, "clamping tcp mss %d -> %d for %s\n", oldmss, newmss, d->name);
1028 csum = (p[16]<<8 | p[17]) ^ 0xFFFF;
1029 csum = updatebyte(csum, p, h+2, newmss>>8);
1030 csum = updatebyte(csum, p, h+3, newmss);
1037 routepkt(Host *s, uchar *p, int n)
1039 uchar src[IPaddrlen], dst[IPaddrlen];
1046 switch(p[EtherType+0]<<8 | p[EtherType+1]){
1049 case 0x8100: /* VLAN */
1050 memmove(p+4, p, 2*Eaddrlen);
1053 case 0x0800: /* IPv4 */
1054 case 0x86DD: /* IPv6 */
1057 switch(p[EtherHdr] & 0xF0){
1061 o = EtherHdr+(p[EtherHdr] & 15)*4;
1062 if(n < EtherHdr+Ip4Hdr || n < o)
1064 type = p[EtherHdr+9];
1065 v4tov6(src, p+EtherHdr+12);
1066 v4tov6(dst, p+EtherHdr+16);
1069 o = EtherHdr+Ip6Hdr;
1072 type = p[EtherHdr+6];
1073 memmove(src, p+EtherHdr+8, 16);
1074 memmove(dst, p+EtherHdr+24, 16);
1078 if((t = lookupnet(dst)) != nil){
1079 if(type == 6) /* TCP */
1080 clampmss(t->owner, p+o, n-o, o);
1081 if(t->owner == myhost)
1082 write(ipdfd, p+EtherHdr, n-EtherHdr);
1084 forward(s, t->owner, p, n);
1090 updateweight(Edge *e, int ms)
1092 e->weight = (e->weight + ms) / 2;
1107 c->pingtime = nsec();
1108 if(consend(c, "%d %s 17", ID, myhost->name) < 0)
1110 n = conrecv(c, f, nelem(f));
1111 if(n != 3 || atoi(f[0]) != ID || atoi(f[2]) != 17)
1113 if((c->host = gethost(f[1], 0)) == nil
1114 || c->host == myhost || c->host->rsapub == nil)
1117 n1 = (mpsignif(c->host->rsapub->n)+7)/8;
1118 if(n1 < AESkeylen+AESbsize || n1 > sizeof(b))
1120 n2 = (mpsignif(myhost->rsapub->n)+7)/8;
1121 if(n2 < AESkeylen+AESbsize || n2 > sizeof(b))
1124 m = mpnrand(c->host->rsapub->n, genrandom, nil);
1126 setupAESstate(c->cout->cs, b+n1-AESkeylen, AESkeylen, b+n1-AESkeylen-AESbsize);
1127 rsaencrypt(c->host->rsapub, m, m);
1130 if(consend(c, "%d %d %d 0 0 %.*H", META_KEY, EVP_AES256CFB, EVP_SHA256, n1, b) < 0)
1132 c->cout->crypt = aesCFBencrypt;
1134 n = conrecv(c, f, nelem(f));
1135 if(n != 6 || atoi(f[0]) != META_KEY || strlen(f[5]) != 2*n2)
1137 if(atoi(f[1]) != EVP_AES256CFB || atoi(f[2]) != EVP_SHA256){
1138 fprint(2, "%s uses unknown cipher/digest agorithms: %s %s\n",
1139 c->host->name, f[1], f[2]);
1143 if((rpc = getrsarpc()) == nil
1144 || auth_rpc(rpc, "write", f[5], strlen(f[5])) != ARok
1145 || auth_rpc(rpc, "read", nil, 0) != ARok){
1150 m = strtomp(rpc->arg, nil, 16, nil);
1154 setupAESstate(c->cin->cs, b+n2-AESkeylen, AESkeylen, b+n2-AESkeylen-AESbsize);
1155 c->cin->crypt = aesCFBdecrypt;
1157 h = mpnrand(c->host->rsapub->n, genrandom, nil);
1159 if(consend(c, "%d %.*H", CHALLENGE, n1, b) < 0){
1163 sha2_256(b, n1, b, nil);
1164 betomp(b, SHA2_256dlen, h);
1166 n = conrecv(c, f, nelem(f));
1167 if(n != 2 || atoi(f[0]) != CHALLENGE){
1171 m = strtomp(f[1], nil, 16, nil);
1174 sha2_256(b, n2, b, nil);
1175 if(consend(c, "%d %.*H", CHAL_REPLY, SHA2_256dlen, b) < 0){
1179 n = conrecv(c, f, nelem(f));
1180 if(n != 2 || atoi(f[0]) != CHAL_REPLY){
1184 m = strtomp(f[1], nil, 16, nil);
1190 ms = (nsec() - c->pingtime)/1000000LL;
1191 if(consend(c, "%d %d %d %x", ACK, myhost->port, ms, myhost->options) < 0)
1193 n = conrecv(c, f, nelem(f));
1194 if(n != 4 || atoi(f[0]) != ACK)
1198 e = getedge(myhost, c->host, 1);
1199 memmove(e->ip, c->ip, IPaddrlen);
1200 e->port = atoi(f[1]);
1201 e->weight = atoi(f[2]);
1202 e->options = strtol(f[3], nil, 16);
1203 updateweight(e, ms);
1215 while(to != nil && to != myhost){
1229 genrandom(to->cin->key, sizeof(to->cin->key));
1230 setupAESstate(to->cin->cs, to->cin->key, AESkeylen, to->cin->key+AESkeylen);
1231 to->cin->crypt = aesCBCdecrypt;
1234 consend(nearcon(to), "%d %s %s %.*H %d %d %d %d", ANS_KEY,
1235 myhost->name, to->name,
1236 sizeof(to->cin->key), to->cin->key,
1237 EVP_AES256CBC, EVP_SHA256, MAClen, 0);
1242 consend(nearcon(from), "%d %s %s", REQ_KEY, myhost->name, from->name);
1245 recvkey(Host *from, char **f)
1247 uchar key[sizeof(from->cout->key)];
1250 if(atoi(f[1]) != EVP_AES256CBC || atoi(f[2]) != EVP_SHA256
1251 || atoi(f[3]) != MAClen || atoi(f[4]) != 0){
1252 fprint(2, "%s key uses unknown parameters: %s %s %s %s\n",
1253 from->name, f[1], f[2], f[3], f[4]);
1256 if(strlen(f[0]) != sizeof(key)*2)
1258 if((m = strtomp(f[0], nil, 16, nil)) == nil)
1260 mptober(m, key, sizeof(key));
1263 if(tsmemcmp(key, from->cout->key, sizeof(key)) == 0)
1265 from->cout->seq = 0;
1266 memmove(from->cout->key, key, sizeof(key));
1267 setupAESstate(from->cout->cs, from->cout->key, AESkeylen, from->cout->key+AESkeylen);
1268 from->cout->crypt = aesCBCencrypt;
1271 memset(key, 0, sizeof(key));
1274 clearkey(Host *from)
1277 from->cout->crypt = nil;
1278 from->cout->seq = 0;
1279 memset(from->cout->cs, 0, sizeof(from->cout->cs));
1280 genrandom(from->cout->key, sizeof(from->cout->key));
1294 for(i=0; i<nsnet; i++)
1295 reportsubnet(c, snet[i]);
1296 for(i=0; i<nedges; i++)
1297 reportedge(c, edges[i]);
1301 while((n = conrecv(c, f, nelem(f))) > 0){
1304 if(consend(c, "%d %x", PONG, rand()) < 0)
1309 if(c->pingtime != 0){
1310 if((e = getedge(myhost, c->host, 0)) != nil)
1311 updateweight(e, (nsec() - c->pingtime) / 1000000LL);
1317 if(n != 4 || (h = gethost(f[2], 1)) == nil || h == myhost)
1320 getsubnet(h, f[3], 1);
1324 if(n != 4 || (h = gethost(f[2], 0)) == nil || h == myhost)
1327 if((t = getsubnet(h, f[3], 0)) != nil)
1332 if(n != 8 || (h = gethost(f[2], 1)) == nil || h == myhost
1333 || (r = gethost(f[3], 1)) == nil)
1336 if((e = getedge(h, r, 1)) != nil){
1337 if(parseip(e->ip, f[4]) == -1)
1338 memmove(e->ip, r->ip, IPaddrlen);
1339 e->port = atoi(f[5]);
1340 e->weight = atoi(f[7]);
1341 e->options = strtol(f[6], nil, 16);
1346 if(n != 4 || (h = gethost(f[2], 0)) == nil || h == myhost
1347 || (r = gethost(f[3], 1)) == nil)
1350 if((e = getedge(h, r, 0)) != nil)
1355 if(n != 3 || (h = gethost(f[2], 0)) == nil || h == myhost)
1359 for(e = myhost->link; e != nil; e = e->next)
1360 if(e->dst->conn != c && e->dst->from == myhost)
1361 consend(e->dst->conn, "%s %s %s", f[0], f[1], f[2]);
1365 if(n != 3 || (h = gethost(f[1], 0)) == nil || h == myhost
1366 || (r = gethost(f[2], 0)) == nil)
1370 consend(nearcon(r), "%s %s %s", f[0], f[1], f[2]);
1376 if(n != 8 || (h = gethost(f[1], 0)) == nil || h == myhost
1377 || (r = gethost(f[2], 0)) == nil)
1381 consend(nearcon(r), "%s %s %s %s %s %s %s %s",
1382 f[0], f[1], f[2], f[3],
1383 f[4], f[5], f[6], f[7]);
1392 if(n < 0 || n > MaxPacket)
1394 while((c->wp - c->rp) < n && conread(c) > 0)
1396 if(c->wp - c->rp < n)
1398 routepkt(c->host, (uchar*)c->rp, n);
1406 tcpclient(int fd, int incoming)
1411 c = emalloc(sizeof(Conn));
1414 c->rp = c->wp = c->buf;
1415 c->port = dir2ipport(fd2dir(fd, dir, sizeof(dir)), c->ip);
1416 procsetname("tcpclient %s %s %s %I!%d", myhost->name,
1417 incoming ? "in" : "out", dir, c->ip, c->port);
1418 if(metaauth(c) == 0){
1419 procsetname("tcpclient %s %s %s %I!%d %s", myhost->name,
1420 incoming ? "in" : "out", dir, c->ip, c->port, c->host->name);
1424 if(c->host != nil && c->host->conn == c){
1425 c->host->conn = nil;
1426 if(c->edge != nil && c->edge->dst == c->host){
1427 deledge(c->edge->rev);
1430 hangupfd(c->host->udpfd);
1433 memset(c, 0, sizeof(*c));
1439 udpclient(int fd, int incoming)
1441 uchar ip[IPaddrlen];
1446 port = dir2ipport(fd2dir(fd, dir, sizeof(dir)), ip);
1447 h = findhost(ip, port);
1448 if(h == nil && incoming)
1449 h = findhost(ip, -1); /* might be behind NAT */
1450 if(h != nil && h != myhost){
1451 procsetname("udpclient %s %s %s %I!%d %s", myhost->name,
1452 incoming ? "in": "out", dir, ip, port, h->name);
1463 } while(recvudp(h, fd) == 0);
1477 dialer(char *proto, char *host, int rport, int lport)
1479 char addr[40], local[16];
1482 snprint(local, sizeof(local), "%d", lport);
1483 snprint(addr, sizeof(addr), "%s/%s!%s!%d", outside, proto, host, rport);
1484 procsetname("dialer %s %s", myhost->name, addr);
1487 if((dfd = dial(addr, lport ? local : nil, nil, nil)) >= 0){
1488 switch(rfork(RFPROC|RFMEM)){
1503 listener(char *proto, int port, int nprocs)
1505 char addr[40], adir[40], ldir[40];
1506 int acfd, lcfd, dfd;
1508 snprint(addr, sizeof(addr), "%s/%s!*!%d", outside, proto, port);
1509 procsetname("listener %s %s", myhost->name, addr);
1511 if((acfd = announce(addr, adir)) < 0)
1513 while((lcfd = listen(adir, ldir)) >= 0){
1514 if((dfd = accept(lcfd, ldir)) >= 0)
1515 switch(rfork(RFPROC|RFMEM)){
1517 if(nprocs > 1 || waitpid() < 0) nprocs--;
1536 procsetname("pingpong %s", myhost->name);
1538 sleep(15*1000 + (rand() % 3000));
1540 for(e = myhost->link; e != nil; e = e->next){
1541 if((c = e->dst->conn) != nil){
1542 if(c->pingtime != 0){
1546 c->pingtime = nsec();
1547 consend(c, "%d %x", PING, rand());
1559 snprint(device, sizeof device, "%s/ipifc/clone", inside);
1560 if((ipcfd = open(device, ORDWR)) < 0)
1561 sysfatal("can't open ip interface: %r");
1562 if((n = read(ipcfd, device, sizeof device - 1)) <= 0)
1563 sysfatal("can't read interface number: %r");
1565 snprint(device, sizeof device, "%s/ipifc/%d/data", inside, atoi(device));
1566 if((ipdfd = open(device, ORDWR)) < 0)
1567 sysfatal("can't open ip data: %r");
1568 fprint(ipcfd, "bind pkt");
1569 fprint(ipcfd, "mtu %d", myhost->pmtu-EtherHdr);
1570 fprint(ipcfd, "add %I %M", localip, localmask);
1571 *strrchr(device, '/') = 0;
1577 uchar buf[MaxPacket];
1580 procsetname("ip2tunnel %s %s %I %M", myhost->name,
1581 fd2dir(ipdfd, (char*)buf, sizeof(buf)),
1582 localip, localmask);
1583 while((n = read(ipdfd, buf+EtherHdr, sizeof buf-EtherHdr)) > 0){
1584 memset(buf, 0, 2*Eaddrlen);
1585 if((buf[EtherHdr]&0xF0) == 0x60){
1586 buf[EtherType+0] = 0x86;
1587 buf[EtherType+1] = 0xDD;
1589 buf[EtherType+0] = 0x08;
1590 buf[EtherType+1] = 0x00;
1592 routepkt(myhost, buf, n+EtherHdr);
1597 catch(void*, char *msg)
1599 if(strcmp(msg, "alarm") == 0 || strcmp(msg, "interrupt") == 0)
1606 postnote(PNGROUP, getpid(), "shutdown");
1612 fprint(2, "%s [-d] [-p maxprocs] [-x inside] [-o outside] [-c confdir] [-n myname] "
1613 "localip localmask [host...]\n", argv0);
1618 main(int argc, char *argv[])
1626 fmtinstall('I', eipfmt);
1627 fmtinstall('M', eipfmt);
1628 fmtinstall('H', encodefmt);
1635 if((maxprocs = atoi(EARGF(usage()))) < 1)
1636 sysfatal("bad number of procs");
1639 if(chdir(EARGF(usage())) < 0)
1640 sysfatal("can't change directory: %r");
1643 myname = EARGF(usage());
1646 outside = inside = EARGF(usage());
1649 outside = EARGF(usage());
1657 if(parseipandmask(localip, localmask, argv[0], argv[1]) == -1)
1658 sysfatal("bad local ip/mask: %s/%s", argv[0], argv[1]);
1659 argv += 2, argc -= 2;
1664 if((myhost = gethost(myname, 0)) == nil)
1665 sysfatal("can't get my host: %r");
1666 if((rpc = getrsarpc()) == nil)
1667 sysfatal("can't find my key in factotum: %r");
1670 for(i = 0; i < argc; i++){
1671 if((h = gethost(argv[i], 0)) == nil)
1672 sysfatal("unknown host: %s", *argv);
1674 sysfatal("will not connect to myself");
1675 if(h->rsapub == nil)
1676 sysfatal("no RSA public key for: %s", h->name);
1679 if(myhost->snet == nil){
1681 snprint(snet, sizeof(snet), "%I/128", localip);
1682 getsubnet(myhost, snet, 1);
1684 if((t = lookupnet(localip)) == nil)
1685 sysfatal("no subnet found for local ip %I", localip);
1686 if(t->owner != myhost)
1687 sysfatal("local ip %I belongs to host %s subnet %I %M",
1688 localip, t->owner->name, t->ip, t->mask);
1691 sysfatal("can't create pipe: %r");
1692 switch(rfork(RFPROC|RFFDG|RFREND|RFNOTEG|RFENVG)){
1694 sysfatal("can't fork: %r");
1701 while(open("/dev/null", OWRITE) == 1)
1704 execl("/bin/rc", "rc", debug? "-v": nil, nil);
1705 sysfatal("can't exec: %r");
1712 switch(rfork(RFPROC|RFFDG|RFREND|RFNOTEG)){
1714 sysfatal("can't fork: %r");
1720 fprint(ipcfd, "unbind");
1726 fprint(rcfd, "NAME=%s NODE=%s DEVICE=%s INTERFACE=%I ./tinc-up\n",
1727 myname, myhost->name, device, localip);
1729 if(rfork(RFPROC|RFMEM) == 0){
1730 tcpclient(listener("tcp", myhost->port, maxprocs), 1);
1733 if((myhost->options & OptTcpOnly) == 0)
1734 if(rfork(RFPROC|RFMEM) == 0){
1735 udpclient(listener("udp", myhost->port, maxprocs), 1);
1738 for(i = 0; i < argc; i++){
1739 if((h = gethost(argv[i], 0)) == nil)
1741 if(rfork(RFPROC|RFMEM) == 0){
1742 tcpclient(dialer("tcp", h->addr, h->port, myhost->port), 0);
1745 if((h->options & OptTcpOnly) == 0)
1746 if(rfork(RFPROC|RFMEM) == 0){
1747 udpclient(dialer("udp", h->addr, h->port, myhost->port), 0);
1751 if(rfork(RFPROC|RFMEM) == 0){
1757 fprint(rcfd, "NAME=%s NODE=%s DEVICE=%s INTERFACE=%I ./tinc-down\n",
1758 myname, myhost->name, device, localip);