Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TCP socket unable to connect to localhost #2237

Closed
RIAEvangelist opened this issue Jul 24, 2015 · 24 comments
Closed

TCP socket unable to connect to localhost #2237

RIAEvangelist opened this issue Jul 24, 2015 · 24 comments
Labels
net Issues and PRs related to the net subsystem. windows Issues and PRs related to the Windows platform.

Comments

@RIAEvangelist
Copy link

If the client machine is not connected to a network, TCP sockets do not work.

An example is to install node-ipc npm install node-ipc

then run the basic TCP server and clients with network connection and without.

tested using iojs install on windows 7 x32
works with network connection
can not connect without network connection even on localhost

tested using nw.js with both iojs and nodejs install on windows 7 x32
nw.js like atom uses io.js on its back end.
works with network connection
can not connect without network connection even on localhost

referenced here in the node-ipc module RIAEvangelist/node-ipc/issues/32
and here on atom electron electron/electron/issues/2299

@user478377
Copy link

The following code seems to work fine on a disconnected machine.

var net=require('net');

net.createServer(function() {
    console.log('request');
}).listen(8000);

net.connect({host: '127.0.0.1', port: 8000}, function() {
    console.log('connected');
});

Verified with both x86 and x64 as well as with the loopback address and "localhost".

@mscdex mscdex added net Issues and PRs related to the net subsystem. windows Issues and PRs related to the Windows platform. labels Jul 24, 2015
@YurySolovyov
Copy link

Maybe it is something wrong with hosts file?

@novacrazy
Copy link

When you first ran your app, did Window's pop up with a notification that looked like This? It's surprisingly easy to miss sometimes. You might want to check your firewall and antivirus to see if either is blocking Node/io.js from accessing networking stuff, even on local networks sometimes. Windows is weird.

@RIAEvangelist
Copy link
Author

@YuriSolovyov nope. went though everything even installing a seperate loop back.

@novacrazy no.

@user478377 when running the same application via node.js it works correctly. iojs causes a failure with this method you can see the server implementation in the node-ipc socket server. I'll run the raw example TCPSocket code as well and give further feedback.

@RIAEvangelist
Copy link
Author

@user478377 The code you provided does seem to work when specifying 127.0.0.1 if ommitted when not on the network it tries to use local host which causes the error.

When ommitted io.js should use 127.0.0.1 as the default instead of localhost as this will not work specifically on the windows environment.

I myself use linux, however... some large portion of users do infact use windows.

@RIAEvangelist
Copy link
Author

I'll see if I can find this in the code and commit a patch

@bnoordhuis
Copy link
Member

It's system-specific what 'localhost' resolves to. It could be 127.0.0.1, ::1, or nothing, if there is no loopback device.

The choice for localhost as the default is intentional. Defaulting to 127.0.0.1 would be wrong on an IPv6-only system, for example.

@RIAEvangelist
Copy link
Author

@bnoordhuis The issue is then that the existing nodejs implementation works while the iojs implementation does not.

node will run as expected, only iojs has this issue.

@bnoordhuis
Copy link
Member

That depends on your point of view. On that aforementioned IPv6-only system, for example, io.js would work but node.js v0.10 would not. I believe v0.12 and io.js have identical behavior but don't quote me on that.

@RIAEvangelist
Copy link
Author

@bnoordhuis They do not have identical behavior. Which is what I am describing. The latest stable node implementation works. The latest "stable" iojs implementation does not. If they did this issue would not be an issue ;)

Both versions were installed from the respective websites.

This is a clear difference between the way iojs and nodejs are normalizing the default value.

I notice tcp_wrap.cc is quite a bit smaller in iojs than in node.

I am assuming it may be as simple as one IF win32 missing. or as complex as a difference in how the ipv6 address is received.

iojs causes a _DNSConfig_ error to be displayed in windows. Where as node does not.

is it possible iojs is always attempting to get the ip of a string via dns? while node was handling the specific case of localhost?

