One of my colleagues at work was struggling with a peculiar problem on his machine. Whenever he tried to access the address of his test project: http://my.project:8080 he was getting connection refused error (my.project points to 127.0.0.1 in the hosts file). The same error appeared when we opened the http://127.0.0.1:8080 address:
We also tried using his machine IPv4 address with a similar result. Interestingly, we soon found that the [::1]:8080 address was working just fine. Updating the hosts file with the following line:
solved the localhost issue but the machine IPv4 address was still not working. I started to wonder which part of Windows network stack is misconfigured on the machine. The next section describes the diagnosing steps we have taken. If you are in a hurry, you may skip it and go directly to the solution at the end of the post.
The first step we took was to diagnose if the IPv4 addresses work on the machine:
> ping 127.0.0.1 Pinging 127.0.0.1 with 32 bytes of data: Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Then we used the awesome psping tool from the Sysinternals package to see if the problem also appears out of the browser:
> psping 127.0.0.1:8080 PsPing v2.10 - PsPing - ping, latency, bandwidth measurement utility Copyright (C) 2012-2016 Mark Russinovich Sysinternals - www.sysinternals.com TCP connect to 127.0.0.1:8080: 5 iterations (warmup 1) ping test: Connecting to 127.0.0.1:8080 (warmup): from 0.0.0.0:20987: The remote computer refused the network connection. Connecting to 127.0.0.1:8080: from 0.0.0.0:20988:
As psping was failing too, we just confirmed nothing was listening on the 8080 port at the 127.0.0.1 address. That posed a question if the problem lies in the web server configuration or the Windows settings. We again used psping to verify this (you could use netcat too). We started psping in the listening mode (normally this mode is used for bandwidth tests):
> psping -b -s 127.0.0.1:2222 PsPing v2.10 - PsPing - ping, latency, bandwidth measurement utility Copyright (C) 2012-2016 Mark Russinovich Sysinternals - www.sysinternals.com Type Control-C to exit. Waiting for TCP connection on 127.0.0.1:2222:
In the other command window we reissued the previous psping test:
> psping 127.0.0.1:8080 PsPing v2.10 - PsPing - ping, latency, bandwidth measurement utility Copyright (C) 2012-2016 Mark Russinovich Sysinternals - www.sysinternals.com TCP connect to 127.0.0.1:8080: 5 iterations (warmup 1) ping test: Connecting to 127.0.0.1:8080 (warmup): from 127.0.0.1:21127: 0.24ms Connecting to 127.0.0.1:8080: from 127.0.0.1:21128: 0.55ms Connecting to 127.0.0.1:8080: from 127.0.0.1:21129: 0.55ms
It succeeded, which ensured us that we need to search for the solution in the web server settings. In the next step we examined the IIS binding configuration for our site:
<site name="my.project" id="1" serverAutoStart="true"> <application path="/"> <virtualDirectory path="/" physicalPath="c:\my.project\" /> </application> <bindings> <binding protocol="http" bindingInformation=":8080:" /> </bindings> </site>
As you could see the binding is specified for any IP address and any hostname, so it should work.
It is time to get a little bit deeper. IIS and IIS Express depend on the HTTP.SYS driver to serve the HTTP requests. The HTTP.SYS configuration is stored in the registry under the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP key. We can use the netsh commands in the http context to change some of the properties. One of the commands grabbed our attention: show iplisten. The result of running it was as follows:
> netsh http show iplisten IP addresses present in the IP listen list: ------------------------------------------- ::
The documentation for the iplisten command clearly explains the output:
Lists all IP addresses in the IP listen list. The IP listen list is used to scope the list of addresses to which the HTTP service binds. “0.0.0.0” means any IPv4 address and “::” means any IPv6 address.
Although IIS binding allowed any IP addresses (both v4 and v6) we found that the HTTP.SYS was accepting only IPv6 addresses. The solution was to add the 0.0.0.0 address to the iplisten settings (clearing the iplisten node should also work):
> netsh http add iplisten 0.0.0.0 IP address successfully added
After restarting IIS, everything went back to normal.