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.3 by pcg, Wed Apr 2 05:15:00 2003 UTC vs.
Revision 1.9 by pcg, Sun Apr 6 04:31:51 2003 UTC

85 rsachallenge chg; 85 rsachallenge chg;
86}; 86};
87 87
88struct rsa_cache : list<rsa_entry> 88struct rsa_cache : list<rsa_entry>
89{ 89{
90 void cleaner_cb (tstamp &ts); time_watcher cleaner; 90 void cleaner_cb (time_watcher &w); time_watcher cleaner;
91 91
92 bool find (const rsaid &id, rsachallenge &chg) 92 bool find (const rsaid &id, rsachallenge &chg)
93 { 93 {
94 for (iterator i = begin (); i != end (); ++i) 94 for (iterator i = begin (); i != end (); ++i)
95 { 95 {
129 : cleaner (this, &rsa_cache::cleaner_cb) 129 : cleaner (this, &rsa_cache::cleaner_cb)
130 { } 130 { }
131 131
132} rsa_cache; 132} rsa_cache;
133 133
134void rsa_cache::cleaner_cb (tstamp &ts) 134void rsa_cache::cleaner_cb (time_watcher &w)
135{ 135{
136 if (empty ()) 136 if (empty ())
137 ts = TSTAMP_CANCEL; 137 w.at = TSTAMP_CANCEL;
138 else 138 else
139 { 139 {
140 ts = NOW + RSA_TTL; 140 w.at = NOW + RSA_TTL;
141 141
142 for (iterator i = begin (); i != end (); ) 142 for (iterator i = begin (); i != end (); )
143 if (i->expire <= NOW) 143 if (i->expire <= NOW)
144 i = erase (i); 144 i = erase (i);
145 else 145 else
197// only do action once every x seconds per host whole allowing bursts. 197// only do action once every x seconds per host whole allowing bursts.
198// this implementation ("splay list" ;) is inefficient, 198// this implementation ("splay list" ;) is inefficient,
199// but low on resources. 199// but low on resources.
200struct net_rate_limiter : list<net_rateinfo> 200struct net_rate_limiter : list<net_rateinfo>
201{ 201{
202 static const double ALPHA = 1. - 1. / 90.; // allow bursts 202 static const double ALPHA = 1. - 1. / 180.; // allow bursts
203 static const double CUTOFF = 20.; // one event every CUTOFF seconds 203 static const double CUTOFF = 10.; // one event every CUTOFF seconds
204 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time 204 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time
205 205
206 bool can (const sockinfo &si) { return can((u32)si.host); } 206 bool can (const sockinfo &si) { return can((u32)si.host); }
207 bool can (u32 host); 207 bool can (u32 host);
208}; 208};
209 209
285 hmac_gen (ctx); 285 hmac_gen (ctx);
286 286
287 return !memcmp (hmac, hmac_digest, HMACLENGTH); 287 return !memcmp (hmac, hmac_digest, HMACLENGTH);
288} 288}
289 289
290void vpn_packet::set_hdr (ptype type, unsigned int dst) 290void vpn_packet::set_hdr (ptype type_, unsigned int dst)
291{ 291{
292 this->type = type; 292 type = type_;
293 293
294 int src = THISNODE->id; 294 int src = THISNODE->id;
295 295
296 src1 = src; 296 src1 = src;
297 srcdst = ((src >> 8) << 4) | (dst >> 8); 297 srcdst = ((src >> 8) << 4) | (dst >> 8);
546}; 546};
547 547
548///////////////////////////////////////////////////////////////////////////// 548/////////////////////////////////////////////////////////////////////////////
549 549
550void 550void
551connection::reset_dstaddr () 551connection::reset_si ()
552{ 552{
553 si.set (conf);
554}
555
556void
557connection::send_ping (const sockinfo &si, u8 pong)
558{
559 ping_packet *pkt = new ping_packet;
560
561 pkt->setup (conf->id, pong ? ping_packet::PT_PONG : ping_packet::PT_PING);
562 send_vpn_packet (pkt, si, IPTOS_LOWDELAY);
563
564 delete pkt;
565}
566
567void
568connection::send_reset (const sockinfo &si)
569{
570 if (reset_rate_limiter.can (si) && connectmode != conf_node::C_DISABLED)
571 {
572 config_packet *pkt = new config_packet;
573
574 pkt->setup (vpn_packet::PT_RESET, conf->id);
575 send_vpn_packet (pkt, si, IPTOS_MINCOST);
576
577 delete pkt;
578 }
579}
580
581void
582connection::send_auth_request (const sockinfo &si, bool initiate)
583{
584 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols);
585
586 protocol = best_protocol (THISNODE->protocols & conf->protocols); 553 protocol = best_protocol (THISNODE->protocols & conf->protocols);
587 554
588 // mask out protocols we cannot establish 555 // mask out protocols we cannot establish
589 if (!conf->udp_port) protocol &= ~PROT_UDPv4; 556 if (!conf->udp_port) protocol &= ~PROT_UDPv4;
590 if (!conf->tcp_port) protocol &= ~PROT_TCPv4; 557 if (!conf->tcp_port) protocol &= ~PROT_TCPv4;
591 558
592 if (protocol) 559 si.set (conf, protocol);
560}
561
562// ensure sockinfo is valid, forward if necessary
563const sockinfo &
564connection::forward_si (const sockinfo &si) const
565{
566 if (!si.valid ())
567 {
568 connection *r = vpn->find_router ();
569
570 if (r)
571 {
572 slog (L_DEBUG, _("%s: no common protocol, trying indirectly through %s"),
573 conf->nodename, r->conf->nodename);
574 return r->si;
575 }
576 else
577 slog (L_DEBUG, _("%s: node unreachable, no common protocol"),
578 conf->nodename);
593 { 579 }
594 rsachallenge chg;
595 580
596 rsa_cache.gen (pkt->id, chg); 581 return si;
582}
597 583
598 if (0 > RSA_public_encrypt (sizeof chg, 584void
599 (unsigned char *)&chg, (unsigned char *)&pkt->encr, 585connection::send_ping (const sockinfo &si, u8 pong)
600 conf->rsa_key, RSA_PKCS1_OAEP_PADDING)) 586{
601 fatal ("RSA_public_encrypt error"); 587 ping_packet *pkt = new ping_packet;
602 588
603 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si); 589 pkt->setup (conf->id, pong ? ping_packet::PT_PONG : ping_packet::PT_PING);
590 vpn->send_vpn_packet (pkt, si, IPTOS_LOWDELAY);
604 591
605 send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly 592 delete pkt;
593}
594
595void
596connection::send_reset (const sockinfo &si)
597{
598 if (reset_rate_limiter.can (si) && connectmode != conf_node::C_DISABLED)
599 {
600 config_packet *pkt = new config_packet;
601
602 pkt->setup (vpn_packet::PT_RESET, conf->id);
603 vpn->send_vpn_packet (pkt, si, IPTOS_MINCOST);
606 604
607 delete pkt; 605 delete pkt;
608 } 606 }
609 else 607}
610 ; // silently fail 608
609void
610connection::send_auth_request (const sockinfo &si, bool initiate)
611{
612 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols);
613
614 rsachallenge chg;
615
616 rsa_cache.gen (pkt->id, chg);
617
618 if (0 > RSA_public_encrypt (sizeof chg,
619 (unsigned char *)&chg, (unsigned char *)&pkt->encr,
620 conf->rsa_key, RSA_PKCS1_OAEP_PADDING))
621 fatal ("RSA_public_encrypt error");
622
623 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si);
624
625 vpn->send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly
626
627 delete pkt;
611} 628}
612 629
613void 630void
614connection::send_auth_response (const sockinfo &si, const rsaid &id, const rsachallenge &chg) 631connection::send_auth_response (const sockinfo &si, const rsaid &id, const rsachallenge &chg)
615{ 632{
621 638
622 pkt->hmac_set (octx); 639 pkt->hmac_set (octx);
623 640
624 slog (L_TRACE, ">>%d PT_AUTH_RES [%s]", conf->id, (const char *)si); 641 slog (L_TRACE, ">>%d PT_AUTH_RES [%s]", conf->id, (const char *)si);
625 642
626 send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly 643 vpn->send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly
627 644
628 delete pkt; 645 delete pkt;
629} 646}
630 647
631void 648void
635 conf->id, rid, (const char *)rsi); 652 conf->id, rid, (const char *)rsi);
636 653
637 connect_info_packet *r = new connect_info_packet (conf->id, rid, rsi, rprotocols); 654 connect_info_packet *r = new connect_info_packet (conf->id, rid, rsi, rprotocols);
638 655
639 r->hmac_set (octx); 656 r->hmac_set (octx);
640 send_vpn_packet (r, si); 657 vpn->send_vpn_packet (r, si);
641 658
642 delete r; 659 delete r;
643} 660}
644 661
645void 662void
646connection::establish_connection_cb (tstamp &ts) 663connection::establish_connection_cb (time_watcher &w)
647{ 664{
648 if (ictx || conf == THISNODE 665 if (ictx || conf == THISNODE
649 || connectmode == conf_node::C_NEVER 666 || connectmode == conf_node::C_NEVER
650 || connectmode == conf_node::C_DISABLED) 667 || connectmode == conf_node::C_DISABLED)
651 ts = TSTAMP_CANCEL; 668 w.at = TSTAMP_CANCEL;
652 else if (ts <= NOW) 669 else if (w.at <= NOW)
653 { 670 {
654 double retry_int = double (retry_cnt & 3 ? (retry_cnt & 3) : 1 << (retry_cnt >> 2)) * 0.6; 671 double retry_int = double (retry_cnt & 3 ? (retry_cnt & 3) : 1 << (retry_cnt >> 2)) * 0.6;
655 672
656 if (retry_int < 3600 * 8) 673 if (retry_int < 3600 * 8)
657 retry_cnt++; 674 retry_cnt++;
658 675
659 ts = NOW + retry_int; 676 w.at = NOW + retry_int;
660 677
661 if (conf->hostname) 678 reset_si ();
679
680 if (si.prot && !si.host)
681 vpn->connect_request (conf->id);
682 else
662 { 683 {
663 reset_dstaddr (); 684 const sockinfo &dsi = forward_si (si);
685
664 if (si.host && auth_rate_limiter.can (si)) 686 if (dsi.valid () && auth_rate_limiter.can (dsi))
665 { 687 {
666 if (retry_cnt < 4) 688 if (retry_cnt < 4)
667 send_auth_request (si, true); 689 send_auth_request (dsi, true);
668 else 690 else
669 send_ping (si, 0); 691 send_ping (dsi, 0);
670 } 692 }
671 } 693 }
672 else
673 vpn->connect_request (conf->id);
674 } 694 }
675} 695}
676 696
677void 697void
678connection::reset_connection () 698connection::reset_connection ()
707 727
708 reset_connection (); 728 reset_connection ();
709} 729}
710 730
711void 731void
712connection::rekey_cb (tstamp &ts) 732connection::rekey_cb (time_watcher &w)
713{ 733{
714 ts = TSTAMP_CANCEL; 734 w.at = TSTAMP_CANCEL;
715 735
716 reset_connection (); 736 reset_connection ();
717 establish_connection (); 737 establish_connection ();
718} 738}
719 739
727 && (*pkt)[12] == 0x08 && (*pkt)[13] == 0x00 // IP 747 && (*pkt)[12] == 0x08 && (*pkt)[13] == 0x00 // IP
728 && ((*pkt)[14] & 0xf0) == 0x40) // IPv4 748 && ((*pkt)[14] & 0xf0) == 0x40) // IPv4
729 tos = (*pkt)[15] & IPTOS_TOS_MASK; 749 tos = (*pkt)[15] & IPTOS_TOS_MASK;
730 750
731 p->setup (this, broadcast ? 0 : conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs 751 p->setup (this, broadcast ? 0 : conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs
732 send_vpn_packet (p, si, tos); 752 vpn->send_vpn_packet (p, si, tos);
733 753
734 delete p; 754 delete p;
735 755
736 if (oseqno > MAX_SEQNO) 756 if (oseqno > MAX_SEQNO)
737 rekey (); 757 rekey ();
747 if (!broadcast)//DDDD 767 if (!broadcast)//DDDD
748 queue.put (new tap_packet (*pkt)); 768 queue.put (new tap_packet (*pkt));
749 769
750 establish_connection (); 770 establish_connection ();
751 } 771 }
772}
773
774void connection::inject_vpn_packet (vpn_packet *pkt, int tos)
775{
776 if (ictx && octx)
777 vpn->send_vpn_packet (pkt, si, tos);
778 else
779 establish_connection ();
752} 780}
753 781
754void 782void
755connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) 783connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi)
756{ 784{
820 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"), 848 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"),
821 conf->nodename, (const char *)rsi); 849 conf->nodename, (const char *)rsi);
822 else 850 else
823 { 851 {
824 retry_cnt = 0; 852 retry_cnt = 0;
825 establish_connection.set (NOW + 8); //? ;) 853 establish_connection.start (NOW + 8); //? ;)
826 keepalive.reset (); 854 keepalive.reset ();
827 rekey.reset (); 855 rekey.reset ();
828 856
829 delete ictx; 857 delete ictx;
830 ictx = 0; 858 ictx = 0;
885 delete ictx; ictx = cctx; 913 delete ictx; ictx = cctx;
886 914
887 iseqno.reset (ntohl (*(u32 *)&chg[CHG_SEQNO]) & 0x7fffffff); // at least 2**31 sequence numbers are valid 915 iseqno.reset (ntohl (*(u32 *)&chg[CHG_SEQNO]) & 0x7fffffff); // at least 2**31 sequence numbers are valid
888 916
889 si = rsi; 917 si = rsi;
918 protocol = rsi.prot;
890 919
891 rekey.set (NOW + ::conf.rekey); 920 rekey.start (NOW + ::conf.rekey);
892 keepalive.set (NOW + ::conf.keepalive); 921 keepalive.start (NOW + ::conf.keepalive);
893 922
894 // send queued packets 923 // send queued packets
895 while (tap_packet *p = queue.get ()) 924 while (tap_packet *p = queue.get ())
896 { 925 {
897 send_data_packet (p); 926 send_data_packet (p);
898 delete p; 927 delete p;
899 } 928 }
900 929
901 connectmode = conf->connectmode; 930 connectmode = conf->connectmode;
902 931
903 slog (L_INFO, _("%s(%s): %s connection established, protocol version %d.%d"), 932 slog (L_INFO, _("%s(%s): connection established, protocol version %d.%d"),
904 conf->nodename, (const char *)rsi, 933 conf->nodename, (const char *)rsi,
905 strprotocol (protocol),
906 p->prot_major, p->prot_minor); 934 p->prot_major, p->prot_minor);
907 935
908 if (::conf.script_node_up) 936 if (::conf.script_node_up)
909 run_script (run_script_cb (this, &connection::script_node_up), false); 937 run_script (run_script_cb (this, &connection::script_node_up), false);
910 938
976 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) 1004 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx))
977 { 1005 {
978 connect_req_packet *p = (connect_req_packet *) pkt; 1006 connect_req_packet *p = (connect_req_packet *) pkt;
979 1007
980 assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything 1008 assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything
1009 connection *c = vpn->conns[p->id - 1];
981 conf->protocols = p->protocols; 1010 conf->protocols = p->protocols;
982 connection *c = vpn->conns[p->id - 1];
983 1011
984 slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]\n", 1012 slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]\n",
985 conf->id, p->id, c->ictx && c->octx); 1013 conf->id, p->id, c->ictx && c->octx);
986 1014
987 if (c->ictx && c->octx) 1015 if (c->ictx && c->octx)
999 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) 1027 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx))
1000 { 1028 {
1001 connect_info_packet *p = (connect_info_packet *) pkt; 1029 connect_info_packet *p = (connect_info_packet *) pkt;
1002 1030
1003 assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything 1031 assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything
1004 conf->protocols = p->protocols; 1032
1005 connection *c = vpn->conns[p->id - 1]; 1033 connection *c = vpn->conns[p->id - 1];
1034
1035 c->conf->protocols = p->protocols;
1036 protocol = best_protocol (c->conf->protocols & THISNODE->protocols & p->si.supported_protocols (c->conf));
1037 p->si.upgrade_protocol (protocol, c->conf);
1006 1038
1007 slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)", 1039 slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)",
1008 conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx); 1040 conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx);
1009 1041
1042 const sockinfo &dsi = forward_si (p->si);
1043
1044 if (dsi.valid ())
1010 c->send_auth_request (p->si, true); 1045 c->send_auth_request (dsi, true);
1011 } 1046 }
1012 1047
1013 break; 1048 break;
1014 1049
1015 default: 1050 default:
1016 send_reset (rsi); 1051 send_reset (rsi);
1017 break; 1052 break;
1018 } 1053 }
1019} 1054}
1020 1055
1021void connection::keepalive_cb (tstamp &ts) 1056void connection::keepalive_cb (time_watcher &w)
1022{ 1057{
1023 if (NOW >= last_activity + ::conf.keepalive + 30) 1058 if (NOW >= last_activity + ::conf.keepalive + 30)
1024 { 1059 {
1025 reset_connection (); 1060 reset_connection ();
1026 establish_connection (); 1061 establish_connection ();
1027 } 1062 }
1028 else if (NOW < last_activity + ::conf.keepalive) 1063 else if (NOW < last_activity + ::conf.keepalive)
1029 ts = last_activity + ::conf.keepalive; 1064 w.at = last_activity + ::conf.keepalive;
1030 else if (conf->connectmode != conf_node::C_ONDEMAND 1065 else if (conf->connectmode != conf_node::C_ONDEMAND
1031 || THISNODE->connectmode != conf_node::C_ONDEMAND) 1066 || THISNODE->connectmode != conf_node::C_ONDEMAND)
1032 { 1067 {
1033 send_ping (si); 1068 send_ping (si);
1034 ts = NOW + 5; 1069 w.at = NOW + 5;
1035 } 1070 }
1036 else 1071 else
1037 reset_connection (); 1072 reset_connection ();
1038} 1073}
1039 1074
1041{ 1076{
1042 connect_req_packet *p = new connect_req_packet (conf->id, id, conf->protocols); 1077 connect_req_packet *p = new connect_req_packet (conf->id, id, conf->protocols);
1043 1078
1044 slog (L_TRACE, ">>%d PT_CONNECT_REQ(%d)", conf->id, id); 1079 slog (L_TRACE, ">>%d PT_CONNECT_REQ(%d)", conf->id, id);
1045 p->hmac_set (octx); 1080 p->hmac_set (octx);
1046 send_vpn_packet (p, si); 1081 vpn->send_vpn_packet (p, si);
1047 1082
1048 delete p; 1083 delete p;
1049} 1084}
1050 1085
1051void connection::script_node () 1086void connection::script_node ()
1075 putenv ("STATE=down"); 1110 putenv ("STATE=down");
1076 1111
1077 return ::conf.script_node_up ? ::conf.script_node_down : "node-down"; 1112 return ::conf.script_node_up ? ::conf.script_node_down : "node-down";
1078} 1113}
1079 1114
1080// send a vpn packet out to other hosts
1081void
1082connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
1083{
1084 switch (protocol)
1085 {
1086 case PROT_IPv4:
1087 vpn->send_ipv4_packet (pkt, si, tos);
1088 break;
1089
1090 case PROT_UDPv4:
1091 vpn->send_udpv4_packet (pkt, si, tos);
1092 break;
1093
1094 case PROT_TCPv4:
1095 vpn->send_tcpv4_packet (pkt, si, tos);
1096 break;
1097 }
1098}
1099
1100connection::connection(struct vpn *vpn_) 1115connection::connection(struct vpn *vpn_)
1101: vpn(vpn_) 1116: vpn(vpn_)
1102, rekey (this, &connection::rekey_cb) 1117, rekey (this, &connection::rekey_cb)
1103, keepalive (this, &connection::keepalive_cb) 1118, keepalive (this, &connection::keepalive_cb)
1104, establish_connection (this, &connection::establish_connection_cb) 1119, establish_connection (this, &connection::establish_connection_cb)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines