Skip to content

Inconsistencies with IPv6 endpoint specification across platforms #7728

Closed
@gireeshpunathil

Description

@gireeshpunathil
  • Version: master
  • Platform: AIX, Windows
  • Subsystem: cluster, test

I have been debuging some of the test failures in AIX and Windows with respect to client-server connectivity on ipv6 addresses. Here is the summary:

Code:

var net = require('net');
var server = net.createServer(function() {
});

server.listen(0, process.argv[2], function(a, b) {
  console.log(server.address());
  net.connect(server.address().port, process.argv[3], function() {
    console.log('connected');
    process.exit(0);
  });
});

Linux and Mac:


# ./node i.js // no hostname for listen, and connect. Default is unspecified address [expected]
{ address: '::', family: 'IPv6', port: 48168 }
connected
# ./node i.js :: // unspecified address for listen, no hostname for connect. Default is unspecified address [expected]
{ address: '::', family: 'IPv6', port: 46366 }
connected
# ./node i.js ::1 // loopback address for listen, no hostname for connect. Server listens at loopback [expected]
{ address: '::1', family: 'IPv6', port: 57099 }
connected
# ./node i.js :: :: // unspecified address for listen and connect. Default is unspecified address [expected]
{ address: '::', family: 'IPv6', port: 48019 }
connected
# ./node i.js ::1 :: // Loopback for listen, unspecified for connect. [Unexpected, but good]
{ address: '::1', family: 'IPv6', port: 52945 }
connected
# ./node i.js ::1 ::1 // Loopback for both listen and connect. Good and expected.
{ address: '::1', family: 'IPv6', port: 58486 }
connected
# ./node i.js :: ::1 // Unspecified for listen and loopback for connect. Good and expected.
{ address: '::', family: 'IPv6', port: 36496 }
connected

Bottom line of Linux and Mac story is that the unspecified and loopback addresses are interchangeably used, and every combination works.

Windows


>node s.js
{ address: '::', family: 'IPv6', port: 53401 }
connected

>node s.js ::
{ address: '::', family: 'IPv6', port: 53403 }
connected

>node s.js ::1
{ address: '::1', family: 'IPv6', port: 53405 }
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: connect ECONNREFUSED 127.0.0.1:53405
    at Object.exports._errnoException (util.js:1008:11)
    at exports._exceptionWithHostPort (util.js:1031:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1080:14)

>node s.js :: ::
{ address: '::', family: 'IPv6', port: 53408 }
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: connect EADDRNOTAVAIL :::53408
    at Object.exports._errnoException (util.js:1008:11)
    at exports._exceptionWithHostPort (util.js:1031:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1080:14)

>node s.js ::1 ::
{ address: '::1', family: 'IPv6', port: 53410 }
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: connect EADDRNOTAVAIL :::53410
    at Object.exports._errnoException (util.js:1008:11)
    at exports._exceptionWithHostPort (util.js:1031:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1080:14)

>node s.js :: ::1
{ address: '::', family: 'IPv6', port: 53413 }
connected

>node s.js ::1 ::1
{ address: '::1', family: 'IPv6', port: 53415 }
connected

Bottom line of Windows story is that the unspecified and loopback addresses are strictly disjoint.

AIX


# ./node i.js        
{ address: '::', family: 'IPv6', port: 50538 }
connected
# ./node i.js ::
{ address: '::', family: 'IPv6', port: 50540 }
connected
# ./node i.js ::1
{ address: '::1', family: 'IPv6', port: 50542 }
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: connect ECONNREFUSED 127.0.0.1:50542
    at Object.exports._errnoException (util.js:1007:11)
    at exports._exceptionWithHostPort (util.js:1030:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1081:14)
# ./node i.js :: ::
{ address: '::', family: 'IPv6', port: 50544 }
connected
# ./node i.js ::1 ::
{ address: '::1', family: 'IPv6', port: 50546 }
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: connect ECONNREFUSED :::50546
    at Object.exports._errnoException (util.js:1007:11)
    at exports._exceptionWithHostPort (util.js:1030:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1081:14)
# ./node i.js :: ::1
{ address: '::', family: 'IPv6', port: 50548 }
connected
# ./node i.js ::1 ::1
{ address: '::1', family: 'IPv6', port: 50550 }
connected
#

Bottom line of AIX story is thar socket listening at unspecified (any address) is able to get connected from a client specifying loopback address, but vice versa is false.

This behavior is in alignment with the IPv4 behavior with 0.0.0.0 and 127.0.0.1 respectively, in these platforms.

The impact of this bejavior difference is that few test cases fail in some platforms (gc/test-net-timeout.js in windows #7291 and parallel/test-cluster-disconnect-handles in AIX #7563 etc.) but these may be just indications of future larger problems in real applications.

Among all these deviations and in the absence of a clear specification about the connectivity, my inference is that the AIX behavior seem correct, but would like to hear from others.

Metadata

Metadata

Assignees

No one assigned

    Labels

    netIssues and PRs related to the net subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions