Implement the max_client_conns config setting
authorJack Allnutt <m2ys4u@Gmail.com>
Mon, 29 Oct 2012 18:47:06 +0000 (18:47 +0000)
committerJack Allnutt <m2ys4u@Gmail.com>
Mon, 29 Oct 2012 18:47:06 +0000 (18:47 +0000)
Issue #98

server/client.js
server/kiwi.js
server/weblistener.js

index a49e5b18c857c37558a101b40e8e55bfec5a68dd..a020f8972a3caff92af7498b1b5ee60cf1997150 100755 (executable)
@@ -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
index 7db9138077dc449a92c20cf0e2e1060002370973..1c9fd8274e2479c027d0f62fa36aeea9e7b4bb09 100755 (executable)
@@ -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);
     });
 });
 
index 386bb716207d33c046477295f5fafe66ce7dff34..c8147649eb2e6505d6185d5c9f477c1b50c92e38 100644 (file)
@@ -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);
 }