From 810beca8eba730009f0a211fd504e0ff80244d5c Mon Sep 17 00:00:00 2001 From: Ryan Graham Date: Thu, 2 Jul 2015 15:26:21 -0700 Subject: [PATCH] net: ensure Socket reported address is current Any time the connection state or the underlying handle itself changes, the socket's name (aka, local address) can change. To deal with this we need to reset the cached sockname any time we set or unset the internal handle or an existing handle establishes a connection. --- lib/net.js | 4 +++ .../parallel/test-net-socket-local-address.js | 34 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 test/parallel/test-net-socket-local-address.js diff --git a/lib/net.js b/lib/net.js index b5ae15e4692393..84540c859e406b 100644 --- a/lib/net.js +++ b/lib/net.js @@ -93,6 +93,7 @@ function initSocketHandle(self) { self.destroyed = false; self.bytesRead = 0; self._bytesDispatched = 0; + self._sockname = null; // Handle creation may be deferred to bind() or connect() time. if (self._handle) { @@ -469,6 +470,7 @@ Socket.prototype._destroy = function(exception, cb) { }); this._handle.onread = noop; this._handle = null; + this._sockname = null; } // we set destroyed to true before firing error callbacks in order @@ -871,6 +873,7 @@ Socket.prototype.connect = function(options, cb) { this.destroyed = false; this._handle = null; this._peername = null; + this._sockname = null; } var self = this; @@ -1023,6 +1026,7 @@ function afterConnect(status, handle, req, readable, writable) { assert.ok(self._connecting); self._connecting = false; + self._sockname = null; if (status == 0) { self.readable = readable; diff --git a/test/parallel/test-net-socket-local-address.js b/test/parallel/test-net-socket-local-address.js new file mode 100644 index 00000000000000..4c0e31d08c4771 --- /dev/null +++ b/test/parallel/test-net-socket-local-address.js @@ -0,0 +1,34 @@ +'use strict'; +var common = require('../common'); +var assert = require('assert'); +var net = require('net'); + +var conns = 0; +var clientLocalPorts = []; +var serverRemotePorts = []; + +var server = net.createServer(function(socket) { + serverRemotePorts.push(socket.remotePort); + conns++; +}); + +var client = new net.Socket(); + +server.on('close', function() { + assert.deepEqual(clientLocalPorts, serverRemotePorts, + 'client and server should agree on the ports used'); + assert.equal(2, conns); +}); + +server.listen(common.PORT, common.localhostIPv4, testConnect); + +function testConnect() { + if (conns == 2) { + return server.close(); + } + client.connect(common.PORT, common.localhostIPv4, function() { + clientLocalPorts.push(this.localPort); + this.once('close', testConnect); + this.destroy(); + }); +}