ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn.C
Revision: 1.68
Committed: Wed Jul 15 23:04:06 2015 UTC (8 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.67: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 vpn.C -- handle the protocol, encryption, handshaking etc.
3 Copyright (C) 2003-2008,2010,2011,2013 Marc Lehmann <gvpe@schmorp.de>
4
5 This file is part of GVPE.
6
7 GVPE is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, see <http://www.gnu.org/licenses/>.
19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this Program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a modified
24 version of that library), containing parts covered by the terms of the
25 OpenSSL or SSLeay licenses, the licensors of this Program grant you
26 additional permission to convey the resulting work. Corresponding
27 Source for a non-source form of such a combination shall include the
28 source code for the parts of OpenSSL used as well as that of the
29 covered work.
30 */
31
32 #include "config.h"
33
34 #include <list>
35
36 #include <cstdio>
37 #include <cstring>
38 #include <cstdlib>
39
40 #include <sys/types.h>
41 #include <sys/socket.h>
42 #include <sys/wait.h>
43 #include <sys/stat.h>
44 #include <errno.h>
45 #include <time.h>
46 #include <unistd.h>
47 #include <fcntl.h>
48 #include <sys/socket.h>
49
50 #include "netcompat.h"
51
52 #include "pidfile.h"
53
54 #include "connection.h"
55 #include "util.h"
56 #include "vpn.h"
57
58 using namespace std;
59
60 vpn network; // THE vpn (bad design...)
61
62 /////////////////////////////////////////////////////////////////////////////
63
64 static void inline
65 set_tos (int fd, int &tos_prev, int tos)
66 {
67 #if defined(SOL_IP) && defined(IP_TOS)
68 if (tos_prev == tos)
69 return;
70
71 tos_prev = tos;
72 setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos);
73 #endif
74 }
75
76 void
77 vpn::script_init_env ()
78 {
79 // the tunnel device mtu should be the physical mtu - overhead
80 // the tricky part is rounding to the cipher key blocksize
81 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD;
82 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion
83 mtu -= mtu % BLOCK_SIZE (CIPHER); // round
84 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again
85
86 char *env;
87 asprintf (&env, "CONFBASE=%s", confbase); putenv (env);
88 asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env);
89 asprintf (&env, "IFTYPE=%s", IFTYPE); putenv (env);
90 asprintf (&env, "IFSUBTYPE=%s", IFSUBTYPE); putenv (env);
91 asprintf (&env, "MTU=%d", mtu); putenv (env);
92 asprintf (&env, "NODES=%d", conns.size ()); putenv (env);
93 asprintf (&env, "NODEID=%d", THISNODE->id); putenv (env);
94
95 conns [THISNODE->id - 1]->script_init_env ("");
96
97 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
98 {
99 char ext[16];
100 snprintf (ext, 16, "_%d", (*c)->conf->id);
101 (*c)->script_init_env (ext);
102 }
103 }
104
105 inline const char *
106 vpn::script_if_init ()
107 {
108 script_init_env ();
109
110 return tap->if_up ();
111 }
112
113 inline const char *
114 vpn::script_if_up ()
115 {
116 script_init_env ();
117
118 return conf.config_filename (::conf.script_if_up, "if-up");
119 }
120
121 int
122 vpn::setup_socket (u8 prot, int family, int type, int proto)
123 {
124 int fd = socket (family, type, proto);
125
126 if (fd < 0)
127 {
128 slog (L_ERR, _("unable to create %s socket: %s."), strprotocol (prot), strerror (errno));
129 return fd;
130 }
131
132 fcntl (fd, F_SETFL, O_NONBLOCK);
133 fcntl (fd, F_SETFD, FD_CLOEXEC);
134
135 #ifdef SO_MARK
136 if (::conf.nfmark)
137 if (setsockopt (fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark))
138 slog (L_WARN, _("unable to set nfmark on %s socket: %s"), strprotocol (prot), strerror (errno));
139 #endif
140
141 return fd;
142 }
143
144 int
145 vpn::setup ()
146 {
147 int success = 0;
148
149 ipv4_tos = -1;
150 ipv4_fd = -1;
151
152 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
153 {
154 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
155
156 if (ipv4_fd < 0)
157 return -1;
158
159 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
160 // this I really consider a linux bug. I am neither connected
161 // nor do I fragment myself. Linux still sets DF and doesn't
162 // fragment for me sometimes.
163 {
164 int oval = IP_PMTUDISC_DONT;
165 setsockopt (ipv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
166 }
167 #endif
168
169 sockinfo si (THISNODE, PROT_IPv4);
170
171 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
172 {
173 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
174 return -1;
175 }
176
177 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
178 ++success;
179 }
180 else
181 THISNODE->protocols &= ~PROT_IPv4;
182
183 udpv4_tos = -1;
184 udpv4_fd = -1;
185
186 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
187 {
188 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
189
190 if (udpv4_fd < 0)
191 return -1;
192
193 // standard daemon practise...
194 {
195 int oval = 1;
196 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
197 }
198
199 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
200 // this I really consider a linux bug. I am neither connected
201 // nor do I fragment myself. Linux still sets DF and doesn't
202 // fragment for me sometimes.
203 {
204 int oval = IP_PMTUDISC_DONT;
205 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
206 }
207 #endif
208
209 sockinfo si (THISNODE, PROT_UDPv4);
210
211 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
212 {
213 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
214 return -1;
215 }
216
217 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
218 ++success;
219 }
220 else
221 THISNODE->protocols &= ~PROT_UDPv4;
222
223 icmpv4_tos = -1;
224 icmpv4_fd = -1;
225
226 #if ENABLE_ICMP
227 if (THISNODE->protocols & PROT_ICMPv4)
228 {
229 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
230
231 if (icmpv4_fd < 0)
232 return -1;
233
234 #ifdef ICMP_FILTER
235 {
236 icmp_filter oval;
237 oval.data = 0xffffffff;
238 if (::conf.icmp_type < 32)
239 oval.data &= ~(1 << ::conf.icmp_type);
240
241 setsockopt (icmpv4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval);
242 }
243 #endif
244
245 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
246 // this I really consider a linux bug. I am neither connected
247 // nor do I fragment myself. Linux still sets DF and doesn't
248 // fragment for me sometimes.
249 {
250 int oval = IP_PMTUDISC_DONT;
251 setsockopt (icmpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
252 }
253 #endif
254
255 sockinfo si (THISNODE, PROT_ICMPv4);
256
257 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
258 {
259 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
260 return -1;
261 }
262
263 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
264 ++success;
265 }
266 #endif
267
268 tcpv4_fd = -1;
269
270 #if ENABLE_TCP
271 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
272 {
273 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
274
275 if (tcpv4_fd < 0)
276 return -1;
277
278 // standard daemon practise...
279 {
280 int oval = 1;
281 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
282 }
283
284 sockinfo si (THISNODE, PROT_TCPv4);
285
286 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
287 {
288 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
289 return -1;
290 }
291
292 if (listen (tcpv4_fd, 5))
293 {
294 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
295 return -1;
296 }
297
298 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
299 ++success;
300 }
301 else
302 THISNODE->protocols &= ~PROT_TCPv4;
303 #endif
304
305 dnsv4_tos = -1;
306 dnsv4_fd = -1;
307
308 #if ENABLE_DNS
309 if (THISNODE->protocols & PROT_DNSv4)
310 {
311 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
312
313 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
314
315 if (dnsv4_fd < 0)
316 return -1;
317
318 # if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
319 // this I really consider a linux bug. I am neither connected
320 // nor do I fragment myself. Linux still sets DF and doesn't
321 // fragment for me sometimes.
322 {
323 int oval = IP_PMTUDISC_DONT;
324 setsockopt (dnsv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
325 }
326 # endif
327
328 // standard daemon practise...
329 {
330 int oval = 1;
331 setsockopt (dnsv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
332 }
333
334 sockinfo si (THISNODE->dns_hostname,
335 THISNODE->dns_hostname ? THISNODE->dns_port : 0,
336 PROT_DNSv4);
337
338 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
339 {
340 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
341 return -1;
342 }
343
344 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
345 ++success;
346 }
347 #endif
348
349 /////////////////////////////////////////////////////////////////////////////
350
351 if (!success)
352 {
353 slog (L_ERR, _("no protocols enabled."));
354 return -1;
355 }
356
357 reconnect_all ();
358
359 /////////////////////////////////////////////////////////////////////////////
360
361 tap = new tap_device ();
362 if (!tap) //D this, of course, never catches
363 {
364 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
365 return -1;
366 }
367
368 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
369
370 run_script_cb cb;
371 cb.set<vpn, &vpn::script_if_init> (this);
372
373 if (tap->if_up () &&
374 !run_script (cb, true))
375 {
376 slog (L_ERR, _("interface initialization command '%s' failed."),
377 tap->if_up ());
378 return -1;
379 }
380
381 cb.set<vpn, &vpn::script_if_up> (this);
382 if (!run_script (cb, true))
383 {
384 slog (L_ERR, _("if-up command execution failed."));
385 return -1;
386 }
387
388 tap_ev_watcher.start (tap->fd, EV_READ);
389
390 return 0;
391 }
392
393 bool
394 vpn::drop_privileges ()
395 {
396 if (::conf.change_root)
397 {
398 if (!strcmp (::conf.change_root, "/"))
399 {
400 char dir [L_tmpnam];
401 if (!tmpnam (dir))
402 {
403 slog (L_CRIT, _("unable to create anonymous root path."));
404 return false;
405 }
406
407 if (mkdir (dir, 0700))
408 {
409 slog (L_CRIT, _("unable to create anonymous root directory."));
410 return false;
411 }
412
413 if (chdir (dir))
414 {
415 slog (L_CRIT, _("unable to change to anonymous root directory."));
416 return false;
417 }
418
419 if (rmdir (dir))
420 slog (L_ERR, _("unable to remove anonymous root directory, continuing."));
421 }
422 else
423 {
424 if (chdir (::conf.change_root))
425 {
426 slog (L_CRIT, _("%s: unable to change to specified root directory."), ::conf.change_root);
427 return false;
428 }
429 }
430
431 if (chroot ("."))
432 {
433 slog (L_CRIT, _("unable to set new root directory."));
434 return false;
435 }
436
437 if (chdir ("/"))
438 {
439 slog (L_CRIT, _("unable to set cwd to new root directory."));
440 return false;
441 }
442 }
443
444 if (::conf.change_gid)
445 if (setgid (::conf.change_gid))
446 {
447 slog (L_CRIT, _("unable to change group id to %d."), ::conf.change_gid);
448 return false;
449 }
450
451 if (::conf.change_uid)
452 if (setuid (::conf.change_uid))
453 {
454 slog (L_CRIT, _("unable to change user id to %d."), ::conf.change_uid);
455 return false;
456 }
457
458 return true;
459 }
460
461 bool
462 vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
463 {
464 set_tos (ipv4_fd, ipv4_tos, tos);
465 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
466
467 return true;
468 }
469
470 static u16
471 ipv4_checksum (u16 *data, unsigned int len)
472 {
473 // use 32 bit accumulator and fold back carry bits at the end
474 u32 sum = 0;
475
476 while (len > 1)
477 {
478 sum += *data++;
479 len -= 2;
480 }
481
482 // odd byte left?
483 if (len)
484 sum += *(u8 *)data;
485
486 // add back carry bits
487 sum = (sum >> 16) + (sum & 0xffff); // lo += hi
488 sum += (sum >> 16); // carry
489
490 return ~sum;
491 }
492
493 #if ENABLE_ICMP
494 bool
495 vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
496 {
497 pkt->unshift_hdr (4);
498
499 icmp_header *hdr = (icmp_header *)&((*pkt)[0]);
500 hdr->type = ::conf.icmp_type;
501 hdr->code = 255;
502 hdr->checksum = 0;
503 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
504
505 set_tos (icmpv4_fd, icmpv4_tos, tos);
506 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
507
508 return true;
509 }
510 #endif
511
512 bool
513 vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
514 {
515 set_tos (udpv4_fd, udpv4_tos, tos);
516 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
517
518 return true;
519 }
520
521 void
522 vpn::inject_data_packet (tap_packet *pkt, int dst)
523 {
524 if (dst)
525 {
526 // unicast
527 if (dst != THISNODE->id)
528 conns[dst - 1]->inject_data_packet (pkt);
529 }
530 else
531 {
532 // broadcast, this is ugly, but due to the security policy
533 // we have to connect to all hosts...
534 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
535 if ((*c)->conf != THISNODE)
536 (*c)->inject_data_packet (pkt);
537 }
538 }
539
540 void
541 vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
542 {
543 unsigned int src = pkt->src ();
544 unsigned int dst = pkt->dst ();
545
546 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d."),
547 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
548
549 if (src == 0 || src > conns.size ()
550 || dst > conns.size ()
551 || pkt->typ () >= vpn_packet::PT_MAX)
552 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
553 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
554 else
555 {
556 connection *c = conns[src - 1];
557
558 if (dst == 0)
559 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
560 c->conf->nodename, (const char *)rsi);
561 else if (dst != THISNODE->id)
562 {
563 if (THISNODE->routerprio)
564 // the tos setting gets lost here. who cares.
565 conns[dst - 1]->inject_vpn_packet (pkt);
566 else
567 slog (L_WARN,
568 _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."),
569 c->conf->nodename, (const char *)rsi,
570 conns[dst - 1]->conf->nodename);
571 }
572 else
573 c->recv_vpn_packet (pkt, rsi);
574 }
575 }
576
577 bool
578 vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
579 {
580 switch (si.prot)
581 {
582 case PROT_IPv4:
583 return send_ipv4_packet (pkt, si, tos);
584
585 case PROT_UDPv4:
586 return send_udpv4_packet (pkt, si, tos);
587
588 #if ENABLE_TCP
589 case PROT_TCPv4:
590 return send_tcpv4_packet (pkt, si, tos);
591 #endif
592 #if ENABLE_ICMP
593 case PROT_ICMPv4:
594 return send_icmpv4_packet (pkt, si, tos);
595 #endif
596 #if ENABLE_DNS
597 case PROT_DNSv4:
598 return send_dnsv4_packet (pkt, si, tos);
599 #endif
600 default:
601 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
602 }
603
604 return false;
605 }
606
607 inline void
608 vpn::ipv4_ev (ev::io &w, int revents)
609 {
610 if (revents & EV_READ)
611 {
612 vpn_packet *pkt = new vpn_packet;
613 struct sockaddr_in sa;
614 socklen_t sa_len = sizeof (sa);
615 int len;
616
617 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
618
619 sockinfo si(sa, PROT_IPv4);
620
621 if (len > 0)
622 {
623 pkt->len = len;
624
625 // raw sockets deliver the ipv4 header, but don't expect it on sends
626 pkt->skip_hdr (pkt->ipv4_hdr_len ());
627
628 recv_vpn_packet (pkt, si);
629 }
630 else
631 {
632 // probably ECONNRESET or somesuch
633 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
634 }
635
636 delete pkt;
637 }
638 else
639 {
640 slog (L_ERR,
641 _("FATAL: unknown revents %08x in socket, exiting.\n"),
642 revents);
643 exit (EXIT_FAILURE);
644 }
645 }
646
647 #if ENABLE_ICMP
648 inline void
649 vpn::icmpv4_ev (ev::io &w, int revents)
650 {
651 if (revents & EV_READ)
652 {
653 vpn_packet *pkt = new vpn_packet;
654 struct sockaddr_in sa;
655 socklen_t sa_len = sizeof (sa);
656 int len;
657
658 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
659
660 sockinfo si(sa, PROT_ICMPv4);
661
662 if (len > 0)
663 {
664 pkt->len = len;
665
666 icmp_header *hdr = (icmp_header *)&((*pkt)[IP_OVERHEAD]);
667
668 if (hdr->type == ::conf.icmp_type
669 && hdr->code == 255)
670 {
671 // raw sockets deliver the ipv4, but don't expect it on sends
672 // this is slow, but...
673 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
674
675 recv_vpn_packet (pkt, si);
676 }
677 }
678 else
679 {
680 // probably ECONNRESET or somesuch
681 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
682 }
683
684 delete pkt;
685 }
686 else
687 {
688 slog (L_ERR,
689 _("FATAL: unknown revents %08x in socket, exiting.\n"),
690 revents);
691 exit (EXIT_FAILURE);
692 }
693 }
694 #endif
695
696 inline void
697 vpn::udpv4_ev (ev::io &w, int revents)
698 {
699 if (revents & EV_READ)
700 {
701 vpn_packet *pkt = new vpn_packet;
702 struct sockaddr_in sa;
703 socklen_t sa_len = sizeof (sa);
704 int len;
705
706 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
707
708 sockinfo si(sa, PROT_UDPv4);
709
710 if (len > 0)
711 {
712 pkt->len = len;
713
714 recv_vpn_packet (pkt, si);
715 }
716 else
717 {
718 // probably ECONNRESET or somesuch
719 slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno));
720 }
721
722 delete pkt;
723 }
724 else
725 {
726 slog (L_ERR,
727 _("FATAL: unknown revents %08x in socket, exiting.\n"),
728 revents);
729 exit (EXIT_FAILURE);
730 }
731 }
732
733 inline void
734 vpn::tap_ev (ev::io &w, int revents)
735 {
736 if (revents & EV_READ)
737 {
738 /* process data */
739 tap_packet *pkt;
740
741 pkt = tap->recv ();
742
743 if (!pkt)
744 return;
745
746 if (pkt->len > 14)
747 {
748 int dst = mac2id (pkt->dst);
749 int src = mac2id (pkt->src);
750
751 if (src != THISNODE->id)
752 {
753 slog (L_ERR, _("FATAL: tap packet not originating on current node received (if-up script not working properly?), exiting."));
754 exit (EXIT_FAILURE);
755 }
756
757 if (dst == THISNODE->id)
758 {
759 slog (L_ERR, _("FATAL: tap packet destined for current node received, exiting."));
760 exit (EXIT_FAILURE);
761 }
762
763 if (dst > conns.size ())
764 slog (L_ERR, _("tap packet for unknown node %d received, ignoring."), dst);
765 else
766 inject_data_packet (pkt, dst);
767 }
768
769 delete pkt;
770 }
771 else
772 abort ();
773 }
774
775 inline void
776 vpn::event_cb (ev::timer &w, int)
777 {
778 if (events)
779 {
780 if (events & EVENT_SHUTDOWN)
781 {
782 slog (L_INFO, _("preparing shutdown..."));
783
784 shutdown_all ();
785 remove_pid (conf.pidfilename);
786 slog (L_INFO, _("exiting."));
787 exit (EXIT_SUCCESS);
788 }
789
790 if (events & EVENT_RECONNECT)
791 {
792 slog (L_INFO, _("forced reconnect."));
793
794 reconnect_all ();
795 }
796
797 events = 0;
798 }
799 }
800
801 void
802 vpn::shutdown_all ()
803 {
804 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
805 (*c)->shutdown ();
806 }
807
808 void
809 vpn::reconnect_all ()
810 {
811 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
812 delete *c;
813
814 conns.clear ();
815
816 connection_init ();
817
818 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
819 conns.push_back (new connection (this, *i));
820
821 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
822 (*c)->establish_connection ();
823 }
824
825 bool
826 vpn::can_direct (conf_node *src, conf_node *dst) const
827 {
828 return src != dst
829 && src->may_direct (dst)
830 && dst->may_direct (src)
831 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
832 || (src->protocols & dst->connectable_protocols ()));
833 }
834
835 // only works for indirect and routed connections: find a router
836 // from THISNODE to dst
837 connection *
838 vpn::find_router_for (const connection *dst)
839 {
840 connection *router = 0;
841
842 // first try to find a router with a direct connection, route there
843 // regardless of any other considerations.
844 {
845 u32 prio = 1;
846
847 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
848 {
849 connection *c = *i;
850
851 if (c->conf->routerprio > prio
852 && c->conf != THISNODE
853 && can_direct (c->conf, dst->conf)
854 && c->ictx && c->octx)
855 {
856 prio = c->conf->routerprio;
857 router = c;
858 }
859 }
860 }
861
862 if (router)
863 return router;
864
865 // second try find the router with the highest priority, higher than ours
866 {
867 u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1;
868
869 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
870 {
871 connection *c = *i;
872
873 if (c->conf->routerprio > prio
874 && c != dst
875 && c->conf != THISNODE
876 && c->ictx && c->octx)
877 {
878 prio = c->conf->routerprio;
879 router = c;
880 }
881 }
882 }
883
884 return router;
885 }
886
887 void
888 vpn::connection_established (connection *c)
889 {
890 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
891 {
892 connection *o = *i;
893
894 if (o->si.valid ()
895 && c->si != o->si
896 && c == find_router_for (o)
897 && !can_direct (THISNODE, o->conf))
898 {
899 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
900 o->conf->nodename, c->conf->nodename);
901 o->rekey ();
902 }
903 }
904 }
905
906 void
907 vpn::send_connect_request (connection *c)
908 {
909 connection *r = find_router_for (c);
910
911 if (r)
912 {
913 slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."),
914 c->conf->nodename, r->conf->nodename);
915 r->send_connect_request (c->conf->id);
916 }
917 else
918 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect at this time."),
919 c->conf->nodename);
920 }
921
922 void
923 connection::dump_status ()
924 {
925 slog (L_NOTICE, _("node %s (id %d)"), conf->nodename, conf->id);
926 slog (L_NOTICE, _(" connectmode %d (%d) / sockaddr %s / minor %d"),
927 connectmode, conf->connectmode, (const char *)si, (int)prot_minor);
928 slog (L_NOTICE, _(" ictx/octx %08lx/%08lx / oseqno %d / retry_cnt %d"),
929 (long)ictx, (long)octx, (int)oseqno, (int)retry_cnt);
930 }
931
932 void
933 vpn::dump_status ()
934 {
935 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)ev_now ());
936
937 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
938 (*c)->dump_status ();
939
940 slog (L_NOTICE, _("END status dump"));
941 }
942
943 vpn::vpn (void)
944 {
945 event .set<vpn, &vpn::event_cb > (this);
946 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this);
947 ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this);
948 #if ENABLE_TCP
949 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
950 #endif
951 #if ENABLE_ICMP
952 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this);
953 #endif
954 #if ENABLE_DNS
955 dnsv4_ev_watcher .set<vpn, &vpn::dnsv4_ev > (this);
956 #endif
957 tap_ev_watcher .set<vpn, &vpn::tap_ev > (this);
958 }
959
960 vpn::~vpn ()
961 {
962 }
963