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

Comparing gvpe/src/protocol.C (file contents):
Revision 1.13 by pcg, Sat Mar 22 22:34:36 2003 UTC vs.
Revision 1.16 by pcg, Tue Mar 25 18:11:58 2003 UTC

62 62
63static const rsachallenge & 63static const rsachallenge &
64challenge_bytes () 64challenge_bytes ()
65{ 65{
66 static rsachallenge challenge; 66 static rsachallenge challenge;
67 static double challenge_ttl; // time this challenge needs to be recreated 67 static tstamp challenge_ttl; // time this challenge needs to be recreated
68 68
69 if (NOW > challenge_ttl) 69 if (NOW > challenge_ttl)
70 { 70 {
71 RAND_bytes ((unsigned char *)&challenge, sizeof (challenge)); 71 RAND_bytes ((unsigned char *)&challenge, sizeof (challenge));
72 challenge_ttl = NOW + CHALLENGE_TTL; 72 challenge_ttl = NOW + CHALLENGE_TTL;
264{ 264{
265 for (i = QUEUEDEPTH; --i > 0; ) 265 for (i = QUEUEDEPTH; --i > 0; )
266 delete queue[i]; 266 delete queue[i];
267} 267}
268 268
269struct net_rateinfo {
270 u32 host;
271 double pcnt, diff;
272 tstamp last;
273};
274
269// only do action once every x seconds per host. 275// only do action once every x seconds per host whole allowing bursts.
270// currently this is quite a slow implementation, 276// this implementation ("splay list" ;) is inefficient,
271// but suffices for normal operation. 277// but low on resources.
272struct u32_rate_limiter : private map<u32, tstamp> 278struct net_rate_limiter : private list<net_rateinfo>
273 { 279{
274 tstamp every; 280 static const double ALPHA = 1. - 1. / 90.; // allow bursts
281 static const double CUTOFF = 20.; // one event every CUTOFF seconds
282 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time
275 283
276 bool can (u32 host); 284 bool can (u32 host);
277
278 u32_rate_limiter (tstamp every = 1)
279 {
280 this->every = every;
281 }
282 };
283
284struct net_rate_limiter : u32_rate_limiter
285 {
286 bool can (SOCKADDR *sa) { return u32_rate_limiter::can((u32)sa->sin_addr.s_addr); } 285 bool can (SOCKADDR *sa) { return can((u32)sa->sin_addr.s_addr); }
287 bool can (sockinfo &si) { return u32_rate_limiter::can((u32)si.host); } 286 bool can (sockinfo &si) { return can((u32)si.host); }
287};
288 288
289 net_rate_limiter (tstamp every) : u32_rate_limiter (every) {} 289net_rate_limiter auth_rate_limiter, reset_rate_limiter;
290 };
291 290
292bool u32_rate_limiter::can (u32 host) 291bool net_rate_limiter::can (u32 host)
293{ 292{
294 iterator i; 293 iterator i;
295 294
296 for (i = begin (); i != end (); ) 295 for (i = begin (); i != end (); )
297 if (i->second <= NOW) 296 if (i->host == host)
298 { 297 break;
298 else if (i->last < NOW - EXPIRE)
299 erase (i); 299 i = erase (i);
300 i = begin ();
301 }
302 else 300 else
303 ++i; 301 i++;
304 302
305 i = find (host);
306
307 if (i != end ()) 303 if (i == end ())
308 return false; 304 {
305 net_rateinfo ri;
309 306
310 insert (value_type (host, NOW + every)); 307 ri.host = host;
308 ri.pcnt = 1.;
309 ri.diff = CUTOFF * (1. / (1. - ALPHA));
310 ri.last = NOW;
311 311
312 push_front (ri);
313
312 return true; 314 return true;
315 }
316 else
317 {
318 net_rateinfo ri (*i);
319 erase (i);
320
321 ri.pcnt = ri.pcnt * ALPHA;
322 ri.diff = ri.diff * ALPHA + (NOW - ri.last);
323
324 ri.last = NOW;
325
326 bool send = ri.diff / ri.pcnt > CUTOFF;
327
328 if (send)
329 ri.pcnt++;
330
331 //printf ("RATE %d %f,%f = %f > %f\n", !!send, ri.pcnt, ri.diff, ri.diff / ri.pcnt, CUTOFF);
332
333 push_front (ri);
334
335 return send;
336 }
313} 337}
314 338
315///////////////////////////////////////////////////////////////////////////// 339/////////////////////////////////////////////////////////////////////////////
316 340
317static void next_wakeup (time_t next) 341static void next_wakeup (time_t next)
546 u32 digest_nid; 570 u32 digest_nid;
547 571
548 const u8 curflags () const 572 const u8 curflags () const
549 { 573 {
550 return 0x80 574 return 0x80
551 | 0x02
552#if PROTOCOL_MAJOR != 2
553#error hi
554#endif
555 | (ENABLE_COMPRESSION ? 0x01 : 0x00); 575 | (ENABLE_COMPRESSION ? 0x01 : 0x00);
556 } 576 }
557 577
558 void setup (ptype type, int dst) 578 void setup (ptype type, int dst)
559 { 579 {
669} 689}
670 690
671void 691void
672connection::send_reset (SOCKADDR *dsa) 692connection::send_reset (SOCKADDR *dsa)
673{ 693{
674 static net_rate_limiter limiter(1);
675
676 if (limiter.can (dsa) && connectmode != conf_node::C_DISABLED) 694 if (reset_rate_limiter.can (dsa) && connectmode != conf_node::C_DISABLED)
677 { 695 {
678 config_packet *pkt = new config_packet; 696 config_packet *pkt = new config_packet;
679 697
680 pkt->setup (vpn_packet::PT_RESET, conf->id); 698 pkt->setup (vpn_packet::PT_RESET, conf->id);
681 vpn->send_vpn_packet (pkt, dsa, IPTOS_MINCOST); 699 vpn->send_vpn_packet (pkt, dsa, IPTOS_MINCOST);
697} 715}
698 716
699void 717void
700connection::send_auth (auth_subtype subtype, SOCKADDR *sa, const rsachallenge *k) 718connection::send_auth (auth_subtype subtype, SOCKADDR *sa, const rsachallenge *k)
701{ 719{
702 static net_rate_limiter limiter(0.2);
703
704 if (subtype != AUTH_INIT || limiter.can (sa)) 720 if (subtype == AUTH_REPLY || auth_rate_limiter.can (sa))
705 { 721 {
706 if (!k) 722 if (!k)
707 k = gen_challenge (seqrand, sa); 723 k = gen_challenge (seqrand, sa);
708 724
709 auth_packet *pkt = new auth_packet (conf->id, subtype); 725 auth_packet *pkt = new auth_packet (conf->id, subtype);
727 { 743 {
728 double retry_int = double (retry_cnt & 3 ? (retry_cnt & 3) : 1 << (retry_cnt >> 2)) * 0.25; 744 double retry_int = double (retry_cnt & 3 ? (retry_cnt & 3) : 1 << (retry_cnt >> 2)) * 0.25;
729 745
730 if (retry_int < 3600 * 8) 746 if (retry_int < 3600 * 8)
731 retry_cnt++; 747 retry_cnt++;
732
733 if (connectmode == conf_node::C_ONDEMAND
734 && retry_int > ::conf.keepalive)
735 retry_int = ::conf.keepalive;
736 748
737 ts = NOW + retry_int; 749 ts = NOW + retry_int;
738 750
739 if (conf->hostname) 751 if (conf->hostname)
740 { 752 {
741 reset_dstaddr (); 753 reset_dstaddr ();
742 if (sa.sin_addr.s_addr) 754 if (sa.sin_addr.s_addr)
743 if (retry_cnt < 4) 755 if (retry_cnt < 4)
744 send_auth (AUTH_INIT, &sa); 756 send_auth (AUTH_INIT, &sa);
745 else 757 else if (auth_rate_limiter.can (&sa))
746 send_ping (&sa, 0); 758 send_ping (&sa, 0);
747 } 759 }
748 else 760 else
749 vpn->connect_request (conf->id); 761 vpn->connect_request (conf->id);
750 } 762 }
837 conf->id, pkt->typ (), pkt->src (), pkt->dst ()); 849 conf->id, pkt->typ (), pkt->src (), pkt->dst ());
838 850
839 switch (pkt->typ ()) 851 switch (pkt->typ ())
840 { 852 {
841 case vpn_packet::PT_PING: 853 case vpn_packet::PT_PING:
842 send_ping (ssa, 1); // pong
843 break;
844
845 case vpn_packet::PT_PONG:
846 // we send pings instead of auth packets after some retries, 854 // we send pings instead of auth packets after some retries,
847 // so reset the retry counter and establish a conenction 855 // so reset the retry counter and establish a conenction
848 // when we receive a pong. 856 // when we receive a pong.
849 if (!ictx && !octx) 857 if (!ictx && !octx)
850 { 858 {
851 retry_cnt = 0; 859 retry_cnt = 0;
852 establish_connection.at = 0; 860 establish_connection.at = 0;
853 establish_connection (); 861 establish_connection ();
854 } 862 }
863 else
864 send_ping (ssa, 1); // pong
855 865
866 break;
867
868 case vpn_packet::PT_PONG:
856 break; 869 break;
857 870
858 case vpn_packet::PT_RESET: 871 case vpn_packet::PT_RESET:
859 { 872 {
860 reset_connection (); 873 reset_connection ();
890 903
891 if (!k) 904 if (!k)
892 { 905 {
893 slog (L_ERR, _("challenge from %s (%s) illegal or corrupted"), 906 slog (L_ERR, _("challenge from %s (%s) illegal or corrupted"),
894 conf->nodename, (const char *)sockinfo (ssa)); 907 conf->nodename, (const char *)sockinfo (ssa));
908 send_reset (ssa);
895 break; 909 break;
896 } 910 }
897 911
898 retry_cnt = 0; 912 retry_cnt = 0;
899 establish_connection.set (NOW + 8); //? ;) 913 establish_connection.set (NOW + 8); //? ;)
1452 } 1466 }
1453 1467
1454 ts = TSTAMP_CANCEL; 1468 ts = TSTAMP_CANCEL;
1455} 1469}
1456 1470
1471#include <sys/time.h>//D
1457vpn::vpn (void) 1472vpn::vpn (void)
1458: udp_ev_watcher (this, &vpn::udp_ev) 1473: udp_ev_watcher (this, &vpn::udp_ev)
1459, vpn_ev_watcher (this, &vpn::vpn_ev) 1474, vpn_ev_watcher (this, &vpn::vpn_ev)
1460, event (this, &vpn::event_cb) 1475, event (this, &vpn::event_cb)
1461{ 1476{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines