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