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.54 by pcg, Mon Mar 23 15:22:00 2009 UTC

120 120
121 return filename; 121 return filename;
122} 122}
123 123
124int 124int
125vpn::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 setsockopt (ipv4_fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark);
141#endif
142
143 return fd;
144}
145
146int
125vpn::setup () 147vpn::setup ()
126{ 148{
149 int success = 0;
150
127 ipv4_tos = -1; 151 ipv4_tos = -1;
128 ipv4_fd = -1; 152 ipv4_fd = -1;
129 153
130 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 154 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
131 { 155 {
132 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 156 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
133 157
134 if (ipv4_fd < 0) 158 if (ipv4_fd < 0)
135 return -1; 159 return -1;
136
137 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK);
138 fcntl (ipv4_fd, F_SETFD, FD_CLOEXEC);
139 160
140#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 161#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
141 // this I really consider a linux bug. I am neither connected 162 // this I really consider a linux bug. I am neither connected
142 // nor do I fragment myself. Linux still sets DF and doesn't 163 // nor do I fragment myself. Linux still sets DF and doesn't
143 // fragment for me sometimes. 164 // fragment for me sometimes.
149 170
150 sockinfo si (THISNODE, PROT_IPv4); 171 sockinfo si (THISNODE, PROT_IPv4);
151 172
152 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 173 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
153 { 174 {
154 slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno)); 175 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
155 exit (EXIT_FAILURE); 176 return -1;
156 } 177 }
157 178
158 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 179 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
180 ++success;
159 } 181 }
182 else
183 THISNODE->protocols &= ~PROT_IPv4;
160 184
161 udpv4_tos = -1; 185 udpv4_tos = -1;
162 udpv4_fd = -1; 186 udpv4_fd = -1;
163 187
164 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 188 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
165 { 189 {
166 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 190 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
167 191
168 if (udpv4_fd < 0) 192 if (udpv4_fd < 0)
169 return -1; 193 return -1;
170
171 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK);
172 fcntl (udpv4_fd, F_SETFD, FD_CLOEXEC);
173 194
174 // standard daemon practise... 195 // standard daemon practise...
175 { 196 {
176 int oval = 1; 197 int oval = 1;
177 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 198 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
189 210
190 sockinfo si (THISNODE, PROT_UDPv4); 211 sockinfo si (THISNODE, PROT_UDPv4);
191 212
192 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 213 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
193 { 214 {
194 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); 215 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
195 exit (EXIT_FAILURE); 216 return -1;
196 } 217 }
197 218
198 udpv4_ev_watcher.start (udpv4_fd, EV_READ); 219 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
220 ++success;
199 } 221 }
222 else
223 THISNODE->protocols &= ~PROT_UDPv4;
200 224
201 icmpv4_tos = -1; 225 icmpv4_tos = -1;
202 icmpv4_fd = -1; 226 icmpv4_fd = -1;
203 227
204#if ENABLE_ICMP 228#if ENABLE_ICMP
205 if (THISNODE->protocols & PROT_ICMPv4) 229 if (THISNODE->protocols & PROT_ICMPv4)
206 { 230 {
207 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 231 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
208 232
209 if (icmpv4_fd < 0) 233 if (icmpv4_fd < 0)
210 return -1; 234 return -1;
211
212 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK);
213 fcntl (icmpv4_fd, F_SETFD, FD_CLOEXEC);
214 235
215#ifdef ICMP_FILTER 236#ifdef ICMP_FILTER
216 { 237 {
217 icmp_filter oval; 238 icmp_filter oval;
218 oval.data = 0xffffffff; 239 oval.data = 0xffffffff;
235 256
236 sockinfo si (THISNODE, PROT_ICMPv4); 257 sockinfo si (THISNODE, PROT_ICMPv4);
237 258
238 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 259 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
239 { 260 {
240 slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno)); 261 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
241 exit (EXIT_FAILURE); 262 return -1;
242 } 263 }
243 264
244 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); 265 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
266 ++success;
245 } 267 }
246#endif 268#endif
247 269
248 tcpv4_fd = -1; 270 tcpv4_fd = -1;
249 271
250#if ENABLE_TCP 272#if ENABLE_TCP
251 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port) 273 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
252 { 274 {
253 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 275 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
254 276
255 if (tcpv4_fd < 0) 277 if (tcpv4_fd < 0)
256 return -1; 278 return -1;
257 279
258 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK);
259 fcntl (tcpv4_fd, F_SETFD, FD_CLOEXEC);
260
261 // standard daemon practise... 280 // standard daemon practise...
262 { 281 {
263 int oval = 1; 282 int oval = 1;
264 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 283 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
265 } 284 }
266 285
267 sockinfo si (THISNODE, PROT_TCPv4); 286 sockinfo si (THISNODE, PROT_TCPv4);
268 287
269 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 288 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
270 { 289 {
271 slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 290 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
272 exit (EXIT_FAILURE); 291 return -1;
273 } 292 }
274 293
275 if (listen (tcpv4_fd, 5)) 294 if (listen (tcpv4_fd, 5))
276 { 295 {
277 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 296 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
278 exit (EXIT_FAILURE); 297 return -1;
279 } 298 }
280 299
281 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); 300 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
301 ++success;
282 } 302 }
303 else
304 THISNODE->protocols &= ~PROT_TCPv4;
283#endif 305#endif
284 306
285 dnsv4_tos = -1; 307 dnsv4_tos = -1;
286 dnsv4_fd = -1; 308 dnsv4_fd = -1;
287 309
288#if ENABLE_DNS 310#if ENABLE_DNS
289 if (THISNODE->protocols & PROT_DNSv4) 311 if (THISNODE->protocols & PROT_DNSv4)
290 { 312 {
291 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); 313 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
292 314
293 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 315 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
294 316
295 if (dnsv4_fd < 0) 317 if (dnsv4_fd < 0)
296 return -1; 318 return -1;
297
298 fcntl (dnsv4_fd, F_SETFL, O_NONBLOCK);
299 fcntl (dnsv4_fd, F_SETFD, FD_CLOEXEC);
300 319
301# if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 320# if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
302 // this I really consider a linux bug. I am neither connected 321 // this I really consider a linux bug. I am neither connected
303 // nor do I fragment myself. Linux still sets DF and doesn't 322 // nor do I fragment myself. Linux still sets DF and doesn't
304 // fragment for me sometimes. 323 // fragment for me sometimes.
318 THISNODE->dns_hostname ? THISNODE->dns_port : 0, 337 THISNODE->dns_hostname ? THISNODE->dns_port : 0,
319 PROT_DNSv4); 338 PROT_DNSv4);
320 339
321 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 340 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
322 { 341 {
323 slog (L_ERR, _("can't bind dnsv4 on %s: %s"), (const char *)si, strerror (errno)); 342 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
324 exit (EXIT_FAILURE); 343 return -1;
325 } 344 }
326 345
327 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); 346 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
347 ++success;
328 } 348 }
329#endif 349#endif
330 350
331 ///////////////////////////////////////////////////////////////////////////// 351 /////////////////////////////////////////////////////////////////////////////
352
353 if (!success)
354 {
355 slog (L_ERR, _("no protocols enabled."));
356 return -1;
357 }
332 358
333 reconnect_all (); 359 reconnect_all ();
334 360
335 ///////////////////////////////////////////////////////////////////////////// 361 /////////////////////////////////////////////////////////////////////////////
336 362
337 tap = new tap_device (); 363 tap = new tap_device ();
338 if (!tap) //D this, of course, never catches 364 if (!tap) //D this, of course, never catches
339 { 365 {
340 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname); 366 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
341 exit (EXIT_FAILURE); 367 return -1;
342 } 368 }
343 369
344 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 370 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
345 371
346 run_script_cb cb; 372 run_script_cb cb;
347 cb.set<vpn, &vpn::script_if_init> (this); 373 cb.set<vpn, &vpn::script_if_init> (this);
348 374
349 if (tap->if_up () && 375 if (tap->if_up () &&
350 !run_script (cb, true)) 376 !run_script (cb, true))
351 { 377 {
352 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 378 slog (L_ERR, _("interface initialization command '%s' failed."),
353 tap->if_up ()); 379 tap->if_up ());
354 exit (EXIT_FAILURE); 380 return -1;
355 } 381 }
356 382
357 cb.set<vpn, &vpn::script_if_up> (this); 383 cb.set<vpn, &vpn::script_if_up> (this);
358 if (!run_script (cb, true)) 384 if (!run_script (cb, true))
359 { 385 {
360 slog (L_ERR, _("if-up command execution failed, exiting.")); 386 slog (L_ERR, _("if-up command execution failed."));
361 exit (EXIT_FAILURE); 387 return -1;
362 } 388 }
363 389
364 tap_ev_watcher.start (tap->fd, EV_READ); 390 tap_ev_watcher.start (tap->fd, EV_READ);
365 391
366 return 0; 392 return 0;
449vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 475vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
450{ 476{
451 unsigned int src = pkt->src (); 477 unsigned int src = pkt->src ();
452 unsigned int dst = pkt->dst (); 478 unsigned int dst = pkt->dst ();
453 479
454 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), 480 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); 481 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
456 482
457 if (src == 0 || src > conns.size () 483 if (src == 0 || src > conns.size ()
458 || dst > conns.size () 484 || dst > conns.size ()
459 || pkt->typ () >= vpn_packet::PT_MAX) 485 || pkt->typ () >= vpn_packet::PT_MAX)
460 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), 486 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
461 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 487 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
462 else if (dst > conns.size ()) 488 else if (dst > conns.size ())
463 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), 489 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
464 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 490 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
465 else 491 else
466 { 492 {
467 connection *c = conns[src - 1]; 493 connection *c = conns[src - 1];
468 494
469 if (dst == 0) 495 if (dst == 0)
470 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)"), 496 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
471 c->conf->nodename, (const char *)rsi); 497 c->conf->nodename, (const char *)rsi);
472 else if (dst != THISNODE->id) 498 else if (dst != THISNODE->id)
473 { 499 {
474 if (THISNODE->routerprio) 500 if (THISNODE->routerprio)
475 // the tos setting gets lost here. who cares. 501 // the tos setting gets lost here. who cares.
476 conns[dst - 1]->inject_vpn_packet (pkt); 502 conns[dst - 1]->inject_vpn_packet (pkt);
477 else 503 else
478 slog (L_WARN, 504 slog (L_WARN,
479 _("%s(%s): forwarding request (=> %s), but we are no router"), 505 _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."),
480 c->conf->nodename, (const char *)rsi, 506 c->conf->nodename, (const char *)rsi,
481 conns[dst - 1]->conf->nodename); 507 conns[dst - 1]->conf->nodename);
482 } 508 }
483 else 509 else
484 c->recv_vpn_packet (pkt, rsi); 510 c->recv_vpn_packet (pkt, rsi);
507#if ENABLE_DNS 533#if ENABLE_DNS
508 case PROT_DNSv4: 534 case PROT_DNSv4:
509 return send_dnsv4_packet (pkt, si, tos); 535 return send_dnsv4_packet (pkt, si, tos);
510#endif 536#endif
511 default: 537 default:
512 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si); 538 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
513 } 539 }
514 540
515 return false; 541 return false;
516} 542}
517 543
539 recv_vpn_packet (pkt, si); 565 recv_vpn_packet (pkt, si);
540 } 566 }
541 else 567 else
542 { 568 {
543 // probably ECONNRESET or somesuch 569 // probably ECONNRESET or somesuch
544 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 570 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
545 } 571 }
546 572
547 delete pkt; 573 delete pkt;
548 } 574 }
549 else 575 else
550 { 576 {
551 slog (L_ERR, 577 slog (L_ERR,
552 _("FATAL: unknown revents %08x in socket, terminating\n"), 578 _("FATAL: unknown revents %08x in socket, exiting.\n"),
553 revents); 579 revents);
554 exit (EXIT_FAILURE); 580 exit (EXIT_FAILURE);
555 } 581 }
556} 582}
557 583
587 } 613 }
588 } 614 }
589 else 615 else
590 { 616 {
591 // probably ECONNRESET or somesuch 617 // probably ECONNRESET or somesuch
592 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 618 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
593 } 619 }
594 620
595 delete pkt; 621 delete pkt;
596 } 622 }
597 else 623 else
598 { 624 {
599 slog (L_ERR, 625 slog (L_ERR,
600 _("FATAL: unknown revents %08x in socket, terminating\n"), 626 _("FATAL: unknown revents %08x in socket, exiting.\n"),
601 revents); 627 revents);
602 exit (EXIT_FAILURE); 628 exit (EXIT_FAILURE);
603 } 629 }
604} 630}
605#endif 631#endif
625 recv_vpn_packet (pkt, si); 651 recv_vpn_packet (pkt, si);
626 } 652 }
627 else 653 else
628 { 654 {
629 // probably ECONNRESET or somesuch 655 // probably ECONNRESET or somesuch
630 slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno)); 656 slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno));
631 } 657 }
632 658
633 delete pkt; 659 delete pkt;
634 } 660 }
635 else 661 else
636 { 662 {
637 slog (L_ERR, 663 slog (L_ERR,
638 _("FATAL: unknown revents %08x in socket, terminating\n"), 664 _("FATAL: unknown revents %08x in socket, exiting.\n"),
639 revents); 665 revents);
640 exit (EXIT_FAILURE); 666 exit (EXIT_FAILURE);
641 } 667 }
642} 668}
643 669
692 { 718 {
693 slog (L_INFO, _("preparing shutdown...")); 719 slog (L_INFO, _("preparing shutdown..."));
694 720
695 shutdown_all (); 721 shutdown_all ();
696 remove_pid (conf.pidfilename); 722 remove_pid (conf.pidfilename);
697 slog (L_INFO, _("terminating")); 723 slog (L_INFO, _("exiting."));
698 exit (EXIT_SUCCESS); 724 exit (EXIT_SUCCESS);
699 } 725 }
700 726
701 if (events & EVENT_RECONNECT) 727 if (events & EVENT_RECONNECT)
702 { 728 {
703 slog (L_INFO, _("forced reconnect")); 729 slog (L_INFO, _("forced reconnect."));
704 730
705 reconnect_all (); 731 reconnect_all ();
706 } 732 }
707 733
708 events = 0; 734 events = 0;
724 750
725 conns.clear (); 751 conns.clear ();
726 752
727 connection_init (); 753 connection_init ();
728 754
729 for (configuration::node_vector::iterator i = conf.nodes.begin (); 755 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
730 i != conf.nodes.end (); ++i) 756 conns.push_back (new connection (this, *i));
731 { 757
732 connection *conn = new connection (this, *i); 758 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
733 conns.push_back (conn);
734 conn->establish_connection (); 759 (*c)->establish_connection ();
735 }
736} 760}
737 761
738connection *vpn::find_router () 762bool vpn::can_direct (conf_node *src, conf_node *dst) const
739{ 763{
740 u32 prio = 1; 764 return src != dst
765 && src->may_direct (dst)
766 && dst->may_direct (src)
767 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
768 || (src->protocols & dst->connectable_protocols ()));
769}
770
771// only works for indirect and routed connections: find a router
772// from THISNODE to dst
773connection *vpn::find_router_for (const connection *dst)
774{
741 connection *router = 0; 775 connection *router = 0;
742 776
777 // first try to find a router with a direct connection, route there
778 // regardless of any other considerations.
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 != THISNODE
788 && can_direct (c->conf, dst->conf)
789 && c->ictx && c->octx)
790 {
791 prio = c->conf->routerprio;
792 router = c;
793 }
794 }
795 }
796
797 if (router)
798 return router;
799
800 // second try find the router with the highest priority, higher than ours
801 {
802 u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1;
803
804 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
805 {
806 connection *c = *i;
807
808 if (c->conf->routerprio > prio
809 && c != dst
810 && c->conf != THISNODE
811 && c->ictx && c->octx)
812 {
813 prio = c->conf->routerprio;
814 router = c;
815 }
816 }
817 }
818
819 return router;
820}
821
822void vpn::connection_established (connection *c)
823{
743 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 824 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
744 { 825 {
745 connection *c = *i; 826 connection *o = *i;
746 827
747 if (c->conf->routerprio > prio 828 if (!o->is_direct
748 && c->connectmode == conf_node::C_ALWAYS // so we don't drop the connection if in use 829 && o->si.valid ()
749 && c->ictx && c->octx 830 && c->si != o->si
750 && c->conf != THISNODE) // redundant, since ictx==octx==0 always on thisnode 831 && c == find_router_for (o))
751 {
752 prio = c->conf->routerprio;
753 router = c;
754 } 832 {
833 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
834 o->conf->nodename, c->conf->nodename);
835 o->rekey ();
836 }
755 } 837 }
756
757 return router;
758} 838}
759 839
760void vpn::send_connect_request (int id) 840void vpn::send_connect_request (connection *c)
761{ 841{
762 connection *c = find_router (); 842 connection *r = find_router_for (c);
763 843
764 if (c) 844 if (r)
845 {
846 slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."),
847 c->conf->nodename, r->conf->nodename);
765 c->send_connect_request (id); 848 r->send_connect_request (c->conf->id);
849 }
766 else 850 else
767 // no router found, aggressively connect to all routers 851 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect at this time."),
768 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 852 c->conf->nodename);
769 if ((*i)->conf->routerprio && (*i)->conf != THISNODE)
770 (*i)->establish_connection ();
771} 853}
772 854
773void 855void
774connection::dump_status () 856connection::dump_status ()
775{ 857{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines