ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn.C
Revision: 1.71
Committed: Thu Oct 6 03:25:54 2022 UTC (19 months, 2 weeks ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.70: +9 -4 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 root 1.71 // no clue where trhis is actually defined
261     #if !defined(ICMP_FILTER) && defined(__linux)
262     #define ICMP_FILTER 1
263     #endif
264    
265 pcg 1.9 #ifdef ICMP_FILTER
266     {
267 root 1.71 uint32_t oval;
268     oval = 0;
269 pcg 1.9 if (::conf.icmp_type < 32)
270 root 1.71 oval |= 1 << ::conf.icmp_type;
271     oval = ~oval;
272 pcg 1.9
273     setsockopt (icmpv4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval);
274     }
275     #endif
276    
277 pcg 1.14 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
278 pcg 1.1 // this I really consider a linux bug. I am neither connected
279     // nor do I fragment myself. Linux still sets DF and doesn't
280     // fragment for me sometimes.
281     {
282     int oval = IP_PMTUDISC_DONT;
283 pcg 1.36 setsockopt (icmpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
284 pcg 1.1 }
285     #endif
286    
287 pcg 1.9 sockinfo si (THISNODE, PROT_ICMPv4);
288    
289     if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
290     {
291 pcg 1.49 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
292 pcg 1.54 return -1;
293 pcg 1.9 }
294    
295 pcg 1.39 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
296 pcg 1.51 ++success;
297 pcg 1.1 }
298 pcg 1.9 #endif
299 pcg 1.1
300 pcg 1.8 tcpv4_fd = -1;
301    
302 pcg 1.2 #if ENABLE_TCP
303 pcg 1.8 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
304 pcg 1.2 {
305 pcg 1.54 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
306 pcg 1.2
307     if (tcpv4_fd < 0)
308     return -1;
309    
310 pcg 1.3 // standard daemon practise...
311     {
312     int oval = 1;
313     setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
314     }
315    
316 pcg 1.2 sockinfo si (THISNODE, PROT_TCPv4);
317    
318     if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
319     {
320 pcg 1.49 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
321 pcg 1.54 return -1;
322 pcg 1.2 }
323    
324     if (listen (tcpv4_fd, 5))
325     {
326 pcg 1.49 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
327 pcg 1.54 return -1;
328 pcg 1.2 }
329    
330 pcg 1.39 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
331 pcg 1.51 ++success;
332 pcg 1.2 }
333 pcg 1.51 else
334     THISNODE->protocols &= ~PROT_TCPv4;
335 pcg 1.2 #endif
336    
337 pcg 1.41 dnsv4_tos = -1;
338     dnsv4_fd = -1;
339    
340 pcg 1.24 #if ENABLE_DNS
341     if (THISNODE->protocols & PROT_DNSv4)
342     {
343 pcg 1.29 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
344    
345 pcg 1.54 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
346 pcg 1.24
347     if (dnsv4_fd < 0)
348     return -1;
349    
350 pcg 1.35 # if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
351 pcg 1.32 // this I really consider a linux bug. I am neither connected
352     // nor do I fragment myself. Linux still sets DF and doesn't
353     // fragment for me sometimes.
354     {
355     int oval = IP_PMTUDISC_DONT;
356 pcg 1.35 setsockopt (dnsv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
357 pcg 1.32 }
358 pcg 1.35 # endif
359 pcg 1.32
360 pcg 1.24 // standard daemon practise...
361     {
362     int oval = 1;
363 pcg 1.31 setsockopt (dnsv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
364 pcg 1.24 }
365    
366 pcg 1.31 sockinfo si (THISNODE->dns_hostname,
367     THISNODE->dns_hostname ? THISNODE->dns_port : 0,
368     PROT_DNSv4);
369 pcg 1.24
370     if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
371     {
372 pcg 1.49 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
373 pcg 1.54 return -1;
374 pcg 1.24 }
375    
376 pcg 1.39 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
377 pcg 1.51 ++success;
378 pcg 1.24 }
379     #endif
380    
381 pcg 1.34 /////////////////////////////////////////////////////////////////////////////
382    
383 pcg 1.51 if (!success)
384     {
385 pcg 1.54 slog (L_ERR, _("no protocols enabled."));
386     return -1;
387 pcg 1.51 }
388    
389 pcg 1.34 reconnect_all ();
390    
391     /////////////////////////////////////////////////////////////////////////////
392    
393 pcg 1.1 tap = new tap_device ();
394     if (!tap) //D this, of course, never catches
395     {
396 pcg 1.54 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
397     return -1;
398 pcg 1.1 }
399    
400 pcg 1.37 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
401    
402 pcg 1.43 run_script_cb cb;
403 pcg 1.44 cb.set<vpn, &vpn::script_if_init> (this);
404 pcg 1.43
405 pcg 1.33 if (tap->if_up () &&
406 pcg 1.43 !run_script (cb, true))
407 pcg 1.33 {
408 pcg 1.54 slog (L_ERR, _("interface initialization command '%s' failed."),
409 pcg 1.33 tap->if_up ());
410 pcg 1.54 return -1;
411 pcg 1.33 }
412    
413 pcg 1.44 cb.set<vpn, &vpn::script_if_up> (this);
414 pcg 1.43 if (!run_script (cb, true))
415 pcg 1.33 {
416 pcg 1.54 slog (L_ERR, _("if-up command execution failed."));
417     return -1;
418 pcg 1.33 }
419 pcg 1.1
420 pcg 1.39 tap_ev_watcher.start (tap->fd, EV_READ);
421 pcg 1.1
422     return 0;
423     }
424    
425 pcg 1.7 bool
426 root 1.64 vpn::drop_privileges ()
427     {
428     if (::conf.change_root)
429     {
430     if (!strcmp (::conf.change_root, "/"))
431     {
432     char dir [L_tmpnam];
433     if (!tmpnam (dir))
434     {
435     slog (L_CRIT, _("unable to create anonymous root path."));
436     return false;
437     }
438    
439     if (mkdir (dir, 0700))
440     {
441 root 1.68 slog (L_CRIT, _("unable to create anonymous root directory."));
442 root 1.64 return false;
443     }
444    
445     if (chdir (dir))
446     {
447     slog (L_CRIT, _("unable to change to anonymous root directory."));
448     return false;
449     }
450    
451     if (rmdir (dir))
452     slog (L_ERR, _("unable to remove anonymous root directory, continuing."));
453     }
454     else
455     {
456     if (chdir (::conf.change_root))
457     {
458     slog (L_CRIT, _("%s: unable to change to specified root directory."), ::conf.change_root);
459     return false;
460     }
461     }
462    
463     if (chroot ("."))
464     {
465     slog (L_CRIT, _("unable to set new root directory."));
466     return false;
467     }
468    
469     if (chdir ("/"))
470     {
471     slog (L_CRIT, _("unable to set cwd to new root directory."));
472     return false;
473     }
474     }
475    
476     if (::conf.change_gid)
477     if (setgid (::conf.change_gid))
478     {
479     slog (L_CRIT, _("unable to change group id to %d."), ::conf.change_gid);
480     return false;
481     }
482    
483     if (::conf.change_uid)
484     if (setuid (::conf.change_uid))
485     {
486     slog (L_CRIT, _("unable to change user id to %d."), ::conf.change_uid);
487     return false;
488     }
489    
490     return true;
491     }
492    
493     bool
494 pcg 1.1 vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
495     {
496 pcg 1.41 set_tos (ipv4_fd, ipv4_tos, tos);
497 root 1.69 xsendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
498 pcg 1.7
499     return true;
500 pcg 1.1 }
501    
502 pcg 1.9 static u16
503     ipv4_checksum (u16 *data, unsigned int len)
504     {
505     // use 32 bit accumulator and fold back carry bits at the end
506     u32 sum = 0;
507    
508     while (len > 1)
509     {
510     sum += *data++;
511     len -= 2;
512     }
513    
514     // odd byte left?
515     if (len)
516     sum += *(u8 *)data;
517    
518     // add back carry bits
519     sum = (sum >> 16) + (sum & 0xffff); // lo += hi
520     sum += (sum >> 16); // carry
521    
522     return ~sum;
523     }
524    
525 pcg 1.13 #if ENABLE_ICMP
526 pcg 1.9 bool
527     vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
528     {
529     pkt->unshift_hdr (4);
530    
531 pcg 1.14 icmp_header *hdr = (icmp_header *)&((*pkt)[0]);
532 pcg 1.9 hdr->type = ::conf.icmp_type;
533     hdr->code = 255;
534     hdr->checksum = 0;
535     hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
536    
537 pcg 1.41 set_tos (icmpv4_fd, icmpv4_tos, tos);
538 root 1.69 xsendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
539 pcg 1.9
540     return true;
541     }
542 pcg 1.13 #endif
543 pcg 1.9
544 pcg 1.7 bool
545 pcg 1.1 vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
546     {
547 pcg 1.41 set_tos (udpv4_fd, udpv4_tos, tos);
548 root 1.69 xsendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
549 pcg 1.7
550     return true;
551 pcg 1.1 }
552    
553     void
554 pcg 1.18 vpn::inject_data_packet (tap_packet *pkt, int dst)
555     {
556     if (dst)
557     {
558     // unicast
559     if (dst != THISNODE->id)
560     conns[dst - 1]->inject_data_packet (pkt);
561     }
562     else
563     {
564     // broadcast, this is ugly, but due to the security policy
565     // we have to connect to all hosts...
566     for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
567     if ((*c)->conf != THISNODE)
568 pcg 1.46 (*c)->inject_data_packet (pkt);
569 pcg 1.18 }
570     }
571    
572     void
573 pcg 1.1 vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
574     {
575     unsigned int src = pkt->src ();
576     unsigned int dst = pkt->dst ();
577    
578 pcg 1.49 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d."),
579 pcg 1.1 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
580    
581     if (src == 0 || src > conns.size ()
582     || dst > conns.size ()
583     || pkt->typ () >= vpn_packet::PT_MAX)
584 pcg 1.49 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
585 pcg 1.1 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
586     else
587     {
588     connection *c = conns[src - 1];
589    
590 pcg 1.13 if (dst == 0)
591 pcg 1.49 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
592 pcg 1.1 c->conf->nodename, (const char *)rsi);
593 pcg 1.18 else if (dst != THISNODE->id)
594 pcg 1.6 {
595     if (THISNODE->routerprio)
596     // the tos setting gets lost here. who cares.
597     conns[dst - 1]->inject_vpn_packet (pkt);
598     else
599     slog (L_WARN,
600 pcg 1.49 _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."),
601 pcg 1.6 c->conf->nodename, (const char *)rsi,
602     conns[dst - 1]->conf->nodename);
603     }
604 pcg 1.1 else
605     c->recv_vpn_packet (pkt, rsi);
606     }
607     }
608    
609 pcg 1.31 bool
610     vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
611     {
612     switch (si.prot)
613     {
614     case PROT_IPv4:
615 root 1.63 return send_ipv4_packet (pkt, si, tos);
616 pcg 1.41
617 pcg 1.31 case PROT_UDPv4:
618 root 1.63 return send_udpv4_packet (pkt, si, tos);
619 pcg 1.41
620 root 1.57 #if ENABLE_TCP
621 pcg 1.31 case PROT_TCPv4:
622 root 1.63 return send_tcpv4_packet (pkt, si, tos);
623 pcg 1.31 #endif
624     #if ENABLE_ICMP
625     case PROT_ICMPv4:
626     return send_icmpv4_packet (pkt, si, tos);
627     #endif
628     #if ENABLE_DNS
629     case PROT_DNSv4:
630 root 1.63 return send_dnsv4_packet (pkt, si, tos);
631 pcg 1.31 #endif
632     default:
633 pcg 1.49 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
634 pcg 1.31 }
635    
636     return false;
637     }
638    
639 pcg 1.45 inline void
640 pcg 1.39 vpn::ipv4_ev (ev::io &w, int revents)
641 pcg 1.1 {
642 pcg 1.39 if (revents & EV_READ)
643 pcg 1.1 {
644     vpn_packet *pkt = new vpn_packet;
645     struct sockaddr_in sa;
646     socklen_t sa_len = sizeof (sa);
647     int len;
648    
649 pcg 1.5 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
650 pcg 1.1
651 pcg 1.9 sockinfo si(sa, PROT_IPv4);
652 pcg 1.1
653     if (len > 0)
654     {
655     pkt->len = len;
656    
657 pcg 1.30 // raw sockets deliver the ipv4 header, but don't expect it on sends
658 root 1.60 pkt->skip_hdr (pkt->ipv4_hdr_len ());
659 pcg 1.9
660 pcg 1.1 recv_vpn_packet (pkt, si);
661     }
662     else
663     {
664     // probably ECONNRESET or somesuch
665 pcg 1.49 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
666 pcg 1.1 }
667    
668     delete pkt;
669     }
670     else
671     {
672     slog (L_ERR,
673 pcg 1.49 _("FATAL: unknown revents %08x in socket, exiting.\n"),
674 pcg 1.30 revents);
675 pcg 1.23 exit (EXIT_FAILURE);
676 pcg 1.1 }
677     }
678    
679 pcg 1.13 #if ENABLE_ICMP
680 pcg 1.45 inline void
681 pcg 1.39 vpn::icmpv4_ev (ev::io &w, int revents)
682 pcg 1.1 {
683 pcg 1.39 if (revents & EV_READ)
684 pcg 1.1 {
685     vpn_packet *pkt = new vpn_packet;
686     struct sockaddr_in sa;
687     socklen_t sa_len = sizeof (sa);
688     int len;
689    
690 pcg 1.5 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
691 pcg 1.1
692 pcg 1.9 sockinfo si(sa, PROT_ICMPv4);
693 pcg 1.1
694     if (len > 0)
695     {
696     pkt->len = len;
697    
698 pcg 1.14 icmp_header *hdr = (icmp_header *)&((*pkt)[IP_OVERHEAD]);
699 pcg 1.9
700     if (hdr->type == ::conf.icmp_type
701     && hdr->code == 255)
702     {
703     // raw sockets deliver the ipv4, but don't expect it on sends
704     // this is slow, but...
705 root 1.60 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
706 pcg 1.9
707     recv_vpn_packet (pkt, si);
708     }
709     }
710     else
711     {
712     // probably ECONNRESET or somesuch
713 pcg 1.49 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
714 pcg 1.9 }
715    
716     delete pkt;
717     }
718     else
719     {
720     slog (L_ERR,
721 pcg 1.49 _("FATAL: unknown revents %08x in socket, exiting.\n"),
722 pcg 1.9 revents);
723 pcg 1.23 exit (EXIT_FAILURE);
724 pcg 1.9 }
725     }
726 pcg 1.13 #endif
727 pcg 1.9
728 pcg 1.45 inline void
729 pcg 1.39 vpn::udpv4_ev (ev::io &w, int revents)
730 pcg 1.9 {
731 pcg 1.39 if (revents & EV_READ)
732 pcg 1.9 {
733     vpn_packet *pkt = new vpn_packet;
734     struct sockaddr_in sa;
735     socklen_t sa_len = sizeof (sa);
736     int len;
737    
738     len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
739    
740     sockinfo si(sa, PROT_UDPv4);
741    
742     if (len > 0)
743     {
744     pkt->len = len;
745 pcg 1.1
746     recv_vpn_packet (pkt, si);
747     }
748     else
749     {
750     // probably ECONNRESET or somesuch
751 pcg 1.49 slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno));
752 pcg 1.1 }
753    
754     delete pkt;
755     }
756     else
757     {
758     slog (L_ERR,
759 pcg 1.49 _("FATAL: unknown revents %08x in socket, exiting.\n"),
760 pcg 1.1 revents);
761 pcg 1.23 exit (EXIT_FAILURE);
762 pcg 1.1 }
763     }
764 pcg 1.2
765 pcg 1.45 inline void
766 pcg 1.39 vpn::tap_ev (ev::io &w, int revents)
767 pcg 1.1 {
768 pcg 1.39 if (revents & EV_READ)
769 pcg 1.1 {
770     /* process data */
771     tap_packet *pkt;
772    
773     pkt = tap->recv ();
774    
775 pcg 1.17 if (!pkt)
776     return;
777 pcg 1.1
778 pcg 1.17 if (pkt->len > 14)
779 pcg 1.1 {
780 pcg 1.17 int dst = mac2id (pkt->dst);
781     int src = mac2id (pkt->src);
782 pcg 1.1
783 pcg 1.17 if (src != THISNODE->id)
784     {
785 pcg 1.30 slog (L_ERR, _("FATAL: tap packet not originating on current node received (if-up script not working properly?), exiting."));
786 pcg 1.23 exit (EXIT_FAILURE);
787 pcg 1.17 }
788 pcg 1.1
789 pcg 1.17 if (dst == THISNODE->id)
790 pcg 1.1 {
791 pcg 1.17 slog (L_ERR, _("FATAL: tap packet destined for current node received, exiting."));
792 pcg 1.23 exit (EXIT_FAILURE);
793 pcg 1.1 }
794 pcg 1.17
795     if (dst > conns.size ())
796     slog (L_ERR, _("tap packet for unknown node %d received, ignoring."), dst);
797 pcg 1.1 else
798 pcg 1.18 inject_data_packet (pkt, dst);
799 pcg 1.1 }
800    
801     delete pkt;
802     }
803     else
804     abort ();
805     }
806    
807 pcg 1.45 inline void
808 pcg 1.39 vpn::event_cb (ev::timer &w, int)
809 pcg 1.1 {
810     if (events)
811     {
812     if (events & EVENT_SHUTDOWN)
813     {
814     slog (L_INFO, _("preparing shutdown..."));
815    
816     shutdown_all ();
817 pcg 1.24 remove_pid (conf.pidfilename);
818 pcg 1.49 slog (L_INFO, _("exiting."));
819 pcg 1.23 exit (EXIT_SUCCESS);
820 pcg 1.1 }
821    
822     if (events & EVENT_RECONNECT)
823     {
824 pcg 1.49 slog (L_INFO, _("forced reconnect."));
825 pcg 1.1
826     reconnect_all ();
827     }
828    
829     events = 0;
830     }
831     }
832    
833     void
834     vpn::shutdown_all ()
835     {
836     for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
837     (*c)->shutdown ();
838     }
839    
840     void
841     vpn::reconnect_all ()
842     {
843     for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
844     delete *c;
845    
846     conns.clear ();
847    
848     connection_init ();
849    
850 pcg 1.50 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
851     conns.push_back (new connection (this, *i));
852    
853     for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
854     (*c)->establish_connection ();
855 pcg 1.1 }
856    
857 root 1.56 bool
858     vpn::can_direct (conf_node *src, conf_node *dst) const
859 pcg 1.49 {
860     return src != dst
861     && src->may_direct (dst)
862     && dst->may_direct (src)
863     && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
864     || (src->protocols & dst->connectable_protocols ()));
865     }
866    
867     // only works for indirect and routed connections: find a router
868     // from THISNODE to dst
869 root 1.56 connection *
870     vpn::find_router_for (const connection *dst)
871 pcg 1.1 {
872     connection *router = 0;
873    
874 pcg 1.52 // first try to find a router with a direct connection, route there
875     // regardless of any other considerations.
876 pcg 1.49 {
877     u32 prio = 1;
878    
879     for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
880     {
881     connection *c = *i;
882    
883     if (c->conf->routerprio > prio
884     && c->conf != THISNODE
885 pcg 1.52 && can_direct (c->conf, dst->conf)
886     && c->ictx && c->octx)
887 pcg 1.49 {
888 pcg 1.52 prio = c->conf->routerprio;
889     router = c;
890 pcg 1.49 }
891     }
892     }
893    
894     if (router)
895     return router;
896    
897 pcg 1.52 // second try find the router with the highest priority, higher than ours
898 pcg 1.49 {
899 pcg 1.52 u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1;
900 pcg 1.49
901     for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
902     {
903     connection *c = *i;
904    
905     if (c->conf->routerprio > prio
906     && c != dst
907 pcg 1.52 && c->conf != THISNODE
908     && c->ictx && c->octx)
909 pcg 1.49 {
910 pcg 1.52 prio = c->conf->routerprio;
911     router = c;
912 pcg 1.49 }
913     }
914     }
915 pcg 1.52
916 pcg 1.49 return router;
917     }
918    
919 root 1.56 void
920     vpn::connection_established (connection *c)
921 pcg 1.49 {
922 pcg 1.1 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
923     {
924 pcg 1.49 connection *o = *i;
925 pcg 1.1
926 root 1.67 if (o->si.valid ()
927 pcg 1.49 && c->si != o->si
928 root 1.67 && c == find_router_for (o)
929     && !can_direct (THISNODE, o->conf))
930 pcg 1.49 {
931     slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
932     o->conf->nodename, c->conf->nodename);
933     o->rekey ();
934 pcg 1.1 }
935     }
936     }
937    
938 root 1.56 void
939     vpn::send_connect_request (connection *c)
940 pcg 1.1 {
941 pcg 1.50 connection *r = find_router_for (c);
942 pcg 1.1
943 pcg 1.50 if (r)
944 pcg 1.49 {
945 pcg 1.53 slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."),
946 pcg 1.50 c->conf->nodename, r->conf->nodename);
947     r->send_connect_request (c->conf->id);
948 pcg 1.49 }
949 pcg 1.7 else
950 pcg 1.53 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect at this time."),
951 pcg 1.50 c->conf->nodename);
952 pcg 1.1 }
953    
954     void
955     connection::dump_status ()
956     {
957     slog (L_NOTICE, _("node %s (id %d)"), conf->nodename, conf->id);
958     slog (L_NOTICE, _(" connectmode %d (%d) / sockaddr %s / minor %d"),
959     connectmode, conf->connectmode, (const char *)si, (int)prot_minor);
960     slog (L_NOTICE, _(" ictx/octx %08lx/%08lx / oseqno %d / retry_cnt %d"),
961     (long)ictx, (long)octx, (int)oseqno, (int)retry_cnt);
962     }
963    
964     void
965     vpn::dump_status ()
966     {
967 pcg 1.40 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)ev_now ());
968 pcg 1.1
969     for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
970     (*c)->dump_status ();
971    
972     slog (L_NOTICE, _("END status dump"));
973     }
974    
975     vpn::vpn (void)
976 pcg 1.44 {
977     event .set<vpn, &vpn::event_cb > (this);
978     udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this);
979     ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this);
980 pcg 1.2 #if ENABLE_TCP
981 pcg 1.44 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
982 pcg 1.9 #endif
983     #if ENABLE_ICMP
984 pcg 1.44 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this);
985 pcg 1.24 #endif
986     #if ENABLE_DNS
987 pcg 1.44 dnsv4_ev_watcher .set<vpn, &vpn::dnsv4_ev > (this);
988 pcg 1.2 #endif
989 pcg 1.44 tap_ev_watcher .set<vpn, &vpn::tap_ev > (this);
990 pcg 1.1 }
991    
992     vpn::~vpn ()
993     {
994     }
995