X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/6c4ac1aa6a6659816080995e649cc640a9290066..b3bf2a185c13656bd5f27fe420e38e7c158b3f39:/l2tpns.c diff --git a/l2tpns.c b/l2tpns.c index a02be1d..bcb14d2 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -1,10 +1,10 @@ // L2TP Network Server // Adrian Kennard 2002 -// Copyright (c) 2003, 2004 Optus Internet Engineering +// Copyright (c) 2003, 2004, 2005 Optus Internet Engineering // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced // vim: sw=8 ts=8 -char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.73 2004/12/17 00:28:00 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.73.2.2 2005/01/10 07:44:49 bodea Exp $"; #include #include @@ -117,6 +117,7 @@ config_descriptt config_values[] = { CONFIG("scheduler_fifo", scheduler_fifo, BOOL), CONFIG("lock_pages", lock_pages, BOOL), CONFIG("icmp_rate", icmp_rate, INT), + CONFIG("packet_limit", max_packets, INT), CONFIG("cluster_address", cluster_address, IP), CONFIG("cluster_interface", cluster_interface, STRING), CONFIG("cluster_hb_interval", cluster_hb_interval, INT), @@ -711,7 +712,7 @@ static void processipout(uint8_t * buf, int len) tunnelidt t; in_addr_t ip; - char * data = buf; // Keep a copy of the originals. + char *data = buf; // Keep a copy of the originals. int size = len; uint8_t b[MAXETHER + 20]; @@ -721,13 +722,13 @@ static void processipout(uint8_t * buf, int len) if (len < MIN_IP_SIZE) { LOG(1, 0, 0, "Short IP, %d bytes\n", len); - STAT(tunnel_tx_errors); + STAT(tun_rx_errors); return; } if (len >= MAXETHER) { LOG(1, 0, 0, "Oversize IP packet %d bytes\n", len); - STAT(tunnel_tx_errors); + STAT(tun_rx_errors); return; } @@ -765,6 +766,43 @@ static void processipout(uint8_t * buf, int len) t = session[s].tunnel; sp = &session[s]; + // DoS prevention: enforce a maximum number of packets per 0.1s for a session + if (config->max_packets > 0) + { + if (sess_count[s].last_packet_out == TIME) + { + int max = config->max_packets; + + // All packets for throttled sessions are handled by the + // master, so further limit by using the throttle rate. + // A bit of a kludge, since throttle rate is in kbps, + // but should still be generous given our average DSL + // packet size is 200 bytes: a limit of 28kbps equates + // to around 180 packets per second. + if (!config->cluster_iam_master && sp->throttle_out && sp->throttle_out < max) + max = sp->throttle_out; + + if (++sess_count[s].packets_out > max) + { + sess_count[s].packets_dropped++; + return; + } + } + else + { + if (sess_count[s].packets_dropped) + { + INC_STAT(tun_rx_dropped, sess_count[s].packets_dropped); + LOG(2, s, t, "Possible DoS attack on %s (%s); dropped %u packets.\n", + fmtaddr(ip, 0), sp->user, sess_count[s].packets_dropped); + } + + sess_count[s].last_packet_out = TIME; + sess_count[s].packets_out = 1; + sess_count[s].packets_dropped = 0; + } + } + // run access-list if any if (session[s].filter_out && !ip_filter(buf, len, session[s].filter_out - 1)) return; @@ -3128,7 +3166,7 @@ int main(int argc, char *argv[]) init_tbf(config->num_tbfs); LOG(0, 0, 0, "L2TPNS version " VERSION "\n"); - LOG(0, 0, 0, "Copyright (c) 2003, 2004 Optus Internet Engineering\n"); + LOG(0, 0, 0, "Copyright (c) 2003, 2004, 2005 Optus Internet Engineering\n"); LOG(0, 0, 0, "Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced\n"); { struct rlimit rlim;