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.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,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{
410 return false; 430 return false;
411 } 431 }
412 432
413 if (mkdir (dir, 0700)) 433 if (mkdir (dir, 0700))
414 { 434 {
415 slog (L_CRIT, _("unable to crate anonymous root directory.")); 435 slog (L_CRIT, _("unable to create anonymous root directory."));
416 return false; 436 return false;
417 } 437 }
418 438
419 if (chdir (dir)) 439 if (chdir (dir))
420 { 440 {
466 486
467bool 487bool
468vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 488vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
469{ 489{
470 set_tos (ipv4_fd, ipv4_tos, tos); 490 set_tos (ipv4_fd, ipv4_tos, tos);
471 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 ());
472 492
473 return true; 493 return true;
474} 494}
475 495
476static u16 496static u16
507 hdr->code = 255; 527 hdr->code = 255;
508 hdr->checksum = 0; 528 hdr->checksum = 0;
509 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); 529 hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len);
510 530
511 set_tos (icmpv4_fd, icmpv4_tos, tos); 531 set_tos (icmpv4_fd, icmpv4_tos, tos);
512 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 ());
513 533
514 return true; 534 return true;
515} 535}
516#endif 536#endif
517 537
518bool 538bool
519vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 539vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
520{ 540{
521 set_tos (udpv4_fd, udpv4_tos, tos); 541 set_tos (udpv4_fd, udpv4_tos, tos);
522 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 ());
523 543
524 return true; 544 return true;
525} 545}
526 546
527void 547void
895{ 915{
896 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 916 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
897 { 917 {
898 connection *o = *i; 918 connection *o = *i;
899 919
900 if (!o->is_direct
901 && o->si.valid () 920 if (o->si.valid ()
902 && c->si != o->si 921 && c->si != o->si
903 && c == find_router_for (o)) 922 && c == find_router_for (o)
923 && !can_direct (THISNODE, o->conf))
904 { 924 {
905 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."), 925 slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."),
906 o->conf->nodename, c->conf->nodename); 926 o->conf->nodename, c->conf->nodename);
907 o->rekey (); 927 o->rekey ();
908 } 928 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines