ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn.C
Revision: 1.47
Committed: Thu Aug 7 17:54:27 2008 UTC (15 years, 9 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.46: +24 -14 lines
Log Message:
update to gplv3, finally

File Contents

# User Rev Content
1 pcg 1.1 /*
2     vpn.C -- handle the protocol, encryption, handshaking etc.
3 pcg 1.47 Copyright (C) 2003-2008 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     #include <errno.h>
44     #include <time.h>
45     #include <unistd.h>
46 pcg 1.11 #include <fcntl.h>
47 pcg 1.14 #include <sys/socket.h>
48 pcg 1.15
49     #include "netcompat.h"
50 pcg 1.1
51     #include "pidfile.h"
52    
53     #include "connection.h"
54     #include "util.h"
55     #include "vpn.h"
56    
57 pcg 1.20 vpn network; // THE vpn (bad design...)
58    
59 pcg 1.1 /////////////////////////////////////////////////////////////////////////////
60    
61 pcg 1.41 static void inline
62     set_tos (int fd, int &tos_prev, int tos)
63     {
64     #if defined(SOL_IP) && defined(IP_TOS)
65     if (tos_prev == tos)
66     return;
67    
68     tos_prev = tos;
69     setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos);
70     #endif
71     }
72    
73 pcg 1.33 void
74     vpn::script_init_env ()
75 pcg 1.1 {
76     // the tunnel device mtu should be the physical mtu - overhead
77     // the tricky part is rounding to the cipher key blocksize
78     int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD;
79     mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion
80     mtu -= mtu % EVP_CIPHER_block_size (CIPHER); // round
81     mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again
82    
83     char *env;
84 pcg 1.21 asprintf (&env, "CONFBASE=%s", confbase); putenv (env);
85     asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env);
86     asprintf (&env, "IFTYPE=%s", IFTYPE); putenv (env);
87     asprintf (&env, "IFSUBTYPE=%s", IFSUBTYPE); putenv (env);
88     asprintf (&env, "MTU=%d", mtu); putenv (env);
89 pcg 1.34 asprintf (&env, "NODES=%d", conns.size ()); putenv (env);
90     asprintf (&env, "NODEID=%d", THISNODE->id); putenv (env);
91    
92     conns [THISNODE->id - 1]->script_init_env ("");
93 pcg 1.33
94 pcg 1.34 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
95     {
96     char ext[16];
97     snprintf (ext, 16, "_%d", (*c)->conf->id);
98     (*c)->script_init_env (ext);
99     }
100 pcg 1.33 }
101    
102 pcg 1.45 inline const char *
103     vpn::script_if_init ()
104 pcg 1.33 {
105     script_init_env ();
106 pcg 1.1
107 pcg 1.33 return tap->if_up ();
108     }
109    
110 pcg 1.45 inline const char *
111     vpn::script_if_up ()
112 pcg 1.33 {
113     script_init_env ();
114    
115     char *filename;
116     asprintf (&filename,
117     "%s/%s",
118     confbase,
119     ::conf.script_if_up ? ::conf.script_if_up : "if-up");
120    
121     return filename;
122 pcg 1.1 }
123    
124     int
125     vpn::setup ()
126     {
127 pcg 1.41 ipv4_tos = -1;
128     ipv4_fd = -1;
129 pcg 1.1
130 pcg 1.8 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
131 pcg 1.1 {
132 pcg 1.8 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto);
133 pcg 1.1
134 pcg 1.8 if (ipv4_fd < 0)
135 pcg 1.1 return -1;
136    
137 pcg 1.11 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK);
138 pcg 1.37 fcntl (ipv4_fd, F_SETFD, FD_CLOEXEC);
139 pcg 1.11
140 pcg 1.14 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
141 pcg 1.1 // this I really consider a linux bug. I am neither connected
142     // nor do I fragment myself. Linux still sets DF and doesn't
143     // fragment for me sometimes.
144     {
145     int oval = IP_PMTUDISC_DONT;
146 pcg 1.8 setsockopt (ipv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
147 pcg 1.1 }
148     #endif
149    
150 pcg 1.9 sockinfo si (THISNODE, PROT_IPv4);
151    
152     if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
153     {
154     slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno));
155 pcg 1.23 exit (EXIT_FAILURE);
156 pcg 1.9 }
157    
158 pcg 1.39 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
159 pcg 1.1 }
160    
161 pcg 1.41 udpv4_tos = -1;
162     udpv4_fd = -1;
163 pcg 1.8
164     if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
165 pcg 1.1 {
166 pcg 1.8 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
167 pcg 1.1
168 pcg 1.8 if (udpv4_fd < 0)
169 pcg 1.1 return -1;
170    
171 pcg 1.11 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK);
172 pcg 1.37 fcntl (udpv4_fd, F_SETFD, FD_CLOEXEC);
173 pcg 1.11
174 pcg 1.8 // standard daemon practise...
175     {
176     int oval = 1;
177     setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
178     }
179    
180 pcg 1.14 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
181 pcg 1.9 // this I really consider a linux bug. I am neither connected
182     // nor do I fragment myself. Linux still sets DF and doesn't
183     // fragment for me sometimes.
184     {
185     int oval = IP_PMTUDISC_DONT;
186     setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
187     }
188     #endif
189    
190 pcg 1.8 sockinfo si (THISNODE, PROT_UDPv4);
191 pcg 1.2
192 pcg 1.8 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
193 pcg 1.1 {
194 pcg 1.8 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno));
195 pcg 1.23 exit (EXIT_FAILURE);
196 pcg 1.1 }
197    
198 pcg 1.39 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
199 pcg 1.9 }
200    
201 pcg 1.41 icmpv4_tos = -1;
202     icmpv4_fd = -1;
203 pcg 1.9
204     #if ENABLE_ICMP
205     if (THISNODE->protocols & PROT_ICMPv4)
206     {
207     icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP);
208    
209     if (icmpv4_fd < 0)
210     return -1;
211    
212 pcg 1.11 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK);
213 pcg 1.37 fcntl (icmpv4_fd, F_SETFD, FD_CLOEXEC);
214 pcg 1.11
215 pcg 1.9 #ifdef ICMP_FILTER
216     {
217     icmp_filter oval;
218     oval.data = 0xffffffff;
219     if (::conf.icmp_type < 32)
220     oval.data &= ~(1 << ::conf.icmp_type);
221    
222     setsockopt (icmpv4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval);
223     }
224     #endif
225    
226 pcg 1.14 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
227 pcg 1.1 // this I really consider a linux bug. I am neither connected
228     // nor do I fragment myself. Linux still sets DF and doesn't
229     // fragment for me sometimes.
230     {
231     int oval = IP_PMTUDISC_DONT;
232 pcg 1.36 setsockopt (icmpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
233 pcg 1.1 }
234     #endif
235    
236 pcg 1.9 sockinfo si (THISNODE, PROT_ICMPv4);
237    
238     if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
239     {
240     slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno));
241 pcg 1.23 exit (EXIT_FAILURE);
242 pcg 1.9 }
243    
244 pcg 1.39 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
245 pcg 1.1 }
246 pcg 1.9 #endif
247 pcg 1.1
248 pcg 1.8 tcpv4_fd = -1;
249    
250 pcg 1.2 #if ENABLE_TCP
251 pcg 1.8 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
252 pcg 1.2 {
253     tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
254    
255     if (tcpv4_fd < 0)
256     return -1;
257    
258 pcg 1.11 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK);
259 pcg 1.37 fcntl (tcpv4_fd, F_SETFD, FD_CLOEXEC);
260 pcg 1.11
261 pcg 1.3 // standard daemon practise...
262     {
263     int oval = 1;
264     setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
265     }
266    
267 pcg 1.2 sockinfo si (THISNODE, PROT_TCPv4);
268    
269     if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
270     {
271     slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno));
272 pcg 1.23 exit (EXIT_FAILURE);
273 pcg 1.2 }
274    
275     if (listen (tcpv4_fd, 5))
276     {
277     slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno));
278 pcg 1.23 exit (EXIT_FAILURE);
279 pcg 1.2 }
280    
281 pcg 1.39 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
282 pcg 1.2 }
283     #endif
284    
285 pcg 1.41 dnsv4_tos = -1;
286     dnsv4_fd = -1;
287    
288 pcg 1.24 #if ENABLE_DNS
289     if (THISNODE->protocols & PROT_DNSv4)
290     {
291 pcg 1.29 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
292    
293 pcg 1.24 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
294    
295     if (dnsv4_fd < 0)
296     return -1;
297    
298 pcg 1.37 fcntl (dnsv4_fd, F_SETFL, O_NONBLOCK);
299     fcntl (dnsv4_fd, F_SETFD, FD_CLOEXEC);
300    
301 pcg 1.35 # if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
302 pcg 1.32 // this I really consider a linux bug. I am neither connected
303     // nor do I fragment myself. Linux still sets DF and doesn't
304     // fragment for me sometimes.
305     {
306     int oval = IP_PMTUDISC_DONT;
307 pcg 1.35 setsockopt (dnsv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
308 pcg 1.32 }
309 pcg 1.35 # endif
310 pcg 1.32
311 pcg 1.24 // standard daemon practise...
312     {
313     int oval = 1;
314 pcg 1.31 setsockopt (dnsv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
315 pcg 1.24 }
316    
317 pcg 1.31 sockinfo si (THISNODE->dns_hostname,
318     THISNODE->dns_hostname ? THISNODE->dns_port : 0,
319     PROT_DNSv4);
320 pcg 1.24
321     if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
322     {
323     slog (L_ERR, _("can't bind dnsv4 on %s: %s"), (const char *)si, strerror (errno));
324     exit (EXIT_FAILURE);
325     }
326    
327 pcg 1.39 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
328 pcg 1.24 }
329     #endif
330    
331 pcg 1.34 /////////////////////////////////////////////////////////////////////////////
332    
333     reconnect_all ();
334    
335     /////////////////////////////////////////////////////////////////////////////
336    
337 pcg 1.1 tap = new tap_device ();
338     if (!tap) //D this, of course, never catches
339     {
340     slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname);
341 pcg 1.23 exit (EXIT_FAILURE);
342 pcg 1.1 }
343    
344 pcg 1.37 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
345    
346 pcg 1.43 run_script_cb cb;
347 pcg 1.44 cb.set<vpn, &vpn::script_if_init> (this);
348 pcg 1.43
349 pcg 1.33 if (tap->if_up () &&
350 pcg 1.43 !run_script (cb, true))
351 pcg 1.33 {
352     slog (L_ERR, _("interface initialization command '%s' failed, exiting."),
353     tap->if_up ());
354     exit (EXIT_FAILURE);
355     }
356    
357 pcg 1.44 cb.set<vpn, &vpn::script_if_up> (this);
358 pcg 1.43 if (!run_script (cb, true))
359 pcg 1.33 {
360     slog (L_ERR, _("if-up command execution failed, exiting."));
361     exit (EXIT_FAILURE);
362     }
363 pcg 1.1
364 pcg 1.39 tap_ev_watcher.start (tap->fd, EV_READ);
365 pcg 1.1
366     return 0;
367     }
368    
369 pcg 1.7 bool
370 pcg 1.1 vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
371     {
372 pcg 1.41 set_tos (ipv4_fd, ipv4_tos, tos);
373 pcg 1.1 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
374 pcg 1.7
375     return true;
376 pcg 1.1 }
377    
378 pcg 1.9 static u16
379     ipv4_checksum (u16 *data, unsigned int len)
380     {
381     // use 32 bit accumulator and fold back carry bits at the end
382     u32 sum = 0;
383    
384     while (len > 1)
385     {
386     sum += *data++;
387     len -= 2;
388     }
389    
390     // odd byte left?
391     if (len)
392     sum += *(u8 *)data;
393    
394     // add back carry bits
395     sum = (sum >> 16) + (sum & 0xffff); // lo += hi
396     sum += (sum >> 16); // carry
397    
398     return ~sum;
399     }
400    
401 pcg 1.13 #if ENABLE_ICMP
402 pcg 1.9 bool
403     vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
404     {
405     pkt->unshift_hdr (4);
406    
407 pcg 1.14 icmp_header *hdr = (icmp_header *)&((*pkt)[0]);
408 pcg 1.9 hdr->type = ::conf.icmp_type;
409     hdr->code = 255;
410     hdr->checksum = 0;
411     hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
412    
413 pcg 1.41 set_tos (icmpv4_fd, icmpv4_tos, tos);
414 pcg 1.9 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
415    
416     return true;
417     }
418 pcg 1.13 #endif
419 pcg 1.9
420 pcg 1.7 bool
421 pcg 1.1 vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
422     {
423 pcg 1.41 set_tos (udpv4_fd, udpv4_tos, tos);
424 pcg 1.1 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
425 pcg 1.7
426     return true;
427 pcg 1.1 }
428    
429     void
430 pcg 1.18 vpn::inject_data_packet (tap_packet *pkt, int dst)
431     {
432     if (dst)
433     {
434     // unicast
435     if (dst != THISNODE->id)
436     conns[dst - 1]->inject_data_packet (pkt);
437     }
438     else
439     {
440     // broadcast, this is ugly, but due to the security policy
441     // we have to connect to all hosts...
442     for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
443     if ((*c)->conf != THISNODE)
444 pcg 1.46 (*c)->inject_data_packet (pkt);
445 pcg 1.18 }
446     }
447    
448     void
449 pcg 1.1 vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
450     {
451     unsigned int src = pkt->src ();
452     unsigned int dst = pkt->dst ();
453    
454     slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"),
455     (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
456    
457     if (src == 0 || src > conns.size ()
458     || dst > conns.size ()
459     || pkt->typ () >= vpn_packet::PT_MAX)
460     slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"),
461     (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
462 pcg 1.6 else if (dst > conns.size ())
463     slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"),
464     (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
465 pcg 1.1 else
466     {
467     connection *c = conns[src - 1];
468    
469 pcg 1.13 if (dst == 0)
470     slog (L_WARN, _("%s(%s): received broadcast (protocol violation)"),
471 pcg 1.1 c->conf->nodename, (const char *)rsi);
472 pcg 1.18 else if (dst != THISNODE->id)
473 pcg 1.6 {
474     if (THISNODE->routerprio)
475     // the tos setting gets lost here. who cares.
476     conns[dst - 1]->inject_vpn_packet (pkt);
477     else
478     slog (L_WARN,
479     _("%s(%s): forwarding request (=> %s), but we are no router"),
480     c->conf->nodename, (const char *)rsi,
481     conns[dst - 1]->conf->nodename);
482     }
483 pcg 1.1 else
484     c->recv_vpn_packet (pkt, rsi);
485     }
486     }
487    
488 pcg 1.31 bool
489     vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
490     {
491     switch (si.prot)
492     {
493     case PROT_IPv4:
494     return send_ipv4_packet (pkt, si, tos);
495 pcg 1.41
496 pcg 1.31 case PROT_UDPv4:
497     return send_udpv4_packet (pkt, si, tos);
498 pcg 1.41
499 pcg 1.31 #if ENABLE_TCP
500     case PROT_TCPv4:
501     return send_tcpv4_packet (pkt, si, tos);
502     #endif
503     #if ENABLE_ICMP
504     case PROT_ICMPv4:
505     return send_icmpv4_packet (pkt, si, tos);
506     #endif
507     #if ENABLE_DNS
508     case PROT_DNSv4:
509     return send_dnsv4_packet (pkt, si, tos);
510     #endif
511     default:
512     slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si);
513     }
514    
515     return false;
516     }
517    
518 pcg 1.45 inline void
519 pcg 1.39 vpn::ipv4_ev (ev::io &w, int revents)
520 pcg 1.1 {
521 pcg 1.39 if (revents & EV_READ)
522 pcg 1.1 {
523     vpn_packet *pkt = new vpn_packet;
524     struct sockaddr_in sa;
525     socklen_t sa_len = sizeof (sa);
526     int len;
527    
528 pcg 1.5 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
529 pcg 1.1
530 pcg 1.9 sockinfo si(sa, PROT_IPv4);
531 pcg 1.1
532     if (len > 0)
533     {
534     pkt->len = len;
535    
536 pcg 1.30 // raw sockets deliver the ipv4 header, but don't expect it on sends
537 pcg 1.9 pkt->skip_hdr (IP_OVERHEAD);
538    
539 pcg 1.1 recv_vpn_packet (pkt, si);
540     }
541     else
542     {
543     // probably ECONNRESET or somesuch
544 pcg 1.9 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno));
545 pcg 1.1 }
546    
547     delete pkt;
548     }
549     else
550     {
551     slog (L_ERR,
552 pcg 1.30 _("FATAL: unknown revents %08x in socket, terminating\n"),
553     revents);
554 pcg 1.23 exit (EXIT_FAILURE);
555 pcg 1.1 }
556     }
557    
558 pcg 1.13 #if ENABLE_ICMP
559 pcg 1.45 inline void
560 pcg 1.39 vpn::icmpv4_ev (ev::io &w, int revents)
561 pcg 1.1 {
562 pcg 1.39 if (revents & EV_READ)
563 pcg 1.1 {
564     vpn_packet *pkt = new vpn_packet;
565     struct sockaddr_in sa;
566     socklen_t sa_len = sizeof (sa);
567     int len;
568    
569 pcg 1.5 len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
570 pcg 1.1
571 pcg 1.9 sockinfo si(sa, PROT_ICMPv4);
572 pcg 1.1
573     if (len > 0)
574     {
575     pkt->len = len;
576    
577 pcg 1.14 icmp_header *hdr = (icmp_header *)&((*pkt)[IP_OVERHEAD]);
578 pcg 1.9
579     if (hdr->type == ::conf.icmp_type
580     && hdr->code == 255)
581     {
582     // raw sockets deliver the ipv4, but don't expect it on sends
583     // this is slow, but...
584     pkt->skip_hdr (ICMP_OVERHEAD);
585    
586     recv_vpn_packet (pkt, si);
587     }
588     }
589     else
590     {
591     // probably ECONNRESET or somesuch
592     slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno));
593     }
594    
595     delete pkt;
596     }
597     else
598     {
599     slog (L_ERR,
600     _("FATAL: unknown revents %08x in socket, terminating\n"),
601     revents);
602 pcg 1.23 exit (EXIT_FAILURE);
603 pcg 1.9 }
604     }
605 pcg 1.13 #endif
606 pcg 1.9
607 pcg 1.45 inline void
608 pcg 1.39 vpn::udpv4_ev (ev::io &w, int revents)
609 pcg 1.9 {
610 pcg 1.39 if (revents & EV_READ)
611 pcg 1.9 {
612     vpn_packet *pkt = new vpn_packet;
613     struct sockaddr_in sa;
614     socklen_t sa_len = sizeof (sa);
615     int len;
616    
617     len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
618    
619     sockinfo si(sa, PROT_UDPv4);
620    
621     if (len > 0)
622     {
623     pkt->len = len;
624 pcg 1.1
625     recv_vpn_packet (pkt, si);
626     }
627     else
628     {
629     // probably ECONNRESET or somesuch
630 pcg 1.9 slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno));
631 pcg 1.1 }
632    
633     delete pkt;
634     }
635     else
636     {
637     slog (L_ERR,
638     _("FATAL: unknown revents %08x in socket, terminating\n"),
639     revents);
640 pcg 1.23 exit (EXIT_FAILURE);
641 pcg 1.1 }
642     }
643 pcg 1.2
644 pcg 1.45 inline void
645 pcg 1.39 vpn::tap_ev (ev::io &w, int revents)
646 pcg 1.1 {
647 pcg 1.39 if (revents & EV_READ)
648 pcg 1.1 {
649     /* process data */
650     tap_packet *pkt;
651    
652     pkt = tap->recv ();
653    
654 pcg 1.17 if (!pkt)
655     return;
656 pcg 1.1
657 pcg 1.17 if (pkt->len > 14)
658 pcg 1.1 {
659 pcg 1.17 int dst = mac2id (pkt->dst);
660     int src = mac2id (pkt->src);
661 pcg 1.1
662 pcg 1.17 if (src != THISNODE->id)
663     {
664 pcg 1.30 slog (L_ERR, _("FATAL: tap packet not originating on current node received (if-up script not working properly?), exiting."));
665 pcg 1.23 exit (EXIT_FAILURE);
666 pcg 1.17 }
667 pcg 1.1
668 pcg 1.17 if (dst == THISNODE->id)
669 pcg 1.1 {
670 pcg 1.17 slog (L_ERR, _("FATAL: tap packet destined for current node received, exiting."));
671 pcg 1.23 exit (EXIT_FAILURE);
672 pcg 1.1 }
673 pcg 1.17
674     if (dst > conns.size ())
675     slog (L_ERR, _("tap packet for unknown node %d received, ignoring."), dst);
676 pcg 1.1 else
677 pcg 1.18 inject_data_packet (pkt, dst);
678 pcg 1.1 }
679    
680     delete pkt;
681     }
682     else
683     abort ();
684     }
685    
686 pcg 1.45 inline void
687 pcg 1.39 vpn::event_cb (ev::timer &w, int)
688 pcg 1.1 {
689     if (events)
690     {
691     if (events & EVENT_SHUTDOWN)
692     {
693     slog (L_INFO, _("preparing shutdown..."));
694    
695     shutdown_all ();
696 pcg 1.24 remove_pid (conf.pidfilename);
697 pcg 1.1 slog (L_INFO, _("terminating"));
698 pcg 1.23 exit (EXIT_SUCCESS);
699 pcg 1.1 }
700    
701     if (events & EVENT_RECONNECT)
702     {
703     slog (L_INFO, _("forced reconnect"));
704    
705     reconnect_all ();
706     }
707    
708     events = 0;
709     }
710     }
711    
712     void
713     vpn::shutdown_all ()
714     {
715     for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
716     (*c)->shutdown ();
717     }
718    
719     void
720     vpn::reconnect_all ()
721     {
722     for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
723     delete *c;
724    
725     conns.clear ();
726    
727     connection_init ();
728    
729     for (configuration::node_vector::iterator i = conf.nodes.begin ();
730     i != conf.nodes.end (); ++i)
731     {
732 pcg 1.27 connection *conn = new connection (this, *i);
733 pcg 1.1 conns.push_back (conn);
734     conn->establish_connection ();
735     }
736     }
737    
738     connection *vpn::find_router ()
739     {
740 pcg 1.26 u32 prio = 1;
741 pcg 1.1 connection *router = 0;
742    
743     for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
744     {
745     connection *c = *i;
746    
747 pcg 1.13 if (c->conf->routerprio > prio
748 pcg 1.11 && c->connectmode == conf_node::C_ALWAYS // so we don't drop the connection if in use
749     && c->ictx && c->octx
750 pcg 1.13 && c->conf != THISNODE) // redundant, since ictx==octx==0 always on thisnode
751 pcg 1.1 {
752     prio = c->conf->routerprio;
753     router = c;
754     }
755     }
756    
757     return router;
758     }
759    
760 pcg 1.7 void vpn::send_connect_request (int id)
761 pcg 1.1 {
762     connection *c = find_router ();
763    
764     if (c)
765 pcg 1.7 c->send_connect_request (id);
766     else
767     // no router found, aggressively connect to all routers
768     for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
769 pcg 1.13 if ((*i)->conf->routerprio && (*i)->conf != THISNODE)
770 pcg 1.7 (*i)->establish_connection ();
771 pcg 1.1 }
772    
773     void
774     connection::dump_status ()
775     {
776     slog (L_NOTICE, _("node %s (id %d)"), conf->nodename, conf->id);
777     slog (L_NOTICE, _(" connectmode %d (%d) / sockaddr %s / minor %d"),
778     connectmode, conf->connectmode, (const char *)si, (int)prot_minor);
779     slog (L_NOTICE, _(" ictx/octx %08lx/%08lx / oseqno %d / retry_cnt %d"),
780     (long)ictx, (long)octx, (int)oseqno, (int)retry_cnt);
781     slog (L_NOTICE, _(" establish_conn %ld / rekey %ld / keepalive %ld"),
782     (long)(establish_connection.at), (long)(rekey.at), (long)(keepalive.at));
783     }
784    
785     void
786     vpn::dump_status ()
787     {
788 pcg 1.40 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)ev_now ());
789 pcg 1.1
790     for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
791     (*c)->dump_status ();
792    
793     slog (L_NOTICE, _("END status dump"));
794     }
795    
796     vpn::vpn (void)
797 pcg 1.44 {
798     event .set<vpn, &vpn::event_cb > (this);
799     udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this);
800     ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this);
801 pcg 1.2 #if ENABLE_TCP
802 pcg 1.44 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
803 pcg 1.9 #endif
804     #if ENABLE_ICMP
805 pcg 1.44 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this);
806 pcg 1.24 #endif
807     #if ENABLE_DNS
808 pcg 1.44 dnsv4_ev_watcher .set<vpn, &vpn::dnsv4_ev > (this);
809 pcg 1.2 #endif
810 pcg 1.44 tap_ev_watcher .set<vpn, &vpn::tap_ev > (this);
811 pcg 1.1 }
812    
813     vpn::~vpn ()
814     {
815     }
816