Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Race condition when getting remoteAddress of connection #7566

Closed
@LinusU

Description

@LinusU

If the connection has already been closed before the connect event is handled by user code, the remoteAddress of the connection will not be available.

Reproducing this is very hard but I managed to get it working sometimes with gnu netcat version 0.7.1 with the close flag, executed on another machine:

hostname | nc -nc <ip> 1337

Testcase

var net = require('net');
var assert = require('assert');

net.createServer(function (c) {
  assert(c.remoteAddress);
}).listen(1337);

Output

assert.js:92
  throw new assert.AssertionError({
        ^
AssertionError: "undefined" == true
    at Server.<anonymous> (/private/tmp/socket-race-condition/test.js:6:3)
    at Server.EventEmitter.emit (events.js:95:17)
    at TCP.onconnection (net.js:1191:8)

More info

Information about the socket can be provided when calling accept, however libuv ignores that data:

https://github.com/joyent/libuv/blob/9b4f2b84f10c96efa37910f324bc66e27aec3828/src/unix/core.c#L406

Instead, when doing c.remoteAddress a call to getpeername is executed.

  1. remoteAddress https://github.com/joyent/node/blob/940974ed039d3c9a8befe608d9c95b2ffdb457d3/lib/net.js#L569
  2. _getpeername https://github.com/joyent/node/blob/940974ed039d3c9a8befe608d9c95b2ffdb457d3/lib/net.js#L555
  3. TCPWrap::GetPeerName https://github.com/joyent/node/blob/940974ed039d3c9a8befe608d9c95b2ffdb457d3/src/tcp_wrap.cc#L182
  4. uv_tcp_getpeername https://github.com/joyent/libuv/blob/9b4f2b84f10c96efa37910f324bc66e27aec3828/src/unix/tcp.c#L187

I think that the only reliable way to get the remoteAddress is to get it from the accept call and store it along with the connection.

Additional error

In addition to the assertion error, if I only log the c.remoteAddress and don't terminate the process, I will get the following error. It's not emitted on the server (net.createServer) and thus I can't trap it with server.on('error', ...).

Error: read ECONNRESET
    at errnoException (net.js:904:11)
    at TCP.onread (net.js:558:19)

syscall: read
code: ECONNRESET

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions