@@ -57,15 +57,26 @@ class PortMap:
5757 def real_port (self , virtual : int , family : int = _AF_INET ) -> int | None :
5858 """Get or allocate the real port for a virtual port.
5959
60- Allocates a free real port from the kernel on first use.
61- If proxy=True, also starts listening on the virtual port.
60+ If the virtual port is free, reserves it and returns it unchanged
61+ (no rewrite, no proxy — the sandbox binds the port directly).
62+ Only allocates a different real port + proxy when the virtual port
63+ is already taken by another sandbox.
6264 Returns None if allocation fails.
6365 """
6466 with self ._lock :
6567 if virtual in self ._virtual_to_real :
6668 return self ._virtual_to_real [virtual ]
6769
68- # Ask the kernel for a free port
70+ # Fast path: try to reserve the virtual port itself.
71+ # If successful, the sandbox binds directly — no proxy needed.
72+ real = self ._try_reserve_port (virtual , family )
73+ if real is not None :
74+ # virtual == real: _remap_sockaddr sees no change, skips rewrite
75+ self ._virtual_to_real [virtual ] = real
76+ self ._real_to_virtual [real ] = virtual
77+ return real
78+
79+ # Slow path: virtual port taken, allocate a different real port
6980 real = self ._allocate_real_port (family )
7081 if real is None :
7182 return None
@@ -106,6 +117,25 @@ def close(self) -> None:
106117 self ._proxy_sockets .clear ()
107118 self ._proxy_threads .clear ()
108119
120+ def _try_reserve_port (self , port : int , family : int ) -> int | None :
121+ """Check if a port is available by probe-and-close.
122+
123+ Returns the port if free, None if already in use.
124+ No holder socket is kept — the sandbox binds the port directly.
125+ There is a tiny race window between the probe and the sandbox's
126+ bind(); if another process grabs the port, the sandbox gets
127+ EADDRINUSE, which is a normal error applications already handle.
128+ """
129+ af = socket .AF_INET6 if family == _AF_INET6 else socket .AF_INET
130+ s = socket .socket (af , socket .SOCK_STREAM )
131+ try :
132+ s .bind (("::1" if af == socket .AF_INET6 else "127.0.0.1" , port ))
133+ return port
134+ except OSError :
135+ return None
136+ finally :
137+ s .close ()
138+
109139 def _allocate_real_port (self , family : int ) -> int | None :
110140 """Bind a socket to port 0 to get a free port from the kernel."""
111141 try :
0 commit comments