Fix tcp connection tracking

This commit is contained in:
Kagami Hiiragi 2015-02-06 16:04:17 +03:00
parent 9ed1c87df8
commit be6234893f
2 changed files with 29 additions and 10 deletions

View File

@ -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();
}

View File

@ -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());
});