镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Why listening "::" (all IPv6) also get "0.0.0.0"(all IPv4) listened? #9390

Description

@jjqq2013
  • Version:v7.0.0
  • Platform:Windows 7 Pro
  • Subsystem:

I found a strange problem, i created a simple TCP server to listen at port 5555 of "::"(all IPv6 interfaces)

net.createServer(c=>console.log).listen(5555,'::')

Then i found all IPv4 interfaces are also listening port 5555.

> netstat -an | findstr /I :5555
  TCP    0.0.0.0:5555           0.0.0.0:0              LISTENING
  TCP    [::]:5555              [::]:0                 LISTENING

Another relevant problem is, if i do not specify host, or use undefined, or empty string,

net.createServer(c=>console.log).listen(5555)
//or net.createServer(c=>console.log).listen(5555,undefined)
//or net.createServer(c=>console.log).listen(5555,'')

It should listen :: OR 0.0.0.0, not both, according the document:

server.listen([port][, hostname][, backlog][, callback])
If the hostname is omitted, the server will accept connections on any IPv6 address (::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise

But the fact is both :: and 0.0.0.0 get listened.

I don't know which is correct? document or implementation? Anyway, this is a bit confusing.
Or maybe this is just a trick implementation of the Windows OS itself ?

Activity

  1. added
    questionIssues asking questions about Node.js.
    netIssues and PRs related to the net subsystem.
    on Nov 1, 2016
  2. bnoordhuis commented on Nov 1, 2016

    @bnoordhuis
    Member

    Or maybe this is just a trick implementation of the Windows OS itself ?

    It's called dual-stack mode and it's platform-specific. Linux lets you enable/disable it through the net.ipv6.bindv6only sysctl, I assume Windows has something similar.

    I'll add doc tags because it doesn't look like the documentation currently mentions this. Libuv has UV_TCP_IPV6ONLY and UV_UDP_IPV6ONLY flags that we could leverage along the lines of net.createServer({ ipv6only: true }).

  3. jjqq2013 commented on Nov 1, 2016

    @jjqq2013
    ContributorAuthor

    Thank you. You saved my time.

  4. silverwind commented on Nov 1, 2016

    @silverwind
    Contributor

    This dual stack mode is certainly confusing, as most people would expect :: (The alias for all v6 addresses) to bind to just v6, not magically also binding v4 on certain platforms.

    The user has no way of knowing if the platform supports dual-stack, so if one wants to listen on v4 and v6, you'd have to try listening on both :: and 0.0.0.0 and catch the EADDRINUSE from the v4 listen on platforms that don't support it (I think macOS is an example).

    I'd argue that ipv6only behavior should be made the default behaviour when hostname is ::. The dual-stack mode could still be in effect when hostname is undefined.

  5. added
    docIssues and PRs related to Node.js documentation.
    and removed
    docIssues and PRs related to Node.js documentation.
    on Dec 1, 2016
  6. mika-fischer commented on Jan 20, 2017

    @mika-fischer
    Contributor

    Two things to note about this bug:

    1. It makes it more difficult than necessary to create portable code.
    2. It makes it impossible to create a IPv6-only socket with nodejs on Linux, and that just seems wrong.
  7. jjqq2013 commented on Feb 5, 2017

    @jjqq2013
    ContributorAuthor

    Hi, i forgot to tell everyone that this phenomenon
    not only happens in Windows, but also Linux, Mac.

    As my test,

    On Mac (OS X EI Captitan 10.11.6), the netstat does shows tcp46 which means TCP4 and TCP6.

    tcp46      0      0  *.5555                 *.*                    LISTEN 
    

    On Linux Ubuntu 16.04, the netstat does show only tcp6, but in fact, the same TCP4 port can be connected!

    tcp6       0      0 :::5555                 :::*                    LISTEN     
    

    After all, this is very OS-dependent.

  8. 5 remaining items

  9. sam-github commented on Feb 14, 2017

    @sam-github
    Contributor

    How do I calculate THE_EQUIVALENT_IPv4_ADDR? I run linux, and node -e "net.createServer(c=>console.log).listen(5555,'fe80::7d2b:81c4:1f2:2ad%wlan1')" worked fine.

  10. jjqq2013 commented on Feb 15, 2017

    @jjqq2013
    ContributorAuthor

    @sam-github thank you for the test. I just run ip addr | grep inet to show all ip4 ip6 pair and find it manually.

  11. sam-github commented on Feb 16, 2017

    @sam-github
    Contributor

    Not sure this is what you want, or if my machine has enough support for IPv6, but here it is:

    % ip addr | grep inet
        inet 127.0.0.1/8 scope host lo
        inet6 ::1/128 scope host 
        inet 192.168.0.181/24 brd 192.168.0.255 scope global dynamic wlan1
        inet6 fe80::7d2b:81c4:1f2:2ad/64 scope link 
    
    % node -e "require('net').createServer(c=>console.log).listen(5555,'fe80::7d2b:81c4:1f2:2ad%wlan1')"
    % node -e "net.connect(5555,'192.168.0.181',()=>console.log('connected'))"
    events.js:161
          throw er; // Unhandled 'error' event
          ^
    
    Error: connect ECONNREFUSED 192.168.0.181:5555
    
  12. jjqq2013 commented on Feb 16, 2017

    @jjqq2013
    ContributorAuthor

    @sam-github thank you.

    This is what i want! This is a proof of that "On linux, without special configuration, listening actual IPv6 address will not cause equivalent IPv4 address also being listened"

    So, what is your linux distribution? (cat /etc/*release* can see it)

  13. sam-github commented on Feb 16, 2017

    @sam-github
    Contributor

    ubuntu 16.10, kernel 4.8.0-34-generic

  14. sam-github commented on Feb 16, 2017

    @sam-github
    Contributor

    I think it likely proves just "on this linux distro, with default configuration...", I could probably config ipv4 to redirect to ipv6

  15. jjqq2013 commented on Feb 16, 2017

    @jjqq2013
    ContributorAuthor

    Yes, with default configuration, this is exactly what i want to prove.

    Thank you.

    So, all typical test are done.

    OS Listen IPv6 address Does equivalent IPv4 auto listened
    Windows 7Pro/10 :: YES
    Mac OS X EI Capitan 10.11.6 :: YES
    Ubuntu 14.04/16.04 :: YES
    Windows 7Pro/10 ::1 NO
    Mac OS X EI Capitan 10.11.6 ::1 NO
    Ubuntu 14.04/16.04 ::1 NO
    Windows 7Pro/10 ActualIPv6Address NO
    Mac OS X EI Capitan 10.11.6 ActualIPv6Address NO
    Ubuntu 16.10 ActualIPv6Address NO

    All test is done under default configuration about IPv6.

    So my conclusion is that we should only mention about the amazing effect of listening ::.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    docIssues and PRs related to Node.js documentation.netIssues and PRs related to the net subsystem.questionIssues asking questions about Node.js.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions