diff --git a/UPGRADING b/UPGRADING
index c25f28c34d6982145be388f36ccc95cdd2fb0a07..e0e12693a1b0fe9d7c63a2e212befb2010d9c2d6 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -1,3 +1,9 @@
+
+2011-01-11:
+	Move configuration file item "use_packet_timestamp=" to "[radius]" section
+
+---
+
 r574:
 	# Database
 
diff --git a/smradius/config.pm b/smradius/config.pm
index 3143f1912eb8d90aa1a346bd34e74a200a654983..d81bb7d38351fe4509577ae6a6dd1e31ad16ae0f 100644
--- a/smradius/config.pm
+++ b/smradius/config.pm
@@ -63,17 +63,17 @@ sub Init
 	$server->{'smradius'}{'database'} = $db;
 
 	# Setup event timezone config
-	if (defined($config->{'server'}{'event_timezone'})) {
-		$server->{'smradius'}{'event_timezone'} = $config->{'server'}{'event_timezone'};
+	if (defined($config->{'system'}{'event_timezone'})) {
+		$server->{'smradius'}{'event_timezone'} = $config->{'system'}{'event_timezone'};
 	} else {
 		$server->{'smradius'}{'event_timezone'} = "GMT";
 	}
 		
 	# Should we use the packet timestamp?
-	if (defined($config->{'server'}{'use_packet_timestamp'})) {
-		if ($config->{'server'}{'use_packet_timestamp'} =~ /^\s*(yes|true|1)\s*$/i) {
+	if (defined($config->{'radius'}{'use_packet_timestamp'})) {
+		if ($config->{'radius'}{'use_packet_timestamp'} =~ /^\s*(yes|true|1)\s*$/i) {
 			$server->{'smradius'}{'use_packet_timestamp'} = 1;
-		} elsif ($config->{'server'}{'use_packet_timestamp'} =~ /^\s*(no|false|0)\s*$/i) {
+		} elsif ($config->{'radius'}{'use_packet_timestamp'} =~ /^\s*(no|false|0)\s*$/i) {
 			$server->{'smradius'}{'use_packet_timestamp'} = 0;
 		} else {
 			$server->log(LOG_NOTICE,"smradius/config.pm: Value for 'use_packet_timestamp' is invalid");
@@ -82,8 +82,43 @@ sub Init
 		$server->{'smradius'}{'use_packet_timestamp'} = 0;
 	}
 		
+	# Should we use abuse prevention?
+	if (defined($config->{'radius'}{'use_abuse_prevention'})) {
+		if ($config->{'radius'}{'use_abuse_prevention'} =~ /^\s*(yes|true|1)\s*$/i) {
+			$server->{'smradius'}{'use_abuse_prevention'} = 1;
+		} elsif ($config->{'radius'}{'use_abuse_prevention'} =~ /^\s*(no|false|0)\s*$/i) {
+			$server->{'smradius'}{'use_abuse_prevention'} = 0;
+		} else {
+			$server->log(LOG_NOTICE,"smradius/config.pm: Value for 'use_abuse_prevention' is invalid");
+		}
+	} else {
+		$server->{'smradius'}{'use_abuse_prevention'} = 0;
+	}
+	if (defined($config->{'radius'}{'access_request_abuse_threshold'})) {
+		if ($config->{'radius'}{'access_request_abuse_threshold'} =~ /^[1-9][0-9]*$/i) {
+			$server->{'smradius'}{'access_request_abuse_threshold'} = $config->{'radius'}{'access_request_abuse_threshold'};
+		} else {
+			$server->log(LOG_NOTICE,"smradius/config.pm: Value for 'access_request_abuse_threshold' is invalid");
+		}
+	} else {
+		$server->{'smradius'}{'access_request_abuse_threshold'} = 10;
+	}
+	if (defined($config->{'radius'}{'accounting_request_abuse_threshold'})) {
+		if ($config->{'radius'}{'accounting_request_abuse_threshold'} =~ /^[1-9][0-9]*$/i) {
+			$server->{'smradius'}{'accounting_request_abuse_threshold'} = $config->{'radius'}{'accounting_request_abuse_threshold'};
+		} else {
+			$server->log(LOG_NOTICE,"smradius/config.pm: Value for 'accounting_request_abuse_threshold' is invalid");
+		}
+	} else {
+		$server->{'smradius'}{'accounting_request_abuse_threshold'} = 5;
+	}
+		
 	$server->log(LOG_NOTICE,"smradius/config.pm: Using ". ( $server->{'smradius'}{'use_packet_timestamp'} ? 'packet' : 'server' ) ." timestamp");
 	$server->log(LOG_NOTICE,"smradius/config.pm: Using timezone '".$server->{'smradius'}{'event_timezone'}."'");
+	$server->log(LOG_NOTICE,"smradius/config.pm: Abuse prevention ".( $server->{'smradius'}{'use_abuse_prevention'} ? 
+			'active (access-threshold = '.$server->{'smradius'}{'access_request_abuse_threshold'}.
+			', accounting-threshold = '.$server->{'smradius'}{'accounting_request_abuse_threshold'}.')'
+			: 'inactive'));
 }
 
 
diff --git a/smradiusd b/smradiusd
index 32ea1d1940409ff4825f09d727d9668ddcf095db..2362c4a247c54058fa7fdb246c437d30ee98f454 100755
--- a/smradiusd
+++ b/smradiusd
@@ -348,7 +348,7 @@ sub post_configure_hook {
 
 	$self->log(LOG_INFO,"[SMRADIUS] Initializing system modules.");
 	# Init caching engine
-#	awitpt::cache::Init($self);
+	awitpt::cache::Init($self);
 	$self->log(LOG_INFO,"[SMRADIUS] System modules initialized.");
 
 }
@@ -447,9 +447,12 @@ sub process_request {
 		return;
 	}
 
-	# Profiling...
+	# Very first timer ...
 	my $timer0 = [gettimeofday];
 
+	# Grab NOW()
+	my $now = time();
+
 	# Parse packet
 	my $pkt = new Radius::Packet($self->{'radius'}->{'dictionary'},$udp_packet);
 
@@ -479,7 +482,7 @@ sub process_request {
 			$timeout = 120;
 		}
 		# Get time left
-		my $timepassed = time() - $self->{'client'}->{'dbh_status'};
+		my $timepassed = $now - $self->{'client'}->{'dbh_status'};
 		# Then check...
 		if ($timepassed >= $timeout) {
 			$self->log(LOG_WARN,"[SMRADIUS] Client BYPASS timeout exceeded, reconnecting...");
@@ -512,7 +515,7 @@ sub process_request {
 	if (defined($pkt->rawattr('Event-Timestamp')) && $self->{'smradius'}->{'use_packet_timestamp'}) {
 		$user->{'_Internal'}->{'Timestamp-Unix'} = $pkt->rawattr('Event-Timestamp');
 	} else {
-		$user->{'_Internal'}->{'Timestamp-Unix'} = time();
+		$user->{'_Internal'}->{'Timestamp-Unix'} = $now;
 	}
 
 	# VERY IMPORTANT!!!!!!
@@ -526,6 +529,25 @@ sub process_request {
 	# Set username
 	$user->{'Username'} = $pkt->attr('User-Name');
 
+	# First thing we do is to make sure the NAS behaves if we using abuse prevention
+	if ($self->{'smradius'}->{'use_abuse_prevention'} && defined($user->{'Username'})) {
+		my ($res,$val) = cacheGetKeyPair('FloodCheck',$server->{'peeraddr'}."/".$user->{'Username'}."/".$pkt->code);
+		if (defined($val)) {
+			my $timePeriod = $now - $val;
+			if ($pkt->code eq "Access-Request" && $timePeriod < $self-{'smradius'}->{'access_request_abuse_threshold'}) {
+				$self->log(LOG_WARN,"[SMRADIUS] ABUSE: Server trying too fast. server = ".$server->{'peeraddr'}.", user = ".$user->{'Username'}.
+						", code = ".$pkt->code.", timeout = ".($now - $val));
+				return;
+			} elsif ($pkt->code eq "Accounting-Request" && $timePeriod < $self->{'smradius'}->{'accounting_request_abuse_threshold'}) {
+				$self->log(LOG_WARN,"[SMRADIUS] ABUSE: Server trying too fast. server = ".$server->{'peeraddr'}.", user = ".$user->{'Username'}.
+						", code = ".$pkt->code.", timeout = ".($now - $val));
+				return;
+			}
+		}
+		# We give the benefit of the doubt and let a query take 60s. We update to right stamp at end of this function
+		cacheStoreKeyPair('FloodCheck',$server->{'peeraddr'}."/".$user->{'Username'}."/".$pkt->code,$now + 60);
+	}
+
 	#
 	# GRAB & PROCESS CONFIG
 	#
@@ -561,6 +583,9 @@ sub process_request {
 		}
 	}
 
+	# Get the user timer
+	my $timer1 = [gettimeofday];
+
 	# FIXME - need secret
 	# FIXME - need acl list
 
@@ -613,6 +638,9 @@ sub process_request {
 		}
 	}
 
+	# Process the packet timer
+	my $timer2 = [gettimeofday];
+
 
 	# Is this an accounting request
 	if ($pkt->code eq "Accounting-Request") {
@@ -1025,9 +1053,16 @@ CHECK_RESULT:
 	}
 
 	# END
-	my $timer1 = [gettimeofday];
-	my $timediff = tv_interval($timer0,$timer1);
-	$self->log(LOG_NOTICE,"[SMRADIUS] Result: $logReason (${timediff}s) => $logLine");
+	my $timer9 = [gettimeofday];
+	my $timediff1 = tv_interval($timer0,$timer1);
+	my $timediff2 = tv_interval($timer1,$timer2);
+	my $timediff = tv_interval($timer0,$timer9);
+	$self->log(LOG_NOTICE,"[SMRADIUS] Result: $logReason (%.3fs + %.3fs = %.3fs) => $logLine",$timediff1,$timediff2,$timediff);
+
+	# If we using abuse prevention record the time we ending off
+	if ($self->{'smradius'}->{'use_abuse_prevention'} && defined($user->{'Username'})) {
+		cacheStoreKeyPair('FloodCheck',$server->{'peeraddr'}."/".$user->{'Username'}."/".$pkt->code,time());
+	}
 
 	return;
 }
@@ -1041,7 +1076,7 @@ sub server_exit
 
 	$self->log(LOG_DEBUG,"Destroying system modules.");
 	# Destroy cache
-#	cbp::cache::Destroy($self);
+	awitpt::cache::Destroy($self);
 	$self->log(LOG_DEBUG,"System modules destroyed.");
 
 	# Parent exit
diff --git a/smradiusd.conf b/smradiusd.conf
index f6c8e78f9d5169a422852c235bbdce9e0838855d..6c816e5436a8ad74c344a6dbbb6dc5796b1e0bc1 100644
--- a/smradiusd.conf
+++ b/smradiusd.conf
@@ -72,6 +72,8 @@
 # Defaults to "GMT"
 event_timezone=GMT
 
+
+[radius]
 # Use packet timestamp, if unset, the default is to use the server
 # timestamp at the moment the packet is received.
 #
@@ -82,8 +84,27 @@ event_timezone=GMT
 # first user logs in .. BAM, you'll have sessions with a period key 
 # in current month but an event timestamp in 1970.
 #
+# Defaults to "no"
 #use_packet_timestamp=yes
 
+# Radius server abuse prevention
+#
+# Abuse prevention will drop packets which flood the radius server,
+# or are duplicated in a short timeframe. You probably want this if
+# you are not being fed by a radius proxy.
+#
+# Defaults to "no"
+#use_abuse_prevention=no
+
+# How fast can a NAS spam the same type of request
+#
+# Access-Request defaults to 10s
+#access_request_abuse_threshold=10
+#
+# Accounting-Request defaults to 5s
+#accounting_request_abuse_threshold=5
+
+
 [database]
 #DSN=DBI:SQLite:dbname=smradius.sqlite
 DSN=DBI:mysql:database=smradius;host=localhost