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.

PR-URL: https://github.com/nodejs/io.js/pull/2095
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
This commit is contained in:
Ryan Graham 2015-07-02 15:26:21 -07:00 committed by Sam Roberts
parent 67987d9d83
commit 5d2acfb8e5
2 changed files with 38 additions and 0 deletions

View File

@ -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;
@ -1032,6 +1035,7 @@ function afterConnect(status, handle, req, readable, writable) {
assert.ok(self._connecting);
self._connecting = false;
self._sockname = null;
if (status == 0) {
self.readable = readable;

View File

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