@RIAEvangelist
Copy link
Author

I believe win shuts down DNS if not connected to a network.

@RIAEvangelist
Copy link
Author

So, important point to note is that it is only the client that has an issue. the server can bind to localhost correctly. The client however, gets ENOENT when trying to connect.

@user478377
Copy link

To be honest, neither node's nor io's behaviour are correct IMNSHO.

Neither runtime should treat the host like an optional field but instead require a host address to be explicitly specified or throw an error otherwise. The host address is one of the most fundamental bits of data in establishing a connection to simply default to some "random" value one might see fit. I couldnt think of any other environment where leaving out the host would be accepted (be it C, Java, Pascal, Perl, heck even PHP).

@RIAEvangelist
Copy link
Author

I stand corrected. With some testing, I was able to show @bnoordhuis is correct, node if the network card is off, the client does have the same issue. This is infact not a bug in iojs. but a windows related issue.

I hate windows. why doesn't it just work like unix?

@RIAEvangelist
Copy link
Author

@user478377 defaulting to localhost is a nice idea. Just not implemented well.

@RIAEvangelist
Copy link
Author

Since this is a bug on both systems I pushed a patch into my module to default to 127.0.0.1 if a host is not specified.

Other than this being wrong just to jack a round a bug in the language does anyone see any potential issues with this?

I believe it should work with ipv4 and ipv6 correct?

@sam-github
Copy link
Contributor

127.0.0.1 will not work with IPv6, its an IPv4 address.

Defaulting to localhost allows the system to be configured as to whether localhost should (edit: "be") IPv4 or IPv6.

Its unfortunate that this may trigger DNS resolution failures on systems where the resolver is not configured to know what localhost is. This isn't specific to Windows, just more common, apparently, it can be seen on Linux, too, if "localhost" isn't in either /etc/hosts, or the upstream DNS hasn't added an entry for localhost (I've seen this):

w/sn % node -e 'require("net").connect(7, console.log)'                                        
events.js:141
      throw er; // Unhandled 'error' event
            ^
Error: getaddrinfo ENOTFOUND localhost undefined:7
    at errnoException (dns.js:25:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)
w/sn % head /etc/hosts
#127.0.0.1      localhost

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback

@RIAEvangelist
Copy link
Author

RIAEvangelist commented Jul 24, 2015 via email

@sam-github
Copy link
Contributor

You could do a dns.resolve of "localhost", and fallback on "127.0.0.1" if its not resolveable.

@RIAEvangelist
Copy link
Author

That's what causes the problem in windows to begin with I believe.

I may be able to use os.networkinterfaces

@RIAEvangelist
Copy link
Author

@sam-github I did some research on both linux and win. looks like your suggestion will be the best solution. Thanks for pointing it out. The variability in the networkInterfaces call is a bit more convoluted even though it does give more information.

@RIAEvangelist
Copy link
Author

in the end to maintain backwards compatibility I detected the first connection family v6 or v4 and used that to form the default localhost.

@user478377
Copy link

Whats not clear to me is why you had to leave the host field empty. Simply using the appropriate IP address for localhost would have prevented the issue in the first place.

I still stand by what I wrote before, having the host optional is not a good idea and leads to problems such as this one. There's a reason why "every" other other (major) language requires the host address.

@RIAEvangelist
Copy link
Author

The module has a LOT of users and was originally designed to mimic the node implementation. So requiring the address or IP now would break backwards compatibilty, and if they put in localhost, it still wouldn't work for windows users without network connection.

Also, if the use case is to be implemented on various machines, IPv6 & IPv4 they would have to write separate code for each, or detect it them selves. Allowing them to follow the node implementation simplifies this for users who may not know about IPv6/IPv4 issues or windows specific localhost issues. Thus allowing the module to "just work" (better than node even)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
net Issues and PRs related to the net subsystem. windows Issues and PRs related to the Windows platform.
Projects
None yet
Development

No branches or pull requests

7 participants