… | |
… | |
122 | } |
122 | } |
123 | |
123 | |
124 | int |
124 | int |
125 | vpn::setup () |
125 | vpn::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 | { |
… | |
… | |
154 | slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (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) |
… | |
… | |
194 | slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (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 |
… | |
… | |
240 | slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (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 | |
… | |
… | |
277 | slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (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 | |
… | |
… | |
323 | slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (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 | |
… | |
… | |
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 | |
738 | bool vpn::can_direct (conf_node *src, conf_node *dst) const |
755 | bool vpn::can_direct (conf_node *src, conf_node *dst) const |
739 | { |
756 | { |
740 | return src != dst |
757 | return src != dst |
… | |
… | |
748 | // from THISNODE to dst |
765 | // from THISNODE to dst |
749 | connection *vpn::find_router_for (const connection *dst) |
766 | connection *vpn::find_router_for (const connection *dst) |
750 | { |
767 | { |
751 | connection *router = 0; |
768 | connection *router = 0; |
752 | |
769 | |
753 | // first try to find a router with a direct connection |
770 | // first try to find a router with a direct connection, route there |
|
|
771 | // regardless of any other considerations. |
754 | { |
772 | { |
755 | u32 prio = 1; |
773 | u32 prio = 1; |
756 | |
774 | |
757 | for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) |
775 | for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) |
758 | { |
776 | { |
759 | connection *c = *i; |
777 | connection *c = *i; |
760 | |
778 | |
761 | if (c->conf->routerprio > prio |
779 | if (c->conf->routerprio > prio |
762 | && c->conf != THISNODE |
780 | && c->conf != THISNODE |
763 | && c != dst |
|
|
764 | && can_direct (c->conf, dst->conf)) |
781 | && can_direct (c->conf, dst->conf) |
|
|
782 | && c->ictx && c->octx) |
765 | { |
783 | { |
766 | if (c->ictx && c->octx) |
|
|
767 | { |
|
|
768 | prio = c->conf->routerprio; |
784 | prio = c->conf->routerprio; |
769 | router = c; |
785 | router = c; |
770 | } |
|
|
771 | else |
|
|
772 | c->establish_connection (); |
|
|
773 | } |
786 | } |
774 | } |
787 | } |
775 | } |
788 | } |
776 | |
789 | |
777 | if (router) |
790 | if (router) |
778 | return router; |
791 | return router; |
779 | |
792 | |
780 | // second try find the router with the highest priority higher than ours |
793 | // second try find the router with the highest priority, higher than ours |
781 | { |
794 | { |
782 | u32 prio = 1; |
795 | u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1; |
783 | |
796 | |
784 | for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) |
797 | for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) |
785 | { |
798 | { |
786 | connection *c = *i; |
799 | connection *c = *i; |
787 | |
800 | |
788 | if (c->conf->routerprio > prio |
801 | if (c->conf->routerprio > prio |
789 | && c->conf->routerprio > THISNODE->routerprio |
|
|
790 | && c != dst |
802 | && c != dst |
791 | && c->conf != THISNODE) |
803 | && c->conf != THISNODE |
|
|
804 | && c->ictx && c->octx) |
792 | { |
805 | { |
793 | if (c->ictx && c->octx) |
|
|
794 | { |
|
|
795 | prio = c->conf->routerprio; |
806 | prio = c->conf->routerprio; |
796 | router = c; |
807 | router = c; |
797 | } |
|
|
798 | else |
|
|
799 | c->establish_connection (); |
|
|
800 | } |
808 | } |
801 | } |
809 | } |
802 | } |
810 | } |
|
|
811 | |
803 | return router; |
812 | return router; |
804 | } |
813 | } |
805 | |
814 | |
806 | void vpn::connection_established (connection *c) |
815 | void vpn::connection_established (connection *c) |
807 | { |
816 | { |
… | |
… | |
819 | o->rekey (); |
828 | o->rekey (); |
820 | } |
829 | } |
821 | } |
830 | } |
822 | } |
831 | } |
823 | |
832 | |
824 | void vpn::send_connect_request (int id) |
833 | void vpn::send_connect_request (connection *c) |
825 | { |
834 | { |
826 | connection *c = find_router_for (conns[id]); |
835 | connection *r = find_router_for (c); |
827 | |
836 | |
828 | if (c) |
837 | if (r) |
829 | { |
838 | { |
830 | slog (L_TRACE, _("%s: no way to connect, sending mediated connection request via %s."), |
839 | slog (L_TRACE, _("%s: no way to connect, sending mediated connection request via %s."), |
831 | conns[id]->conf->nodename, c->conf->nodename); |
840 | c->conf->nodename, r->conf->nodename); |
832 | c->send_connect_request (id); |
841 | r->send_connect_request (c->conf->id); |
833 | } |
842 | } |
834 | else |
843 | else |
835 | slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect."), conns[id]->conf->nodename); |
844 | slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect."), |
|
|
845 | c->conf->nodename); |
836 | } |
846 | } |
837 | |
847 | |
838 | void |
848 | void |
839 | connection::dump_status () |
849 | connection::dump_status () |
840 | { |
850 | { |