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.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{
147 int success = 0;
148
127 ipv4_tos = -1; 149 ipv4_tos = -1;
128 ipv4_fd = -1; 150 ipv4_fd = -1;
129 151
130 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 152 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
131 { 153 {
132 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 154 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
133 155
134 if (ipv4_fd < 0) 156 if (ipv4_fd < 0)
135 return -1; 157 return -1;
136
137 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK);
138 fcntl (ipv4_fd, F_SETFD, FD_CLOEXEC);
139 158
140#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 159#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
141 // this I really consider a linux bug. I am neither connected 160 // this I really consider a linux bug. I am neither connected
142 // 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
143 // fragment for me sometimes. 162 // fragment for me sometimes.
149 168
150 sockinfo si (THISNODE, PROT_IPv4); 169 sockinfo si (THISNODE, PROT_IPv4);
151 170
152 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 171 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
153 { 172 {
154 slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno)); 173 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
155 exit (EXIT_FAILURE); 174 return -1;
156 } 175 }
157 176
158 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 177 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
178 ++success;
159 } 179 }
180 else
181 THISNODE->protocols &= ~PROT_IPv4;
160 182
161 udpv4_tos = -1; 183 udpv4_tos = -1;
162 udpv4_fd = -1; 184 udpv4_fd = -1;
163 185
164 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 186 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
165 { 187 {
166 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 188 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
167 189
168 if (udpv4_fd < 0) 190 if (udpv4_fd < 0)
169 return -1; 191 return -1;
170
171 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK);
172 fcntl (udpv4_fd, F_SETFD, FD_CLOEXEC);
173 192
174 // standard daemon practise... 193 // standard daemon practise...
175 { 194 {
176 int oval = 1; 195 int oval = 1;
177 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 196 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
189 208
190 sockinfo si (THISNODE, PROT_UDPv4); 209 sockinfo si (THISNODE, PROT_UDPv4);
191 210
192 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 211 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
193 { 212 {
194 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); 213 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
195 exit (EXIT_FAILURE); 214 return -1;
196 } 215 }
197 216
198 udpv4_ev_watcher.start (udpv4_fd, EV_READ); 217 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
218 ++success;
199 } 219 }
220 else
221 THISNODE->protocols &= ~PROT_UDPv4;
200 222
201 icmpv4_tos = -1; 223 icmpv4_tos = -1;
202 icmpv4_fd = -1; 224 icmpv4_fd = -1;
203 225
204#if ENABLE_ICMP 226#if ENABLE_ICMP
205 if (THISNODE->protocols & PROT_ICMPv4) 227 if (THISNODE->protocols & PROT_ICMPv4)
206 { 228 {
207 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 229 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
208 230
209 if (icmpv4_fd < 0) 231 if (icmpv4_fd < 0)
210 return -1; 232 return -1;
211
212 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK);
213 fcntl (icmpv4_fd, F_SETFD, FD_CLOEXEC);
214 233
215#ifdef ICMP_FILTER 234#ifdef ICMP_FILTER
216 { 235 {
217 icmp_filter oval; 236 icmp_filter oval;
218 oval.data = 0xffffffff; 237 oval.data = 0xffffffff;
235 254
236 sockinfo si (THISNODE, PROT_ICMPv4); 255 sockinfo si (THISNODE, PROT_ICMPv4);
237 256
238 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 257 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
239 { 258 {
240 slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno)); 259 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
241 exit (EXIT_FAILURE); 260 return -1;
242 } 261 }
243 262
244 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); 263 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
264 ++success;
245 } 265 }
246#endif 266#endif
247 267
248 tcpv4_fd = -1; 268 tcpv4_fd = -1;
249 269
250#if ENABLE_TCP 270#if ENABLE_TCP
251 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port) 271 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
252 { 272 {
253 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 273 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
254 274
255 if (tcpv4_fd < 0) 275 if (tcpv4_fd < 0)
256 return -1; 276 return -1;
257 277
258 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK);
259 fcntl (tcpv4_fd, F_SETFD, FD_CLOEXEC);
260
261 // standard daemon practise... 278 // standard daemon practise...
262 { 279 {
263 int oval = 1; 280 int oval = 1;
264 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 281 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
265 } 282 }
266 283
267 sockinfo si (THISNODE, PROT_TCPv4); 284 sockinfo si (THISNODE, PROT_TCPv4);
268 285
269 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 286 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
270 { 287 {
271 slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 288 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
272 exit (EXIT_FAILURE); 289 return -1;
273 } 290 }
274 291
275 if (listen (tcpv4_fd, 5)) 292 if (listen (tcpv4_fd, 5))
276 { 293 {
277 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 294 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
278 exit (EXIT_FAILURE); 295 return -1;
279 } 296 }
280 297
281 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); 298 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
299 ++success;
282 } 300 }
301 else
302 THISNODE->protocols &= ~PROT_TCPv4;
283#endif 303#endif
284 304
285 dnsv4_tos = -1; 305 dnsv4_tos = -1;
286 dnsv4_fd = -1; 306 dnsv4_fd = -1;
287 307
288#if ENABLE_DNS 308#if ENABLE_DNS
289 if (THISNODE->protocols & PROT_DNSv4) 309 if (THISNODE->protocols & PROT_DNSv4)
290 { 310 {
291 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);
292 312
293 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 313 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
294 314
295 if (dnsv4_fd < 0) 315 if (dnsv4_fd < 0)
296 return -1; 316 return -1;
297
298 fcntl (dnsv4_fd, F_SETFL, O_NONBLOCK);
299 fcntl (dnsv4_fd, F_SETFD, FD_CLOEXEC);
300 317
301# if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 318# if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
302 // this I really consider a linux bug. I am neither connected 319 // this I really consider a linux bug. I am neither connected
303 // 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
304 // fragment for me sometimes. 321 // fragment for me sometimes.
318 THISNODE->dns_hostname ? THISNODE->dns_port : 0, 335 THISNODE->dns_hostname ? THISNODE->dns_port : 0,
319 PROT_DNSv4); 336 PROT_DNSv4);
320 337
321 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 338 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
322 { 339 {
323 slog (L_ERR, _("can't bind dnsv4 on %s: %s"), (const char *)si, strerror (errno)); 340 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
324 exit (EXIT_FAILURE); 341 return -1;
325 } 342 }
326 343
327 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); 344 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
345 ++success;
328 } 346 }
329#endif 347#endif
330 348
331 ///////////////////////////////////////////////////////////////////////////// 349 /////////////////////////////////////////////////////////////////////////////
350
351 if (!success)
352 {
353 slog (L_ERR, _("no protocols enabled."));
354 return -1;
355 }
332 356
333 reconnect_all (); 357 reconnect_all ();
334 358
335 ///////////////////////////////////////////////////////////////////////////// 359 /////////////////////////////////////////////////////////////////////////////
336 360
337 tap = new tap_device (); 361 tap = new tap_device ();
338 if (!tap) //D this, of course, never catches 362 if (!tap) //D this, of course, never catches
339 { 363 {
340 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname); 364 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
341 exit (EXIT_FAILURE); 365 return -1;
342 } 366 }
343 367
344 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 368 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
345 369
346 run_script_cb cb; 370 run_script_cb cb;
347 cb.set<vpn, &vpn::script_if_init> (this); 371 cb.set<vpn, &vpn::script_if_init> (this);
348 372
349 if (tap->if_up () && 373 if (tap->if_up () &&
350 !run_script (cb, true)) 374 !run_script (cb, true))
351 { 375 {
352 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 376 slog (L_ERR, _("interface initialization command '%s' failed."),
353 tap->if_up ()); 377 tap->if_up ());
354 exit (EXIT_FAILURE); 378 return -1;
355 } 379 }
356 380
357 cb.set<vpn, &vpn::script_if_up> (this); 381 cb.set<vpn, &vpn::script_if_up> (this);
358 if (!run_script (cb, true)) 382 if (!run_script (cb, true))
359 { 383 {
360 slog (L_ERR, _("if-up command execution failed, exiting.")); 384 slog (L_ERR, _("if-up command execution failed."));
361 exit (EXIT_FAILURE); 385 return -1;
362 } 386 }
363 387
364 tap_ev_watcher.start (tap->fd, EV_READ); 388 tap_ev_watcher.start (tap->fd, EV_READ);
365 389
366 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;
367} 459}
368 460
369bool 461bool
370vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 462vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
371{ 463{
449vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 541vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
450{ 542{
451 unsigned int src = pkt->src (); 543 unsigned int src = pkt->src ();
452 unsigned int dst = pkt->dst (); 544 unsigned int dst = pkt->dst ();
453 545
454 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), 546 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); 547 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
456 548
457 if (src == 0 || src > conns.size () 549 if (src == 0 || src > conns.size ()
458 || dst > conns.size () 550 || dst > conns.size ()
459 || pkt->typ () >= vpn_packet::PT_MAX) 551 || pkt->typ () >= vpn_packet::PT_MAX)
460 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)."),
461 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
462 else if (dst > conns.size ())
463 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"),
464 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 553 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
465 else 554 else
466 { 555 {
467 connection *c = conns[src - 1]; 556 connection *c = conns[src - 1];
468 557
469 if (dst == 0) 558 if (dst == 0)
470 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)"), 559 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
471 c->conf->nodename, (const char *)rsi); 560 c->conf->nodename, (const char *)rsi);
472 else if (dst != THISNODE->id) 561 else if (dst != THISNODE->id)
473 { 562 {
474 if (THISNODE->routerprio) 563 if (THISNODE->routerprio)
475 // the tos setting gets lost here. who cares. 564 // the tos setting gets lost here. who cares.
476 conns[dst - 1]->inject_vpn_packet (pkt); 565 conns[dst - 1]->inject_vpn_packet (pkt);
477 else 566 else
478 slog (L_WARN, 567 slog (L_WARN,
479 _("%s(%s): forwarding request (=> %s), but we are no router"), 568 _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."),
480 c->conf->nodename, (const char *)rsi, 569 c->conf->nodename, (const char *)rsi,
481 conns[dst - 1]->conf->nodename); 570 conns[dst - 1]->conf->nodename);
482 } 571 }
483 else 572 else
484 c->recv_vpn_packet (pkt, rsi); 573 c->recv_vpn_packet (pkt, rsi);
489vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 578vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
490{ 579{
491 switch (si.prot) 580 switch (si.prot)
492 { 581 {
493 case PROT_IPv4: 582 case PROT_IPv4:
494 return send_ipv4_packet (pkt, si, tos); 583 return send_ipv4_packet (pkt, si, tos);
495 584
496 case PROT_UDPv4: 585 case PROT_UDPv4:
497 return send_udpv4_packet (pkt, si, tos); 586 return send_udpv4_packet (pkt, si, tos);
498 587
499#if ENABLE_TCP 588#if ENABLE_TCP
500 case PROT_TCPv4: 589 case PROT_TCPv4:
501 return send_tcpv4_packet (pkt, si, tos); 590 return send_tcpv4_packet (pkt, si, tos);
502#endif 591#endif
503#if ENABLE_ICMP 592#if ENABLE_ICMP
504 case PROT_ICMPv4: 593 case PROT_ICMPv4:
505 return send_icmpv4_packet (pkt, si, tos); 594 return send_icmpv4_packet (pkt, si, tos);
506#endif 595#endif
507#if ENABLE_DNS 596#if ENABLE_DNS
508 case PROT_DNSv4: 597 case PROT_DNSv4:
509 return send_dnsv4_packet (pkt, si, tos); 598 return send_dnsv4_packet (pkt, si, tos);
510#endif 599#endif
511 default: 600 default:
512 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);
513 } 602 }
514 603
515 return false; 604 return false;
516} 605}
517 606
532 if (len > 0) 621 if (len > 0)
533 { 622 {
534 pkt->len = len; 623 pkt->len = len;
535 624
536 // 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
537 pkt->skip_hdr (IP_OVERHEAD); 626 pkt->skip_hdr (pkt->ipv4_hdr_len ());
538 627
539 recv_vpn_packet (pkt, si); 628 recv_vpn_packet (pkt, si);
540 } 629 }
541 else 630 else
542 { 631 {
543 // probably ECONNRESET or somesuch 632 // probably ECONNRESET or somesuch
544 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 633 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
545 } 634 }
546 635
547 delete pkt; 636 delete pkt;
548 } 637 }
549 else 638 else
550 { 639 {
551 slog (L_ERR, 640 slog (L_ERR,
552 _("FATAL: unknown revents %08x in socket, terminating\n"), 641 _("FATAL: unknown revents %08x in socket, exiting.\n"),
553 revents); 642 revents);
554 exit (EXIT_FAILURE); 643 exit (EXIT_FAILURE);
555 } 644 }
556} 645}
557 646
579 if (hdr->type == ::conf.icmp_type 668 if (hdr->type == ::conf.icmp_type
580 && hdr->code == 255) 669 && hdr->code == 255)
581 { 670 {
582 // 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
583 // this is slow, but... 672 // this is slow, but...
584 pkt->skip_hdr (ICMP_OVERHEAD); 673 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
585 674
586 recv_vpn_packet (pkt, si); 675 recv_vpn_packet (pkt, si);
587 } 676 }
588 } 677 }
589 else 678 else
590 { 679 {
591 // probably ECONNRESET or somesuch 680 // probably ECONNRESET or somesuch
592 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 681 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
593 } 682 }
594 683
595 delete pkt; 684 delete pkt;
596 } 685 }
597 else 686 else
598 { 687 {
599 slog (L_ERR, 688 slog (L_ERR,
600 _("FATAL: unknown revents %08x in socket, terminating\n"), 689 _("FATAL: unknown revents %08x in socket, exiting.\n"),
601 revents); 690 revents);
602 exit (EXIT_FAILURE); 691 exit (EXIT_FAILURE);
603 } 692 }
604} 693}
605#endif 694#endif
625 recv_vpn_packet (pkt, si); 714 recv_vpn_packet (pkt, si);
626 } 715 }
627 else 716 else
628 { 717 {
629 // probably ECONNRESET or somesuch 718 // probably ECONNRESET or somesuch
630 slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno)); 719 slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno));
631 } 720 }
632 721
633 delete pkt; 722 delete pkt;
634 } 723 }
635 else 724 else
636 { 725 {
637 slog (L_ERR, 726 slog (L_ERR,
638 _("FATAL: unknown revents %08x in socket, terminating\n"), 727 _("FATAL: unknown revents %08x in socket, exiting.\n"),
639 revents); 728 revents);
640 exit (EXIT_FAILURE); 729 exit (EXIT_FAILURE);
641 } 730 }
642} 731}
643 732
692 { 781 {
693 slog (L_INFO, _("preparing shutdown...")); 782 slog (L_INFO, _("preparing shutdown..."));
694 783
695 shutdown_all (); 784 shutdown_all ();
696 remove_pid (conf.pidfilename); 785 remove_pid (conf.pidfilename);
697 slog (L_INFO, _("terminating")); 786 slog (L_INFO, _("exiting."));
698 exit (EXIT_SUCCESS); 787 exit (EXIT_SUCCESS);
699 } 788 }
700 789
701 if (events & EVENT_RECONNECT) 790 if (events & EVENT_RECONNECT)
702 { 791 {
703 slog (L_INFO, _("forced reconnect")); 792 slog (L_INFO, _("forced reconnect."));
704 793
705 reconnect_all (); 794 reconnect_all ();
706 } 795 }
707 796
708 events = 0; 797 events = 0;
724 813
725 conns.clear (); 814 conns.clear ();
726 815
727 connection_init (); 816 connection_init ();
728 817
729 for (configuration::node_vector::iterator i = conf.nodes.begin (); 818 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
730 i != conf.nodes.end (); ++i) 819 conns.push_back (new connection (this, *i));
731 { 820
732 connection *conn = new connection (this, *i); 821 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
733 conns.push_back (conn);
734 conn->establish_connection (); 822 (*c)->establish_connection ();
735 }
736} 823}
737 824
738connection *vpn::find_router () 825bool
826vpn::can_direct (conf_node *src, conf_node *dst) const
739{ 827{
740 u32 prio = 1; 828 return src != dst
829 && src->may_direct (dst)
830 && dst->may_direct (src)
831 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
832 || (src->protocols & dst->connectable_protocols ()));
833}
834
835// only works for indirect and routed connections: find a router
836// from THISNODE to dst
837connection *
838vpn::find_router_for (const connection *dst)
839{
741 connection *router = 0; 840 connection *router = 0;
742 841
842 // first try to find a router with a direct connection, route there
843 // regardless of any other considerations.
844 {
845 u32 prio = 1;
846
847 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
848 {
849 connection *c = *i;
850
851 if (c->conf->routerprio > prio
852 && c->conf != THISNODE
853 && can_direct (c->conf, dst->conf)
854 && c->ictx && c->octx)
855 {
856 prio = c->conf->routerprio;
857 router = c;
858 }
859 }
860 }
861
862 if (router)
863 return router;
864
865 // second try find the router with the highest priority, higher than ours
866 {
867 u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1;
868
869 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
870 {
871 connection *c = *i;
872
873 if (c->conf->routerprio > prio
874 && c != dst
875 && c->conf != THISNODE
876 && c->ictx && c->octx)
877 {
878 prio = c->conf->routerprio;
879 router = c;
880 }
881 }
882 }
883
884 return router;
885}
886
887void
888vpn::connection_established (connection *c)
889{
743 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 890 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
744 { 891 {
745 connection *c = *i; 892 connection *o = *i;
746 893
747 if (c->conf->routerprio > prio 894 if (o->si.valid ()
748 && c->connectmode == conf_node::C_ALWAYS // so we don't drop the connection if in use 895 && c->si != o->si
749 && c->ictx && c->octx 896 && c == find_router_for (o)
750 && c->conf != THISNODE) // redundant, since ictx==octx==0 always on thisnode 897 && !can_direct (THISNODE, o->conf))
751 {
752 prio = c->conf->routerprio;
753 router = c;
754 } 898 {
899 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
900 o->conf->nodename, c->conf->nodename);
901 o->rekey ();
902 }
755 } 903 }
756
757 return router;
758} 904}
759 905
906void
760void vpn::send_connect_request (int id) 907vpn::send_connect_request (connection *c)
761{ 908{
762 connection *c = find_router (); 909 connection *r = find_router_for (c);
763 910
764 if (c) 911 if (r)
912 {
913 slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."),
914 c->conf->nodename, r->conf->nodename);
765 c->send_connect_request (id); 915 r->send_connect_request (c->conf->id);
916 }
766 else 917 else
767 // no router found, aggressively connect to all routers 918 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) 919 c->conf->nodename);
769 if ((*i)->conf->routerprio && (*i)->conf != THISNODE)
770 (*i)->establish_connection ();
771} 920}
772 921
773void 922void
774connection::dump_status () 923connection::dump_status ()
775{ 924{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines