diff --git a/lib/net/tcp.js b/lib/net/tcp.js index f939a96..3a51030 100644 --- a/lib/net/tcp.js +++ b/lib/net/tcp.js @@ -13,8 +13,6 @@ var assert = require("../_util").assert; var PPromise = require("../platform").Promise; var BaseTransport = require("./base"); -var sockIdCounter = 0; - /** * TCP transport constructor. * @constructor @@ -113,6 +111,15 @@ Transport.prototype.connect = function() { this._setupClient(client); }; +// Unmap IPv4-mapped IPv6 addresses. +function unmap(addr) { + if (addr.indexOf("::ffff:") === 0) { + return addr.slice(7); + } else { + return addr; + } +} + Transport.prototype.listen = function() { assert(!this._client, "Already connected"); assert(!this._server, "Already listening"); @@ -122,17 +129,26 @@ Transport.prototype.listen = function() { server.listen.apply(server, arguments); server.on("connection", function(sock) { - sock.id = sockIdCounter++; - self._clients[sock.id] = sock; + var addr = sock.remoteAddress; + var port = sock.remotePort; + if (self._clients[addr]) { + // NOTE(Kagami): Doesn't allow more than one connection per IP. + // This may obstruct people behind NAT but we copy PyBitmessage's + // behavior here. + sock.end(); + self.emit("warning", addr + " was tried to connect once more"); + return; + } + self._clients[addr] = sock; sock.on("close", function() { - delete self._clients[sock.id]; + delete self._clients[addr]; }); var transport = new self.constructor({ client: sock, seeds: self.seeds, dnsSeeds: self.dnsSeeds, }); - self.emit("connection", transport); + self.emit("connection", transport, unmap(addr), port); }); server.on("error", function(err) { @@ -155,8 +171,8 @@ Transport.prototype.send = function(data) { Transport.prototype.broadcast = function(data) { if (this._server) { - Object.keys(this._clients).forEach(function(id) { - this._clients[id].write(data); + Object.keys(this._clients).forEach(function(ip) { + this._clients[ip].write(data); }, this); } else { throw new Error("Not listening"); @@ -167,8 +183,8 @@ Transport.prototype.close = function() { if (this._client) { this._client.end(); } else if (this._server) { - Object.keys(this._clients).forEach(function(id) { - this._clients[id].end(); + Object.keys(this._clients).forEach(function(ip) { + this._clients[ip].end(); }, this); this._server.close(); } diff --git a/tests/run-test-nodes.js b/tests/run-test-nodes.js index e602716..a00e4d9 100644 --- a/tests/run-test-nodes.js +++ b/tests/run-test-nodes.js @@ -11,6 +11,9 @@ var WS_NODE_PATH = path.join(__dirname, "ws-node.js"); function spawn(path) { var p = child.spawn("node", [path]); + p.stdout.on("data", function(data) { + console.log("Info from", path, ":", data.toString().trim()); + }); p.stderr.on("data", function(err) { console.log("Error from", path, ":", err.toString()); });