Opened 8 years ago

Closed 7 years ago

Last modified 7 years ago

#5374 closed defect (fixed)

getsockname() to check for address change failed

Reported by: funkstar Owned by:
Priority: High Milestone: Tor: 0.2.3.x-final
Component: Core Tor/Tor Version: Tor: 0.2.3.12-alpha
Severity: Keywords: tor-relay
Cc: Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

Full line:
[Warning] getsockname() to check for address change failed: Invalid argument [WSAEINVAL]

I was using the latest Vidalia 0.3.1 alpha with the latest Tor 0.2.3.12 alpha running on Windows 8 as a bridge for censored users. I noticed that this error kept on repeating until I enabled the "Attempt to automatically configure port forwarding" option.

Firstly: I opened the port in my router and entered it into the config myself.
Secondly: Automatic port forwarding doesn't work on Windows 8 so I don't need it enabled.

After enabling the option, Tor actually started working. I also didn't get a Windows firewall popup asking for network access until I enabled this option. It seems like there's some network code that only runs when this option is enabled, where as it should always run?

On an unrelated note, it seems that the GEOIP file doesn't exist in this version:
[Warning] Failed to open GEOIP file C:\Users\<snip>\AppData\Roaming\tor\geoip. We've been configured to see which countries can access us as a bridge, and we need GEOIP information to tell which countries clients are in.

Child Tickets

Attachments (1)

gsa.c (1.1 KB) - added by nickm 7 years ago.

Download all attachments as: .zip

Change History (16)

comment:1 Changed 8 years ago by arma

Milestone: Tor: unspecifiedTor: 0.2.3.x-final

comment:2 Changed 8 years ago by arma

Sounds related to #1827 (which got merged in Tor 0.2.3.11-alpha):

    - Try to use system facilities for enumerating local interface
      addresses, before falling back to our old approach (which was
      binding a UDP socket, and calling getsockname() on it). That
      approach was scaring OS X users whose draconian firewall
      software warned about binding to UDP sockets, regardless of
      whether packets were sent. Now we try to use getifaddrs(),
      SIOCGIFCONF, or GetAdaptersAddresses(), depending on what the
      system supports. Resolves ticket 1827.

comment:3 Changed 8 years ago by funkstar

Ok, what now? :D

comment:4 Changed 8 years ago by arma

Component: Tor BridgeTor Relay

One next step might be to ask somebody else to run the latest Tor 0.2.3.x release on Windows as a relay or bridge, and see if they encounter the problem too? It might be that the patch from #1827 simply doesn't work well on Windows.

Any volunteers here? :)

comment:5 Changed 8 years ago by funkstar

Well Windows 8 is currently free so you can do it yourself in a VM if you wish. I do have a laptop I can wipe as many times as needed for testing and have a copy of win7 to double check if you'd like.

comment:6 Changed 8 years ago by nickm

So, the "attempt to automatically configure port forwarding" option is a Vidalia thing that turns on Vidalia's UPNP feature.

I wonder if this could be an IPv6 issue: the client_check_address_changed code is totally IPv4 specific.

But the MSDN documentation for getsockname() says that a WSAEINVAL means, "The socket has not been bound to an address with bind, or ADDR_ANY is specified in bind but connection has not yet occurred." So that doesn't sound like an IPv6 issue. But looking at the code for the one function that calls client_check_address_changed(), it only calls it if the connect has happened. So that's weird. Maybe there's something crazy going on in windows, and it only wants to have getsockname() work once the connect() is finished? That would be crazy. I'll try writing a little test program there, I guess.

Opening another ticket for the IPv6 issue: conceivably it's related and the documentation is just wrong.

Changed 7 years ago by nickm

Attachment: gsa.c added

comment:7 Changed 7 years ago by nickm

Milestone: Tor: 0.2.3.x-finalTor: 0.2.2.x-final
Status: newneeds_review

Okay, after investigating a little, I can confirm that we're doing the wrong thing for XP here too -- it's just that XP behaves wrong in a different way than windows 8.

It looks like Windows doesn't want you to call getsockname() on a nonblocking socket on which you have called connect, but which has not yet finished connecting. On XP, it succeeds, and calls your address INADDR_ANY. On Windows 8, it appears to fail with this warning.

The right fix, I think, is to delay our call to client_check_address_changed until the connection has actually completed.

Please see branch "bug5374" in my public repository. This could apply to 0.2.2.

comment:8 Changed 7 years ago by nickm

To see whether I'm right about the cause, I've attached a short test program "gsa.c". You can build it with mingw using "gcc -Wall gsa.c -lws2_32 -o gsa.exe". To run it, try doing "./gsa.exe" and then "./gsa.exe 1". The first time, it will try a nonblocking socket. The second time, it will try a blocking socket.

For me, on XP, using a nonblocking socket, it reports my address as 0x0. Using a blocking socket, it reports my address correctly. Notably, if I insert a one second delay between the connect() and the getsockname(), the blocking case works too... so I'm pretty sure that's what the problem is on XP.

Let's see if the win 8 problem is the same. Shandoit is going to try to run it, but doesn't currently have a win8 installation, so it might take a little while for an answer there. If you've got a win8 installation and a C compiler, you might want to give it a shot.

comment:9 Changed 7 years ago by Shondoit

When built and run on Windows 8 the first test case reports "Error from getsockname: 10022"
The second test case returns "getsockname() was happy. My address was 0xa00020f"
The first test case with Sleep(1000) before getsockname() reports it's happy too.

comment:10 Changed 7 years ago by nickm

Shondoit confirmed my guess! Bwa ha ha!

To summarize: unlike other operating systems, when you connect() a nonblocking socket on windows, it doesn't work if the socket isn't yet connected.

We didn't notice on XP or Win 7, because it failed by declaring success (!) and reporting the _bound_ address (INADDR_ANY). On Win 8, it apparently declares failure and reports WSAEINVAL.

The lingering mysteries are:

  • Using vidalia's automatic port forwarding feature suppressed the warning -- does that make Vidalia use OutboundBindAddress?
  • Why doesn't Windows know what network address you're using for a connection until it gets a SYN ACK on the connection? Surely once the SYN has been sent, it knows what address it sent it from.

But let's set those aside for now, since my branch should fix the issue anyway. "bug5374" is still the one to look at.

comment:11 Changed 7 years ago by nickm

Milestone: Tor: 0.2.2.x-finalTor: 0.2.3.x-final
Resolution: fixed
Status: needs_reviewclosed

Applying this to 0.2.3 rather than 0.2.2: windows users for versions other than win8 are bumping along without noticing and reporting the problem here, and win8 users are bleeding-edge enough that they should be happy with the 0.2.3.x series.

comment:12 Changed 7 years ago by Jessica_XY

So what's the fix?

comment:13 Changed 7 years ago by arma

Wait for 0.2.3.16-alpha, and (if necessary) wait for Windows TBB bundles for it.

comment:14 Changed 7 years ago by nickm

Keywords: tor-relay added

comment:15 Changed 7 years ago by nickm

Component: Tor RelayTor
Note: See TracTickets for help on using tickets.