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.47 by pcg, Thu Aug 7 17:54:27 2008 UTC vs.
Revision 1.69 by root, Sat Sep 5 17:40:22 2015 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...)
61
62/////////////////////////////////////////////////////////////////////////////
63
64// hopefully temporary workaround for rare buffer full conditions
65// if it happens, usually instantly retrying or retrying ~5ms later
66// is good enough with current network technologies/kernels
67
68static ssize_t
69xsendto (int fd, const void *buf, size_t len, int flags,
70 const struct sockaddr *sa, socklen_t salen)
71{
72 ssize_t res;
73
74 for (int retry = 0; retry <= 13; ++retry) // ~100ms
75 {
76 res = sendto (fd, buf, len, flags, sa, salen);
77
78 if (res >= 0 || errno != ENOBUFS)
79 break;
80
81 struct timespec ts = { 0, 1000 * retry };
82 nanosleep (&ts, 0);
83 }
84
85 return res;
86}
58 87
59///////////////////////////////////////////////////////////////////////////// 88/////////////////////////////////////////////////////////////////////////////
60 89
61static void inline 90static void inline
62set_tos (int fd, int &tos_prev, int tos) 91set_tos (int fd, int &tos_prev, int tos)
75{ 104{
76 // the tunnel device mtu should be the physical mtu - overhead 105 // the tunnel device mtu should be the physical mtu - overhead
77 // the tricky part is rounding to the cipher key blocksize 106 // the tricky part is rounding to the cipher key blocksize
78 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD; 107 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD;
79 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion 108 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion
80 mtu -= mtu % EVP_CIPHER_block_size (CIPHER); // round 109 mtu -= mtu % BLOCK_SIZE (CIPHER); // round
81 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again 110 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again
82 111
83 char *env; 112 char *env;
84 asprintf (&env, "CONFBASE=%s", confbase); putenv (env); 113 asprintf (&env, "CONFBASE=%s", confbase); putenv (env);
85 asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env); 114 asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env);
110inline const char * 139inline const char *
111vpn::script_if_up () 140vpn::script_if_up ()
112{ 141{
113 script_init_env (); 142 script_init_env ();
114 143
115 char *filename; 144 return conf.config_filename (::conf.script_if_up, "if-up");
116 asprintf (&filename, 145}
117 "%s/%s",
118 confbase,
119 ::conf.script_if_up ? ::conf.script_if_up : "if-up");
120 146
121 return filename; 147int
148vpn::setup_socket (u8 prot, int family, int type, int proto)
149{
150 int fd = socket (family, type, proto);
151
152 if (fd < 0)
153 {
154 slog (L_ERR, _("unable to create %s socket: %s."), strprotocol (prot), strerror (errno));
155 return fd;
156 }
157
158 fcntl (fd, F_SETFL, O_NONBLOCK);
159 fcntl (fd, F_SETFD, FD_CLOEXEC);
160
161#ifdef SO_MARK
162 if (::conf.nfmark)
163 if (setsockopt (fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark))
164 slog (L_WARN, _("unable to set nfmark on %s socket: %s"), strprotocol (prot), strerror (errno));
165#endif
166
167 return fd;
122} 168}
123 169
124int 170int
125vpn::setup () 171vpn::setup ()
126{ 172{
173 int success = 0;
174
127 ipv4_tos = -1; 175 ipv4_tos = -1;
128 ipv4_fd = -1; 176 ipv4_fd = -1;
129 177
130 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) 178 if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto)
131 { 179 {
132 ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); 180 ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto);
133 181
134 if (ipv4_fd < 0) 182 if (ipv4_fd < 0)
135 return -1; 183 return -1;
136
137 fcntl (ipv4_fd, F_SETFL, O_NONBLOCK);
138 fcntl (ipv4_fd, F_SETFD, FD_CLOEXEC);
139 184
140#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 185#if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
141 // this I really consider a linux bug. I am neither connected 186 // this I really consider a linux bug. I am neither connected
142 // nor do I fragment myself. Linux still sets DF and doesn't 187 // nor do I fragment myself. Linux still sets DF and doesn't
143 // fragment for me sometimes. 188 // fragment for me sometimes.
149 194
150 sockinfo si (THISNODE, PROT_IPv4); 195 sockinfo si (THISNODE, PROT_IPv4);
151 196
152 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) 197 if (bind (ipv4_fd, si.sav4 (), si.salenv4 ()))
153 { 198 {
154 slog (L_ERR, _("can't bind ipv4 socket on %s: %s"), (const char *)si, strerror (errno)); 199 slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno));
155 exit (EXIT_FAILURE); 200 return -1;
156 } 201 }
157 202
158 ipv4_ev_watcher.start (ipv4_fd, EV_READ); 203 ipv4_ev_watcher.start (ipv4_fd, EV_READ);
204 ++success;
159 } 205 }
206 else
207 THISNODE->protocols &= ~PROT_IPv4;
160 208
161 udpv4_tos = -1; 209 udpv4_tos = -1;
162 udpv4_fd = -1; 210 udpv4_fd = -1;
163 211
164 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) 212 if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port)
165 { 213 {
166 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 214 udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
167 215
168 if (udpv4_fd < 0) 216 if (udpv4_fd < 0)
169 return -1; 217 return -1;
170
171 fcntl (udpv4_fd, F_SETFL, O_NONBLOCK);
172 fcntl (udpv4_fd, F_SETFD, FD_CLOEXEC);
173 218
174 // standard daemon practise... 219 // standard daemon practise...
175 { 220 {
176 int oval = 1; 221 int oval = 1;
177 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 222 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
189 234
190 sockinfo si (THISNODE, PROT_UDPv4); 235 sockinfo si (THISNODE, PROT_UDPv4);
191 236
192 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 237 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
193 { 238 {
194 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); 239 slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
195 exit (EXIT_FAILURE); 240 return -1;
196 } 241 }
197 242
198 udpv4_ev_watcher.start (udpv4_fd, EV_READ); 243 udpv4_ev_watcher.start (udpv4_fd, EV_READ);
244 ++success;
199 } 245 }
246 else
247 THISNODE->protocols &= ~PROT_UDPv4;
200 248
201 icmpv4_tos = -1; 249 icmpv4_tos = -1;
202 icmpv4_fd = -1; 250 icmpv4_fd = -1;
203 251
204#if ENABLE_ICMP 252#if ENABLE_ICMP
205 if (THISNODE->protocols & PROT_ICMPv4) 253 if (THISNODE->protocols & PROT_ICMPv4)
206 { 254 {
207 icmpv4_fd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP); 255 icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP);
208 256
209 if (icmpv4_fd < 0) 257 if (icmpv4_fd < 0)
210 return -1; 258 return -1;
211
212 fcntl (icmpv4_fd, F_SETFL, O_NONBLOCK);
213 fcntl (icmpv4_fd, F_SETFD, FD_CLOEXEC);
214 259
215#ifdef ICMP_FILTER 260#ifdef ICMP_FILTER
216 { 261 {
217 icmp_filter oval; 262 icmp_filter oval;
218 oval.data = 0xffffffff; 263 oval.data = 0xffffffff;
235 280
236 sockinfo si (THISNODE, PROT_ICMPv4); 281 sockinfo si (THISNODE, PROT_ICMPv4);
237 282
238 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) 283 if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ()))
239 { 284 {
240 slog (L_ERR, _("can't bind icmpv4 on %s: %s"), (const char *)si, strerror (errno)); 285 slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
241 exit (EXIT_FAILURE); 286 return -1;
242 } 287 }
243 288
244 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); 289 icmpv4_ev_watcher.start (icmpv4_fd, EV_READ);
290 ++success;
245 } 291 }
246#endif 292#endif
247 293
248 tcpv4_fd = -1; 294 tcpv4_fd = -1;
249 295
250#if ENABLE_TCP 296#if ENABLE_TCP
251 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port) 297 if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port)
252 { 298 {
253 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 299 tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP);
254 300
255 if (tcpv4_fd < 0) 301 if (tcpv4_fd < 0)
256 return -1; 302 return -1;
257 303
258 fcntl (tcpv4_fd, F_SETFL, O_NONBLOCK);
259 fcntl (tcpv4_fd, F_SETFD, FD_CLOEXEC);
260
261 // standard daemon practise... 304 // standard daemon practise...
262 { 305 {
263 int oval = 1; 306 int oval = 1;
264 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 307 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
265 } 308 }
266 309
267 sockinfo si (THISNODE, PROT_TCPv4); 310 sockinfo si (THISNODE, PROT_TCPv4);
268 311
269 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) 312 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
270 { 313 {
271 slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 314 slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
272 exit (EXIT_FAILURE); 315 return -1;
273 } 316 }
274 317
275 if (listen (tcpv4_fd, 5)) 318 if (listen (tcpv4_fd, 5))
276 { 319 {
277 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno)); 320 slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
278 exit (EXIT_FAILURE); 321 return -1;
279 } 322 }
280 323
281 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); 324 tcpv4_ev_watcher.start (tcpv4_fd, EV_READ);
325 ++success;
282 } 326 }
327 else
328 THISNODE->protocols &= ~PROT_TCPv4;
283#endif 329#endif
284 330
285 dnsv4_tos = -1; 331 dnsv4_tos = -1;
286 dnsv4_fd = -1; 332 dnsv4_fd = -1;
287 333
288#if ENABLE_DNS 334#if ENABLE_DNS
289 if (THISNODE->protocols & PROT_DNSv4) 335 if (THISNODE->protocols & PROT_DNSv4)
290 { 336 {
291 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); 337 dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
292 338
293 dnsv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 339 dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP);
294 340
295 if (dnsv4_fd < 0) 341 if (dnsv4_fd < 0)
296 return -1; 342 return -1;
297
298 fcntl (dnsv4_fd, F_SETFL, O_NONBLOCK);
299 fcntl (dnsv4_fd, F_SETFD, FD_CLOEXEC);
300 343
301# if defined(SOL_IP) && defined(IP_MTU_DISCOVER) 344# if defined(SOL_IP) && defined(IP_MTU_DISCOVER)
302 // this I really consider a linux bug. I am neither connected 345 // this I really consider a linux bug. I am neither connected
303 // nor do I fragment myself. Linux still sets DF and doesn't 346 // nor do I fragment myself. Linux still sets DF and doesn't
304 // fragment for me sometimes. 347 // fragment for me sometimes.
318 THISNODE->dns_hostname ? THISNODE->dns_port : 0, 361 THISNODE->dns_hostname ? THISNODE->dns_port : 0,
319 PROT_DNSv4); 362 PROT_DNSv4);
320 363
321 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) 364 if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ()))
322 { 365 {
323 slog (L_ERR, _("can't bind dnsv4 on %s: %s"), (const char *)si, strerror (errno)); 366 slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno));
324 exit (EXIT_FAILURE); 367 return -1;
325 } 368 }
326 369
327 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); 370 dnsv4_ev_watcher.start (dnsv4_fd, EV_READ);
371 ++success;
328 } 372 }
329#endif 373#endif
330 374
331 ///////////////////////////////////////////////////////////////////////////// 375 /////////////////////////////////////////////////////////////////////////////
376
377 if (!success)
378 {
379 slog (L_ERR, _("no protocols enabled."));
380 return -1;
381 }
332 382
333 reconnect_all (); 383 reconnect_all ();
334 384
335 ///////////////////////////////////////////////////////////////////////////// 385 /////////////////////////////////////////////////////////////////////////////
336 386
337 tap = new tap_device (); 387 tap = new tap_device ();
338 if (!tap) //D this, of course, never catches 388 if (!tap) //D this, of course, never catches
339 { 389 {
340 slog (L_ERR, _("cannot create network interface '%s'"), conf.ifname); 390 slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname);
341 exit (EXIT_FAILURE); 391 return -1;
342 } 392 }
343 393
344 fcntl (tap->fd, F_SETFD, FD_CLOEXEC); 394 fcntl (tap->fd, F_SETFD, FD_CLOEXEC);
345 395
346 run_script_cb cb; 396 run_script_cb cb;
347 cb.set<vpn, &vpn::script_if_init> (this); 397 cb.set<vpn, &vpn::script_if_init> (this);
348 398
349 if (tap->if_up () && 399 if (tap->if_up () &&
350 !run_script (cb, true)) 400 !run_script (cb, true))
351 { 401 {
352 slog (L_ERR, _("interface initialization command '%s' failed, exiting."), 402 slog (L_ERR, _("interface initialization command '%s' failed."),
353 tap->if_up ()); 403 tap->if_up ());
354 exit (EXIT_FAILURE); 404 return -1;
355 } 405 }
356 406
357 cb.set<vpn, &vpn::script_if_up> (this); 407 cb.set<vpn, &vpn::script_if_up> (this);
358 if (!run_script (cb, true)) 408 if (!run_script (cb, true))
359 { 409 {
360 slog (L_ERR, _("if-up command execution failed, exiting.")); 410 slog (L_ERR, _("if-up command execution failed."));
361 exit (EXIT_FAILURE); 411 return -1;
362 } 412 }
363 413
364 tap_ev_watcher.start (tap->fd, EV_READ); 414 tap_ev_watcher.start (tap->fd, EV_READ);
365 415
366 return 0; 416 return 0;
417}
418
419bool
420vpn::drop_privileges ()
421{
422 if (::conf.change_root)
423 {
424 if (!strcmp (::conf.change_root, "/"))
425 {
426 char dir [L_tmpnam];
427 if (!tmpnam (dir))
428 {
429 slog (L_CRIT, _("unable to create anonymous root path."));
430 return false;
431 }
432
433 if (mkdir (dir, 0700))
434 {
435 slog (L_CRIT, _("unable to create anonymous root directory."));
436 return false;
437 }
438
439 if (chdir (dir))
440 {
441 slog (L_CRIT, _("unable to change to anonymous root directory."));
442 return false;
443 }
444
445 if (rmdir (dir))
446 slog (L_ERR, _("unable to remove anonymous root directory, continuing."));
447 }
448 else
449 {
450 if (chdir (::conf.change_root))
451 {
452 slog (L_CRIT, _("%s: unable to change to specified root directory."), ::conf.change_root);
453 return false;
454 }
455 }
456
457 if (chroot ("."))
458 {
459 slog (L_CRIT, _("unable to set new root directory."));
460 return false;
461 }
462
463 if (chdir ("/"))
464 {
465 slog (L_CRIT, _("unable to set cwd to new root directory."));
466 return false;
467 }
468 }
469
470 if (::conf.change_gid)
471 if (setgid (::conf.change_gid))
472 {
473 slog (L_CRIT, _("unable to change group id to %d."), ::conf.change_gid);
474 return false;
475 }
476
477 if (::conf.change_uid)
478 if (setuid (::conf.change_uid))
479 {
480 slog (L_CRIT, _("unable to change user id to %d."), ::conf.change_uid);
481 return false;
482 }
483
484 return true;
367} 485}
368 486
369bool 487bool
370vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 488vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
371{ 489{
372 set_tos (ipv4_fd, ipv4_tos, tos); 490 set_tos (ipv4_fd, ipv4_tos, tos);
373 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 491 xsendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
374 492
375 return true; 493 return true;
376} 494}
377 495
378static u16 496static u16
409 hdr->code = 255; 527 hdr->code = 255;
410 hdr->checksum = 0; 528 hdr->checksum = 0;
411 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); 529 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
412 530
413 set_tos (icmpv4_fd, icmpv4_tos, tos); 531 set_tos (icmpv4_fd, icmpv4_tos, tos);
414 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 532 xsendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
415 533
416 return true; 534 return true;
417} 535}
418#endif 536#endif
419 537
420bool 538bool
421vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 539vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
422{ 540{
423 set_tos (udpv4_fd, udpv4_tos, tos); 541 set_tos (udpv4_fd, udpv4_tos, tos);
424 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 542 xsendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
425 543
426 return true; 544 return true;
427} 545}
428 546
429void 547void
449vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 567vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
450{ 568{
451 unsigned int src = pkt->src (); 569 unsigned int src = pkt->src ();
452 unsigned int dst = pkt->dst (); 570 unsigned int dst = pkt->dst ();
453 571
454 slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), 572 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); 573 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
456 574
457 if (src == 0 || src > conns.size () 575 if (src == 0 || src > conns.size ()
458 || dst > conns.size () 576 || dst > conns.size ()
459 || pkt->typ () >= vpn_packet::PT_MAX) 577 || pkt->typ () >= vpn_packet::PT_MAX)
460 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), 578 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 ()); 579 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
465 else 580 else
466 { 581 {
467 connection *c = conns[src - 1]; 582 connection *c = conns[src - 1];
468 583
469 if (dst == 0) 584 if (dst == 0)
470 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)"), 585 slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."),
471 c->conf->nodename, (const char *)rsi); 586 c->conf->nodename, (const char *)rsi);
472 else if (dst != THISNODE->id) 587 else if (dst != THISNODE->id)
473 { 588 {
474 if (THISNODE->routerprio) 589 if (THISNODE->routerprio)
475 // the tos setting gets lost here. who cares. 590 // the tos setting gets lost here. who cares.
476 conns[dst - 1]->inject_vpn_packet (pkt); 591 conns[dst - 1]->inject_vpn_packet (pkt);
477 else 592 else
478 slog (L_WARN, 593 slog (L_WARN,
479 _("%s(%s): forwarding request (=> %s), but we are no router"), 594 _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."),
480 c->conf->nodename, (const char *)rsi, 595 c->conf->nodename, (const char *)rsi,
481 conns[dst - 1]->conf->nodename); 596 conns[dst - 1]->conf->nodename);
482 } 597 }
483 else 598 else
484 c->recv_vpn_packet (pkt, rsi); 599 c->recv_vpn_packet (pkt, rsi);
489vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 604vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
490{ 605{
491 switch (si.prot) 606 switch (si.prot)
492 { 607 {
493 case PROT_IPv4: 608 case PROT_IPv4:
494 return send_ipv4_packet (pkt, si, tos); 609 return send_ipv4_packet (pkt, si, tos);
495 610
496 case PROT_UDPv4: 611 case PROT_UDPv4:
497 return send_udpv4_packet (pkt, si, tos); 612 return send_udpv4_packet (pkt, si, tos);
498 613
499#if ENABLE_TCP 614#if ENABLE_TCP
500 case PROT_TCPv4: 615 case PROT_TCPv4:
501 return send_tcpv4_packet (pkt, si, tos); 616 return send_tcpv4_packet (pkt, si, tos);
502#endif 617#endif
503#if ENABLE_ICMP 618#if ENABLE_ICMP
504 case PROT_ICMPv4: 619 case PROT_ICMPv4:
505 return send_icmpv4_packet (pkt, si, tos); 620 return send_icmpv4_packet (pkt, si, tos);
506#endif 621#endif
507#if ENABLE_DNS 622#if ENABLE_DNS
508 case PROT_DNSv4: 623 case PROT_DNSv4:
509 return send_dnsv4_packet (pkt, si, tos); 624 return send_dnsv4_packet (pkt, si, tos);
510#endif 625#endif
511 default: 626 default:
512 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol"), (const char *)si); 627 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
513 } 628 }
514 629
515 return false; 630 return false;
516} 631}
517 632
532 if (len > 0) 647 if (len > 0)
533 { 648 {
534 pkt->len = len; 649 pkt->len = len;
535 650
536 // raw sockets deliver the ipv4 header, but don't expect it on sends 651 // raw sockets deliver the ipv4 header, but don't expect it on sends
537 pkt->skip_hdr (IP_OVERHEAD); 652 pkt->skip_hdr (pkt->ipv4_hdr_len ());
538 653
539 recv_vpn_packet (pkt, si); 654 recv_vpn_packet (pkt, si);
540 } 655 }
541 else 656 else
542 { 657 {
543 // probably ECONNRESET or somesuch 658 // probably ECONNRESET or somesuch
544 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 659 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
545 } 660 }
546 661
547 delete pkt; 662 delete pkt;
548 } 663 }
549 else 664 else
550 { 665 {
551 slog (L_ERR, 666 slog (L_ERR,
552 _("FATAL: unknown revents %08x in socket, terminating\n"), 667 _("FATAL: unknown revents %08x in socket, exiting.\n"),
553 revents); 668 revents);
554 exit (EXIT_FAILURE); 669 exit (EXIT_FAILURE);
555 } 670 }
556} 671}
557 672
579 if (hdr->type == ::conf.icmp_type 694 if (hdr->type == ::conf.icmp_type
580 && hdr->code == 255) 695 && hdr->code == 255)
581 { 696 {
582 // raw sockets deliver the ipv4, but don't expect it on sends 697 // raw sockets deliver the ipv4, but don't expect it on sends
583 // this is slow, but... 698 // this is slow, but...
584 pkt->skip_hdr (ICMP_OVERHEAD); 699 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
585 700
586 recv_vpn_packet (pkt, si); 701 recv_vpn_packet (pkt, si);
587 } 702 }
588 } 703 }
589 else 704 else
590 { 705 {
591 // probably ECONNRESET or somesuch 706 // probably ECONNRESET or somesuch
592 slog (L_DEBUG, _("%s: %s"), (const char *)si, strerror (errno)); 707 slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno));
593 } 708 }
594 709
595 delete pkt; 710 delete pkt;
596 } 711 }
597 else 712 else
598 { 713 {
599 slog (L_ERR, 714 slog (L_ERR,
600 _("FATAL: unknown revents %08x in socket, terminating\n"), 715 _("FATAL: unknown revents %08x in socket, exiting.\n"),
601 revents); 716 revents);
602 exit (EXIT_FAILURE); 717 exit (EXIT_FAILURE);
603 } 718 }
604} 719}
605#endif 720#endif
625 recv_vpn_packet (pkt, si); 740 recv_vpn_packet (pkt, si);
626 } 741 }
627 else 742 else
628 { 743 {
629 // probably ECONNRESET or somesuch 744 // probably ECONNRESET or somesuch
630 slog (L_DEBUG, _("%s: fd %d, %s"), (const char *)si, w.fd, strerror (errno)); 745 slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno));
631 } 746 }
632 747
633 delete pkt; 748 delete pkt;
634 } 749 }
635 else 750 else
636 { 751 {
637 slog (L_ERR, 752 slog (L_ERR,
638 _("FATAL: unknown revents %08x in socket, terminating\n"), 753 _("FATAL: unknown revents %08x in socket, exiting.\n"),
639 revents); 754 revents);
640 exit (EXIT_FAILURE); 755 exit (EXIT_FAILURE);
641 } 756 }
642} 757}
643 758
692 { 807 {
693 slog (L_INFO, _("preparing shutdown...")); 808 slog (L_INFO, _("preparing shutdown..."));
694 809
695 shutdown_all (); 810 shutdown_all ();
696 remove_pid (conf.pidfilename); 811 remove_pid (conf.pidfilename);
697 slog (L_INFO, _("terminating")); 812 slog (L_INFO, _("exiting."));
698 exit (EXIT_SUCCESS); 813 exit (EXIT_SUCCESS);
699 } 814 }
700 815
701 if (events & EVENT_RECONNECT) 816 if (events & EVENT_RECONNECT)
702 { 817 {
703 slog (L_INFO, _("forced reconnect")); 818 slog (L_INFO, _("forced reconnect."));
704 819
705 reconnect_all (); 820 reconnect_all ();
706 } 821 }
707 822
708 events = 0; 823 events = 0;
724 839
725 conns.clear (); 840 conns.clear ();
726 841
727 connection_init (); 842 connection_init ();
728 843
729 for (configuration::node_vector::iterator i = conf.nodes.begin (); 844 for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i)
730 i != conf.nodes.end (); ++i) 845 conns.push_back (new connection (this, *i));
731 { 846
732 connection *conn = new connection (this, *i); 847 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
733 conns.push_back (conn);
734 conn->establish_connection (); 848 (*c)->establish_connection ();
735 }
736} 849}
737 850
738connection *vpn::find_router () 851bool
852vpn::can_direct (conf_node *src, conf_node *dst) const
739{ 853{
740 u32 prio = 1; 854 return src != dst
855 && src->may_direct (dst)
856 && dst->may_direct (src)
857 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
858 || (src->protocols & dst->connectable_protocols ()));
859}
860
861// only works for indirect and routed connections: find a router
862// from THISNODE to dst
863connection *
864vpn::find_router_for (const connection *dst)
865{
741 connection *router = 0; 866 connection *router = 0;
742 867
868 // first try to find a router with a direct connection, route there
869 // regardless of any other considerations.
870 {
871 u32 prio = 1;
872
873 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
874 {
875 connection *c = *i;
876
877 if (c->conf->routerprio > prio
878 && c->conf != THISNODE
879 && can_direct (c->conf, dst->conf)
880 && c->ictx && c->octx)
881 {
882 prio = c->conf->routerprio;
883 router = c;
884 }
885 }
886 }
887
888 if (router)
889 return router;
890
891 // second try find the router with the highest priority, higher than ours
892 {
893 u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1;
894
895 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
896 {
897 connection *c = *i;
898
899 if (c->conf->routerprio > prio
900 && c != dst
901 && c->conf != THISNODE
902 && c->ictx && c->octx)
903 {
904 prio = c->conf->routerprio;
905 router = c;
906 }
907 }
908 }
909
910 return router;
911}
912
913void
914vpn::connection_established (connection *c)
915{
743 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 916 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
744 { 917 {
745 connection *c = *i; 918 connection *o = *i;
746 919
747 if (c->conf->routerprio > prio 920 if (o->si.valid ()
748 && c->connectmode == conf_node::C_ALWAYS // so we don't drop the connection if in use 921 && c->si != o->si
749 && c->ictx && c->octx 922 && c == find_router_for (o)
750 && c->conf != THISNODE) // redundant, since ictx==octx==0 always on thisnode 923 && !can_direct (THISNODE, o->conf))
751 {
752 prio = c->conf->routerprio;
753 router = c;
754 } 924 {
925 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
926 o->conf->nodename, c->conf->nodename);
927 o->rekey ();
928 }
755 } 929 }
756
757 return router;
758} 930}
759 931
932void
760void vpn::send_connect_request (int id) 933vpn::send_connect_request (connection *c)
761{ 934{
762 connection *c = find_router (); 935 connection *r = find_router_for (c);
763 936
764 if (c) 937 if (r)
938 {
939 slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."),
940 c->conf->nodename, r->conf->nodename);
765 c->send_connect_request (id); 941 r->send_connect_request (c->conf->id);
942 }
766 else 943 else
767 // no router found, aggressively connect to all routers 944 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) 945 c->conf->nodename);
769 if ((*i)->conf->routerprio && (*i)->conf != THISNODE)
770 (*i)->establish_connection ();
771} 946}
772 947
773void 948void
774connection::dump_status () 949connection::dump_status ()
775{ 950{
776 slog (L_NOTICE, _("node %s (id %d)"), conf->nodename, conf->id); 951 slog (L_NOTICE, _("node %s (id %d)"), conf->nodename, conf->id);
777 slog (L_NOTICE, _(" connectmode %d (%d) / sockaddr %s / minor %d"), 952 slog (L_NOTICE, _(" connectmode %d (%d) / sockaddr %s / minor %d"),
778 connectmode, conf->connectmode, (const char *)si, (int)prot_minor); 953 connectmode, conf->connectmode, (const char *)si, (int)prot_minor);
779 slog (L_NOTICE, _(" ictx/octx %08lx/%08lx / oseqno %d / retry_cnt %d"), 954 slog (L_NOTICE, _(" ictx/octx %08lx/%08lx / oseqno %d / retry_cnt %d"),
780 (long)ictx, (long)octx, (int)oseqno, (int)retry_cnt); 955 (long)ictx, (long)octx, (int)oseqno, (int)retry_cnt);
781 slog (L_NOTICE, _(" establish_conn %ld / rekey %ld / keepalive %ld"),
782 (long)(establish_connection.at), (long)(rekey.at), (long)(keepalive.at));
783} 956}
784 957
785void 958void
786vpn::dump_status () 959vpn::dump_status ()
787{ 960{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines