ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn.C
(Generate patch)

Comparing gvpe/src/vpn.C (file contents):
Revision 1.38 by pcg, Tue Apr 26 00:55:56 2005 UTC vs.
Revision 1.50 by pcg, Sun Aug 10 02:49:21 2008 UTC

1/* 1/*
2 vpn.C -- handle the protocol, encryption, handshaking etc. 2 vpn.C -- handle the protocol, encryption, handshaking etc.
3 Copyright (C) 2003-2005 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de>
4 4
5 This file is part of GVPE. 5 This file is part of GVPE.
6 6
7 GVPE is free software; you can redistribute it and/or modify 7 GVPE is free software; you can redistribute it and/or modify it
8 it under the terms of the GNU General Public License as published by 8 under the terms of the GNU General Public License as published by the
9 the Free Software Foundation; either version 2 of the License, or 9 Free Software Foundation; either version 3 of the License, or (at your
10 (at your option) any later version. 10 option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful, but
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 GNU General Public License for more details. 15 Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License along
18 along with gvpe; if not, write to the Free Software 18 with this program; if not, see <http://www.gnu.org/licenses/>.
19 Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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.
20*/ 30*/
21 31
22#include "config.h" 32#include "config.h"
23 33
24#include <list> 34#include <list>
46 56
47vpn network; // THE vpn (bad design...) 57vpn network; // THE vpn (bad design...)
48 58
49///////////////////////////////////////////////////////////////////////////// 59/////////////////////////////////////////////////////////////////////////////
50 60
61static void inline
62set_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
51void 73void
52vpn::script_init_env () 74vpn::script_init_env ()
53{ 75{
54 // the tunnel device mtu should be the physical mtu - overhead 76 // the tunnel device mtu should be the physical mtu - overhead
55 // the tricky part is rounding to the cipher key blocksize 77 // the tricky part is rounding to the cipher key blocksize
75 snprintf (ext, 16, "_%d", (*c)->conf->id); 97 snprintf (ext, 16, "_%d", (*c)->conf->id);
76 (*c)->script_init_env (ext); 98 (*c)->script_init_env (ext);
77 } 99 }
78} 100}
79 101
102inline const char *
80const char *vpn::script_if_init () 103vpn::script_if_init ()
81{ 104{
82 script_init_env (); 105 script_init_env ();
83 106
84 return tap->if_up (); 107 return tap->if_up ();
85} 108}
86 109
110inline const char *
87const char *vpn::script_if_up () 111vpn::script_if_up ()
88{ 112{
89 script_init_env (); 113 script_init_env ();
90 114
91 char *filename; 115 char *filename;
92 asprintf (&filename, 116 asprintf (&filename,
98} 122}
99 123
100int 124int
101vpn::setup () 125vpn::setup ()
102{ 126{
127 ipv4_tos = -1;
103 ipv4_fd = -1; 128 ipv4_fd = -1;
104 129
105 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 130 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
106 { 131 {
107 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 132 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto);
108 133
124 149
125 sockinfo si (THISNODE, PROT_IPv4); 150 sockinfo si (THISNODE, PROT_IPv4);
126 151
127 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 152 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
128 { 153 {
129 slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno)); 154 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
130 exit (EXIT_FAILURE); 155 exit (EXIT_FAILURE);
131 } 156 }
132 157
133 ipv4_ev_watcher.start (ipv4_fd, EVENT_READ); 158 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
134 } 159 }
135 160
161 udpv4_tos = -1;
136 udpv4_fd = -1; 162 udpv4_fd = -1;
137 163
138 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 164 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
139 { 165 {
140 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 166 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
141 167
163 189
164 sockinfo si (THISNODE, PROT_UDPv4); 190 sockinfo si (THISNODE, PROT_UDPv4);
165 191
166 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 192 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
167 { 193 {
168 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); 194 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
169 exit (EXIT_FAILURE); 195 exit (EXIT_FAILURE);
170 } 196 }
171 197
172 udpv4_ev_watcher.start (udpv4_fd, EVENT_READ); 198 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
173 } 199 }
174 200
201 icmpv4_tos = -1;
175 icmpv4_fd = -1; 202 icmpv4_fd = -1;
176 203
177#if ENABLE_ICMP 204#if ENABLE_ICMP
178 if (THISNODE->protocols & PROT_ICMPv4) 205 if (THISNODE->protocols & PROT_ICMPv4)
179 { 206 {
180 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 207 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP);
208 235
209 sockinfo si (THISNODE, PROT_ICMPv4); 236 sockinfo si (THISNODE, PROT_ICMPv4);
210 237
211 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 238 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
212 { 239 {
213 slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno)); 240 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
214 exit (EXIT_FAILURE); 241 exit (EXIT_FAILURE);
215 } 242 }
216 243
217 icmpv4_ev_watcher.start (icmpv4_fd, EVENT_READ); 244 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
218 } 245 }
219#endif 246#endif
220 247
221 tcpv4_fd = -1; 248 tcpv4_fd = -1;
222 249
239 266
240 sockinfo si (THISNODE, PROT_TCPv4); 267 sockinfo si (THISNODE, PROT_TCPv4);
241 268
242 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 269 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
243 { 270 {
244 slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 271 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
245 exit (EXIT_FAILURE); 272 exit (EXIT_FAILURE);
246 } 273 }
247 274
248 if (listen (tcpv4_fd, 5)) 275 if (listen (tcpv4_fd, 5))
249 { 276 {
250 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 277 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
251 exit (EXIT_FAILURE); 278 exit (EXIT_FAILURE);
252 } 279 }
253 280
254 tcpv4_ev_watcher.start (tcpv4_fd, EVENT_READ); 281 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
255 } 282 }
256#endif 283#endif
284
285 dnsv4_tos = -1;
286 dnsv4_fd = -1;
257 287
258#if ENABLE_DNS 288#if ENABLE_DNS
259 if (THISNODE->protocols & PROT_DNSv4) 289 if (THISNODE->protocols & PROT_DNSv4)
260 { 290 {
261 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); 291 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
288 THISNODE->dns_hostname ? THISNODE->dns_port : 0, 318 THISNODE->dns_hostname ? THISNODE->dns_port : 0,
289 PROT_DNSv4); 319 PROT_DNSv4);
290 320
291 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 321 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
292 { 322 {
293 slog (L_ERR, _("can't bind dnsv4 on %s: %s"), (const char *)si, strerror (errno)); 323 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
294 exit (EXIT_FAILURE); 324 exit (EXIT_FAILURE);
295 } 325 }
296 326
297 dnsv4_ev_watcher.start (dnsv4_fd, EVENT_READ); 327 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
298 } 328 }
299#endif 329#endif
300 330
301 ///////////////////////////////////////////////////////////////////////////// 331 /////////////////////////////////////////////////////////////////////////////
302 332
305 ///////////////////////////////////////////////////////////////////////////// 335 /////////////////////////////////////////////////////////////////////////////
306 336
307 tap = new tap_device (); 337 tap = new tap_device ();
308 if (!tap) //D this, of course, never catches 338 if (!tap) //D this, of course, never catches
309 { 339 {
310 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname); 340 slog (L_ERR, _("cannot create network interface '%s', exiting."), conf.ifname);
311 exit (EXIT_FAILURE); 341 exit (EXIT_FAILURE);
312 } 342 }
313 343
314 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 344 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
315 345
346 run_script_cb cb;
347 cb.set<vpn, &vpn::script_if_init> (this);
348
316 if (tap->if_up () && 349 if (tap->if_up () &&
317 !run_script (run_script_cb (this, &vpn::script_if_init), true)) 350 !run_script (cb, true))
318 { 351 {
319 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 352 slog (L_ERR, _("interface initialization command '%s' failed, exiting."),
320 tap->if_up ()); 353 tap->if_up ());
321 exit (EXIT_FAILURE); 354 exit (EXIT_FAILURE);
322 } 355 }
323 356
324 if (!run_script (run_script_cb (this, &vpn::script_if_up), true)) 357 cb.set<vpn, &vpn::script_if_up> (this);
358 if (!run_script (cb, true))
325 { 359 {
326 slog (L_ERR, _("if-up command execution failed, exiting.")); 360 slog (L_ERR, _("if-up command execution failed, exiting."));
327 exit (EXIT_FAILURE); 361 exit (EXIT_FAILURE);
328 } 362 }
329 363
330 tap_ev_watcher.start (tap->fd, EVENT_READ); 364 tap_ev_watcher.start (tap->fd, EV_READ);
331 365
332 return 0; 366 return 0;
333} 367}
334 368
335bool 369bool
336vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 370vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
337{ 371{
338#if defined(SOL_IP) && defined(IP_TOS) 372 set_tos (ipv4_fd, ipv4_tos, tos);
339 setsockopt (ipv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
340#endif
341 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 373 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
342 374
343 return true; 375 return true;
344} 376}
345 377
368 400
369#if ENABLE_ICMP 401#if ENABLE_ICMP
370bool 402bool
371vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 403vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
372{ 404{
373#if defined(SOL_IP) && defined(IP_TOS)
374 setsockopt (icmpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
375#endif
376
377 pkt->unshift_hdr (4); 405 pkt->unshift_hdr (4);
378 406
379 icmp_header *hdr = (icmp_header *)&((*pkt)[0]); 407 icmp_header *hdr = (icmp_header *)&((*pkt)[0]);
380 hdr->type = ::conf.icmp_type; 408 hdr->type = ::conf.icmp_type;
381 hdr->code = 255; 409 hdr->code = 255;
382 hdr->checksum = 0; 410 hdr->checksum = 0;
383 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); 411 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
384 412
413 set_tos (icmpv4_fd, icmpv4_tos, tos);
385 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 414 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
386 415
387 return true; 416 return true;
388} 417}
389#endif 418#endif
390 419
391bool 420bool
392vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 421vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
393{ 422{
394#if defined(SOL_IP) && defined(IP_TOS) 423 set_tos (udpv4_fd, udpv4_tos, tos);
395 setsockopt (udpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
396#endif
397 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 424 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
398 425
399 return true; 426 return true;
400} 427}
401 428
412 { 439 {
413 // broadcast, this is ugly, but due to the security policy 440 // broadcast, this is ugly, but due to the security policy
414 // we have to connect to all hosts... 441 // we have to connect to all hosts...
415 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) 442 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
416 if ((*c)->conf != THISNODE) 443 if ((*c)->conf != THISNODE)
417 (*c)->inject_data_packet (pkt, true); 444 (*c)->inject_data_packet (pkt);
418 } 445 }
419} 446}
420 447
421void 448void
422vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 449vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
423{ 450{
424 unsigned int src = pkt->src (); 451 unsigned int src = pkt->src ();
425 unsigned int dst = pkt->dst (); 452 unsigned int dst = pkt->dst ();
426 453
427 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), 454 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d."),
428 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); 455 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
429 456
430 if (src == 0 || src > conns.size () 457 if (src == 0 || src > conns.size ()
431 || dst > conns.size () 458 || dst > conns.size ()
432 || pkt->typ () >= vpn_packet::PT_MAX) 459 || pkt->typ () >= vpn_packet::PT_MAX)
433 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), 460 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
434 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 461 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
435 else if (dst > conns.size ()) 462 else if (dst > conns.size ())
436 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), 463 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
437 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 464 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
438 else 465 else
439 { 466 {
440 connection *c = conns[src - 1]; 467 connection *c = conns[src - 1];
441 468
442 if (dst == 0) 469 if (dst == 0)
443 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)"), 470 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
444 c->conf->nodename, (const char *)rsi); 471 c->conf->nodename, (const char *)rsi);
445 else if (dst != THISNODE->id) 472 else if (dst != THISNODE->id)
446 { 473 {
447 if (THISNODE->routerprio) 474 if (THISNODE->routerprio)
448 // the tos setting gets lost here. who cares. 475 // the tos setting gets lost here. who cares.
449 conns[dst - 1]->inject_vpn_packet (pkt); 476 conns[dst - 1]->inject_vpn_packet (pkt);
450 else 477 else
451 slog (L_WARN, 478 slog (L_WARN,
452 _("%s(%s): forwarding request (=> %s), but we are no router"), 479 _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."),
453 c->conf->nodename, (const char *)rsi, 480 c->conf->nodename, (const char *)rsi,
454 conns[dst - 1]->conf->nodename); 481 conns[dst - 1]->conf->nodename);
455 } 482 }
456 else 483 else
457 c->recv_vpn_packet (pkt, rsi); 484 c->recv_vpn_packet (pkt, rsi);
463{ 490{
464 switch (si.prot) 491 switch (si.prot)
465 { 492 {
466 case PROT_IPv4: 493 case PROT_IPv4:
467 return send_ipv4_packet (pkt, si, tos); 494 return send_ipv4_packet (pkt, si, tos);
495
468 case PROT_UDPv4: 496 case PROT_UDPv4:
469 return send_udpv4_packet (pkt, si, tos); 497 return send_udpv4_packet (pkt, si, tos);
498
470#if ENABLE_TCP 499#if ENABLE_TCP
471 case PROT_TCPv4: 500 case PROT_TCPv4:
472 return send_tcpv4_packet (pkt, si, tos); 501 return send_tcpv4_packet (pkt, si, tos);
473#endif 502#endif
474#if ENABLE_ICMP 503#if ENABLE_ICMP
477#endif 506#endif
478#if ENABLE_DNS 507#if ENABLE_DNS
479 case PROT_DNSv4: 508 case PROT_DNSv4:
480 return send_dnsv4_packet (pkt, si, tos); 509 return send_dnsv4_packet (pkt, si, tos);
481#endif 510#endif
482
483 default: 511 default:
484 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si); 512 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
485 } 513 }
486 514
487 return false; 515 return false;
488} 516}
489 517
490void 518inline void
491vpn::ipv4_ev (io_watcher &w, short revents) 519vpn::ipv4_ev (ev::io &w, int revents)
492{ 520{
493 if (revents & EVENT_READ) 521 if (revents & EV_READ)
494 { 522 {
495 vpn_packet *pkt = new vpn_packet; 523 vpn_packet *pkt = new vpn_packet;
496 struct sockaddr_in sa; 524 struct sockaddr_in sa;
497 socklen_t sa_len = sizeof (sa); 525 socklen_t sa_len = sizeof (sa);
498 int len; 526 int len;
511 recv_vpn_packet (pkt, si); 539 recv_vpn_packet (pkt, si);
512 } 540 }
513 else 541 else
514 { 542 {
515 // probably ECONNRESET or somesuch 543 // probably ECONNRESET or somesuch
516 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 544 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
517 } 545 }
518 546
519 delete pkt; 547 delete pkt;
520 } 548 }
521 else 549 else
522 { 550 {
523 slog (L_ERR, 551 slog (L_ERR,
524 _("FATAL: unknown revents %08x in socket, terminating\n"), 552 _("FATAL: unknown revents %08x in socket, exiting.\n"),
525 revents); 553 revents);
526 exit (EXIT_FAILURE); 554 exit (EXIT_FAILURE);
527 } 555 }
528} 556}
529 557
530#if ENABLE_ICMP 558#if ENABLE_ICMP
531void 559inline void
532vpn::icmpv4_ev (io_watcher &w, short revents) 560vpn::icmpv4_ev (ev::io &w, int revents)
533{ 561{
534 if (revents & EVENT_READ) 562 if (revents & EV_READ)
535 { 563 {
536 vpn_packet *pkt = new vpn_packet; 564 vpn_packet *pkt = new vpn_packet;
537 struct sockaddr_in sa; 565 struct sockaddr_in sa;
538 socklen_t sa_len = sizeof (sa); 566 socklen_t sa_len = sizeof (sa);
539 int len; 567 int len;
559 } 587 }
560 } 588 }
561 else 589 else
562 { 590 {
563 // probably ECONNRESET or somesuch 591 // probably ECONNRESET or somesuch
564 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 592 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
565 } 593 }
566 594
567 delete pkt; 595 delete pkt;
568 } 596 }
569 else 597 else
570 { 598 {
571 slog (L_ERR, 599 slog (L_ERR,
572 _("FATAL: unknown revents %08x in socket, terminating\n"), 600 _("FATAL: unknown revents %08x in socket, exiting.\n"),
573 revents); 601 revents);
574 exit (EXIT_FAILURE); 602 exit (EXIT_FAILURE);
575 } 603 }
576} 604}
577#endif 605#endif
578 606
579void 607inline void
580vpn::udpv4_ev (io_watcher &w, short revents) 608vpn::udpv4_ev (ev::io &w, int revents)
581{ 609{
582 if (revents & EVENT_READ) 610 if (revents & EV_READ)
583 { 611 {
584 vpn_packet *pkt = new vpn_packet; 612 vpn_packet *pkt = new vpn_packet;
585 struct sockaddr_in sa; 613 struct sockaddr_in sa;
586 socklen_t sa_len = sizeof (sa); 614 socklen_t sa_len = sizeof (sa);
587 int len; 615 int len;
597 recv_vpn_packet (pkt, si); 625 recv_vpn_packet (pkt, si);
598 } 626 }
599 else 627 else
600 { 628 {
601 // probably ECONNRESET or somesuch 629 // probably ECONNRESET or somesuch
602 slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno)); 630 slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno));
603 } 631 }
604 632
605 delete pkt; 633 delete pkt;
606 } 634 }
607 else 635 else
608 { 636 {
609 slog (L_ERR, 637 slog (L_ERR,
610 _("FATAL: unknown revents %08x in socket, terminating\n"), 638 _("FATAL: unknown revents %08x in socket, exiting.\n"),
611 revents); 639 revents);
612 exit (EXIT_FAILURE); 640 exit (EXIT_FAILURE);
613 } 641 }
614} 642}
615 643
616void 644inline void
617vpn::tap_ev (io_watcher &w, short revents) 645vpn::tap_ev (ev::io &w, int revents)
618{ 646{
619 if (revents & EVENT_READ) 647 if (revents & EV_READ)
620 { 648 {
621 /* process data */ 649 /* process data */
622 tap_packet *pkt; 650 tap_packet *pkt;
623 651
624 pkt = tap->recv (); 652 pkt = tap->recv ();
653 } 681 }
654 else 682 else
655 abort (); 683 abort ();
656} 684}
657 685
658void 686inline void
659vpn::event_cb (time_watcher &w) 687vpn::event_cb (ev::timer &w, int)
660{ 688{
661 if (events) 689 if (events)
662 { 690 {
663 if (events & EVENT_SHUTDOWN) 691 if (events & EVENT_SHUTDOWN)
664 { 692 {
665 slog (L_INFO, _("preparing shutdown...")); 693 slog (L_INFO, _("preparing shutdown..."));
666 694
667 shutdown_all (); 695 shutdown_all ();
668 remove_pid (conf.pidfilename); 696 remove_pid (conf.pidfilename);
669 slog (L_INFO, _("terminating")); 697 slog (L_INFO, _("exiting."));
670 exit (EXIT_SUCCESS); 698 exit (EXIT_SUCCESS);
671 } 699 }
672 700
673 if (events & EVENT_RECONNECT) 701 if (events & EVENT_RECONNECT)
674 { 702 {
675 slog (L_INFO, _("forced reconnect")); 703 slog (L_INFO, _("forced reconnect."));
676 704
677 reconnect_all (); 705 reconnect_all ();
678 } 706 }
679 707
680 events = 0; 708 events = 0;
696 724
697 conns.clear (); 725 conns.clear ();
698 726
699 connection_init (); 727 connection_init ();
700 728
701 for (configuration::node_vector::iterator i = conf.nodes.begin (); 729 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
702 i != conf.nodes.end (); ++i) 730 conns.push_back (new connection (this, *i));
703 { 731
704 connection *conn = new connection (this, *i); 732 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
705 conns.push_back (conn);
706 conn->establish_connection (); 733 (*c)->establish_connection ();
707 }
708} 734}
709 735
710connection *vpn::find_router () 736bool vpn::can_direct (conf_node *src, conf_node *dst) const
711{ 737{
712 u32 prio = 1; 738 return src != dst
739 && src->may_direct (dst)
740 && dst->may_direct (src)
741 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
742 || (src->protocols & dst->connectable_protocols ()));
743}
744
745// only works for indirect and routed connections: find a router
746// from THISNODE to dst
747connection *vpn::find_router_for (const connection *dst)
748{
713 connection *router = 0; 749 connection *router = 0;
714 750
751 // first try to find a router with a direct connection
752 {
753 u32 prio = 1;
754
755 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
756 {
757 connection *c = *i;
758
759 if (c->conf->routerprio > prio
760 && c->conf != THISNODE
761 && c != dst
762 && can_direct (c->conf, dst->conf))
763 {
764 if (c->ictx && c->octx)
765 {
766 prio = c->conf->routerprio;
767 router = c;
768 }
769 else
770 c->establish_connection ();
771 }
772 }
773 }
774
775 if (router)
776 return router;
777
778 // second try find the router with the highest priority higher than ours
779 {
780 u32 prio = 1;
781
782 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
783 {
784 connection *c = *i;
785
786 if (c->conf->routerprio > prio
787 && c->conf->routerprio > THISNODE->routerprio
788 && c != dst
789 && c->conf != THISNODE)
790 {
791 if (c->ictx && c->octx)
792 {
793 prio = c->conf->routerprio;
794 router = c;
795 }
796 else
797 c->establish_connection ();
798 }
799 }
800 }
801 return router;
802}
803
804void vpn::connection_established (connection *c)
805{
715 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 806 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
716 { 807 {
717 connection *c = *i; 808 connection *o = *i;
718 809
719 if (c->conf->routerprio > prio 810 if (!o->is_direct
720 && c->connectmode == conf_node::C_ALWAYS // so we don't drop the connection if in use 811 && o->si.valid ()
721 && c->ictx && c->octx 812 && c->si != o->si
722 && c->conf != THISNODE) // redundant, since ictx==octx==0 always on thisnode 813 && c == find_router_for (o))
723 {
724 prio = c->conf->routerprio;
725 router = c;
726 } 814 {
815 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
816 o->conf->nodename, c->conf->nodename);
817 o->rekey ();
818 }
727 } 819 }
728
729 return router;
730} 820}
731 821
732void vpn::send_connect_request (int id) 822void vpn::send_connect_request (connection *c)
733{ 823{
734 connection *c = find_router (); 824 connection *r = find_router_for (c);
735 825
736 if (c) 826 if (r)
827 {
828 slog (L_TRACE, _("%s: no way to connect, sending mediated connection request via %s."),
829 c->conf->nodename, r->conf->nodename);
737 c->send_connect_request (id); 830 r->send_connect_request (c->conf->id);
831 }
738 else 832 else
739 // no router found, aggressively connect to all routers 833 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect."),
740 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 834 c->conf->nodename);
741 if ((*i)->conf->routerprio && (*i)->conf != THISNODE)
742 (*i)->establish_connection ();
743} 835}
744 836
745void 837void
746connection::dump_status () 838connection::dump_status ()
747{ 839{
748 slog (L_NOTICE, _("node %s (id %d)"), conf->nodename, conf->id); 840 slog (L_NOTICE, _("node %s (id %d)"), conf->nodename, conf->id);
749 slog (L_NOTICE, _(" connectmode %d (%d) / sockaddr %s / minor %d"), 841 slog (L_NOTICE, _(" connectmode %d (%d) / sockaddr %s / minor %d"),
750 connectmode, conf->connectmode, (const char *)si, (int)prot_minor); 842 connectmode, conf->connectmode, (const char *)si, (int)prot_minor);
751 slog (L_NOTICE, _(" ictx/octx %08lx/%08lx / oseqno %d / retry_cnt %d"), 843 slog (L_NOTICE, _(" ictx/octx %08lx/%08lx / oseqno %d / retry_cnt %d"),
752 (long)ictx, (long)octx, (int)oseqno, (int)retry_cnt); 844 (long)ictx, (long)octx, (int)oseqno, (int)retry_cnt);
753 slog (L_NOTICE, _(" establish_conn %ld / rekey %ld / keepalive %ld"),
754 (long)(establish_connection.at), (long)(rekey.at), (long)(keepalive.at));
755} 845}
756 846
757void 847void
758vpn::dump_status () 848vpn::dump_status ()
759{ 849{
760 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)NOW); 850 slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)ev_now ());
761 851
762 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) 852 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
763 (*c)->dump_status (); 853 (*c)->dump_status ();
764 854
765 slog (L_NOTICE, _("END status dump")); 855 slog (L_NOTICE, _("END status dump"));
766} 856}
767 857
768vpn::vpn (void) 858vpn::vpn (void)
859{
769: event (this, &vpn::event_cb) 860 event .set<vpn, &vpn::event_cb > (this);
770, udpv4_ev_watcher (this, &vpn::udpv4_ev) 861 udpv4_ev_watcher .set<vpn, &vpn::udpv4_ev > (this);
771, ipv4_ev_watcher (this, &vpn::ipv4_ev) 862 ipv4_ev_watcher .set<vpn, &vpn::ipv4_ev > (this);
772#if ENABLE_TCP 863#if ENABLE_TCP
773, tcpv4_ev_watcher (this, &vpn::tcpv4_ev) 864 tcpv4_ev_watcher .set<vpn, &vpn::tcpv4_ev > (this);
774#endif 865#endif
775#if ENABLE_ICMP 866#if ENABLE_ICMP
776, icmpv4_ev_watcher(this, &vpn::icmpv4_ev) 867 icmpv4_ev_watcher.set<vpn, &vpn::icmpv4_ev> (this);
777#endif 868#endif
778#if ENABLE_DNS 869#if ENABLE_DNS
779, dnsv4_ev_watcher (this, &vpn::dnsv4_ev) 870 dnsv4_ev_watcher .set<vpn, &vpn::dnsv4_ev > (this);
780#endif 871#endif
781, tap_ev_watcher (this, &vpn::tap_ev) 872 tap_ev_watcher .set<vpn, &vpn::tap_ev > (this);
782{
783} 873}
784 874
785vpn::~vpn () 875vpn::~vpn ()
786{ 876{
787} 877}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines