Add a limit to the number of connections made to irc servers
authorJack Allnutt <m2ys4u@gmail.com>
Sat, 30 Mar 2013 20:48:14 +0000 (20:48 +0000)
committerJack Allnutt <m2ys4u@gmail.com>
Sat, 30 Mar 2013 20:53:06 +0000 (20:53 +0000)
New configuration setting: conf.max_server_conns.

Limit is ignored if there is a WEBIRC password set for the server or if the server is running
in restricted mode.

config.example.js
server/irc/state.js
server/kiwi.js

index fadbd48c6c4dd1af38ada564a3b19fd5b7f99a2c..a44ed93eca092686e27c18edccf5940414e76626 100644 (file)
@@ -53,6 +53,10 @@ conf.public_http = "client/";
 // Max connections per connection. 0 to disable
 conf.max_client_conns = 5;
 
+// Max connections per server. 0 to disable.
+// Setting is ignored if there is a WEBIRC password configured for the server or kiwi is running in restricted server mode.
+conf.max_server_conns = 0;
+
 
 /*
  * Client side plugins
index aa531bee12fc87bf60cf2abe0aed1b5e2b34ba6a..8dd24ed0529465fa2d687e83f6c96edf6c386094 100755 (executable)
@@ -19,6 +19,7 @@ var State = function (client, save_state) {
                 if (irc_connection) {
                     irc_connection.end('QUIT :' + (global.config.quit_message || ''));
                     irc_connection.dispose();
+                    global.servers.removeConnection(irc_connection);
                     cons[i] = null;
                 }
             });
@@ -46,6 +47,11 @@ State.prototype.connect = function (hostname, port, ssl, nick, user, pass, callb
             this);
 
     } else {
+        if ((global.config.max_server_conns > 0) && (!(global.config.webirc_pass && global.config.webirc_passs[hostname])))  {
+            if (global.servers.numOnHost(hostname) >= global.config.max_server_conns) {
+                return callback('Too many connections to host', {host: hostname, limit: global.config.max_server_conns});
+            }
+        }
         con = new IrcConnection(
             hostname,
             port,
@@ -63,6 +69,7 @@ State.prototype.connect = function (hostname, port, ssl, nick, user, pass, callb
     new IrcCommands(con, con_num, this).bindEvents();
     
     con.on('connected', function () {
+        global.servers.addConnection(this);
         return callback(null, con_num);
     });
     
@@ -73,6 +80,7 @@ State.prototype.connect = function (hostname, port, ssl, nick, user, pass, callb
 
     con.on('close', function () {
         that.irc_connections[con_num] = null;
+        global.servers.removeConnection(this);
     });
 };
 
index 014cac09a19ff74f40424b5f530d6da97614fb17..0dc1d491bea0f6152d64f501562e6e4154c2b529 100755 (executable)
@@ -109,6 +109,36 @@ global.clients = {
     }
 };
 
+global.servers = {
+    servers: Object.create(null),
+    
+    addConnection: function (connection) {
+        var host = connection.irc_host.hostname;
+        if (!this.servers[host]) {
+            this.servers[host] = [];
+        }
+        this.servers[host].push(connection);
+    },
+    
+    removeConnection: function (connection) {
+        var host = connection.irc_host.hostname
+        if (this.servers[host]) {
+            this.servers[host] = _.without(this.servers[host], connection);
+            if (this.servers[host].length === 0) {
+                delete this.servers[host];
+            }
+        }
+    },
+    
+    numOnHost: function (host) {
+        if (this.servers[host]) {
+            return this.servers[host].length;
+        } else {
+            return 0;
+        }
+    }
+};
+