Background Info
I'm developing a network-enabled embedded device that is intended to communicate with a server. Because this server will be running linux (but I require Windows tools for development), I'm running a VM with Ubuntu Server 14.04 for dev purposes.
The embedded aspect isn't important for this question, as I'm stripping back to the simplest test setup (just have host connect to server on VM to see a TCP connection get established) for troubleshooting.
Network Setup
D-Link DIR-615 running DD-WRT [v24-sp2 (03/25/13) std (SVN revision 21061)], static IPs assigned to host and VM by MAC filter, DNS feature enabled
Development Machine (192.168.5.117, dev.test.lan)
Ubuntu VM (192.168.5.118, vm.test.lan) - using a bridged connection (NAT doesn't work as the client will initiate connection to VM)
Router isn't connected to any sort of WAN, only wired connections, Wi-fi is disabled
Sanity Checks Performed
ping host from VM succeeds (using IP or dns name)
ping VM from host succeeds (using IP or dns name)
nc between host <-> VM (can listen/connect from either side) [listening on port 9050]
within VM, can connect via nc to server application running on VM, a connection is successfully established [to port 9050]
Windows firewall opened for incoming/outgoing TCP connections on port 9050
Problem Analysis
Using wireshark, I'm able to see TCP connections working succesfully when performing the nc sanity test (host <-> VM).
When I run the server (written in python, using asyncio) on the VM, and try to connect via nc from the host, the server doesn't see any connection come in (but we know that connecting from nc to the server works, as that was tested inside the VM successfully).
From wireshark I see the host sending a SYN to the VM, after which the VM responds with [RST, ACK]. The host retries transmission twice before giving up.
Questions
Is a bridged connection the appropriate setting to use for the VM?
What is the best way to find out where the RST is coming from? (is it the router, the VMs TCP/IP stack, or is some part of Python causing it?)
Update:
Tried nc 192.168.5.118 9050
within the VM and observed the same refused connection behaviour as if I had tried from host. Based on what Adam has said, it looks like we're getting closer. Will try Adam's suggestion as well and post an update.
The RST packet is being sent by the OS to indicate that the port is closed—no process is bound to it and listening. As a result, the client trying to connect will very quickly fail with ECONNREFUSED
(connection refused). This is perfectly normal behavior.
How exactly are you binding to the port in your Python server process? Are you binding to the correct network interface? If you accidentally bound to only the loopback device (localhost
or 127.0.0.1
), then you'll see exactly what you're describing: local connections from the machine to itself will succeed just fine, but connections from external hosts will fail.
In Python, you typically use either ''
or '0.0.0.0'
as the address portion to indicate that you want to bind to all network interfaces; this is equivalent to the C constant INADDR_ANY
:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', port))