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.48 by pcg, Sat Aug 9 18:30:55 2008 UTC vs.
Revision 1.49 by pcg, Sun Aug 10 01:34:36 2008 UTC

149 149
150 sockinfo si (THISNODE, PROT_IPv4); 150 sockinfo si (THISNODE, PROT_IPv4);
151 151
152 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 152 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
153 { 153 {
154 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));
155 exit (EXIT_FAILURE); 155 exit (EXIT_FAILURE);
156 } 156 }
157 157
158 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 158 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
159 } 159 }
189 189
190 sockinfo si (THISNODE, PROT_UDPv4); 190 sockinfo si (THISNODE, PROT_UDPv4);
191 191
192 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 192 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
193 { 193 {
194 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));
195 exit (EXIT_FAILURE); 195 exit (EXIT_FAILURE);
196 } 196 }
197 197
198 udpv4_ev_watcher.start (udpv4_fd, EV_READ); 198 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
199 } 199 }
235 235
236 sockinfo si (THISNODE, PROT_ICMPv4); 236 sockinfo si (THISNODE, PROT_ICMPv4);
237 237
238 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 238 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
239 { 239 {
240 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));
241 exit (EXIT_FAILURE); 241 exit (EXIT_FAILURE);
242 } 242 }
243 243
244 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); 244 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
245 } 245 }
266 266
267 sockinfo si (THISNODE, PROT_TCPv4); 267 sockinfo si (THISNODE, PROT_TCPv4);
268 268
269 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 269 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
270 { 270 {
271 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));
272 exit (EXIT_FAILURE); 272 exit (EXIT_FAILURE);
273 } 273 }
274 274
275 if (listen (tcpv4_fd, 5)) 275 if (listen (tcpv4_fd, 5))
276 { 276 {
277 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));
278 exit (EXIT_FAILURE); 278 exit (EXIT_FAILURE);
279 } 279 }
280 280
281 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); 281 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
282 } 282 }
318 THISNODE->dns_hostname ? THISNODE->dns_port : 0, 318 THISNODE->dns_hostname ? THISNODE->dns_port : 0,
319 PROT_DNSv4); 319 PROT_DNSv4);
320 320
321 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 321 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
322 { 322 {
323 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));
324 exit (EXIT_FAILURE); 324 exit (EXIT_FAILURE);
325 } 325 }
326 326
327 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); 327 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
328 } 328 }
335 ///////////////////////////////////////////////////////////////////////////// 335 /////////////////////////////////////////////////////////////////////////////
336 336
337 tap = new tap_device (); 337 tap = new tap_device ();
338 if (!tap) //D this, of course, never catches 338 if (!tap) //D this, of course, never catches
339 { 339 {
340 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname); 340 slog (L_ERR, _("cannot create network interface '%s', exiting."), conf.ifname);
341 exit (EXIT_FAILURE); 341 exit (EXIT_FAILURE);
342 } 342 }
343 343
344 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 344 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
345 345
449vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 449vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
450{ 450{
451 unsigned int src = pkt->src (); 451 unsigned int src = pkt->src ();
452 unsigned int dst = pkt->dst (); 452 unsigned int dst = pkt->dst ();
453 453
454 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."),
455 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); 455 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
456 456
457 if (src == 0 || src > conns.size () 457 if (src == 0 || src > conns.size ()
458 || dst > conns.size () 458 || dst > conns.size ()
459 || pkt->typ () >= vpn_packet::PT_MAX) 459 || pkt->typ () >= vpn_packet::PT_MAX)
460 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)."),
461 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 461 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
462 else if (dst > conns.size ()) 462 else if (dst > conns.size ())
463 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)."),
464 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 464 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
465 else 465 else
466 { 466 {
467 connection *c = conns[src - 1]; 467 connection *c = conns[src - 1];
468 468
469 if (dst == 0) 469 if (dst == 0)
470 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)"), 470 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
471 c->conf->nodename, (const char *)rsi); 471 c->conf->nodename, (const char *)rsi);
472 else if (dst != THISNODE->id) 472 else if (dst != THISNODE->id)
473 { 473 {
474 if (THISNODE->routerprio) 474 if (THISNODE->routerprio)
475 // the tos setting gets lost here. who cares. 475 // the tos setting gets lost here. who cares.
476 conns[dst - 1]->inject_vpn_packet (pkt); 476 conns[dst - 1]->inject_vpn_packet (pkt);
477 else 477 else
478 slog (L_WARN, 478 slog (L_WARN,
479 _("%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?)."),
480 c->conf->nodename, (const char *)rsi, 480 c->conf->nodename, (const char *)rsi,
481 conns[dst - 1]->conf->nodename); 481 conns[dst - 1]->conf->nodename);
482 } 482 }
483 else 483 else
484 c->recv_vpn_packet (pkt, rsi); 484 c->recv_vpn_packet (pkt, rsi);
507#if ENABLE_DNS 507#if ENABLE_DNS
508 case PROT_DNSv4: 508 case PROT_DNSv4:
509 return send_dnsv4_packet (pkt, si, tos); 509 return send_dnsv4_packet (pkt, si, tos);
510#endif 510#endif
511 default: 511 default:
512 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);
513 } 513 }
514 514
515 return false; 515 return false;
516} 516}
517 517
539 recv_vpn_packet (pkt, si); 539 recv_vpn_packet (pkt, si);
540 } 540 }
541 else 541 else
542 { 542 {
543 // probably ECONNRESET or somesuch 543 // probably ECONNRESET or somesuch
544 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 544 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
545 } 545 }
546 546
547 delete pkt; 547 delete pkt;
548 } 548 }
549 else 549 else
550 { 550 {
551 slog (L_ERR, 551 slog (L_ERR,
552 _("FATAL: unknown revents %08x in socket, terminating\n"), 552 _("FATAL: unknown revents %08x in socket, exiting.\n"),
553 revents); 553 revents);
554 exit (EXIT_FAILURE); 554 exit (EXIT_FAILURE);
555 } 555 }
556} 556}
557 557
587 } 587 }
588 } 588 }
589 else 589 else
590 { 590 {
591 // probably ECONNRESET or somesuch 591 // probably ECONNRESET or somesuch
592 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 592 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
593 } 593 }
594 594
595 delete pkt; 595 delete pkt;
596 } 596 }
597 else 597 else
598 { 598 {
599 slog (L_ERR, 599 slog (L_ERR,
600 _("FATAL: unknown revents %08x in socket, terminating\n"), 600 _("FATAL: unknown revents %08x in socket, exiting.\n"),
601 revents); 601 revents);
602 exit (EXIT_FAILURE); 602 exit (EXIT_FAILURE);
603 } 603 }
604} 604}
605#endif 605#endif
625 recv_vpn_packet (pkt, si); 625 recv_vpn_packet (pkt, si);
626 } 626 }
627 else 627 else
628 { 628 {
629 // probably ECONNRESET or somesuch 629 // probably ECONNRESET or somesuch
630 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));
631 } 631 }
632 632
633 delete pkt; 633 delete pkt;
634 } 634 }
635 else 635 else
636 { 636 {
637 slog (L_ERR, 637 slog (L_ERR,
638 _("FATAL: unknown revents %08x in socket, terminating\n"), 638 _("FATAL: unknown revents %08x in socket, exiting.\n"),
639 revents); 639 revents);
640 exit (EXIT_FAILURE); 640 exit (EXIT_FAILURE);
641 } 641 }
642} 642}
643 643
692 { 692 {
693 slog (L_INFO, _("preparing shutdown...")); 693 slog (L_INFO, _("preparing shutdown..."));
694 694
695 shutdown_all (); 695 shutdown_all ();
696 remove_pid (conf.pidfilename); 696 remove_pid (conf.pidfilename);
697 slog (L_INFO, _("terminating")); 697 slog (L_INFO, _("exiting."));
698 exit (EXIT_SUCCESS); 698 exit (EXIT_SUCCESS);
699 } 699 }
700 700
701 if (events & EVENT_RECONNECT) 701 if (events & EVENT_RECONNECT)
702 { 702 {
703 slog (L_INFO, _("forced reconnect")); 703 slog (L_INFO, _("forced reconnect."));
704 704
705 reconnect_all (); 705 reconnect_all ();
706 } 706 }
707 707
708 events = 0; 708 events = 0;
733 conns.push_back (conn); 733 conns.push_back (conn);
734 conn->establish_connection (); 734 conn->establish_connection ();
735 } 735 }
736} 736}
737 737
738connection *vpn::find_router () 738bool vpn::can_direct (conf_node *src, conf_node *dst) const
739{ 739{
740 u32 prio = 1; 740 return src != dst
741 && src->may_direct (dst)
742 && dst->may_direct (src)
743 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
744 || (src->protocols & dst->connectable_protocols ()));
745}
746
747// only works for indirect and routed connections: find a router
748// from THISNODE to dst
749connection *vpn::find_router_for (const connection *dst)
750{
741 connection *router = 0; 751 connection *router = 0;
742 752
753 // first try to find a router with a direct connection
754 {
755 u32 prio = 1;
756
757 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
758 {
759 connection *c = *i;
760
761 if (c->conf->routerprio > prio
762 && c->conf != THISNODE
763 && c != dst
764 && can_direct (c->conf, dst->conf))
765 {
766 if (c->ictx && c->octx)
767 {
768 prio = c->conf->routerprio;
769 router = c;
770 }
771 else
772 c->establish_connection ();
773 }
774 }
775 }
776
777 if (router)
778 return router;
779
780 // second try find the router with the highest priority higher than ours
781 {
782 u32 prio = 1;
783
784 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
785 {
786 connection *c = *i;
787
788 if (c->conf->routerprio > prio
789 && c->conf->routerprio > THISNODE->routerprio
790 && c != dst
791 && c->conf != THISNODE)
792 {
793 if (c->ictx && c->octx)
794 {
795 prio = c->conf->routerprio;
796 router = c;
797 }
798 else
799 c->establish_connection ();
800 }
801 }
802 }
803 return router;
804}
805
806void vpn::connection_established (connection *c)
807{
743 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 808 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
744 { 809 {
745 connection *c = *i; 810 connection *o = *i;
746 811
747 if (c->conf->routerprio > prio 812 if (!o->is_direct
748 && c->connectmode == conf_node::C_ALWAYS // so we don't drop the connection if in use 813 && o->si.valid ()
749 && c->ictx && c->octx 814 && c->si != o->si
750 && c->conf != THISNODE) // redundant, since ictx==octx==0 always on thisnode 815 && c == find_router_for (o))
751 {
752 prio = c->conf->routerprio;
753 router = c;
754 } 816 {
817 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
818 o->conf->nodename, c->conf->nodename);
819 o->rekey ();
820 }
755 } 821 }
756
757 return router;
758} 822}
759 823
760void vpn::send_connect_request (int id) 824void vpn::send_connect_request (int id)
761{ 825{
762 connection *c = find_router (); 826 connection *c = find_router_for (conns[id]);
763 827
764 if (c) 828 if (c)
829 {
830 slog (L_TRACE, _("%s: no way to connect, sending mediated connection request via %s."),
831 conns[id]->conf->nodename, c->conf->nodename);
765 c->send_connect_request (id); 832 c->send_connect_request (id);
833 }
766 else 834 else
767 // no router found, aggressively connect to all routers 835 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect."), conns[id]->conf->nodename);
768 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
769 if ((*i)->conf->routerprio && (*i)->conf != THISNODE)
770 (*i)->establish_connection ();
771} 836}
772 837
773void 838void
774connection::dump_status () 839connection::dump_status ()
775{ 840{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines