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.64 by root, Tue Dec 4 10:29:43 2012 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
59 59
60vpn network; // THE vpn (bad design...) 60vpn network; // THE vpn (bad design...)
61 61
62///////////////////////////////////////////////////////////////////////////// 62/////////////////////////////////////////////////////////////////////////////
63 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}
87
88/////////////////////////////////////////////////////////////////////////////
89
64static void inline 90static void inline
65set_tos (int fd, int &tos_prev, int tos) 91set_tos (int fd, int &tos_prev, int tos)
66{ 92{
67#if defined(SOL_IP) && defined(IP_TOS) 93#if defined(SOL_IP) && defined(IP_TOS)
68 if (tos_prev == tos) 94 if (tos_prev == tos)
78{ 104{
79 // the tunnel device mtu should be the physical mtu - overhead 105 // the tunnel device mtu should be the physical mtu - overhead
80 // the tricky part is rounding to the cipher key blocksize 106 // the tricky part is rounding to the cipher key blocksize
81 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD; 107 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD;
82 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion 108 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion
83 mtu -= mtu % EVP_CIPHER_block_size (CIPHER); // round 109 mtu -= mtu % BLOCK_SIZE (CIPHER); // round
84 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again 110 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again
85 111
86 char *env; 112 char *env;
87 asprintf (&env, "CONFBASE=%s", confbase); putenv (env); 113 asprintf (&env, "CONFBASE=%s", confbase); putenv (env);
88 asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env); 114 asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env);
113inline const char * 139inline const char *
114vpn::script_if_up () 140vpn::script_if_up ()
115{ 141{
116 script_init_env (); 142 script_init_env ();
117 143
118 char *filename; 144 return conf.config_filename (::conf.script_if_up, "if-up");
119 asprintf (&filename,
120 "%s/%s",
121 confbase,
122 ::conf.script_if_up ? ::conf.script_if_up : "if-up");
123
124 return filename;
125} 145}
126 146
127int 147int
128vpn::setup_socket (u8 prot, int family, int type, int proto) 148vpn::setup_socket (u8 prot, int family, int type, int proto)
129{ 149{
238 return -1; 258 return -1;
239 259
240#ifdef ICMP_FILTER 260#ifdef ICMP_FILTER
241 { 261 {
242 icmp_filter oval; 262 icmp_filter oval;
243 oval.data = 0xffffffff; 263 oval.data = 0;
244 if (::conf.icmp_type < 32) 264 if (::conf.icmp_type < 32)
245 oval.data &= ~(1 << ::conf.icmp_type); 265 oval.data |= 1 << ::conf.icmp_type;
266 oval.data = ~oval.data;
246 267
247 setsockopt (icmpv4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval); 268 setsockopt (icmpv4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval);
248 } 269 }
249#endif 270#endif
250 271
410 return false; 431 return false;
411 } 432 }
412 433
413 if (mkdir (dir, 0700)) 434 if (mkdir (dir, 0700))
414 { 435 {
415 slog (L_CRIT, _("unable to crate anonymous root directory.")); 436 slog (L_CRIT, _("unable to create anonymous root directory."));
416 return false; 437 return false;
417 } 438 }
418 439
419 if (chdir (dir)) 440 if (chdir (dir))
420 { 441 {
466 487
467bool 488bool
468vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 489vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
469{ 490{
470 set_tos (ipv4_fd, ipv4_tos, tos); 491 set_tos (ipv4_fd, ipv4_tos, tos);
471 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 ());
472 493
473 return true; 494 return true;
474} 495}
475 496
476static u16 497static u16
507 hdr->code = 255; 528 hdr->code = 255;
508 hdr->checksum = 0; 529 hdr->checksum = 0;
509 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); 530 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
510 531
511 set_tos (icmpv4_fd, icmpv4_tos, tos); 532 set_tos (icmpv4_fd, icmpv4_tos, tos);
512 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 ());
513 534
514 return true; 535 return true;
515} 536}
516#endif 537#endif
517 538
518bool 539bool
519vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 540vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
520{ 541{
521 set_tos (udpv4_fd, udpv4_tos, tos); 542 set_tos (udpv4_fd, udpv4_tos, tos);
522 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 ());
523 544
524 return true; 545 return true;
525} 546}
526 547
527void 548void
895{ 916{
896 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 917 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
897 { 918 {
898 connection *o = *i; 919 connection *o = *i;
899 920
900 if (!o->is_direct
901 && o->si.valid () 921 if (o->si.valid ()
902 && c->si != o->si 922 && c->si != o->si
903 && c == find_router_for (o)) 923 && c == find_router_for (o)
924 && !can_direct (THISNODE, o->conf))
904 { 925 {
905 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."),
906 o->conf->nodename, c->conf->nodename); 927 o->conf->nodename, c->conf->nodename);
907 o->rekey (); 928 o->rekey ();
908 } 929 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines