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.14 by pcg, Sat Mar 22 22:39:11 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)
665} 689}
666 690
667void 691void
668connection::send_reset (SOCKADDR *dsa) 692connection::send_reset (SOCKADDR *dsa)
669{ 693{
670 static net_rate_limiter limiter(1);
671
672 if (limiter.can (dsa) && connectmode != conf_node::C_DISABLED) 694 if (reset_rate_limiter.can (dsa) && connectmode != conf_node::C_DISABLED)
673 { 695 {
674 config_packet *pkt = new config_packet; 696 config_packet *pkt = new config_packet;
675 697
676 pkt->setup (vpn_packet::PT_RESET, conf->id); 698 pkt->setup (vpn_packet::PT_RESET, conf->id);
677 vpn->send_vpn_packet (pkt, dsa, IPTOS_MINCOST); 699 vpn->send_vpn_packet (pkt, dsa, IPTOS_MINCOST);
693} 715}
694 716
695void 717void
696connection::send_auth (auth_subtype subtype, SOCKADDR *sa, const rsachallenge *k) 718connection::send_auth (auth_subtype subtype, SOCKADDR *sa, const rsachallenge *k)
697{ 719{
698 static net_rate_limiter limiter(0.2);
699
700 if (subtype != AUTH_INIT || limiter.can (sa)) 720 if (subtype == AUTH_REPLY || auth_rate_limiter.can (sa))
701 { 721 {
702 if (!k) 722 if (!k)
703 k = gen_challenge (seqrand, sa); 723 k = gen_challenge (seqrand, sa);
704 724
705 auth_packet *pkt = new auth_packet (conf->id, subtype); 725 auth_packet *pkt = new auth_packet (conf->id, subtype);
723 { 743 {
724 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;
725 745
726 if (retry_int < 3600 * 8) 746 if (retry_int < 3600 * 8)
727 retry_cnt++; 747 retry_cnt++;
728
729 if (connectmode == conf_node::C_ONDEMAND
730 && retry_int > ::conf.keepalive)
731 retry_int = ::conf.keepalive;
732 748
733 ts = NOW + retry_int; 749 ts = NOW + retry_int;
734 750
735 if (conf->hostname) 751 if (conf->hostname)
736 { 752 {
737 reset_dstaddr (); 753 reset_dstaddr ();
738 if (sa.sin_addr.s_addr) 754 if (sa.sin_addr.s_addr)
739 if (retry_cnt < 4) 755 if (retry_cnt < 4)
740 send_auth (AUTH_INIT, &sa); 756 send_auth (AUTH_INIT, &sa);
741 else 757 else if (auth_rate_limiter.can (&sa))
742 send_ping (&sa, 0); 758 send_ping (&sa, 0);
743 } 759 }
744 else 760 else
745 vpn->connect_request (conf->id); 761 vpn->connect_request (conf->id);
746 } 762 }
833 conf->id, pkt->typ (), pkt->src (), pkt->dst ()); 849 conf->id, pkt->typ (), pkt->src (), pkt->dst ());
834 850
835 switch (pkt->typ ()) 851 switch (pkt->typ ())
836 { 852 {
837 case vpn_packet::PT_PING: 853 case vpn_packet::PT_PING:
838 send_ping (ssa, 1); // pong
839 break;
840
841 case vpn_packet::PT_PONG:
842 // we send pings instead of auth packets after some retries, 854 // we send pings instead of auth packets after some retries,
843 // so reset the retry counter and establish a conenction 855 // so reset the retry counter and establish a conenction
844 // when we receive a pong. 856 // when we receive a pong.
845 if (!ictx && !octx) 857 if (!ictx && !octx)
846 { 858 {
847 retry_cnt = 0; 859 retry_cnt = 0;
848 establish_connection.at = 0; 860 establish_connection.at = 0;
849 establish_connection (); 861 establish_connection ();
850 } 862 }
863 else
864 send_ping (ssa, 1); // pong
851 865
866 break;
867
868 case vpn_packet::PT_PONG:
852 break; 869 break;
853 870
854 case vpn_packet::PT_RESET: 871 case vpn_packet::PT_RESET:
855 { 872 {
856 reset_connection (); 873 reset_connection ();
886 903
887 if (!k) 904 if (!k)
888 { 905 {
889 slog (L_ERR, _("challenge from %s (%s) illegal or corrupted"), 906 slog (L_ERR, _("challenge from %s (%s) illegal or corrupted"),
890 conf->nodename, (const char *)sockinfo (ssa)); 907 conf->nodename, (const char *)sockinfo (ssa));
908 send_reset (ssa);
891 break; 909 break;
892 } 910 }
893 911
894 retry_cnt = 0; 912 retry_cnt = 0;
895 establish_connection.set (NOW + 8); //? ;) 913 establish_connection.set (NOW + 8); //? ;)
1448 } 1466 }
1449 1467
1450 ts = TSTAMP_CANCEL; 1468 ts = TSTAMP_CANCEL;
1451} 1469}
1452 1470
1471#include <sys/time.h>//D
1453vpn::vpn (void) 1472vpn::vpn (void)
1454: udp_ev_watcher (this, &vpn::udp_ev) 1473: udp_ev_watcher (this, &vpn::udp_ev)
1455, vpn_ev_watcher (this, &vpn::vpn_ev) 1474, vpn_ev_watcher (this, &vpn::vpn_ev)
1456, event (this, &vpn::event_cb) 1475, event (this, &vpn::event_cb)
1457{ 1476{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines