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.76 by pcg, Sun Aug 10 15:16:55 2008 UTC vs.
Revision 1.89 by root, Thu Dec 2 08:15:09 2010 UTC

1/* 1/*
2 connection.C -- manage a single connection 2 connection.C -- manage a single connection
3 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008,2010 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
50 50
51#if !HAVE_RAND_PSEUDO_BYTES 51#if !HAVE_RAND_PSEUDO_BYTES
52# define RAND_pseudo_bytes RAND_bytes 52# define RAND_pseudo_bytes RAND_bytes
53#endif 53#endif
54 54
55#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic 55#define MAGIC_OLD "vped\xbd\xc6\xdb\x82" // 8 bytes of magic (still used in the protocol)
56#define MAGIC "gvpe\xbd\xc6\xdb\x82" // 8 bytes of magic (understood but not generated)
56 57
57#define ULTRA_FAST 1 58#define ULTRA_FAST 1
58#define HLOG 15 59#define HLOG 15
59#include "lzf/lzf.h" 60#include "lzf/lzf.h"
60#include "lzf/lzf_c.c" 61#include "lzf/lzf_c.c"
424 ptype type = PT_DATA_UNCOMPRESSED; 425 ptype type = PT_DATA_UNCOMPRESSED;
425 426
426#if ENABLE_COMPRESSION 427#if ENABLE_COMPRESSION
427 u8 cdata[MAX_MTU]; 428 u8 cdata[MAX_MTU];
428 429
429 if (conn->features & ENABLE_COMPRESSION) 430 if (conn->features & FEATURE_COMPRESSION)
430 { 431 {
431 u32 cl = lzf_compress (d, l, cdata + 2, (l - 2) & ~7); 432 u32 cl = lzf_compress (d, l, cdata + 2, (l - 2) & ~7);
432 433
433 if (cl) 434 if (cl)
434 { 435 {
613 rsaencrdata encr; 614 rsaencrdata encr;
614 615
615 auth_req_packet (int dst, bool initiate_, u8 protocols_) 616 auth_req_packet (int dst, bool initiate_, u8 protocols_)
616 { 617 {
617 config_packet::setup (PT_AUTH_REQ, dst); 618 config_packet::setup (PT_AUTH_REQ, dst);
618 strncpy (magic, MAGIC, 8); 619 strncpy (magic, MAGIC_OLD, 8);
619 initiate = !!initiate_; 620 initiate = !!initiate_;
620 protocols = protocols_; 621 protocols = protocols_;
621 622
622 len = sizeof (*this) - sizeof (net_packet); 623 len = sizeof (*this) - sizeof (net_packet);
623 } 624 }
672///////////////////////////////////////////////////////////////////////////// 673/////////////////////////////////////////////////////////////////////////////
673 674
674void 675void
675connection::connection_established () 676connection::connection_established ()
676{ 677{
677 slog (L_TRACE, _("%s: possible connection establish (ictx %d, octx %d)"), conf->nodename, !!ictx, !!octx); 678 slog (L_NOISE, _("%s: possible connection establish (ictx %d, octx %d)"), conf->nodename, !!ictx, !!octx);
678 679
679 if (ictx && octx) 680 if (ictx && octx)
680 { 681 {
681 // make sure rekeying timeouts are slightly asymmetric 682 // make sure rekeying timeouts are slightly asymmetric
682 ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0); 683 ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0);
760{ 761{
761 ping_packet *pkt = new ping_packet; 762 ping_packet *pkt = new ping_packet;
762 763
763 pkt->setup (conf->id, pong ? ping_packet::PT_PONG : ping_packet::PT_PING); 764 pkt->setup (conf->id, pong ? ping_packet::PT_PONG : ping_packet::PT_PING);
764 765
765 slog (L_TRACE, ">>%d %s [%s]", conf->id, pong ? "PT_PONG" : "PT_PING", (const char *)si); 766 slog (L_TRACE, "%s << %s [%s]", conf->nodename, pong ? "PT_PONG" : "PT_PING", (const char *)si);
766 767
767 send_vpn_packet (pkt, si, IPTOS_LOWDELAY); 768 send_vpn_packet (pkt, si, IPTOS_LOWDELAY);
768 769
769 delete pkt; 770 delete pkt;
770} 771}
790 791
791 rsachallenge chg; 792 rsachallenge chg;
792 rsa_cache.gen (pkt->id, chg); 793 rsa_cache.gen (pkt->id, chg);
793 rsa_encrypt (conf->rsa_key, chg, pkt->encr); 794 rsa_encrypt (conf->rsa_key, chg, pkt->encr);
794 795
795 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si); 796 slog (L_TRACE, "%s << PT_AUTH_REQ [%s]", conf->nodename, (const char *)si);
796 797
797 send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly 798 send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly
798 799
799 delete pkt; 800 delete pkt;
800} 801}
808 809
809 rsa_hash (id, chg, pkt->response); 810 rsa_hash (id, chg, pkt->response);
810 811
811 pkt->hmac_set (octx); 812 pkt->hmac_set (octx);
812 813
813 slog (L_TRACE, ">>%d PT_AUTH_RES [%s]", conf->id, (const char *)si); 814 slog (L_TRACE, "%s << PT_AUTH_RES [%s]", conf->nodename, (const char *)si);
814 815
815 send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly 816 send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly
816 817
817 delete pkt; 818 delete pkt;
818} 819}
819 820
820void 821void
821connection::send_connect_info (int rid, const sockinfo &rsi, u8 rprotocols) 822connection::send_connect_info (int rid, const sockinfo &rsi, u8 rprotocols)
822{ 823{
823 slog (L_TRACE, ">>%d PT_CONNECT_INFO(%d,%s)", 824 slog (L_TRACE, "%s << PT_CONNECT_INFO(%s,%s)", conf->nodename,
824 conf->id, rid, (const char *)rsi); 825 vpn->conns[rid - 1]->conf->nodename, (const char *)rsi);
825 826
826 connect_info_packet *r = new connect_info_packet (conf->id, rid, rsi, rprotocols); 827 connect_info_packet *r = new connect_info_packet (conf->id, rid, rsi, rprotocols);
827 828
828 r->hmac_set (octx); 829 r->hmac_set (octx);
829 send_vpn_packet (r, si); 830 send_vpn_packet (r, si);
999void 1000void
1000connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 1001connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
1001{ 1002{
1002 last_activity = ev_now (); 1003 last_activity = ev_now ();
1003 1004
1004 slog (L_NOISE, "<<%d received packet type %d from %d to %d.", 1005 slog (L_NOISE, "%s >> received packet type %d from %d to %d.",
1005 conf->id, pkt->typ (), pkt->src (), pkt->dst ()); 1006 conf->nodename, pkt->typ (), pkt->src (), pkt->dst ());
1006 1007
1007 if (connectmode == conf_node::C_DISABLED) 1008 if (connectmode == conf_node::C_DISABLED)
1008 return; 1009 return;
1009 1010
1010 switch (pkt->typ ()) 1011 switch (pkt->typ ())
1011 { 1012 {
1012 case vpn_packet::PT_PING: 1013 case vpn_packet::PT_PING:
1014 slog (L_TRACE, "%s >> PT_PING", conf->nodename);
1015
1013 // we send pings instead of auth packets after some retries, 1016 // we send pings instead of auth packets after some retries,
1014 // so reset the retry counter and establish a connection 1017 // so reset the retry counter and establish a connection
1015 // when we receive a ping. 1018 // when we receive a ping.
1016 if (!ictx) 1019 if (!ictx)
1017 { 1020 {
1018 if (auth_rate_limiter.can (rsi)) 1021 if (auth_rate_limiter.can (rsi))
1019 send_auth_request (rsi, true); 1022 send_auth_request (rsi, true);
1020 } 1023 }
1021 else 1024 else
1022 // we would love to change thre socket address here, but ping's aren't 1025 // we would love to change the socket address here, but ping's aren't
1023 // authenticated, so we best ignore it. 1026 // authenticated, so we best ignore it.
1024 send_ping (rsi, 1); // pong 1027 send_ping (rsi, 1); // pong
1025 1028
1026 break; 1029 break;
1027 1030
1028 case vpn_packet::PT_PONG: 1031 case vpn_packet::PT_PONG:
1032 slog (L_TRACE, "%s >> PT_PONG", conf->nodename);
1033
1034 // a PONG might mean that the other side doesn't really know
1035 // about our desire for communication.
1036 establish_connection ();
1029 break; 1037 break;
1030 1038
1031 case vpn_packet::PT_RESET: 1039 case vpn_packet::PT_RESET:
1032 { 1040 {
1033 reset_connection (); 1041 reset_connection ();
1048 case vpn_packet::PT_AUTH_REQ: 1056 case vpn_packet::PT_AUTH_REQ:
1049 if (auth_rate_limiter.can (rsi)) 1057 if (auth_rate_limiter.can (rsi))
1050 { 1058 {
1051 auth_req_packet *p = (auth_req_packet *) pkt; 1059 auth_req_packet *p = (auth_req_packet *) pkt;
1052 1060
1053 slog (L_TRACE, "<<%d PT_AUTH_REQ(%d)", conf->id, p->initiate); 1061 slog (L_TRACE, "%s >> PT_AUTH_REQ(%s)", conf->nodename, p->initiate ? "initiate" : "reply");
1054 1062
1055 if (p->chk_config () && !strncmp (p->magic, MAGIC, 8)) 1063 if (p->chk_config ()
1064 && (!strncmp (p->magic, MAGIC_OLD, 8) || !strncmp (p->magic, MAGIC, 8)))
1056 { 1065 {
1057 if (p->prot_minor != PROTOCOL_MINOR) 1066 if (p->prot_minor != PROTOCOL_MINOR)
1058 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."), 1067 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
1059 conf->nodename, (const char *)rsi, 1068 conf->nodename, (const char *)rsi,
1060 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 1069 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
1096 1105
1097 break; 1106 break;
1098 1107
1099 case vpn_packet::PT_AUTH_RES: 1108 case vpn_packet::PT_AUTH_RES:
1100 { 1109 {
1101 auth_res_packet *p = (auth_res_packet *) pkt; 1110 auth_res_packet *p = (auth_res_packet *)pkt;
1102 1111
1103 slog (L_TRACE, "<<%d PT_AUTH_RES", conf->id); 1112 slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename);
1104 1113
1105 if (p->chk_config ()) 1114 if (p->chk_config ())
1106 { 1115 {
1107 if (p->prot_minor != PROTOCOL_MINOR) 1116 if (p->prot_minor != PROTOCOL_MINOR)
1108 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."), 1117 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
1145 si = rsi; 1154 si = rsi;
1146 protocol = rsi.prot; 1155 protocol = rsi.prot;
1147 1156
1148 slog (L_INFO, _("%s(%s): connection established (%s), protocol version %d.%d."), 1157 slog (L_INFO, _("%s(%s): connection established (%s), protocol version %d.%d."),
1149 conf->nodename, (const char *)rsi, 1158 conf->nodename, (const char *)rsi,
1150 is_direct ? "direct" : "routed", 1159 is_direct ? "direct" : "forwarded",
1151 p->prot_major, p->prot_minor); 1160 p->prot_major, p->prot_minor);
1152 1161
1153 connection_established (); 1162 connection_established ();
1154 1163
1155 if (::conf.script_node_up) 1164 if (::conf.script_node_up)
1203 if (si != rsi) 1212 if (si != rsi)
1204 { 1213 {
1205 // fast re-sync on source address changes, useful especially for tcp/ip 1214 // fast re-sync on source address changes, useful especially for tcp/ip
1206 //if (last_si_change < ev_now () + 5.) 1215 //if (last_si_change < ev_now () + 5.)
1207 // { 1216 // {
1217 slog (L_INFO, _("%s(%s): changing socket address to %s."),
1218 conf->nodename, (const char *)si, (const char *)rsi);
1219
1208 si = rsi; 1220 si = rsi;
1209 1221
1210 slog (L_INFO, _("%s(%s): socket address changed to %s."), 1222 if (::conf.script_node_change)
1211 conf->nodename, (const char *)si, (const char *)rsi); 1223 {
1224 run_script_cb *cb = new run_script_cb;
1225 cb->set<connection, &connection::script_node_change> (this);
1226 run_script_queued (cb, _("node-change command execution failed, continuing."));
1227 }
1228
1212 // } 1229 // }
1213 //else 1230 //else
1214 // slog (L_INFO, _("%s(%s): accepted packet from %s, not (yet) redirecting traffic."), 1231 // slog (L_INFO, _("%s(%s): accepted packet from %s, not (yet) redirecting traffic."),
1215 // conf->nodename, (const char *)si, (const char *)rsi); 1232 // conf->nodename, (const char *)si, (const char *)rsi);
1216 } 1233 }
1237 break; 1254 break;
1238 1255
1239 case vpn_packet::PT_CONNECT_REQ: 1256 case vpn_packet::PT_CONNECT_REQ:
1240 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) 1257 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx))
1241 { 1258 {
1242 connect_req_packet *p = (connect_req_packet *) pkt; 1259 connect_req_packet *p = (connect_req_packet *)pkt;
1243 1260
1244 if (p->id > 0 && p->id <= vpn->conns.size ()) 1261 if (p->id > 0 && p->id <= vpn->conns.size ())
1245 { 1262 {
1246 connection *c = vpn->conns[p->id - 1]; 1263 connection *c = vpn->conns[p->id - 1];
1247 conf->protocols = p->protocols; 1264 conf->protocols = p->protocols;
1248 1265
1249 slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]", 1266 slog (L_TRACE, "%s >> PT_CONNECT_REQ(%s) [%d]",
1250 conf->id, p->id, c->ictx && c->octx); 1267 conf->nodename, vpn->conns[p->id - 1]->conf->nodename, c->ictx && c->octx);
1251 1268
1252 if (c->ictx && c->octx) 1269 if (c->ictx && c->octx)
1253 { 1270 {
1254 // send connect_info packets to both sides, in case one is 1271 // send connect_info packets to both sides, in case one is
1255 // behind a nat firewall (or both ;) 1272 // behind a nat firewall (or both ;)
1278 1295
1279 c->conf->protocols = p->protocols; 1296 c->conf->protocols = p->protocols;
1280 protocol = best_protocol (c->conf->protocols & THISNODE->protocols & p->si.supported_protocols (c->conf)); 1297 protocol = best_protocol (c->conf->protocols & THISNODE->protocols & p->si.supported_protocols (c->conf));
1281 p->si.upgrade_protocol (protocol, c->conf); 1298 p->si.upgrade_protocol (protocol, c->conf);
1282 1299
1283 slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)", 1300 slog (L_TRACE, "%s >> PT_CONNECT_INFO(%s,%s) [%d]",
1301 conf->nodename, vpn->conns[p->id - 1]->conf->nodename,
1284 conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx); 1302 (const char *)p->si, !c->ictx && !c->octx);
1285 1303
1286 const sockinfo &dsi = forward_si (p->si); 1304 const sockinfo &dsi = forward_si (p->si);
1287 1305
1288 if (dsi.valid ()) 1306 if (dsi.valid ())
1289 c->send_auth_request (dsi, true); 1307 c->send_auth_request (dsi, true);
1303} 1321}
1304 1322
1305inline void 1323inline void
1306connection::keepalive_cb (ev::timer &w, int revents) 1324connection::keepalive_cb (ev::timer &w, int revents)
1307{ 1325{
1308 if (ev_now () >= last_activity + ::conf.keepalive + 30) 1326 if (ev_now () >= last_activity + ::conf.keepalive + 15)
1309 { 1327 {
1310 reset_connection (); 1328 reset_connection ();
1311 establish_connection (); 1329 establish_connection ();
1312 } 1330 }
1313 else if (ev_now () < last_activity + ::conf.keepalive) 1331 else if (ev_now () < last_activity + ::conf.keepalive)
1314 w.start (last_activity + ::conf.keepalive - ev::now ()); 1332 w.start (last_activity + ::conf.keepalive - ev::now ());
1315 else if (conf->connectmode != conf_node::C_ONDEMAND 1333 else if (conf->connectmode != conf_node::C_ONDEMAND
1316 || THISNODE->connectmode != conf_node::C_ONDEMAND) 1334 || THISNODE->connectmode != conf_node::C_ONDEMAND)
1317 { 1335 {
1318 send_ping (si); 1336 send_ping (si);
1319 w.start (5); 1337 w.start (3);
1320 } 1338 }
1321 else if (ev_now () < last_activity + ::conf.keepalive + 10) 1339 else if (ev_now () < last_activity + ::conf.keepalive + 10)
1322 // hold ondemand connections implicitly a few seconds longer 1340 // hold ondemand connections implicitly a few seconds longer
1323 // should delete octx, though, or something like that ;) 1341 // should delete octx, though, or something like that ;)
1324 w.start (last_activity + ::conf.keepalive + 10 - ev::now ()); 1342 w.start (last_activity + ::conf.keepalive + 10 - ev::now ());
1328 1346
1329void connection::send_connect_request (int id) 1347void connection::send_connect_request (int id)
1330{ 1348{
1331 connect_req_packet *p = new connect_req_packet (conf->id, id, conf->protocols); 1349 connect_req_packet *p = new connect_req_packet (conf->id, id, conf->protocols);
1332 1350
1333 slog (L_TRACE, ">>%d PT_CONNECT_REQ(%d)", conf->id, id); 1351 slog (L_TRACE, "%s << PT_CONNECT_REQ(%s)",
1352 conf->nodename, vpn->conns[id - 1]->conf->nodename);
1334 p->hmac_set (octx); 1353 p->hmac_set (octx);
1335 send_vpn_packet (p, si); 1354 send_vpn_packet (p, si);
1336 1355
1337 delete p; 1356 delete p;
1338} 1357}
1339 1358
1340void connection::script_init_env (const char *ext) 1359void connection::script_init_env (const char *ext)
1341{ 1360{
1342 char *env; 1361 char *env;
1343 asprintf (&env, "IFUPDATA%s=%s", ext, conf->if_up_data); putenv (env); 1362 asprintf (&env, "IFUPDATA%s=%s", ext, conf->if_up_data); putenv (env);
1344 asprintf (&env, "NODENAME%s=%s", ext, conf->nodename); putenv (env); 1363 asprintf (&env, "NODENAME%s=%s", ext, conf->nodename); putenv (env);
1345 asprintf (&env, "MAC%s=%02x:%02x:%02x:%02x:%02x:%02x", ext, 1364 asprintf (&env, "MAC%s=%02x:%02x:%02x:%02x:%02x:%02x", ext,
1346 0xfe, 0xfd, 0x80, 0x00, conf->id >> 8, 1365 0xfe, 0xfd, 0x80, 0x00, conf->id >> 8,
1347 conf->id & 0xff); putenv (env); 1366 conf->id & 0xff); putenv (env);
1348} 1367}
1349 1368
1350void connection::script_init_connect_env () 1369void connection::script_init_connect_env ()
1351{ 1370{
1352 vpn->script_init_env (); 1371 vpn->script_init_env ();
1353 1372
1354 char *env; 1373 char *env;
1355 asprintf (&env, "DESTID=%d", conf->id); putenv (env); 1374 asprintf (&env, "DESTID=%d", conf->id); putenv (env);
1375 asprintf (&env, "DESTSI=%s", (const char *)si); putenv (env);
1356 asprintf (&env, "DESTNODE=%s", conf->nodename); putenv (env); 1376 asprintf (&env, "DESTNODE=%s", conf->nodename); putenv (env);
1357 asprintf (&env, "DESTIP=%s", si.ntoa ()); putenv (env); 1377 asprintf (&env, "DESTIP=%s", si.ntoa ()); putenv (env);
1358 asprintf (&env, "DESTPORT=%d", ntohs (si.port)); putenv (env); 1378 asprintf (&env, "DESTPORT=%d", ntohs (si.port)); putenv (env);
1359} 1379}
1360 1380
1361inline const char * 1381inline const char *
1362connection::script_node_up () 1382connection::script_node_up ()
1363{ 1383{
1368 char *filename; 1388 char *filename;
1369 asprintf (&filename, 1389 asprintf (&filename,
1370 "%s/%s", 1390 "%s/%s",
1371 confbase, 1391 confbase,
1372 ::conf.script_node_up ? ::conf.script_node_up : "node-up"); 1392 ::conf.script_node_up ? ::conf.script_node_up : "node-up");
1393
1394 return filename;
1395}
1396
1397inline const char *
1398connection::script_node_change ()
1399{
1400 script_init_connect_env ();
1401
1402 putenv ((char *)"STATE=change");
1403
1404 char *filename;
1405 asprintf (&filename,
1406 "%s/%s",
1407 confbase,
1408 ::conf.script_node_change ? ::conf.script_node_change : "node-change");
1373 1409
1374 return filename; 1410 return filename;
1375} 1411}
1376 1412
1377inline const char * 1413inline const char *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines