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.107 by root, Fri Sep 20 11:57:03 2013 UTC vs.
Revision 1.111 by root, Thu Jan 16 07:53:44 2014 UTC

56#include "hkdf.h" 56#include "hkdf.h"
57 57
58#include "netcompat.h" 58#include "netcompat.h"
59 59
60#define MAGIC "gvpe\xbd\xc6\xdb\x82" // 8 bytes of magic 60#define MAGIC "gvpe\xbd\xc6\xdb\x82" // 8 bytes of magic
61#define MAGIC "HUHN\xbd\xc6\xdb\x82" // 8 bytes of magic//D
62 61
63#define ULTRA_FAST 1 62#define ULTRA_FAST 1
64#define HLOG 15 63#define HLOG 15
65#include "lzf/lzf.h" 64#include "lzf/lzf.h"
66#include "lzf/lzf_c.c" 65#include "lzf/lzf_c.c"
390bool 389bool
391hmac_packet::hmac_chk (crypto_ctx *ctx) 390hmac_packet::hmac_chk (crypto_ctx *ctx)
392{ 391{
393 unsigned char hmac_digest[EVP_MAX_MD_SIZE]; 392 unsigned char hmac_digest[EVP_MAX_MD_SIZE];
394 hmac_gen (ctx, hmac_digest); 393 hmac_gen (ctx, hmac_digest);
395 return !memcmp (hmac, hmac_digest, HMACLENGTH); 394 return slow_memeq (hmac, hmac_digest, HMACLENGTH);
396} 395}
397 396
398void 397void
399vpn_packet::set_hdr (ptype type_, unsigned int dst) 398vpn_packet::set_hdr (ptype type_, unsigned int dst)
400{ 399{
701 si = rsi; 700 si = rsi;
702 protocol = rsi.prot; 701 protocol = rsi.prot;
703 702
704 slog (L_INFO, _("%s(%s): connection established (%s), protocol version %d.%d."), 703 slog (L_INFO, _("%s(%s): connection established (%s), protocol version %d.%d."),
705 conf->nodename, (const char *)rsi, 704 conf->nodename, (const char *)rsi,
706 is_direct ? "direct" : "forwarded", 705 vpn->can_direct (THISNODE, conf) ? "direct" : "forwarded",
707 PROTOCOL_MAJOR, prot_minor); 706 PROTOCOL_MAJOR, prot_minor);
708 707
709 if (::conf.script_node_up) 708 if (::conf.script_node_up)
710 { 709 {
711 run_script_cb *cb = new run_script_cb; 710 run_script_cb *cb = new run_script_cb;
723 722
724 // make sure rekeying timeouts are slightly asymmetric 723 // make sure rekeying timeouts are slightly asymmetric
725 ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0); 724 ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0);
726 rekey.start (rekey_interval, rekey_interval); 725 rekey.start (rekey_interval, rekey_interval);
727 726
727 hmac_error = 0.;
728
728 keepalive.start (::conf.keepalive); 729 keepalive.start (::conf.keepalive);
729 730
730 // send queued packets 731 // send queued packets
731 if (ictx && octx)
732 {
733 while (tap_packet *p = (tap_packet *)data_queue.get ()) 732 while (tap_packet *p = (tap_packet *)data_queue.get ())
734 { 733 {
735 if (p->len) send_data_packet (p); 734 if (p->len) send_data_packet (p);
736 delete p; 735 delete p;
737 } 736 }
738 737
739 while (vpn_packet *p = (vpn_packet *)vpn_queue.get ()) 738 while (vpn_packet *p = (vpn_packet *)vpn_queue.get ())
740 { 739 {
741 if (p->len) send_vpn_packet (p, si, IPTOS_RELIABILITY); 740 if (p->len) send_vpn_packet (p, si, IPTOS_RELIABILITY);
742 delete p; 741 delete p;
743 }
744 } 742 }
745 743
746 vpn->connection_established (this); 744 vpn->connection_established (this);
747} 745}
748 746
756 slog (L_TRACE, _("%s: direct connection denied by config."), conf->nodename); 754 slog (L_TRACE, _("%s: direct connection denied by config."), conf->nodename);
757 protocol = 0; 755 protocol = 0;
758 } 756 }
759 757
760 si.set (conf, protocol); 758 si.set (conf, protocol);
761
762 is_direct = si.valid ();
763} 759}
764 760
765// ensure sockinfo is valid, forward if necessary 761// ensure sockinfo is valid, forward if necessary
766const sockinfo & 762const sockinfo &
767connection::forward_si (const sockinfo &si) const 763connection::forward_si (const sockinfo &si) const
786 782
787void 783void
788connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 784connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
789{ 785{
790 if (!vpn->send_vpn_packet (pkt, si, tos)) 786 if (!vpn->send_vpn_packet (pkt, si, tos))
791 reset_connection (); 787 reset_connection ("packet send error");
792} 788}
793 789
794void 790void
795connection::send_ping (const sockinfo &si, u8 pong) 791connection::send_ping (const sockinfo &si, u8 pong)
796{ 792{
872 { 868 {
873 // a bit hacky, if ondemand, and packets are no longer queued, then reset the connection 869 // a bit hacky, if ondemand, and packets are no longer queued, then reset the connection
874 // and stop trying. should probably be handled by a per-connection expire handler. 870 // and stop trying. should probably be handled by a per-connection expire handler.
875 if (connectmode == conf_node::C_ONDEMAND && vpn_queue.empty () && data_queue.empty ()) 871 if (connectmode == conf_node::C_ONDEMAND && vpn_queue.empty () && data_queue.empty ())
876 { 872 {
877 reset_connection (); 873 reset_connection ("no demand");
878 return; 874 return;
879 } 875 }
880 876
881 last_establish_attempt = ev_now (); 877 last_establish_attempt = ev_now ();
882 878
884 ? (retry_cnt & 3) + 1 880 ? (retry_cnt & 3) + 1
885 : 1 << (retry_cnt >> 2)); 881 : 1 << (retry_cnt >> 2));
886 882
887 reset_si (); 883 reset_si ();
888 884
889 bool slow = si.prot & PROT_SLOW; 885 bool slow = (si.prot & PROT_SLOW) || (conf->low_power || THISNODE->low_power);
890 886
891 if (si.prot && !si.host && vpn->can_direct (THISNODE, conf)) 887 if (si.prot && !si.host && vpn->can_direct (THISNODE, conf))
892 { 888 {
893 /*TODO*/ /* start the timer so we don't recurse endlessly */ 889 /*TODO*/ /* start the timer so we don't recurse endlessly */
894 w.start (1); 890 w.start (1);
904 900
905 slow = slow || (dsi.prot & PROT_SLOW); 901 slow = slow || (dsi.prot & PROT_SLOW);
906 902
907 if (dsi.valid () && auth_rate_limiter.can (dsi)) 903 if (dsi.valid () && auth_rate_limiter.can (dsi))
908 { 904 {
909 if (retry_cnt < 4) 905 // use ping after the first few retries
906 // TODO: on rekeys, the other node might not interpret ping correctly,
907 // TODO: as it will still have a valid connection
908 if (retry_cnt < 4 && (!conf->low_power || THISNODE->low_power))
910 send_auth_request (dsi, true); 909 send_auth_request (dsi, true);
911 else 910 else
912 send_ping (dsi, 0); 911 send_ping (dsi, 0);
913 } 912 }
914 } 913 }
915 914
916 retry_int *= slow ? 8. : 0.9; 915 retry_int *= slow ? 4. : 0.9;
917 916
918 if (retry_int < conf->max_retry) 917 if (retry_int < conf->max_retry)
919 retry_cnt++; 918 retry_cnt++;
920 else 919 else
921 retry_int = conf->max_retry; 920 retry_int = conf->max_retry;
923 w.start (retry_int); 922 w.start (retry_int);
924 } 923 }
925} 924}
926 925
927void 926void
928connection::reset_connection () 927connection::reset_connection (const char *reason)
929{ 928{
930 if (ictx && octx) 929 if (ictx && octx)
931 { 930 {
932 slog (L_INFO, _("%s(%s): connection lost"), 931 slog (L_INFO, _("%s(%s): connection lost (%s)"),
933 conf->nodename, (const char *)si); 932 conf->nodename, (const char *)si, reason);
934 933
935 if (::conf.script_node_down) 934 if (::conf.script_node_down)
936 { 935 {
937 run_script_cb *cb = new run_script_cb; 936 run_script_cb *cb = new run_script_cb;
938 cb->set<connection, &connection::script_node_down> (this); 937 cb->set<connection, &connection::script_node_down> (this);
962connection::shutdown () 961connection::shutdown ()
963{ 962{
964 if (ictx && octx) 963 if (ictx && octx)
965 send_reset (si); 964 send_reset (si);
966 965
967 reset_connection (); 966 reset_connection ("shutdown");
968} 967}
969 968
970// poor-man's rekeying 969// poor-man's rekeying
971inline void 970inline void
972connection::rekey_cb (ev::timer &w, int revents) 971connection::rekey_cb (ev::timer &w, int revents)
973{ 972{
974 reset_connection (); 973 reset_connection ("rekeying");
975 establish_connection (); 974 establish_connection ();
976} 975}
977 976
978void 977void
979connection::send_data_packet (tap_packet *pkt) 978connection::send_data_packet (tap_packet *pkt)
996 995
997void 996void
998connection::post_inject_queue () 997connection::post_inject_queue ()
999{ 998{
1000 // force a connection every now and when when packets are sent (max 1/s) 999 // force a connection every now and when when packets are sent (max 1/s)
1001 if (ev_now () - last_establish_attempt >= 0.95) // arbitrary 1000 if (ev_now () - last_establish_attempt >= (conf->low_power || THISNODE->low_power ? 2.95 : 0.95)) // arbitrary
1002 establish_connection.stop (); 1001 establish_connection.stop ();
1003 1002
1004 establish_connection (); 1003 establish_connection ();
1005} 1004}
1006 1005
1066 // about our desire for communication. 1065 // about our desire for communication.
1067 establish_connection (); 1066 establish_connection ();
1068 break; 1067 break;
1069 1068
1070 case vpn_packet::PT_RESET: 1069 case vpn_packet::PT_RESET:
1070 slog (L_TRACE, "%s >> PT_RESET", conf->nodename);
1071
1072 if (ictx && octx)
1071 { 1073 {
1072 reset_connection (); 1074 reset_connection ("remote reset");
1073 1075
1074 config_packet *p = (config_packet *) pkt; 1076 config_packet *p = (config_packet *) pkt;
1075 1077
1076 if (p->chk_config (conf, rsi) && connectmode == conf_node::C_ALWAYS) 1078 if (p->chk_config (conf, rsi) && connectmode == conf_node::C_ALWAYS)
1077 establish_connection (); 1079 establish_connection ();
1078 } 1080 }
1081
1079 break; 1082 break;
1080 1083
1081 case vpn_packet::PT_AUTH_REQ: 1084 case vpn_packet::PT_AUTH_REQ:
1082 if (auth_rate_limiter.can (rsi)) 1085 if (auth_rate_limiter.can (rsi))
1083 { 1086 {
1098 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."), 1101 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
1099 conf->nodename, (const char *)rsi, 1102 conf->nodename, (const char *)rsi,
1100 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 1103 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
1101 1104
1102 if (p->initiate) 1105 if (p->initiate)
1106 {
1103 send_auth_request (rsi, false); 1107 send_auth_request (rsi, false);
1108
1109 if (ictx && octx)
1110 reset_connection ("reconnect");
1111 }
1104 1112
1105 auth_data auth; 1113 auth_data auth;
1106 1114
1107 if (!auth_decrypt (::conf.rsa_key, p->encr, auth)) 1115 if (!auth_decrypt (::conf.rsa_key, p->encr, auth))
1108 { 1116 {
1109 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"), 1117 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"),
1110 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0)); 1118 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0));
1111 } 1119 }
1112 else 1120 else
1113 { 1121 {
1114 bool chg = !have_rcv_auth || memcmp (&rcv_auth, &auth, sizeof auth); 1122 bool chg = !have_rcv_auth || !slow_memeq (&rcv_auth, &auth, sizeof auth);
1115 1123
1116 rcv_auth = auth; 1124 rcv_auth = auth;
1117 have_rcv_auth = true; 1125 have_rcv_auth = true;
1118 1126
1119 send_auth_response (rsi); 1127 send_auth_response (rsi);
1142 slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename); 1150 slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename);
1143 1151
1144 auth_mac local_mac; 1152 auth_mac local_mac;
1145 auth_hash (snd_auth, p->response.ecdh, local_mac); 1153 auth_hash (snd_auth, p->response.ecdh, local_mac);
1146 1154
1147 if (memcmp (&p->response.mac, local_mac, sizeof local_mac)) 1155 if (!slow_memeq (&p->response.mac, local_mac, sizeof local_mac))
1148 { 1156 {
1149 slog (L_ERR, _("%s(%s): unrequested or outdated auth response, ignoring."), 1157 slog (L_ERR, _("%s(%s): unrequested or outdated auth response, ignoring."),
1150 conf->nodename, (const char *)rsi); 1158 conf->nodename, (const char *)rsi);
1151 } 1159 }
1152 else if (!have_snd_auth) 1160 else if (!have_snd_auth)
1170 if (ictx && octx) 1178 if (ictx && octx)
1171 { 1179 {
1172 vpndata_packet *p = (vpndata_packet *)pkt; 1180 vpndata_packet *p = (vpndata_packet *)pkt;
1173 1181
1174 if (!p->hmac_chk (ictx)) 1182 if (!p->hmac_chk (ictx))
1183 {
1184 // rekeying often creates temporary hmac auth floods
1185 // we assume they don't take longer than a few seconds normally,
1186 // and suppress messages and resets during that time.
1187 //TODO: should be done per source address
1188 if (!hmac_error)
1189 {
1190 hmac_error = ev_now () + 3;
1191 break;
1192 }
1193 else if (hmac_error >= ev_now ())
1194 break; // silently suppress
1195 else
1196 {
1175 slog (L_ERR, _("%s(%s): hmac authentication error, received invalid packet\n" 1197 slog (L_ERR, _("%s(%s): hmac authentication error, received invalid packet\n"
1176 "could be an attack, or just corruption or a synchronization error."), 1198 "could be an attack, or just corruption or a synchronization error."),
1177 conf->nodename, (const char *)rsi); 1199 conf->nodename, (const char *)rsi);
1200 // reset
1201 }
1202 }
1178 else 1203 else
1179 { 1204 {
1180 u32 seqno; 1205 u32 seqno;
1181 tap_packet *d = p->unpack (this, seqno); 1206 tap_packet *d = p->unpack (this, seqno);
1182 int seqclass = iseqno.seqno_classify (seqno); 1207 int seqclass = iseqno.seqno_classify (seqno);
1208
1209 hmac_error = 0;
1183 1210
1184 if (seqclass == 0) // ok 1211 if (seqclass == 0) // ok
1185 { 1212 {
1186 vpn->tap->send (d); 1213 vpn->tap->send (d);
1187 1214
1314 1341
1315 if (when >= 0) 1342 if (when >= 0)
1316 w.start (when); 1343 w.start (when);
1317 else if (when < -15) 1344 else if (when < -15)
1318 { 1345 {
1319 reset_connection (); 1346 reset_connection ("keepalive overdue");
1320 establish_connection (); 1347 establish_connection ();
1321 } 1348 }
1322 else if (conf->connectmode != conf_node::C_ONDEMAND 1349 else if (conf->connectmode != conf_node::C_ONDEMAND
1323 || THISNODE->connectmode != conf_node::C_ONDEMAND) 1350 || THISNODE->connectmode != conf_node::C_ONDEMAND)
1324 { 1351 {
1328 else if (when >= -10) 1355 else if (when >= -10)
1329 // hold ondemand connections implicitly a few seconds longer 1356 // hold ondemand connections implicitly a few seconds longer
1330 // should delete octx, though, or something like that ;) 1357 // should delete octx, though, or something like that ;)
1331 w.start (when + 10); 1358 w.start (when + 10);
1332 else 1359 else
1333 reset_connection (); 1360 reset_connection ("keepalive timeout");
1334} 1361}
1335 1362
1336void 1363void
1337connection::send_connect_request (int id) 1364connection::send_connect_request (int id)
1338{ 1365{
1438 1465
1439 // queue a dummy packet to force an initial connection attempt 1466 // queue a dummy packet to force an initial connection attempt
1440 if (connectmode != conf_node::C_ALWAYS && connectmode != conf_node::C_DISABLED) 1467 if (connectmode != conf_node::C_ALWAYS && connectmode != conf_node::C_DISABLED)
1441 vpn_queue.put (new net_packet); 1468 vpn_queue.put (new net_packet);
1442 1469
1443 reset_connection (); 1470 reset_connection ("startup");
1444} 1471}
1445 1472
1446connection::~connection () 1473connection::~connection ()
1447{ 1474{
1448 shutdown (); 1475 shutdown ();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines