Skip to content

Commit

Permalink
net: ensure Socket reported address is current
Browse files Browse the repository at this point in the history
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: #2095
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
  • Loading branch information
rmg authored and sam-github committed Aug 6, 2015
1 parent 67987d9 commit 5d2acfb
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
34 changes: 34 additions & 0 deletions test/parallel/test-net-socket-local-address.js
Original file line number Diff line number Diff line change
@@ -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();
});
}

0 comments on commit 5d2acfb

Please sign in to comment.