ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/connection.C
(Generate patch)

Comparing gvpe/src/connection.C (file contents):
Revision 1.67 by pcg, Thu Aug 7 16:34:21 2008 UTC vs.
Revision 1.71 by pcg, Fri Aug 8 06:51:56 2008 UTC

1/* 1/*
2 connection.C -- manage a single connection 2 connection.C -- manage a single connection
3 Copyright (C) 2003-2005 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008 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 7 GVPE is free software; you can redistribute it and/or modify it
8 it under the terms of the GNU General Public License as published by 8 under the terms of the GNU General Public License as published by the
9 the Free Software Foundation; either version 2 of the License, or 9 Free Software Foundation; either version 3 of the License, or (at your
10 (at your option) any later version. 10 option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful, but
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 GNU General Public License for more details. 15 Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License along
18 along with gvpe; if not, write to the Free Software 18 with this program; if not, see <http://www.gnu.org/licenses/>.
19 Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this Program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a modified
24 version of that library), containing parts covered by the terms of the
25 OpenSSL or SSLeay licenses, the licensors of this Program grant you
26 additional permission to convey the resulting work. Corresponding
27 Source for a non-source form of such a combination shall include the
28 source code for the parts of OpenSSL used as well as that of the
29 covered work.
20*/ 30*/
21 31
22#include "config.h" 32#include "config.h"
23 33
24#include <list> 34#include <list>
35#include <queue>
36#include <utility>
25 37
26#include <openssl/rand.h> 38#include <openssl/rand.h>
27#include <openssl/evp.h> 39#include <openssl/evp.h>
28#include <openssl/rsa.h> 40#include <openssl/rsa.h>
29#include <openssl/err.h> 41#include <openssl/err.h>
45#define ULTRA_FAST 1 57#define ULTRA_FAST 1
46#define HLOG 15 58#define HLOG 15
47#include "lzf/lzf.h" 59#include "lzf/lzf.h"
48#include "lzf/lzf_c.c" 60#include "lzf/lzf_c.c"
49#include "lzf/lzf_d.c" 61#include "lzf/lzf_d.c"
62
63//////////////////////////////////////////////////////////////////////////////
64
65static std::queue< std::pair<run_script_cb *, const char *> > rs_queue;
66static ev::child rs_child_ev;
67
68void // c++ requires external linkage here, apparently :(
69rs_child_cb (ev::child &w, int revents)
70{
71 w.stop ();
72
73 if (rs_queue.empty ())
74 return;
75
76 pid_t pid = run_script (*rs_queue.front ().first, false);
77 if (pid)
78 {
79 w.set (pid);
80 w.start ();
81 }
82 else
83 slog (L_WARN, rs_queue.front ().second);
84
85 delete rs_queue.front ().first;
86 rs_queue.pop ();
87}
88
89// despite the fancy name, this is quite a hack
90static void
91run_script_queued (run_script_cb *cb, const char *warnmsg)
92{
93 rs_queue.push (std::make_pair (cb, warnmsg));
94
95 if (!rs_child_ev.is_active ())
96 {
97 rs_child_ev.set<rs_child_cb> ();
98 rs_child_ev ();
99 }
100}
101
102//////////////////////////////////////////////////////////////////////////////
50 103
51struct crypto_ctx 104struct crypto_ctx
52{ 105{
53 EVP_CIPHER_CTX cctx; 106 EVP_CIPHER_CTX cctx;
54 HMAC_CTX hctx; 107 HMAC_CTX hctx;
658void 711void
659connection::reset_si () 712connection::reset_si ()
660{ 713{
661 protocol = best_protocol (THISNODE->protocols & conf->protocols); 714 protocol = best_protocol (THISNODE->protocols & conf->protocols);
662 715
663 // mask out protocols we cannot establish 716 // mask out endpoints we can't connect to
664 if (!conf->udp_port) protocol &= ~PROT_UDPv4; 717 if (!conf->udp_port) protocol &= ~PROT_UDPv4;
665 if (!conf->tcp_port) protocol &= ~PROT_TCPv4; 718 if (!conf->tcp_port) protocol &= ~PROT_TCPv4;
666 if (!conf->dns_port) protocol &= ~PROT_DNSv4; 719 if (!conf->dns_port) protocol &= ~PROT_DNSv4;
667 720
668 if (protocol 721 if (protocol
689 slog (L_DEBUG, _("%s: no common protocol, trying indirectly through %s (%s)"), 742 slog (L_DEBUG, _("%s: no common protocol, trying indirectly through %s (%s)"),
690 conf->nodename, r->conf->nodename, (const char *)r->si); 743 conf->nodename, r->conf->nodename, (const char *)r->si);
691 return r->si; 744 return r->si;
692 } 745 }
693 else 746 else
694 slog (L_DEBUG, _("%s: node unreachable, no common protocol"), 747 slog (L_DEBUG, _("%s: node unreachable, no common protocol, no router"),
695 conf->nodename); 748 conf->nodename);
696 } 749 }
697 750
698 return si; 751 return si;
699} 752}
792 if (connectmode == conf_node::C_ONDEMAND && vpn_queue.empty () && data_queue.empty ()) 845 if (connectmode == conf_node::C_ONDEMAND && vpn_queue.empty () && data_queue.empty ())
793 { 846 {
794 reset_connection (); 847 reset_connection ();
795 return; 848 return;
796 } 849 }
850
851 last_establish_attempt = ev_now ();
797 852
798 ev::tstamp retry_int = ev::tstamp (retry_cnt & 3 853 ev::tstamp retry_int = ev::tstamp (retry_cnt & 3
799 ? (retry_cnt & 3) + 1 854 ? (retry_cnt & 3) + 1
800 : 1 << (retry_cnt >> 2)); 855 : 1 << (retry_cnt >> 2));
801 856
825 else 880 else
826 send_ping (dsi, 0); 881 send_ping (dsi, 0);
827 } 882 }
828 } 883 }
829 884
830 retry_int *= slow ? 8. : 0.7; 885 retry_int *= slow ? 8. : 0.9;
831 886
832 if (retry_int < conf->max_retry) 887 if (retry_int < conf->max_retry)
833 retry_cnt++; 888 retry_cnt++;
834 else 889 else
835 retry_int = conf->max_retry; 890 retry_int = conf->max_retry;
846 slog (L_INFO, _("%s(%s): connection lost"), 901 slog (L_INFO, _("%s(%s): connection lost"),
847 conf->nodename, (const char *)si); 902 conf->nodename, (const char *)si);
848 903
849 if (::conf.script_node_down) 904 if (::conf.script_node_down)
850 { 905 {
851 run_script_cb cb; 906 run_script_cb *cb = new run_script_cb;
852 cb.set<connection, &connection::script_node_down> (this); 907 cb->set<connection, &connection::script_node_down> (this);
853 if (!run_script (cb, false))
854 slog (L_WARN, _("node-down command execution failed, continuing.")); 908 run_script_queued (cb, _("node-down command execution failed, continuing."));
855 } 909 }
856 } 910 }
857 911
858 delete ictx; ictx = 0; 912 delete ictx; ictx = 0;
859 delete octx; octx = 0; 913 delete octx; octx = 0;
905 if (oseqno > MAX_SEQNO) 959 if (oseqno > MAX_SEQNO)
906 rekey (); 960 rekey ();
907} 961}
908 962
909void 963void
964connection::post_inject_queue ()
965{
966 // force a connection every now and when when packets are sent (max 1/s)
967 if (ev_now () - last_establish_attempt >= 0.95) // arbitrary
968 establish_connection.stop ();
969
970 establish_connection ();
971}
972
973void
910connection::inject_data_packet (tap_packet *pkt, bool broadcast/*TODO DDD*/) 974connection::inject_data_packet (tap_packet *pkt)
911{ 975{
912 if (ictx && octx) 976 if (ictx && octx)
913 send_data_packet (pkt); 977 send_data_packet (pkt);
914 else 978 else
915 { 979 {
916 if (!broadcast)
917 data_queue.put (new tap_packet (*pkt)); 980 data_queue.put (new tap_packet (*pkt));
918 981 post_inject_queue ();
919 establish_connection ();
920 } 982 }
921} 983}
922 984
923void connection::inject_vpn_packet (vpn_packet *pkt, int tos) 985void connection::inject_vpn_packet (vpn_packet *pkt, int tos)
924{ 986{
925 if (ictx && octx) 987 if (ictx && octx)
926 send_vpn_packet (pkt, si, tos); 988 send_vpn_packet (pkt, si, tos);
927 else 989 else
928 { 990 {
929 vpn_queue.put ((vpn_packet *)new data_packet (*(data_packet *)pkt)); 991 vpn_queue.put ((vpn_packet *)new data_packet (*(data_packet *)pkt));
930 992 post_inject_queue ();
931 establish_connection ();
932 } 993 }
933} 994}
934 995
935void 996void
936connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 997connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
1085 conf->nodename, (const char *)rsi, 1146 conf->nodename, (const char *)rsi,
1086 p->prot_major, p->prot_minor); 1147 p->prot_major, p->prot_minor);
1087 1148
1088 if (::conf.script_node_up) 1149 if (::conf.script_node_up)
1089 { 1150 {
1090 run_script_cb cb; 1151 run_script_cb *cb = new run_script_cb;
1091 cb.set<connection, &connection::script_node_up> (this); 1152 cb->set<connection, &connection::script_node_up> (this);
1092 if (!run_script (cb, false))
1093 slog (L_WARN, _("node-up command execution failed, continuing.")); 1153 run_script_queued (cb, _("node-up command execution failed, continuing."));
1094 } 1154 }
1095 1155
1096 break; 1156 break;
1097 } 1157 }
1098 else 1158 else
1315{ 1375{
1316 rekey .set<connection, &connection::rekey_cb > (this); 1376 rekey .set<connection, &connection::rekey_cb > (this);
1317 keepalive .set<connection, &connection::keepalive_cb > (this); 1377 keepalive .set<connection, &connection::keepalive_cb > (this);
1318 establish_connection.set<connection, &connection::establish_connection_cb> (this); 1378 establish_connection.set<connection, &connection::establish_connection_cb> (this);
1319 1379
1380 last_establish_attempt = 0.;
1320 octx = ictx = 0; 1381 octx = ictx = 0;
1321 retry_cnt = 0;
1322 1382
1323 if (!conf->protocols) // make sure some protocol is enabled 1383 if (!conf->protocols) // make sure some protocol is enabled
1324 conf->protocols = PROT_UDPv4; 1384 conf->protocols = PROT_UDPv4;
1325 1385
1326 connectmode = conf->connectmode; 1386 connectmode = conf->connectmode;
1327 1387
1328 // queue a dummy packet to force an initial connection attempt 1388 // queue a dummy packet to force an initial connection attempt
1329 if (connectmode != conf_node::C_ALWAYS && connectmode != conf_node::C_DISABLED) 1389 if (connectmode != conf_node::C_ALWAYS && connectmode != conf_node::C_DISABLED)
1330 { 1390 vpn_queue.put (new net_packet);
1331 net_packet *p = new net_packet;
1332 p->len = 0;
1333 vpn_queue.put (p);
1334 }
1335 1391
1336 reset_connection (); 1392 reset_connection ();
1337} 1393}
1338 1394
1339connection::~connection () 1395connection::~connection ()

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines