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.51 by pcg, Sun Aug 10 14:48:57 2008 UTC

122} 122}
123 123
124int 124int
125vpn::setup () 125vpn::setup ()
126{ 126{
127 int success = 0;
128
127 ipv4_tos = -1; 129 ipv4_tos = -1;
128 ipv4_fd = -1; 130 ipv4_fd = -1;
129 131
130 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 132 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
131 { 133 {
149 151
150 sockinfo si (THISNODE, PROT_IPv4); 152 sockinfo si (THISNODE, PROT_IPv4);
151 153
152 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 154 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
153 { 155 {
154 slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno)); 156 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
155 exit (EXIT_FAILURE); 157 exit (EXIT_FAILURE);
156 } 158 }
157 159
158 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 160 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
161 ++success;
159 } 162 }
163 else
164 THISNODE->protocols &= ~PROT_IPv4;
160 165
161 udpv4_tos = -1; 166 udpv4_tos = -1;
162 udpv4_fd = -1; 167 udpv4_fd = -1;
163 168
164 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 169 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
189 194
190 sockinfo si (THISNODE, PROT_UDPv4); 195 sockinfo si (THISNODE, PROT_UDPv4);
191 196
192 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 197 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
193 { 198 {
194 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); 199 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
195 exit (EXIT_FAILURE); 200 exit (EXIT_FAILURE);
196 } 201 }
197 202
198 udpv4_ev_watcher.start (udpv4_fd, EV_READ); 203 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
204 ++success;
199 } 205 }
206 else
207 THISNODE->protocols &= ~PROT_UDPv4;
200 208
201 icmpv4_tos = -1; 209 icmpv4_tos = -1;
202 icmpv4_fd = -1; 210 icmpv4_fd = -1;
203 211
204#if ENABLE_ICMP 212#if ENABLE_ICMP
235 243
236 sockinfo si (THISNODE, PROT_ICMPv4); 244 sockinfo si (THISNODE, PROT_ICMPv4);
237 245
238 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 246 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
239 { 247 {
240 slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno)); 248 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
241 exit (EXIT_FAILURE); 249 exit (EXIT_FAILURE);
242 } 250 }
243 251
244 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); 252 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
253 ++success;
245 } 254 }
246#endif 255#endif
247 256
248 tcpv4_fd = -1; 257 tcpv4_fd = -1;
249 258
266 275
267 sockinfo si (THISNODE, PROT_TCPv4); 276 sockinfo si (THISNODE, PROT_TCPv4);
268 277
269 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 278 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
270 { 279 {
271 slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 280 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
272 exit (EXIT_FAILURE); 281 exit (EXIT_FAILURE);
273 } 282 }
274 283
275 if (listen (tcpv4_fd, 5)) 284 if (listen (tcpv4_fd, 5))
276 { 285 {
277 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 286 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
278 exit (EXIT_FAILURE); 287 exit (EXIT_FAILURE);
279 } 288 }
280 289
281 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); 290 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
291 ++success;
282 } 292 }
293 else
294 THISNODE->protocols &= ~PROT_TCPv4;
283#endif 295#endif
284 296
285 dnsv4_tos = -1; 297 dnsv4_tos = -1;
286 dnsv4_fd = -1; 298 dnsv4_fd = -1;
287 299
318 THISNODE->dns_hostname ? THISNODE->dns_port : 0, 330 THISNODE->dns_hostname ? THISNODE->dns_port : 0,
319 PROT_DNSv4); 331 PROT_DNSv4);
320 332
321 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 333 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
322 { 334 {
323 slog (L_ERR, _("can't bind dnsv4 on %s: %s"), (const char *)si, strerror (errno)); 335 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
324 exit (EXIT_FAILURE); 336 exit (EXIT_FAILURE);
325 } 337 }
326 338
327 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); 339 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
340 ++success;
328 } 341 }
329#endif 342#endif
330 343
331 ///////////////////////////////////////////////////////////////////////////// 344 /////////////////////////////////////////////////////////////////////////////
345
346 if (!success)
347 {
348 slog (L_ERR, _("no protocols enabled, exiting."));
349 exit (EXIT_FAILURE);
350 }
332 351
333 reconnect_all (); 352 reconnect_all ();
334 353
335 ///////////////////////////////////////////////////////////////////////////// 354 /////////////////////////////////////////////////////////////////////////////
336 355
337 tap = new tap_device (); 356 tap = new tap_device ();
338 if (!tap) //D this, of course, never catches 357 if (!tap) //D this, of course, never catches
339 { 358 {
340 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname); 359 slog (L_ERR, _("cannot create network interface '%s', exiting."), conf.ifname);
341 exit (EXIT_FAILURE); 360 exit (EXIT_FAILURE);
342 } 361 }
343 362
344 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 363 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
345 364
449vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 468vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
450{ 469{
451 unsigned int src = pkt->src (); 470 unsigned int src = pkt->src ();
452 unsigned int dst = pkt->dst (); 471 unsigned int dst = pkt->dst ();
453 472
454 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), 473 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); 474 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
456 475
457 if (src == 0 || src > conns.size () 476 if (src == 0 || src > conns.size ()
458 || dst > conns.size () 477 || dst > conns.size ()
459 || pkt->typ () >= vpn_packet::PT_MAX) 478 || pkt->typ () >= vpn_packet::PT_MAX)
460 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), 479 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
461 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 480 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
462 else if (dst > conns.size ()) 481 else if (dst > conns.size ())
463 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), 482 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
464 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 483 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
465 else 484 else
466 { 485 {
467 connection *c = conns[src - 1]; 486 connection *c = conns[src - 1];
468 487
469 if (dst == 0) 488 if (dst == 0)
470 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)"), 489 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
471 c->conf->nodename, (const char *)rsi); 490 c->conf->nodename, (const char *)rsi);
472 else if (dst != THISNODE->id) 491 else if (dst != THISNODE->id)
473 { 492 {
474 if (THISNODE->routerprio) 493 if (THISNODE->routerprio)
475 // the tos setting gets lost here. who cares. 494 // the tos setting gets lost here. who cares.
476 conns[dst - 1]->inject_vpn_packet (pkt); 495 conns[dst - 1]->inject_vpn_packet (pkt);
477 else 496 else
478 slog (L_WARN, 497 slog (L_WARN,
479 _("%s(%s): forwarding request (=> %s), but we are no router"), 498 _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."),
480 c->conf->nodename, (const char *)rsi, 499 c->conf->nodename, (const char *)rsi,
481 conns[dst - 1]->conf->nodename); 500 conns[dst - 1]->conf->nodename);
482 } 501 }
483 else 502 else
484 c->recv_vpn_packet (pkt, rsi); 503 c->recv_vpn_packet (pkt, rsi);
507#if ENABLE_DNS 526#if ENABLE_DNS
508 case PROT_DNSv4: 527 case PROT_DNSv4:
509 return send_dnsv4_packet (pkt, si, tos); 528 return send_dnsv4_packet (pkt, si, tos);
510#endif 529#endif
511 default: 530 default:
512 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si); 531 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
513 } 532 }
514 533
515 return false; 534 return false;
516} 535}
517 536
539 recv_vpn_packet (pkt, si); 558 recv_vpn_packet (pkt, si);
540 } 559 }
541 else 560 else
542 { 561 {
543 // probably ECONNRESET or somesuch 562 // probably ECONNRESET or somesuch
544 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 563 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
545 } 564 }
546 565
547 delete pkt; 566 delete pkt;
548 } 567 }
549 else 568 else
550 { 569 {
551 slog (L_ERR, 570 slog (L_ERR,
552 _("FATAL: unknown revents %08x in socket, terminating\n"), 571 _("FATAL: unknown revents %08x in socket, exiting.\n"),
553 revents); 572 revents);
554 exit (EXIT_FAILURE); 573 exit (EXIT_FAILURE);
555 } 574 }
556} 575}
557 576
587 } 606 }
588 } 607 }
589 else 608 else
590 { 609 {
591 // probably ECONNRESET or somesuch 610 // probably ECONNRESET or somesuch
592 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 611 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
593 } 612 }
594 613
595 delete pkt; 614 delete pkt;
596 } 615 }
597 else 616 else
598 { 617 {
599 slog (L_ERR, 618 slog (L_ERR,
600 _("FATAL: unknown revents %08x in socket, terminating\n"), 619 _("FATAL: unknown revents %08x in socket, exiting.\n"),
601 revents); 620 revents);
602 exit (EXIT_FAILURE); 621 exit (EXIT_FAILURE);
603 } 622 }
604} 623}
605#endif 624#endif
625 recv_vpn_packet (pkt, si); 644 recv_vpn_packet (pkt, si);
626 } 645 }
627 else 646 else
628 { 647 {
629 // probably ECONNRESET or somesuch 648 // probably ECONNRESET or somesuch
630 slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno)); 649 slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno));
631 } 650 }
632 651
633 delete pkt; 652 delete pkt;
634 } 653 }
635 else 654 else
636 { 655 {
637 slog (L_ERR, 656 slog (L_ERR,
638 _("FATAL: unknown revents %08x in socket, terminating\n"), 657 _("FATAL: unknown revents %08x in socket, exiting.\n"),
639 revents); 658 revents);
640 exit (EXIT_FAILURE); 659 exit (EXIT_FAILURE);
641 } 660 }
642} 661}
643 662
692 { 711 {
693 slog (L_INFO, _("preparing shutdown...")); 712 slog (L_INFO, _("preparing shutdown..."));
694 713
695 shutdown_all (); 714 shutdown_all ();
696 remove_pid (conf.pidfilename); 715 remove_pid (conf.pidfilename);
697 slog (L_INFO, _("terminating")); 716 slog (L_INFO, _("exiting."));
698 exit (EXIT_SUCCESS); 717 exit (EXIT_SUCCESS);
699 } 718 }
700 719
701 if (events & EVENT_RECONNECT) 720 if (events & EVENT_RECONNECT)
702 { 721 {
703 slog (L_INFO, _("forced reconnect")); 722 slog (L_INFO, _("forced reconnect."));
704 723
705 reconnect_all (); 724 reconnect_all ();
706 } 725 }
707 726
708 events = 0; 727 events = 0;
724 743
725 conns.clear (); 744 conns.clear ();
726 745
727 connection_init (); 746 connection_init ();
728 747
729 for (configuration::node_vector::iterator i = conf.nodes.begin (); 748 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
730 i != conf.nodes.end (); ++i) 749 conns.push_back (new connection (this, *i));
731 { 750
732 connection *conn = new connection (this, *i); 751 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
733 conns.push_back (conn);
734 conn->establish_connection (); 752 (*c)->establish_connection ();
735 }
736} 753}
737 754
738connection *vpn::find_router () 755bool vpn::can_direct (conf_node *src, conf_node *dst) const
739{ 756{
740 u32 prio = 1; 757 return src != dst
758 && src->may_direct (dst)
759 && dst->may_direct (src)
760 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
761 || (src->protocols & dst->connectable_protocols ()));
762}
763
764// only works for indirect and routed connections: find a router
765// from THISNODE to dst
766connection *vpn::find_router_for (const connection *dst)
767{
741 connection *router = 0; 768 connection *router = 0;
742 769
770 // first try to find a router with a direct connection
771 {
772 u32 prio = 1;
773
774 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
775 {
776 connection *c = *i;
777
778 if (c->conf->routerprio > prio
779 && c->conf != THISNODE
780 && c != dst
781 && can_direct (c->conf, dst->conf))
782 {
783 if (c->ictx && c->octx)
784 {
785 prio = c->conf->routerprio;
786 router = c;
787 }
788 else
789 c->establish_connection ();
790 }
791 }
792 }
793
794 if (router)
795 return router;
796
797 // second try find the router with the highest priority higher than ours
798 {
799 u32 prio = 1;
800
801 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
802 {
803 connection *c = *i;
804
805 if (c->conf->routerprio > prio
806 && c->conf->routerprio > THISNODE->routerprio
807 && c != dst
808 && c->conf != THISNODE)
809 {
810 if (c->ictx && c->octx)
811 {
812 prio = c->conf->routerprio;
813 router = c;
814 }
815 else
816 c->establish_connection ();
817 }
818 }
819 }
820 return router;
821}
822
823void vpn::connection_established (connection *c)
824{
743 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 825 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
744 { 826 {
745 connection *c = *i; 827 connection *o = *i;
746 828
747 if (c->conf->routerprio > prio 829 if (!o->is_direct
748 && c->connectmode == conf_node::C_ALWAYS // so we don't drop the connection if in use 830 && o->si.valid ()
749 && c->ictx && c->octx 831 && c->si != o->si
750 && c->conf != THISNODE) // redundant, since ictx==octx==0 always on thisnode 832 && c == find_router_for (o))
751 {
752 prio = c->conf->routerprio;
753 router = c;
754 } 833 {
834 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
835 o->conf->nodename, c->conf->nodename);
836 o->rekey ();
837 }
755 } 838 }
756
757 return router;
758} 839}
759 840
760void vpn::send_connect_request (int id) 841void vpn::send_connect_request (connection *c)
761{ 842{
762 connection *c = find_router (); 843 connection *r = find_router_for (c);
763 844
764 if (c) 845 if (r)
846 {
847 slog (L_TRACE, _("%s: no way to connect, sending mediated connection request via %s."),
848 c->conf->nodename, r->conf->nodename);
765 c->send_connect_request (id); 849 r->send_connect_request (c->conf->id);
850 }
766 else 851 else
767 // no router found, aggressively connect to all routers 852 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect."),
768 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 853 c->conf->nodename);
769 if ((*i)->conf->routerprio && (*i)->conf != THISNODE)
770 (*i)->establish_connection ();
771} 854}
772 855
773void 856void
774connection::dump_status () 857connection::dump_status ()
775{ 858{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines