Repository: benoitc/gunicorn

Issue:
Upgrading to 19.7.0 means can't bind anymore
Upgraded to latest gunicorn and could not bind ip address anymore (simple wsgi app, ipv4 or ipv6 same story).

```
foo@xxx:~$ cd current
foo@xxx:~/current$ . env/bin/activate
foo@xxx:~/current$ gunicorn my.wsgi.package
[2017-03-10 18:50:46 +0000] [9242] [INFO] Starting gunicorn 19.7.0
[2017-03-10 18:50:46 +0000] [9242] [ERROR] Retrying in 1 second.
[2017-03-10 18:50:47 +0000] [9242] [ERROR] Retrying in 1 second.
[2017-03-10 18:50:48 +0000] [9242] [ERROR] Retrying in 1 second.
[2017-03-10 18:50:49 +0000] [9242] [ERROR] Retrying in 1 second.
[2017-03-10 18:50:50 +0000] [9242] [ERROR] Retrying in 1 second.
[2017-03-10 18:50:51 +0000] [9242] [ERROR] Can't connect to ('127.0.0.1', 8000)
```

Reverting to 19.6.0 fixes the problem.

System version : Linux xxx 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u1 x86_64 GNU/Linux

Let me know if I can provide more info, 19.6.0 is acceptable solution for me but I guess that's a regression you wanna at least understand ?


Discussion:
Adding to @hartym comment using --log-level debug I get the following:

```
[2017-03-13 15:49:39 +0100] [7175] [INFO] Starting gunicorn 19.7.0
[2017-03-13 15:49:39 +0100] [7175] [DEBUG] connection to ('0.0.0.0', 8000) failed: [Errno 92] Protocol not available
[2017-03-13 15:49:39 +0100] [7175] [ERROR] Retrying in 1 second.
[2017-03-13 15:49:40 +0100] [7175] [DEBUG] connection to ('0.0.0.0', 8000) failed: [Errno 92] Protocol not available
[2017-03-13 15:49:40 +0100] [7175] [ERROR] Retrying in 1 second.
[2017-03-13 15:49:41 +0100] [7175] [DEBUG] connection to ('0.0.0.0', 8000) failed: [Errno 92] Protocol not available
[2017-03-13 15:49:41 +0100] [7175] [ERROR] Retrying in 1 second.
[2017-03-13 15:49:42 +0100] [7175] [DEBUG] connection to ('0.0.0.0', 8000) failed: [Errno 92] Protocol not available
[2017-03-13 15:49:42 +0100] [7175] [ERROR] Retrying in 1 second.
[2017-03-13 15:49:43 +0100] [7175] [DEBUG] connection to ('0.0.0.0', 8000) failed: [Errno 92] Protocol not available
[2017-03-13 15:49:43 +0100] [7175] [ERROR] Retrying in 1 second.
[2017-03-13 15:49:44 +0100] [7175] [ERROR] Can't connect to ('0.0.0.0', 8000)
```
It's very hard to imagine why this would be. Are you positive that nothing else was bound on the port at that time?
Hmm. It does seem you're binding to 0.0.0.0 now, when you used to be using 127.0.0.1. Does this make a difference?
Oh, I see. Both logs are from 19.7.0.
@tilgovi  For my part I double checked, on the VM and try on another "empty" VM and the result is the same, in both case using 19.6 worked perfectly.
I suspect this is due to SO_REUSEPORT issues.

We probably need to make a change like this one in thriftpy: https://github.com/eleme/thriftpy/pull/264
Any chance you can test this?

The change would be in `gunicorn/sock.py` in the `set_options` method of `BaseSocket` class.

Resolving patch:
diff --git a/gunicorn/sock.py b/gunicorn/sock.py
--- a/gunicorn/sock.py
+++ b/gunicorn/sock.py
@@ -39,8 +39,12 @@ def __getattr__(self, name):
 
     def set_options(self, sock, bound=False):
         sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-        if hasattr(socket, 'SO_REUSEPORT'):
-            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
+        if hasattr(socket, 'SO_REUSEPORT'):  # pragma: no cover
+            try:
+                sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
+            except socket.error as err:
+                if err[0] not in (errno.ENOPROTOOPT, errno.EINVAL):
+                    raise
         if not bound:
             self.bind(sock)
         sock.setblocking(0)


Test patch: