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.58 by root, Tue Feb 15 13:31:23 2011 UTC vs.
Revision 1.70 by root, Thu Oct 6 03:03:09 2022 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,2010,2011 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,
117 "%s/%s",
118 confbase,
119 ::conf.script_if_up ? ::conf.script_if_up : "if-up");
120
121 return filename;
122} 145}
123 146
124int 147int
125vpn::setup_socket (u8 prot, int family, int type, int proto) 148vpn::setup_socket (u8 prot, int family, int type, int proto)
126{ 149{
235 return -1; 258 return -1;
236 259
237#ifdef ICMP_FILTER 260#ifdef ICMP_FILTER
238 { 261 {
239 icmp_filter oval; 262 icmp_filter oval;
240 oval.data = 0xffffffff; 263 oval.data = 0;
241 if (::conf.icmp_type < 32) 264 if (::conf.icmp_type < 32)
242 oval.data &= ~(1 << ::conf.icmp_type); 265 oval.data |= 1 << ::conf.icmp_type;
266 oval.data = ~oval.data;
243 267
244 setsockopt (icmpv4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval); 268 setsockopt (icmpv4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval);
245 } 269 }
246#endif 270#endif
247 271
392 416
393 return 0; 417 return 0;
394} 418}
395 419
396bool 420bool
421vpn::drop_privileges ()
422{
423 if (::conf.change_root)
424 {
425 if (!strcmp (::conf.change_root, "/"))
426 {
427 char dir [L_tmpnam];
428 if (!tmpnam (dir))
429 {
430 slog (L_CRIT, _("unable to create anonymous root path."));
431 return false;
432 }
433
434 if (mkdir (dir, 0700))
435 {
436 slog (L_CRIT, _("unable to create anonymous root directory."));
437 return false;
438 }
439
440 if (chdir (dir))
441 {
442 slog (L_CRIT, _("unable to change to anonymous root directory."));
443 return false;
444 }
445
446 if (rmdir (dir))
447 slog (L_ERR, _("unable to remove anonymous root directory, continuing."));
448 }
449 else
450 {
451 if (chdir (::conf.change_root))
452 {
453 slog (L_CRIT, _("%s: unable to change to specified root directory."), ::conf.change_root);
454 return false;
455 }
456 }
457
458 if (chroot ("."))
459 {
460 slog (L_CRIT, _("unable to set new root directory."));
461 return false;
462 }
463
464 if (chdir ("/"))
465 {
466 slog (L_CRIT, _("unable to set cwd to new root directory."));
467 return false;
468 }
469 }
470
471 if (::conf.change_gid)
472 if (setgid (::conf.change_gid))
473 {
474 slog (L_CRIT, _("unable to change group id to %d."), ::conf.change_gid);
475 return false;
476 }
477
478 if (::conf.change_uid)
479 if (setuid (::conf.change_uid))
480 {
481 slog (L_CRIT, _("unable to change user id to %d."), ::conf.change_uid);
482 return false;
483 }
484
485 return true;
486}
487
488bool
397vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 489vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
398{ 490{
399 set_tos (ipv4_fd, ipv4_tos, tos); 491 set_tos (ipv4_fd, ipv4_tos, tos);
400 sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 492 xsendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
401 493
402 return true; 494 return true;
403} 495}
404 496
405static u16 497static u16
436 hdr->code = 255; 528 hdr->code = 255;
437 hdr->checksum = 0; 529 hdr->checksum = 0;
438 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); 530 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
439 531
440 set_tos (icmpv4_fd, icmpv4_tos, tos); 532 set_tos (icmpv4_fd, icmpv4_tos, tos);
441 sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 533 xsendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
442 534
443 return true; 535 return true;
444} 536}
445#endif 537#endif
446 538
447bool 539bool
448vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 540vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
449{ 541{
450 set_tos (udpv4_fd, udpv4_tos, tos); 542 set_tos (udpv4_fd, udpv4_tos, tos);
451 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 543 xsendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
452 544
453 return true; 545 return true;
454} 546}
455 547
456void 548void
482 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); 574 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
483 575
484 if (src == 0 || src > conns.size () 576 if (src == 0 || src > conns.size ()
485 || dst > conns.size () 577 || dst > conns.size ()
486 || pkt->typ () >= vpn_packet::PT_MAX) 578 || pkt->typ () >= vpn_packet::PT_MAX)
487 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
488 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
489 else if (dst > conns.size ())
490 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."), 579 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
491 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 580 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
492 else 581 else
493 { 582 {
494 connection *c = conns[src - 1]; 583 connection *c = conns[src - 1];
516vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 605vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
517{ 606{
518 switch (si.prot) 607 switch (si.prot)
519 { 608 {
520 case PROT_IPv4: 609 case PROT_IPv4:
521 return send_ipv4_packet (pkt, si, tos); 610 return send_ipv4_packet (pkt, si, tos);
522 611
523 case PROT_UDPv4: 612 case PROT_UDPv4:
524 return send_udpv4_packet (pkt, si, tos); 613 return send_udpv4_packet (pkt, si, tos);
525 614
526#if ENABLE_TCP 615#if ENABLE_TCP
527 case PROT_TCPv4: 616 case PROT_TCPv4:
528 return send_tcpv4_packet (pkt, si, tos); 617 return send_tcpv4_packet (pkt, si, tos);
529#endif 618#endif
530#if ENABLE_ICMP 619#if ENABLE_ICMP
531 case PROT_ICMPv4: 620 case PROT_ICMPv4:
532 return send_icmpv4_packet (pkt, si, tos); 621 return send_icmpv4_packet (pkt, si, tos);
533#endif 622#endif
534#if ENABLE_DNS 623#if ENABLE_DNS
535 case PROT_DNSv4: 624 case PROT_DNSv4:
536 return send_dnsv4_packet (pkt, si, tos); 625 return send_dnsv4_packet (pkt, si, tos);
537#endif 626#endif
538 default: 627 default:
539 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si); 628 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
540 } 629 }
541 630
559 if (len > 0) 648 if (len > 0)
560 { 649 {
561 pkt->len = len; 650 pkt->len = len;
562 651
563 // raw sockets deliver the ipv4 header, but don't expect it on sends 652 // raw sockets deliver the ipv4 header, but don't expect it on sends
564 pkt->skip_hdr (IP_OVERHEAD); 653 pkt->skip_hdr (pkt->ipv4_hdr_len ());
565 654
566 recv_vpn_packet (pkt, si); 655 recv_vpn_packet (pkt, si);
567 } 656 }
568 else 657 else
569 { 658 {
606 if (hdr->type == ::conf.icmp_type 695 if (hdr->type == ::conf.icmp_type
607 && hdr->code == 255) 696 && hdr->code == 255)
608 { 697 {
609 // raw sockets deliver the ipv4, but don't expect it on sends 698 // raw sockets deliver the ipv4, but don't expect it on sends
610 // this is slow, but... 699 // this is slow, but...
611 pkt->skip_hdr (ICMP_OVERHEAD); 700 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
612 701
613 recv_vpn_packet (pkt, si); 702 recv_vpn_packet (pkt, si);
614 } 703 }
615 } 704 }
616 else 705 else
827{ 916{
828 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 917 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
829 { 918 {
830 connection *o = *i; 919 connection *o = *i;
831 920
832 if (!o->is_direct
833 && o->si.valid () 921 if (o->si.valid ()
834 && c->si != o->si 922 && c->si != o->si
835 && c == find_router_for (o)) 923 && c == find_router_for (o)
924 && !can_direct (THISNODE, o->conf))
836 { 925 {
837 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."), 926 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
838 o->conf->nodename, c->conf->nodename); 927 o->conf->nodename, c->conf->nodename);
839 o->rekey (); 928 o->rekey ();
840 } 929 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines