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

Windows: SO_REUSEADDR allows listening on occupied port #550

Closed
minrk opened this issue Jun 27, 2012 · 7 comments · Fixed by #551
Closed

Windows: SO_REUSEADDR allows listening on occupied port #550

minrk opened this issue Jun 27, 2012 · 7 comments · Fixed by #551

Comments

@minrk
Copy link
Contributor

minrk commented Jun 27, 2012

Context:

Try to run two instances of helloworld.py example

Symptom:

Linux/OS X (expected): second instance raises Address already in use.
Windows: second instance runs happily, but receives no requests until the first instance shuts down.

Cause:

Setting SO_REUSEADDR seems to result in different behavior between Windows and other platforms.

I don't know if it makes sense to simply skip setting REUSEADDR on Windows or what, but it would be nice if tornado's behavior was consistent.

@bdarnell
Copy link
Member

What about TIME_WAIT? If you don't use SO_REUSEADDR do you sometimes have to wait for the previous incarnation's bindings to expire before you can restart a server? That seems worse than allowing a second non-functioning process to start up.

@alekstorm
Copy link
Contributor

Windows is broken - it interprets SO_REUSEADDR differently from POSIX. From reading this Python bug and the Microsoft documentation, I believe the fix is to set SO_EXCLUSIVEADDRUSE instead on Windows (the only platform it exists on), so that EADDRINUSE is raised.

@minrk
Copy link
Contributor Author

minrk commented Jun 28, 2012

@alekstorm - thanks for the pointer, PR #551 issued

@bdarnell
Copy link
Member

Neither of the linked documents discuss the TIME_WAIT state, which is the reason for using SO_REUSEADDR on posix. I've found contradictory information on the subject, but it looks like maybe windows ignores TIME_WAIT connections by default (eliminating the need for SO_REUSEADDR), but SO_EXCLUSIVEADDDRUSE does check for TIME_WAIT so it may not be appropriate to add it by default. Can you find anything more definitive about the interaction of these options with TIME_WAIT?

@alekstorm
Copy link
Contributor

Looks like we're between a rock and a hard place. You're right - with no
settings, Windows ignores TIME_WAIT, like POSIX does with SO_REUSEADDR, but
it's susceptible to having the connection stolen by a malicious process.
With SO_EXCLUSIVEADDRUSE, it's protected from connection hijacking, but
TIME_WAIT is respected. Which behavior do we want?

See http://twistedmatrix.com/trac/ticket/1151#comment:19,
http://bugs.python.org/msg152697

On Thu, Jun 28, 2012 at 1:09 AM, bdarnell <
reply@reply.github.com

wrote:

Neither of the linked documents discuss the TIME_WAIT state, which is the
reason for using SO_REUSEADDR on posix. I've found contradictory
information on the subject, but it looks like maybe windows ignores
TIME_WAIT connections by default (eliminating the need for SO_REUSEADDR),
but SO_EXCLUSIVEADDDRUSE does check for TIME_WAIT so it may not be
appropriate to add it by default. Can you find anything more definitive
about the interaction of these options with TIME_WAIT?


Reply to this email directly or view it on GitHub:
#550 (comment)

@bdarnell
Copy link
Member

For development the question is easy - TIME_WAIT is a major annoyance while hijacking isn't really a concern, so we want windows' default behavior there. For production it's less clear - security is more important, but avoiding the three minute TIME_WAIT downtime still matters. In practice it seems to be rare for servers to be hardened to the degree that SO_EXCLUSIVEADDRUSE implies (if you've got rogue processes on the local machine you're probably in trouble regardless). It would be nice to let people set this option (or really a hook for setting arbitrary options, as with prepare_curl_callback), but it should probably be off by default.

@alekstorm
Copy link
Contributor

The problem is that socket hijacking doesn't require process elevation - any process can hijack from a server running with Administrator privileges. I was going to suggest SO_EXCLUSIVEADDRUSE with telling users to modify the TcpTimedWaitDelay registry setting, but it appears the minimum value is 30 seconds. I suppose you're right, we should just use no settings at all. Thanks, Microsoft.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants