ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn.C
Revision: 1.66
Committed: Thu Jul 18 13:35:16 2013 UTC (10 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.65: +1 -7 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 pcg 1.41 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 pcg 1.33 void
77     vpn::script_init_env ()
78 pcg 1.1 {
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 root 1.65 mtu -= mtu % BLOCK_SIZE (CIPHER); // round
84 pcg 1.1 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again
85    
86     char *env;
87 pcg 1.21 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 pcg 1.34 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 pcg 1.33
97 pcg 1.34 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 pcg 1.33 }
104    
105 pcg 1.45 inline const char *
106     vpn::script_if_init ()
107 pcg 1.33 {
108     script_init_env ();
109 pcg 1.1
110 pcg 1.33 return tap->if_up ();
111     }
112    
113 pcg 1.45 inline const char *
114     vpn::script_if_up ()
115 pcg 1.33 {
116     script_init_env ();
117    
118 root 1.66 return conf.config_filename (::conf.script_if_up, "if-up");
119 pcg 1.1 }
120    
121     int
122 pcg 1.54 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 pcg 1.55 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 pcg 1.54 #endif
140    
141     return fd;
142     }
143    
144     int
145 pcg 1.1 vpn::setup ()
146     {
147 pcg 1.51 int success = 0;
148    
149 pcg 1.41 ipv4_tos = -1;
150     ipv4_fd = -1;
151 pcg 1.1
152 pcg 1.8 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
153 pcg 1.1 {
154 pcg 1.54 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
155 pcg 1.1
156 pcg 1.8 if (ipv4_fd < 0)
157 pcg 1.1 return -1;
158    
159 pcg 1.14 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
160 pcg 1.1 // 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 pcg 1.8 setsockopt (ipv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
166 pcg 1.1 }
167     #endif
168    
169 pcg 1.9 sockinfo si (THISNODE, PROT_IPv4);
170    
171     if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
172     {
173 pcg 1.49 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
174 pcg 1.54 return -1;
175 pcg 1.9 }
176    
177 pcg 1.39 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
178 pcg 1.51 ++success;
179 pcg 1.1 }
180 pcg 1.51 else
181     THISNODE->protocols &= ~PROT_IPv4;
182 pcg 1.1
183 pcg 1.41 udpv4_tos = -1;
184     udpv4_fd = -1;
185 pcg 1.8
186     if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
187 pcg 1.1 {
188 pcg 1.54 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
189 pcg 1.1
190 pcg 1.8 if (udpv4_fd < 0)
191 pcg 1.1 return -1;
192    
193 pcg 1.8 // standard daemon practise...
194     {
195     int oval = 1;
196     setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
197     }
198    
199 pcg 1.14 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
200 pcg 1.9 // 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 pcg 1.8 sockinfo si (THISNODE, PROT_UDPv4);
210 pcg 1.2
211 pcg 1.8 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
212 pcg 1.1 {
213 pcg 1.49 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
214 pcg 1.54 return -1;
215 pcg 1.1 }
216    
217 pcg 1.39 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
218 pcg 1.51 ++success;
219 pcg 1.9 }
220 pcg 1.51 else
221     THISNODE->protocols &= ~PROT_UDPv4;
222 pcg 1.9
223 pcg 1.41 icmpv4_tos = -1;
224     icmpv4_fd = -1;
225 pcg 1.9
226     #if ENABLE_ICMP
227     if (THISNODE->protocols & PROT_ICMPv4)
228     {
229 pcg 1.54 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
230 pcg 1.9
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 pcg 1.14 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
246 pcg 1.1 // 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 pcg 1.36 setsockopt (icmpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
252 pcg 1.1 }
253     #endif
254    
255 pcg 1.9 sockinfo si (THISNODE, PROT_ICMPv4);
256    
257     if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
258     {
259 pcg 1.49 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
260 pcg 1.54 return -1;
261 pcg 1.9 }
262    
263 pcg 1.39 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
264 pcg 1.51 ++success;
265 pcg 1.1 }
266 pcg 1.9 #endif
267 pcg 1.1
268 pcg 1.8 tcpv4_fd = -1;
269    
270 pcg 1.2 #if ENABLE_TCP
271 pcg 1.8 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
272 pcg 1.2 {
273 pcg 1.54 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
274 pcg 1.2
275     if (tcpv4_fd < 0)
276     return -1;
277    
278 pcg 1.3 // standard daemon practise...
279     {
280     int oval = 1;
281     setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
282     }
283    
284 pcg 1.2 sockinfo si (THISNODE, PROT_TCPv4);
285    
286     if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
287     {
288 pcg 1.49 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
289 pcg 1.54 return -1;
290 pcg 1.2 }
291    
292     if (listen (tcpv4_fd, 5))
293     {
294 pcg 1.49 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
295 pcg 1.54 return -1;
296 pcg 1.2 }
297    
298 pcg 1.39 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
299 pcg 1.51 ++success;
300 pcg 1.2 }
301 pcg 1.51 else
302     THISNODE->protocols &= ~PROT_TCPv4;
303 pcg 1.2 #endif
304    
305 pcg 1.41 dnsv4_tos = -1;
306     dnsv4_fd = -1;
307    
308 pcg 1.24 #if ENABLE_DNS
309     if (THISNODE->protocols & PROT_DNSv4)
310     {
311 pcg 1.29 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
312    
313 pcg 1.54 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
314 pcg 1.24
315     if (dnsv4_fd < 0)
316     return -1;
317    
318 pcg 1.35 # if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
319 pcg 1.32 // 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 pcg 1.35 setsockopt (dnsv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
325 pcg 1.32 }
326 pcg 1.35 # endif
327 pcg 1.32
328 pcg 1.24 // standard daemon practise...
329     {
330     int oval = 1;
331 pcg 1.31 setsockopt (dnsv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
332 pcg 1.24 }
333    
334 pcg 1.31 sockinfo si (THISNODE->dns_hostname,
335     THISNODE->dns_hostname ? THISNODE->dns_port : 0,
336     PROT_DNSv4);
337 pcg 1.24
338     if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
339     {
340 pcg 1.49 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
341 pcg 1.54 return -1;
342 pcg 1.24 }
343    
344 pcg 1.39 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
345 pcg 1.51 ++success;
346 pcg 1.24 }
347     #endif
348    
349 pcg 1.34 /////////////////////////////////////////////////////////////////////////////
350    
351 pcg 1.51 if (!success)
352     {
353 pcg 1.54 slog (L_ERR, _("no protocols enabled."));
354     return -1;
355 pcg 1.51 }
356    
357 pcg 1.34 reconnect_all ();
358    
359     /////////////////////////////////////////////////////////////////////////////
360    
361 pcg 1.1 tap = new tap_device ();
362     if (!tap) //D this, of course, never catches
363     {
364 pcg 1.54 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
365     return -1;
366 pcg 1.1 }
367    
368 pcg 1.37 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
369    
370 pcg 1.43 run_script_cb cb;
371 pcg 1.44 cb.set<vpn, &vpn::script_if_init> (this);
372 pcg 1.43
373 pcg 1.33 if (tap->if_up () &&
374 pcg 1.43 !run_script (cb, true))
375 pcg 1.33 {
376 pcg 1.54 slog (L_ERR, _("interface initialization command '%s' failed."),
377 pcg 1.33 tap->if_up ());
378 pcg 1.54 return -1;
379 pcg 1.33 }
380    
381 pcg 1.44 cb.set<vpn, &vpn::script_if_up> (this);
382 pcg 1.43 if (!run_script (cb, true))
383 pcg 1.33 {
384 pcg 1.54 slog (L_ERR, _("if-up command execution failed."));
385     return -1;
386 pcg 1.33 }
387 pcg 1.1
388 pcg 1.39 tap_ev_watcher.start (tap->fd, EV_READ);
389 pcg 1.1
390     return 0;
391     }
392    
393 pcg 1.7 bool
394 root 1.64 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 crate 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 pcg 1.1 vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
463     {
464 pcg 1.41 set_tos (ipv4_fd, ipv4_tos, tos);
465 pcg 1.1 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
466 pcg 1.7
467     return true;
468 pcg 1.1 }
469    
470 pcg 1.9 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 pcg 1.13 #if ENABLE_ICMP
494 pcg 1.9 bool
495     vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
496     {
497     pkt->unshift_hdr (4);
498    
499 pcg 1.14 icmp_header *hdr = (icmp_header *)&((*pkt)[0]);
500 pcg 1.9 hdr->type = ::conf.icmp_type;
501     hdr->code = 255;
502     hdr->checksum = 0;
503     hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
504    
505 pcg 1.41 set_tos (icmpv4_fd, icmpv4_tos, tos);
506 pcg 1.9 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
507    
508     return true;
509     }
510 pcg 1.13 #endif
511 pcg 1.9
512 pcg 1.7 bool
513 pcg 1.1 vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
514     {
515 pcg 1.41 set_tos (udpv4_fd, udpv4_tos, tos);
516 pcg 1.1 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
517 pcg 1.7
518     return true;
519 pcg 1.1 }
520    
521     void
522 pcg 1.18 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 pcg 1.46 (*c)->inject_data_packet (pkt);
537 pcg 1.18 }
538     }
539    
540     void
541 pcg 1.1 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 pcg 1.49 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d."),
547 pcg 1.1 (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 pcg 1.49 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
553 pcg 1.1 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
554     else
555     {
556     connection *c = conns[src - 1];
557    
558 pcg 1.13 if (dst == 0)
559 pcg 1.49 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
560 pcg 1.1 c->conf->nodename, (const char *)rsi);
561 pcg 1.18 else if (dst != THISNODE->id)
562 pcg 1.6 {
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 pcg 1.49 _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."),
569 pcg 1.6 c->conf->nodename, (const char *)rsi,
570     conns[dst - 1]->conf->nodename);
571     }
572 pcg 1.1 else
573     c->recv_vpn_packet (pkt, rsi);
574     }
575     }
576    
577 pcg 1.31 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 root 1.63 return send_ipv4_packet (pkt, si, tos);
584 pcg 1.41
585 pcg 1.31 case PROT_UDPv4:
586 root 1.63 return send_udpv4_packet (pkt, si, tos);
587 pcg 1.41
588 root 1.57 #if ENABLE_TCP
589 pcg 1.31 case PROT_TCPv4:
590 root 1.63 return send_tcpv4_packet (pkt, si, tos);
591 pcg 1.31 #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 root 1.63 return send_dnsv4_packet (pkt, si, tos);
599 pcg 1.31 #endif
600     default:
601 pcg 1.49 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
602 pcg 1.31 }
603    
604     return false;
605     }
606    
607 pcg 1.45 inline void
608 pcg 1.39 vpn::ipv4_ev (ev::io &w, int revents)
609 pcg 1.1 {
610 pcg 1.39 if (revents & EV_READ)
611 pcg 1.1 {
612     vpn_packet *pkt = new vpn_packet;
613     struct sockaddr_in sa;
614     socklen_t sa_len = sizeof (sa);
615     int len;
616    
617 pcg 1.5 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
618 pcg 1.1
619 pcg 1.9 sockinfo si(sa, PROT_IPv4);
620 pcg 1.1
621     if (len > 0)
622     {
623     pkt->len = len;
624    
625 pcg 1.30 // raw sockets deliver the ipv4 header, but don't expect it on sends
626 root 1.60 pkt->skip_hdr (pkt->ipv4_hdr_len ());
627 pcg 1.9
628 pcg 1.1 recv_vpn_packet (pkt, si);
629     }
630     else
631     {
632     // probably ECONNRESET or somesuch
633 pcg 1.49 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
634 pcg 1.1 }
635    
636     delete pkt;
637     }
638     else
639     {
640     slog (L_ERR,
641 pcg 1.49 _("FATAL: unknown revents %08x in socket, exiting.\n"),
642 pcg 1.30 revents);
643 pcg 1.23 exit (EXIT_FAILURE);
644 pcg 1.1 }
645     }
646    
647 pcg 1.13 #if ENABLE_ICMP
648 pcg 1.45 inline void
649 pcg 1.39 vpn::icmpv4_ev (ev::io &w, int revents)
650 pcg 1.1 {
651 pcg 1.39 if (revents & EV_READ)
652 pcg 1.1 {
653     vpn_packet *pkt = new vpn_packet;
654     struct sockaddr_in sa;
655     socklen_t sa_len = sizeof (sa);
656     int len;
657    
658 pcg 1.5 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
659 pcg 1.1
660 pcg 1.9 sockinfo si(sa, PROT_ICMPv4);
661 pcg 1.1
662     if (len > 0)
663     {
664     pkt->len = len;
665    
666 pcg 1.14 icmp_header *hdr = (icmp_header *)&((*pkt)[IP_OVERHEAD]);
667 pcg 1.9
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 root 1.60 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
674 pcg 1.9
675     recv_vpn_packet (pkt, si);
676     }
677     }
678     else
679     {
680     // probably ECONNRESET or somesuch
681 pcg 1.49 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
682 pcg 1.9 }
683    
684     delete pkt;
685     }
686     else
687     {
688     slog (L_ERR,
689 pcg 1.49 _("FATAL: unknown revents %08x in socket, exiting.\n"),
690 pcg 1.9 revents);
691 pcg 1.23 exit (EXIT_FAILURE);
692 pcg 1.9 }
693     }
694 pcg 1.13 #endif
695 pcg 1.9
696 pcg 1.45 inline void
697 pcg 1.39 vpn::udpv4_ev (ev::io &w, int revents)
698 pcg 1.9 {
699 pcg 1.39 if (revents & EV_READ)
700 pcg 1.9 {
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 pcg 1.1
714     recv_vpn_packet (pkt, si);
715     }
716     else
717     {
718     // probably ECONNRESET or somesuch
719 pcg 1.49 slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno));
720 pcg 1.1 }
721    
722     delete pkt;
723     }
724     else
725     {
726     slog (L_ERR,
727 pcg 1.49 _("FATAL: unknown revents %08x in socket, exiting.\n"),
728 pcg 1.1 revents);
729 pcg 1.23 exit (EXIT_FAILURE);
730 pcg 1.1 }
731     }
732 pcg 1.2
733 pcg 1.45 inline void
734 pcg 1.39 vpn::tap_ev (ev::io &w, int revents)
735 pcg 1.1 {
736 pcg 1.39 if (revents & EV_READ)
737 pcg 1.1 {
738     /* process data */
739     tap_packet *pkt;
740    
741     pkt = tap->recv ();
742    
743 pcg 1.17 if (!pkt)
744     return;
745 pcg 1.1
746 pcg 1.17 if (pkt->len > 14)
747 pcg 1.1 {
748 pcg 1.17 int dst = mac2id (pkt->dst);
749     int src = mac2id (pkt->src);
750 pcg 1.1
751 pcg 1.17 if (src != THISNODE->id)
752     {
753 pcg 1.30 slog (L_ERR, _("FATAL: tap packet not originating on current node received (if-up script not working properly?), exiting."));
754 pcg 1.23 exit (EXIT_FAILURE);
755 pcg 1.17 }
756 pcg 1.1
757 pcg 1.17 if (dst == THISNODE->id)
758 pcg 1.1 {
759 pcg 1.17 slog (L_ERR, _("FATAL: tap packet destined for current node received, exiting."));
760 pcg 1.23 exit (EXIT_FAILURE);
761 pcg 1.1 }
762 pcg 1.17
763     if (dst > conns.size ())
764     slog (L_ERR, _("tap packet for unknown node %d received, ignoring."), dst);
765 pcg 1.1 else
766 pcg 1.18 inject_data_packet (pkt, dst);
767 pcg 1.1 }
768    
769     delete pkt;
770     }
771     else
772     abort ();
773     }
774    
775 pcg 1.45 inline void
776 pcg 1.39 vpn::event_cb (ev::timer &w, int)
777 pcg 1.1 {
778     if (events)
779     {
780     if (events & EVENT_SHUTDOWN)
781     {
782     slog (L_INFO, _("preparing shutdown..."));
783    
784     shutdown_all ();
785 pcg 1.24 remove_pid (conf.pidfilename);
786 pcg 1.49 slog (L_INFO, _("exiting."));
787 pcg 1.23 exit (EXIT_SUCCESS);
788 pcg 1.1 }
789    
790     if (events & EVENT_RECONNECT)
791     {
792 pcg 1.49 slog (L_INFO, _("forced reconnect."));
793 pcg 1.1
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 pcg 1.50 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 pcg 1.1 }
824    
825 root 1.56 bool
826     vpn::can_direct (conf_node *src, conf_node *dst) const
827 pcg 1.49 {
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 root 1.56 connection *
838     vpn::find_router_for (const connection *dst)
839 pcg 1.1 {
840     connection *router = 0;
841    
842 pcg 1.52 // first try to find a router with a direct connection, route there
843     // regardless of any other considerations.
844 pcg 1.49 {
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 pcg 1.52 && can_direct (c->conf, dst->conf)
854     && c->ictx && c->octx)
855 pcg 1.49 {
856 pcg 1.52 prio = c->conf->routerprio;
857     router = c;
858 pcg 1.49 }
859     }
860     }
861    
862     if (router)
863     return router;
864    
865 pcg 1.52 // second try find the router with the highest priority, higher than ours
866 pcg 1.49 {
867 pcg 1.52 u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1;
868 pcg 1.49
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 pcg 1.52 && c->conf != THISNODE
876     && c->ictx && c->octx)
877 pcg 1.49 {
878 pcg 1.52 prio = c->conf->routerprio;
879     router = c;
880 pcg 1.49 }
881     }
882     }
883 pcg 1.52
884 pcg 1.49 return router;
885     }
886    
887 root 1.56 void
888     vpn::connection_established (connection *c)
889 pcg 1.49 {
890 pcg 1.1 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
891     {
892 pcg 1.49 connection *o = *i;
893 pcg 1.1
894 pcg 1.49 if (!o->is_direct
895     && o->si.valid ()
896     && c->si != o->si
897     && c == find_router_for (o))
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 pcg 1.1 }
903     }
904     }
905    
906 root 1.56 void
907     vpn::send_connect_request (connection *c)
908 pcg 1.1 {
909 pcg 1.50 connection *r = find_router_for (c);
910 pcg 1.1
911 pcg 1.50 if (r)
912 pcg 1.49 {
913 pcg 1.53 slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."),
914 pcg 1.50 c->conf->nodename, r->conf->nodename);
915     r->send_connect_request (c->conf->id);
916 pcg 1.49 }
917 pcg 1.7 else
918 pcg 1.53 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect at this time."),
919 pcg 1.50 c->conf->nodename);
920 pcg 1.1 }
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 pcg 1.40 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)ev_now ());
936 pcg 1.1
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 pcg 1.44 {
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 pcg 1.2 #if ENABLE_TCP
949 pcg 1.44 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
950 pcg 1.9 #endif
951     #if ENABLE_ICMP
952 pcg 1.44 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this);
953 pcg 1.24 #endif
954     #if ENABLE_DNS
955 pcg 1.44 dnsv4_ev_watcher .set<vpn, &vpn::dnsv4_ev > (this);
956 pcg 1.2 #endif
957 pcg 1.44 tap_ev_watcher .set<vpn, &vpn::tap_ev > (this);
958 pcg 1.1 }
959    
960     vpn::~vpn ()
961     {
962     }
963