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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines