From 6cb19a9ab7c100286104d7c9cef7cdf502dc592a Mon Sep 17 00:00:00 2001
From: cyan <>
Date: Sat, 31 Mar 2007 06:01:08 +0000
Subject: [PATCH] * Remove detection of whether Synchronet supports
 socket_select(), as any   BBS running this version of the IRCd should support
 it by now. * Insert the beginnings of a real recvq system that will properly
 throttle   clients that flood the server.

---
 exec/ircd.js           | 24 +++++++++++++++++++++---
 exec/load/ircd_user.js | 21 +++++++++++++++++++--
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/exec/ircd.js b/exec/ircd.js
index 18938fc806..d4e95b2986 100644
--- a/exec/ircd.js
+++ b/exec/ircd.js
@@ -135,6 +135,8 @@ rebuild_socksel_array = false;
 
 network_debug = false;
 
+last_recvq_check = 0;
+
 // Parse command-line arguments.
 config_filename="";
 var cmdline_port;
@@ -232,6 +234,16 @@ while (!server.terminated) {
 		}
 	}
 
+	/* Clear out the recvq, but only every 2 seconds */
+	if ( (time() - last_recvq_check) > 2) {
+		for(this_sock in Selectable_Sockets) {
+			if (Selectable_Sockets_Map[this_sock] &&
+				Selectable_Sockets_Map[this_sock].recvq.bytes) {
+				Selectable_Sockets_Map[this_sock].work(true);
+			}
+		}
+	}
+
 	// Check for pending DNS hostname resolutions.
 	for(this_unreg in Unregistered) {
 		if (Unregistered[this_unreg] &&
@@ -251,9 +263,7 @@ while (!server.terminated) {
 	}
 
 	// do some work.
-	if (!Selectable_Sockets.length) {
-		mswait(1000);
-	} else if (this.socket_select!=undefined) {
+	if (this.socket_select!=undefined) {
 		var readme = socket_select(Selectable_Sockets, 1 /*secs*/);
 		try {
 			for(thisPolled in readme) {
@@ -967,6 +977,13 @@ function Queue_Add(str) {
 	this.queue.push(str);
 }
 
+function Queue_Del() {
+	var str = this.queue[0];
+	this.bytes -= str.length;
+	this.queue.shift();
+	return str;
+}
+
 function IRCClient_server_notice(str) {
 	this.ircout("NOTICE " + this.nick + " :" + str);
 }
@@ -2952,6 +2969,7 @@ function IRC_Queue() {
 	this.queue = new Array;
 	this.bytes = 0;
 	this.add = Queue_Add;
+	this.del = Queue_Del;
 }
 
 /* /STATS M, for profiling. */
diff --git a/exec/load/ircd_user.js b/exec/load/ircd_user.js
index 231b48d439..c8c9e75906 100644
--- a/exec/load/ircd_user.js
+++ b/exec/load/ircd_user.js
@@ -144,6 +144,7 @@ function IRC_User(id) {
 	this.talkidle = time();
 	this.uprefix = "";
 	this.id = id;
+	this.throttle_count = 0;
 	// Variables (consts, really) that point to various state information
 	this.socket = "";
 	////////// FUNCTIONS
@@ -247,7 +248,7 @@ function IRC_User(id) {
 }
 
 ////////// Command Parser //////////
-function User_Work() {
+function User_Work(from_recvq) {
 	var clockticks = system.timer;
 	var cmdline;
 	var cmd;
@@ -258,7 +259,23 @@ function User_Work() {
 		return 0;
 	}
 
-	cmdline=this.socket.recvline(4096,0)
+	var cmdline;
+	if (from_recvq) {
+		cmdline = this.recvq.del();
+	} else {
+		var incoming_cmd = this.socket.recvline(4096,0);
+		if (this.recvq.bytes || (this.throttle_count > 4)) {
+			this.recvq.add(incoming_cmd);
+			this.throttle_count = 0;
+			return 0;
+		} else {
+			cmdline = incoming_cmd;
+		}
+		if ( (time() - this.idletime) < 2)
+			this.throttle_count++;
+		else
+			this.throttle_count = 0;
+	}
 
 	if (!cmdline)
 		return 0;
-- 
GitLab