ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn.C
Revision: 1.69
Committed: Sat Sep 5 17:40:22 2015 UTC (8 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-3_0
Changes since 1.68: +29 -3 lines
Log Message:
*** empty log message ***

File Contents

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