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.52 by pcg, Sun Aug 10 22:18:58 2008 UTC vs.
Revision 1.67 by root, Fri Oct 11 04:07:24 2013 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-2008 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008,2010,2011,2013 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 it 7 GVPE is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
38#include <cstdlib> 38#include <cstdlib>
39 39
40#include <sys/types.h> 40#include <sys/types.h>
41#include <sys/socket.h> 41#include <sys/socket.h>
42#include <sys/wait.h> 42#include <sys/wait.h>
43#include <sys/stat.h>
43#include <errno.h> 44#include <errno.h>
44#include <time.h> 45#include <time.h>
45#include <unistd.h> 46#include <unistd.h>
46#include <fcntl.h> 47#include <fcntl.h>
47#include <sys/socket.h> 48#include <sys/socket.h>
52 53
53#include "connection.h" 54#include "connection.h"
54#include "util.h" 55#include "util.h"
55#include "vpn.h" 56#include "vpn.h"
56 57
58using namespace std;
59
57vpn network; // THE vpn (bad design...) 60vpn network; // THE vpn (bad design...)
58 61
59///////////////////////////////////////////////////////////////////////////// 62/////////////////////////////////////////////////////////////////////////////
60 63
61static void inline 64static void inline
75{ 78{
76 // the tunnel device mtu should be the physical mtu - overhead 79 // the tunnel device mtu should be the physical mtu - overhead
77 // the tricky part is rounding to the cipher key blocksize 80 // the tricky part is rounding to the cipher key blocksize
78 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD; 81 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD;
79 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion 82 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion
80 mtu -= mtu % EVP_CIPHER_block_size (CIPHER); // round 83 mtu -= mtu % BLOCK_SIZE (CIPHER); // round
81 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again 84 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again
82 85
83 char *env; 86 char *env;
84 asprintf (&env, "CONFBASE=%s", confbase); putenv (env); 87 asprintf (&env, "CONFBASE=%s", confbase); putenv (env);
85 asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env); 88 asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env);
110inline const char * 113inline const char *
111vpn::script_if_up () 114vpn::script_if_up ()
112{ 115{
113 script_init_env (); 116 script_init_env ();
114 117
115 char *filename; 118 return conf.config_filename (::conf.script_if_up, "if-up");
116 asprintf (&filename, 119}
117 "%s/%s",
118 confbase,
119 ::conf.script_if_up ? ::conf.script_if_up : "if-up");
120 120
121 return filename; 121int
122vpn::setup_socket (u8 prot, int family, int type, int proto)
123{
124 int fd = socket (family, type, proto);
125
126 if (fd < 0)
127 {
128 slog (L_ERR, _("unable to create %s socket: %s."), strprotocol (prot), strerror (errno));
129 return fd;
130 }
131
132 fcntl (fd, F_SETFL, O_NONBLOCK);
133 fcntl (fd, F_SETFD, FD_CLOEXEC);
134
135#ifdef SO_MARK
136 if (::conf.nfmark)
137 if (setsockopt (fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark))
138 slog (L_WARN, _("unable to set nfmark on %s socket: %s"), strprotocol (prot), strerror (errno));
139#endif
140
141 return fd;
122} 142}
123 143
124int 144int
125vpn::setup () 145vpn::setup ()
126{ 146{
129 ipv4_tos = -1; 149 ipv4_tos = -1;
130 ipv4_fd = -1; 150 ipv4_fd = -1;
131 151
132 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 152 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
133 { 153 {
134 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 154 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
135 155
136 if (ipv4_fd < 0) 156 if (ipv4_fd < 0)
137 return -1; 157 return -1;
138
139 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK);
140 fcntl (ipv4_fd, F_SETFD, FD_CLOEXEC);
141 158
142#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 159#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
143 // this I really consider a linux bug. I am neither connected 160 // this I really consider a linux bug. I am neither connected
144 // nor do I fragment myself. Linux still sets DF and doesn't 161 // nor do I fragment myself. Linux still sets DF and doesn't
145 // fragment for me sometimes. 162 // fragment for me sometimes.
152 sockinfo si (THISNODE, PROT_IPv4); 169 sockinfo si (THISNODE, PROT_IPv4);
153 170
154 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 171 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
155 { 172 {
156 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno)); 173 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
157 exit (EXIT_FAILURE); 174 return -1;
158 } 175 }
159 176
160 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 177 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
161 ++success; 178 ++success;
162 } 179 }
166 udpv4_tos = -1; 183 udpv4_tos = -1;
167 udpv4_fd = -1; 184 udpv4_fd = -1;
168 185
169 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 186 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
170 { 187 {
171 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 188 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
172 189
173 if (udpv4_fd < 0) 190 if (udpv4_fd < 0)
174 return -1; 191 return -1;
175
176 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK);
177 fcntl (udpv4_fd, F_SETFD, FD_CLOEXEC);
178 192
179 // standard daemon practise... 193 // standard daemon practise...
180 { 194 {
181 int oval = 1; 195 int oval = 1;
182 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 196 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
195 sockinfo si (THISNODE, PROT_UDPv4); 209 sockinfo si (THISNODE, PROT_UDPv4);
196 210
197 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 211 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
198 { 212 {
199 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 213 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
200 exit (EXIT_FAILURE); 214 return -1;
201 } 215 }
202 216
203 udpv4_ev_watcher.start (udpv4_fd, EV_READ); 217 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
204 ++success; 218 ++success;
205 } 219 }
210 icmpv4_fd = -1; 224 icmpv4_fd = -1;
211 225
212#if ENABLE_ICMP 226#if ENABLE_ICMP
213 if (THISNODE->protocols & PROT_ICMPv4) 227 if (THISNODE->protocols & PROT_ICMPv4)
214 { 228 {
215 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 229 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
216 230
217 if (icmpv4_fd < 0) 231 if (icmpv4_fd < 0)
218 return -1; 232 return -1;
219
220 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK);
221 fcntl (icmpv4_fd, F_SETFD, FD_CLOEXEC);
222 233
223#ifdef ICMP_FILTER 234#ifdef ICMP_FILTER
224 { 235 {
225 icmp_filter oval; 236 icmp_filter oval;
226 oval.data = 0xffffffff; 237 oval.data = 0xffffffff;
244 sockinfo si (THISNODE, PROT_ICMPv4); 255 sockinfo si (THISNODE, PROT_ICMPv4);
245 256
246 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 257 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
247 { 258 {
248 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 259 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
249 exit (EXIT_FAILURE); 260 return -1;
250 } 261 }
251 262
252 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); 263 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
253 ++success; 264 ++success;
254 } 265 }
257 tcpv4_fd = -1; 268 tcpv4_fd = -1;
258 269
259#if ENABLE_TCP 270#if ENABLE_TCP
260 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port) 271 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
261 { 272 {
262 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 273 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
263 274
264 if (tcpv4_fd < 0) 275 if (tcpv4_fd < 0)
265 return -1; 276 return -1;
266 277
267 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK);
268 fcntl (tcpv4_fd, F_SETFD, FD_CLOEXEC);
269
270 // standard daemon practise... 278 // standard daemon practise...
271 { 279 {
272 int oval = 1; 280 int oval = 1;
273 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 281 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
274 } 282 }
276 sockinfo si (THISNODE, PROT_TCPv4); 284 sockinfo si (THISNODE, PROT_TCPv4);
277 285
278 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 286 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
279 { 287 {
280 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 288 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
281 exit (EXIT_FAILURE); 289 return -1;
282 } 290 }
283 291
284 if (listen (tcpv4_fd, 5)) 292 if (listen (tcpv4_fd, 5))
285 { 293 {
286 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 294 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
287 exit (EXIT_FAILURE); 295 return -1;
288 } 296 }
289 297
290 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); 298 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
291 ++success; 299 ++success;
292 } 300 }
300#if ENABLE_DNS 308#if ENABLE_DNS
301 if (THISNODE->protocols & PROT_DNSv4) 309 if (THISNODE->protocols & PROT_DNSv4)
302 { 310 {
303 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); 311 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
304 312
305 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 313 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
306 314
307 if (dnsv4_fd < 0) 315 if (dnsv4_fd < 0)
308 return -1; 316 return -1;
309
310 fcntl (dnsv4_fd, F_SETFL, O_NONBLOCK);
311 fcntl (dnsv4_fd, F_SETFD, FD_CLOEXEC);
312 317
313# if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 318# if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
314 // this I really consider a linux bug. I am neither connected 319 // this I really consider a linux bug. I am neither connected
315 // nor do I fragment myself. Linux still sets DF and doesn't 320 // nor do I fragment myself. Linux still sets DF and doesn't
316 // fragment for me sometimes. 321 // fragment for me sometimes.
331 PROT_DNSv4); 336 PROT_DNSv4);
332 337
333 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 338 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
334 { 339 {
335 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); 340 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
336 exit (EXIT_FAILURE); 341 return -1;
337 } 342 }
338 343
339 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); 344 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
340 ++success; 345 ++success;
341 } 346 }
343 348
344 ///////////////////////////////////////////////////////////////////////////// 349 /////////////////////////////////////////////////////////////////////////////
345 350
346 if (!success) 351 if (!success)
347 { 352 {
348 slog (L_ERR, _("no protocols enabled, exiting.")); 353 slog (L_ERR, _("no protocols enabled."));
349 exit (EXIT_FAILURE); 354 return -1;
350 } 355 }
351 356
352 reconnect_all (); 357 reconnect_all ();
353 358
354 ///////////////////////////////////////////////////////////////////////////// 359 /////////////////////////////////////////////////////////////////////////////
355 360
356 tap = new tap_device (); 361 tap = new tap_device ();
357 if (!tap) //D this, of course, never catches 362 if (!tap) //D this, of course, never catches
358 { 363 {
359 slog (L_ERR, _("cannot create network interface '%s', exiting."), conf.ifname); 364 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
360 exit (EXIT_FAILURE); 365 return -1;
361 } 366 }
362 367
363 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 368 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
364 369
365 run_script_cb cb; 370 run_script_cb cb;
366 cb.set<vpn, &vpn::script_if_init> (this); 371 cb.set<vpn, &vpn::script_if_init> (this);
367 372
368 if (tap->if_up () && 373 if (tap->if_up () &&
369 !run_script (cb, true)) 374 !run_script (cb, true))
370 { 375 {
371 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 376 slog (L_ERR, _("interface initialization command '%s' failed."),
372 tap->if_up ()); 377 tap->if_up ());
373 exit (EXIT_FAILURE); 378 return -1;
374 } 379 }
375 380
376 cb.set<vpn, &vpn::script_if_up> (this); 381 cb.set<vpn, &vpn::script_if_up> (this);
377 if (!run_script (cb, true)) 382 if (!run_script (cb, true))
378 { 383 {
379 slog (L_ERR, _("if-up command execution failed, exiting.")); 384 slog (L_ERR, _("if-up command execution failed."));
380 exit (EXIT_FAILURE); 385 return -1;
381 } 386 }
382 387
383 tap_ev_watcher.start (tap->fd, EV_READ); 388 tap_ev_watcher.start (tap->fd, EV_READ);
384 389
385 return 0; 390 return 0;
391}
392
393bool
394vpn::drop_privileges ()
395{
396 if (::conf.change_root)
397 {
398 if (!strcmp (::conf.change_root, "/"))
399 {
400 char dir [L_tmpnam];
401 if (!tmpnam (dir))
402 {
403 slog (L_CRIT, _("unable to create anonymous root path."));
404 return false;
405 }
406
407 if (mkdir (dir, 0700))
408 {
409 slog (L_CRIT, _("unable to crate anonymous root directory."));
410 return false;
411 }
412
413 if (chdir (dir))
414 {
415 slog (L_CRIT, _("unable to change to anonymous root directory."));
416 return false;
417 }
418
419 if (rmdir (dir))
420 slog (L_ERR, _("unable to remove anonymous root directory, continuing."));
421 }
422 else
423 {
424 if (chdir (::conf.change_root))
425 {
426 slog (L_CRIT, _("%s: unable to change to specified root directory."), ::conf.change_root);
427 return false;
428 }
429 }
430
431 if (chroot ("."))
432 {
433 slog (L_CRIT, _("unable to set new root directory."));
434 return false;
435 }
436
437 if (chdir ("/"))
438 {
439 slog (L_CRIT, _("unable to set cwd to new root directory."));
440 return false;
441 }
442 }
443
444 if (::conf.change_gid)
445 if (setgid (::conf.change_gid))
446 {
447 slog (L_CRIT, _("unable to change group id to %d."), ::conf.change_gid);
448 return false;
449 }
450
451 if (::conf.change_uid)
452 if (setuid (::conf.change_uid))
453 {
454 slog (L_CRIT, _("unable to change user id to %d."), ::conf.change_uid);
455 return false;
456 }
457
458 return true;
386} 459}
387 460
388bool 461bool
389vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 462vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
390{ 463{
474 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); 547 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
475 548
476 if (src == 0 || src > conns.size () 549 if (src == 0 || src > conns.size ()
477 || dst > conns.size () 550 || dst > conns.size ()
478 || pkt->typ () >= vpn_packet::PT_MAX) 551 || pkt->typ () >= vpn_packet::PT_MAX)
479 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
480 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
481 else if (dst > conns.size ())
482 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."), 552 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
483 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 553 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
484 else 554 else
485 { 555 {
486 connection *c = conns[src - 1]; 556 connection *c = conns[src - 1];
508vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 578vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
509{ 579{
510 switch (si.prot) 580 switch (si.prot)
511 { 581 {
512 case PROT_IPv4: 582 case PROT_IPv4:
513 return send_ipv4_packet (pkt, si, tos); 583 return send_ipv4_packet (pkt, si, tos);
514 584
515 case PROT_UDPv4: 585 case PROT_UDPv4:
516 return send_udpv4_packet (pkt, si, tos); 586 return send_udpv4_packet (pkt, si, tos);
517 587
518#if ENABLE_TCP 588#if ENABLE_TCP
519 case PROT_TCPv4: 589 case PROT_TCPv4:
520 return send_tcpv4_packet (pkt, si, tos); 590 return send_tcpv4_packet (pkt, si, tos);
521#endif 591#endif
522#if ENABLE_ICMP 592#if ENABLE_ICMP
523 case PROT_ICMPv4: 593 case PROT_ICMPv4:
524 return send_icmpv4_packet (pkt, si, tos); 594 return send_icmpv4_packet (pkt, si, tos);
525#endif 595#endif
526#if ENABLE_DNS 596#if ENABLE_DNS
527 case PROT_DNSv4: 597 case PROT_DNSv4:
528 return send_dnsv4_packet (pkt, si, tos); 598 return send_dnsv4_packet (pkt, si, tos);
529#endif 599#endif
530 default: 600 default:
531 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si); 601 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
532 } 602 }
533 603
551 if (len > 0) 621 if (len > 0)
552 { 622 {
553 pkt->len = len; 623 pkt->len = len;
554 624
555 // raw sockets deliver the ipv4 header, but don't expect it on sends 625 // raw sockets deliver the ipv4 header, but don't expect it on sends
556 pkt->skip_hdr (IP_OVERHEAD); 626 pkt->skip_hdr (pkt->ipv4_hdr_len ());
557 627
558 recv_vpn_packet (pkt, si); 628 recv_vpn_packet (pkt, si);
559 } 629 }
560 else 630 else
561 { 631 {
598 if (hdr->type == ::conf.icmp_type 668 if (hdr->type == ::conf.icmp_type
599 && hdr->code == 255) 669 && hdr->code == 255)
600 { 670 {
601 // raw sockets deliver the ipv4, but don't expect it on sends 671 // raw sockets deliver the ipv4, but don't expect it on sends
602 // this is slow, but... 672 // this is slow, but...
603 pkt->skip_hdr (ICMP_OVERHEAD); 673 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
604 674
605 recv_vpn_packet (pkt, si); 675 recv_vpn_packet (pkt, si);
606 } 676 }
607 } 677 }
608 else 678 else
750 820
751 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) 821 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
752 (*c)->establish_connection (); 822 (*c)->establish_connection ();
753} 823}
754 824
825bool
755bool vpn::can_direct (conf_node *src, conf_node *dst) const 826vpn::can_direct (conf_node *src, conf_node *dst) const
756{ 827{
757 return src != dst 828 return src != dst
758 && src->may_direct (dst) 829 && src->may_direct (dst)
759 && dst->may_direct (src) 830 && dst->may_direct (src)
760 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS) 831 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
761 || (src->protocols & dst->connectable_protocols ())); 832 || (src->protocols & dst->connectable_protocols ()));
762} 833}
763 834
764// only works for indirect and routed connections: find a router 835// only works for indirect and routed connections: find a router
765// from THISNODE to dst 836// from THISNODE to dst
837connection *
766connection *vpn::find_router_for (const connection *dst) 838vpn::find_router_for (const connection *dst)
767{ 839{
768 connection *router = 0; 840 connection *router = 0;
769 841
770 // first try to find a router with a direct connection, route there 842 // first try to find a router with a direct connection, route there
771 // regardless of any other considerations. 843 // regardless of any other considerations.
810 } 882 }
811 883
812 return router; 884 return router;
813} 885}
814 886
887void
815void vpn::connection_established (connection *c) 888vpn::connection_established (connection *c)
816{ 889{
817 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 890 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
818 { 891 {
819 connection *o = *i; 892 connection *o = *i;
820 893
821 if (!o->is_direct
822 && o->si.valid () 894 if (o->si.valid ()
823 && c->si != o->si 895 && c->si != o->si
824 && c == find_router_for (o)) 896 && c == find_router_for (o)
897 && !can_direct (THISNODE, o->conf))
825 { 898 {
826 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."), 899 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
827 o->conf->nodename, c->conf->nodename); 900 o->conf->nodename, c->conf->nodename);
828 o->rekey (); 901 o->rekey ();
829 } 902 }
830 } 903 }
831} 904}
832 905
906void
833void vpn::send_connect_request (connection *c) 907vpn::send_connect_request (connection *c)
834{ 908{
835 connection *r = find_router_for (c); 909 connection *r = find_router_for (c);
836 910
837 if (r) 911 if (r)
838 { 912 {
839 slog (L_TRACE, _("%s: no way to connect, sending mediated connection request via %s."), 913 slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."),
840 c->conf->nodename, r->conf->nodename); 914 c->conf->nodename, r->conf->nodename);
841 r->send_connect_request (c->conf->id); 915 r->send_connect_request (c->conf->id);
842 } 916 }
843 else 917 else
844 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect."), 918 slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect at this time."),
845 c->conf->nodename); 919 c->conf->nodename);
846} 920}
847 921
848void 922void
849connection::dump_status () 923connection::dump_status ()

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines