From: Jack Allnutt Date: Mon, 29 Oct 2012 18:47:06 +0000 (+0000) Subject: Implement the max_client_conns config setting X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=c36ed4ebd110cfa18ffde6aaf65ff9f74de4775b;p=KiwiIRC.git Implement the max_client_conns config setting Issue #98 --- diff --git a/server/client.js b/server/client.js index a49e5b1..a020f89 100755 --- a/server/client.js +++ b/server/client.js @@ -1,10 +1,11 @@ var util = require('util'), events = require('events'), + crypto = require('crypto'), _ = require('underscore'), config = require('./configuration.js'), IrcConnection = require('./irc/connection.js').IrcConnection, IrcCommands = require('./irc/commands.js'), - ClientCommands = require('./clientcommands.js'); + ClientCommands = require('./clientcommands.js'); var Client = function (websocket) { @@ -12,6 +13,8 @@ var Client = function (websocket) { events.EventEmitter.call(this); this.websocket = websocket; + this.real_address = this.websocket.handshake.real_address; + this.hash = crypto.createHash('sha256').update(this.real_address).update('' + Date.now()).digest('hex'); this.irc_connections = []; this.next_connection = 0; @@ -152,4 +155,5 @@ function websocketDisconnect() { // TODO: Should this close all the websocket connections too? function websocketError() { this.emit('destroy'); + this.dispose(); } \ No newline at end of file diff --git a/server/kiwi.js b/server/kiwi.js index 7db9138..1c9fd82 100755 --- a/server/kiwi.js +++ b/server/kiwi.js @@ -61,25 +61,44 @@ if ((!config.get().servers) || (config.get().servers.length < 1)) { */ // Holder for all the connected clients -// TODO: Change from an array to an object. Generate sha1 hash within the client -// and use that as the key. (Much less work involved in removing a client) -var clients = []; +global.clients = { clients: Object.create(null), + addresses: Object.create(null), + add: function (client) { + this.clients[client.hash] = client; + if (typeof this.addresses[client.real_address] === 'undefined') { + this.addresses[client.real_address] = Object.create(null); + } + this.addresses[client.real_address][client.hash] = client; + }, + remove: function (client) { + if (typeof this.clients[client.hash] !== 'undefined') { + delete this.clients[client.hash]; + delete this.addresses[client.real_address][client.hash]; + if (Object.keys(this.addresses[client.real_address]).length < 1) { + delete this.addresses[client.real_address]; + } + } + }, + numOnAddress: function (addr) { + if (typeof this.addresses[addr] !== 'undefined') { + return Object.keys(this.addresses[addr]).length; + } else { + return 0; + } + } +}; // Start up a weblistener for each found in the config _.each(config.get().servers, function (server) { var wl = new WebListener(server, config.get().transports); wl.on('connection', function (client) { - clients.push(client); + clients.add(client); + console.log(clients); }); wl.on('destroy', function (client) { - clients = _.reject(clients, function (c) { - if (client === c) { - c.dispose(); - return true; - } - - return false; - }); + clients.remove(client); + //client.dispose(); + console.log(clients); }); }); diff --git a/server/weblistener.js b/server/weblistener.js index 386bb71..c814764 100644 --- a/server/weblistener.js +++ b/server/weblistener.js @@ -117,6 +117,12 @@ function authoriseConnection(handshakeData, callback) { address = handshakeData.headers['x-forwarded-for']; } + handshakeData.real_address = address; + + if (global.clients.numOnAddress(address) + 1 > config.get().max_client_conns) { + return callback(null, false); + } + dns.reverse(address, function (err, domains) { if (err || domains.length === 0) { handshakeData.revdns = address; @@ -130,8 +136,12 @@ function authoriseConnection(handshakeData, callback) { } function newConnection(websocket) { - //console.log(websocket); - this.emit('connection', new Client(websocket)); + var client, that = this; + client = new Client(websocket); + client.on('destroy', function () { + that.emit('destroy', this); + }); + this.emit('connection', client); }