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.72 by pcg, Fri Aug 8 16:48:00 2008 UTC vs.
Revision 1.73 by pcg, Sun Aug 10 01:34:36 2008 UTC

696 { 696 {
697 if (p->len) send_vpn_packet (p, si, IPTOS_RELIABILITY); 697 if (p->len) send_vpn_packet (p, si, IPTOS_RELIABILITY);
698 delete p; 698 delete p;
699 } 699 }
700 } 700 }
701
702 vpn->connection_established (this);
701 } 703 }
702 else 704 else
703 { 705 {
704 retry_cnt = 0; 706 retry_cnt = 0;
705 establish_connection.start (5); 707 establish_connection.start (5);
709} 711}
710 712
711void 713void
712connection::reset_si () 714connection::reset_si ()
713{ 715{
716 if (vpn->can_direct (THISNODE, conf))
714 protocol = best_protocol (THISNODE->protocols & conf->protocols); 717 protocol = best_protocol (THISNODE->protocols & conf->connectable_protocols ());
715 718 else
716 // mask out endpoints we can't connect to
717 if (!conf->udp_port) protocol &= ~PROT_UDPv4;
718 if (!conf->tcp_port) protocol &= ~PROT_TCPv4;
719 if (!conf->dns_port) protocol &= ~PROT_DNSv4;
720
721 if (protocol
722 && (!conf->can_direct (THISNODE)
723 || !THISNODE->can_direct (conf)))
724 { 719 {
725 slog (L_DEBUG, _("%s: direct connection denied"), conf->nodename); 720 slog (L_TRACE, _("%s: direct connection denied by config."), conf->nodename);
726 protocol = 0; 721 protocol = 0;
727 } 722 }
728 723
729 si.set (conf, protocol); 724 si.set (conf, protocol);
725
726 is_direct = si.valid ();
730} 727}
731 728
732// ensure sockinfo is valid, forward if necessary 729// ensure sockinfo is valid, forward if necessary
733const sockinfo & 730const sockinfo &
734connection::forward_si (const sockinfo &si) const 731connection::forward_si (const sockinfo &si) const
735{ 732{
736 if (!si.valid ()) 733 if (!si.valid ())
737 { 734 {
738 connection *r = vpn->find_router (); 735 connection *r = vpn->find_router_for (this);
739 736
740 if (r) 737 if (r)
741 { 738 {
742 slog (L_DEBUG, _("%s: no common protocol, trying indirectly through %s (%s)"), 739 slog (L_DEBUG, _("%s: no common protocol, trying to route through %s."),
743 conf->nodename, r->conf->nodename, (const char *)r->si); 740 conf->nodename, r->conf->nodename);
744 return r->si; 741 return r->si;
745 } 742 }
746 else 743 else
747 slog (L_DEBUG, _("%s: node unreachable, no common protocol, no router"), 744 slog (L_DEBUG, _("%s: node unreachable, no common protocol or no router available."),
748 conf->nodename); 745 conf->nodename);
749 } 746 }
750 747
751 return si; 748 return si;
752} 749}
762connection::send_ping (const sockinfo &si, u8 pong) 759connection::send_ping (const sockinfo &si, u8 pong)
763{ 760{
764 ping_packet *pkt = new ping_packet; 761 ping_packet *pkt = new ping_packet;
765 762
766 pkt->setup (conf->id, pong ? ping_packet::PT_PONG : ping_packet::PT_PING); 763 pkt->setup (conf->id, pong ? ping_packet::PT_PONG : ping_packet::PT_PING);
764
765 slog (L_TRACE, ">>%d %s [%s]", conf->id, pong ? "PT_PONG" : "PT_PING", (const char *)si);
766
767 send_vpn_packet (pkt, si, IPTOS_LOWDELAY); 767 send_vpn_packet (pkt, si, IPTOS_LOWDELAY);
768 768
769 delete pkt; 769 delete pkt;
770} 770}
771 771
856 856
857 reset_si (); 857 reset_si ();
858 858
859 bool slow = si.prot & PROT_SLOW; 859 bool slow = si.prot & PROT_SLOW;
860 860
861 if (si.prot && !si.host) 861 if (si.prot && !si.host && vpn->can_direct (THISNODE, conf))
862 { 862 {
863 slog (L_TRACE, _("%s: connection request (indirect)"), conf->nodename);
864 /*TODO*/ /* start the timer so we don't recurse endlessly */ 863 /*TODO*/ /* start the timer so we don't recurse endlessly */
865 w.start (1); 864 w.start (1);
866 vpn->send_connect_request (conf->id); 865 vpn->send_connect_request (conf->id);
867 } 866 }
868 else 867 else
869 { 868 {
870 slog (L_TRACE, _("%s: connection request (direct)"), conf->nodename, !!ictx, !!octx); 869 if (si.valid ())
870 slog (L_DEBUG, _("%s: sending direct connection request to %s."),
871 conf->nodename, (const char *)si);
871 872
872 const sockinfo &dsi = forward_si (si); 873 const sockinfo &dsi = forward_si (si);
873 874
874 slow = slow || (dsi.prot & PROT_SLOW); 875 slow = slow || (dsi.prot & PROT_SLOW);
875 876
915 dnsv4_reset_connection (); 916 dnsv4_reset_connection ();
916#endif 917#endif
917 918
918 si.host = 0; 919 si.host = 0;
919 920
920 last_activity = 0; 921 last_activity = 0.;
922 //last_si_change = 0.;
921 retry_cnt = 0; 923 retry_cnt = 0;
922 924
923 rekey.stop (); 925 rekey.stop ();
924 keepalive.stop (); 926 keepalive.stop ();
925 establish_connection.stop (); 927 establish_connection.stop ();
932 send_reset (si); 934 send_reset (si);
933 935
934 reset_connection (); 936 reset_connection ();
935} 937}
936 938
939// poor-man's rekeying
937inline void 940inline void
938connection::rekey_cb (ev::timer &w, int revents) 941connection::rekey_cb (ev::timer &w, int revents)
939{ 942{
940 reset_connection (); 943 reset_connection ();
941 establish_connection (); 944 establish_connection ();
996void 999void
997connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 1000connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
998{ 1001{
999 last_activity = ev_now (); 1002 last_activity = ev_now ();
1000 1003
1001 slog (L_NOISE, "<<%d received packet type %d from %d to %d", 1004 slog (L_NOISE, "<<%d received packet type %d from %d to %d.",
1002 conf->id, pkt->typ (), pkt->src (), pkt->dst ()); 1005 conf->id, pkt->typ (), pkt->src (), pkt->dst ());
1003 1006
1004 if (connectmode == conf_node::C_DISABLED) 1007 if (connectmode == conf_node::C_DISABLED)
1005 return; 1008 return;
1006 1009
1014 { 1017 {
1015 if (auth_rate_limiter.can (rsi)) 1018 if (auth_rate_limiter.can (rsi))
1016 send_auth_request (rsi, true); 1019 send_auth_request (rsi, true);
1017 } 1020 }
1018 else 1021 else
1022 // we would love to change thre socket address here, but ping's aren't
1023 // authenticated, so we best ignore it.
1019 send_ping (rsi, 1); // pong 1024 send_ping (rsi, 1); // pong
1020 1025
1021 break; 1026 break;
1022 1027
1023 case vpn_packet::PT_PONG: 1028 case vpn_packet::PT_PONG:
1029 1034
1030 config_packet *p = (config_packet *) pkt; 1035 config_packet *p = (config_packet *) pkt;
1031 1036
1032 if (!p->chk_config ()) 1037 if (!p->chk_config ())
1033 { 1038 {
1034 slog (L_WARN, _("%s(%s): protocol mismatch, disabling node"), 1039 slog (L_WARN, _("%s(%s): protocol mismatch, disabling node."),
1035 conf->nodename, (const char *)rsi); 1040 conf->nodename, (const char *)rsi);
1036 connectmode = conf_node::C_DISABLED; 1041 connectmode = conf_node::C_DISABLED;
1037 } 1042 }
1038 else if (connectmode == conf_node::C_ALWAYS) 1043 else if (connectmode == conf_node::C_ALWAYS)
1039 establish_connection (); 1044 establish_connection ();
1081 1086
1082 break; 1087 break;
1083 } 1088 }
1084 } 1089 }
1085 else 1090 else
1086 slog (L_WARN, _("%s(%s): protocol mismatch"), 1091 slog (L_WARN, _("%s(%s): protocol mismatch."),
1087 conf->nodename, (const char *)rsi); 1092 conf->nodename, (const char *)rsi);
1088 1093
1089 send_reset (rsi); 1094 send_reset (rsi);
1090 } 1095 }
1091 1096
1106 1111
1107 rsachallenge chg; 1112 rsachallenge chg;
1108 1113
1109 if (!rsa_cache.find (p->id, chg)) 1114 if (!rsa_cache.find (p->id, chg))
1110 { 1115 {
1111 slog (L_ERR, _("%s(%s): unrequested auth response ignored"), 1116 slog (L_ERR, _("%s(%s): unrequested auth response, ignoring."),
1112 conf->nodename, (const char *)rsi); 1117 conf->nodename, (const char *)rsi);
1113 break; 1118 break;
1114 } 1119 }
1115 else 1120 else
1116 { 1121 {
1117 crypto_ctx *cctx = new crypto_ctx (chg, 0); 1122 crypto_ctx *cctx = new crypto_ctx (chg, 0);
1118 1123
1119 if (!p->hmac_chk (cctx)) 1124 if (!p->hmac_chk (cctx))
1120 { 1125 {
1121 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n" 1126 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n"
1122 "could be an attack, or just corruption or a synchronization error"), 1127 "could be an attack, or just corruption or a synchronization error."),
1123 conf->nodename, (const char *)rsi); 1128 conf->nodename, (const char *)rsi);
1124 break; 1129 break;
1125 } 1130 }
1126 else 1131 else
1127 { 1132 {
1138 iseqno.reset (ntohl (*(u32 *)&chg[CHG_SEQNO]) & 0x7fffffff); // at least 2**31 sequence numbers are valid 1143 iseqno.reset (ntohl (*(u32 *)&chg[CHG_SEQNO]) & 0x7fffffff); // at least 2**31 sequence numbers are valid
1139 1144
1140 si = rsi; 1145 si = rsi;
1141 protocol = rsi.prot; 1146 protocol = rsi.prot;
1142 1147
1143 connection_established ();
1144
1145 slog (L_INFO, _("%s(%s): connection established, protocol version %d.%d"), 1148 slog (L_INFO, _("%s(%s): connection established, protocol version %d.%d."),
1146 conf->nodename, (const char *)rsi, 1149 conf->nodename, (const char *)rsi,
1147 p->prot_major, p->prot_minor); 1150 p->prot_major, p->prot_minor);
1151
1152 connection_established ();
1148 1153
1149 if (::conf.script_node_up) 1154 if (::conf.script_node_up)
1150 { 1155 {
1151 run_script_cb *cb = new run_script_cb; 1156 run_script_cb *cb = new run_script_cb;
1152 cb->set<connection, &connection::script_node_up> (this); 1157 cb->set<connection, &connection::script_node_up> (this);
1154 } 1159 }
1155 1160
1156 break; 1161 break;
1157 } 1162 }
1158 else 1163 else
1159 slog (L_ERR, _("%s(%s): sent and received challenge do not match"), 1164 slog (L_ERR, _("%s(%s): sent and received challenge do not match."),
1160 conf->nodename, (const char *)rsi); 1165 conf->nodename, (const char *)rsi);
1161 } 1166 }
1162 1167
1163 delete cctx; 1168 delete cctx;
1164 } 1169 }
1180 { 1185 {
1181 vpndata_packet *p = (vpndata_packet *)pkt; 1186 vpndata_packet *p = (vpndata_packet *)pkt;
1182 1187
1183 if (!p->hmac_chk (ictx)) 1188 if (!p->hmac_chk (ictx))
1184 slog (L_ERR, _("%s(%s): hmac authentication error, received invalid packet\n" 1189 slog (L_ERR, _("%s(%s): hmac authentication error, received invalid packet\n"
1185 "could be an attack, or just corruption or a synchronization error"), 1190 "could be an attack, or just corruption or a synchronization error."),
1186 conf->nodename, (const char *)rsi); 1191 conf->nodename, (const char *)rsi);
1187 else 1192 else
1188 { 1193 {
1189 u32 seqno; 1194 u32 seqno;
1190 tap_packet *d = p->unpack (this, seqno); 1195 tap_packet *d = p->unpack (this, seqno);
1196 int seqclass = iseqno.seqno_classify (seqno);
1191 1197
1192 if (iseqno.recv_ok (seqno)) 1198 if (seqclass == 0) // ok
1193 { 1199 {
1194 vpn->tap->send (d); 1200 vpn->tap->send (d);
1195 1201
1196 if (si != rsi) 1202 if (si != rsi)
1197 { 1203 {
1198 // fast re-sync on source address changes, useful especially for tcp/ip 1204 // fast re-sync on source address changes, useful especially for tcp/ip
1205 //if (last_si_change < ev_now () + 5.)
1206 // {
1199 si = rsi; 1207 si = rsi;
1200 1208
1201 slog (L_INFO, _("%s(%s): socket address changed to %s"), 1209 slog (L_INFO, _("%s(%s): socket address changed to %s."),
1202 conf->nodename, (const char *)si, (const char *)rsi); 1210 conf->nodename, (const char *)si, (const char *)rsi);
1211 // }
1212 //else
1213 // slog (L_INFO, _("%s(%s): accepted packet from %s, not (yet) redirecting traffic."),
1214 // conf->nodename, (const char *)si, (const char *)rsi);
1203 } 1215 }
1216 }
1217 else if (seqclass == 1) // silently ignore
1218 slog (L_ERR, _("received duplicate packet (received %08lx, expected %08lx)\n"
1219 "possible replay attack, or just packet duplication, ignoring."), seqno, iseqno.seq + 1);
1220 else if (seqclass == 2) // reset
1221 {
1222 slog (L_ERR, _("received duplicate or out-of-sync packet (received %08lx, expected %08lx)\n"
1223 "possible replay attack, or just massive packet loss, resetting connection."), seqno, iseqno.seq + 1);
1224 send_reset (rsi);
1204 } 1225 }
1205 1226
1206 delete d; 1227 delete d;
1207 break; 1228 break;
1208 } 1229 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines