From 8838bdd67014b9ad78d88667b8249db04aab30e4 Mon Sep 17 00:00:00 2001 From: Jack Allnutt Date: Sat, 30 Mar 2013 20:48:14 +0000 Subject: [PATCH] Add a limit to the number of connections made to irc servers 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 | 4 ++++ server/irc/state.js | 8 ++++++++ server/kiwi.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/config.example.js b/config.example.js index fadbd48..a44ed93 100644 --- a/config.example.js +++ b/config.example.js @@ -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 diff --git a/server/irc/state.js b/server/irc/state.js index aa531be..8dd24ed 100755 --- a/server/irc/state.js +++ b/server/irc/state.js @@ -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); }); }; diff --git a/server/kiwi.js b/server/kiwi.js index 014cac0..0dc1d49 100755 --- a/server/kiwi.js +++ b/server/kiwi.js @@ -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; + } + } +}; + -- 2.25.1