ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn.C
Revision: 1.62
Committed: Sat Dec 17 22:05:34 2011 UTC (12 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.61: +97 -0 lines
Log Message:
ipv42_hack

File Contents

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