aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory P. Smith <gps@google.com>2021-11-08 18:44:25 -0800
committerGitHub <noreply@github.com>2021-11-08 18:44:25 -0800
commit30d279a5675f7c1af7f289a4328bd3fc77bf3416 (patch)
treef3c70c0684caf18697bb1416bf5bdf4c7cb211ba
parentd5a84793a54bbe4fa6357f1e68ce1bfc0580704e (diff)
downloadportpicker-30d279a5675f7c1af7f289a4328bd3fc77bf3416.tar.gz
bind(0) before probing for random available ports. (#28)
When not using a portserver, assume that the OS knows best. This should improve reliability. Though the best thing to do is to use a portserver...
-rw-r--r--ChangeLog.md6
-rw-r--r--setup.cfg2
-rw-r--r--src/portpicker.py16
3 files changed, 15 insertions, 9 deletions
diff --git a/ChangeLog.md b/ChangeLog.md
index 8ca7f80..3cda728 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,9 @@
+## 1.5.1
+
+* When not using a portserver *(you really should)*, try the `bind(0)`
+ approach before hunting for random unused ports. More reliable per
+ https://github.com/google/python_portpicker/issues/16.
+
## 1.5.0
* Add portserver support to Windows using named pipes. To create or connect to
diff --git a/setup.cfg b/setup.cfg
index 6a1e788..63c1ac4 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
# https://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files
[metadata]
name = portpicker
-version = 1.5.0
+version = 1.5.1b1
maintainer = Google LLC
maintainer_email = greg@krypto.org
license = Apache 2.0
diff --git a/src/portpicker.py b/src/portpicker.py
index 4717bbc..fc2825b 100644
--- a/src/portpicker.py
+++ b/src/portpicker.py
@@ -198,14 +198,6 @@ def _pick_unused_port_without_server(): # Protected. pylint: disable=invalid-na
Raises:
NoFreePortFoundError: No free port could be found.
"""
- # Try random ports first.
- rng = random.Random()
- for _ in range(10):
- port = int(rng.randrange(15000, 25000))
- if is_port_free(port):
- _random_ports.add(port)
- return port
-
# Next, try a few times to get an OS-assigned port.
# Ambrose discovered that on the 2.6 kernel, calling Bind() on UDP socket
# returns the same port over and over. So always try TCP first.
@@ -217,6 +209,14 @@ def _pick_unused_port_without_server(): # Protected. pylint: disable=invalid-na
_random_ports.add(port)
return port
+ # Try random ports as a last resort.
+ rng = random.Random()
+ for _ in range(10):
+ port = int(rng.randrange(15000, 25000))
+ if is_port_free(port):
+ _random_ports.add(port)
+ return port
+
# Give up.
raise NoFreePortFoundError()