multiprocessing.connection.Client deadlocks when trying to connect to a listener without a password
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 35.9k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug report
Bug description:
We set up a multiprocessing.connection.Listener with no authkey. When we try to connect to it with a Client with an authkey, the Client deadlocks. Here is a working example:
import socket
import threading
import time
from multiprocessing.connection import Client, Listener
def _test(*, listener: str | None, client: str | None) -> tuple[Exception | None, Exception | None, list]:
_autkey_listener = listener.encode() if listener else None
_authkey_client = client.encode() if client else None
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(("localhost", 0))
address = s.getsockname()
thread_exc = None
thread_got = []
client_exc = None
def target() -> None:
try:
with Listener(address, authkey=_autkey_listener) as l:
c = l.accept()
while True:
value = c.recv()
if not value:
break
thread_got.append(value)
except Exception as e:
nonlocal thread_exc
thread_exc = e
t = threading.Thread(target=target)
t.start()
try:
with Client(address, authkey=_authkey_client) as c:
c.send("hello")
time.sleep(0.1)
c.send(None)
t.join()
except Exception as e:
client_exc = e
return thread_exc, client_exc, thread_got
if __name__ == "__main__":
print(" no passwords ".center(40, "-"))
print(_test(listener=None, client=None))
print(" two matching passwords ".center(40, "-"))
print(_test(listener="password", client="password"))
print(" client has wrong password ".center(40, "-"))
print(_test(listener="password", client="wrong"))
print(" client has no password ".center(40, "-"))
print(_test(listener="password", client=None))
# This is the case which deadlocks
print(" listener has no password ".center(40, "-"))
print(_test(listener=None, client="password"))
which outputs:
------------- no passwords -------------
(None, None, ['hello'])
-------- two matching passwords --------
(None, None, ['hello'])
------ client has wrong password -------
(AuthenticationError('digest received was wrong'), AuthenticationError('digest sent was rejected'), [])
-------- client has no password --------
(AuthenticationError("expected 'md5' of length 16 got 20"), None, [])
------- listener has no password -------
and then stops.
Upon some investigation, the following bit of code from Client is to blame:
if authkey is not None:
answer_challenge(c, authkey)
deliver_challenge(c, authkey)
since the listener is not configured to deliver the challenge to the connections. I think this would be resolved with an optional timeout kwarg in answer_challenge. If this suggestion is accepted I would be very happy to work on it 👍
CPython versions tested on:
3.9, 3.10, 3.11, 3.12
Operating systems tested on:
macOS, Windows
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginnen Sie mit multiprocessing.connection.Client und dem im Bericht identifizierten answer_challenge-Pfad, und führen Sie dann den bereitgestellten Reproducer über seine Authentifizierungskombinationen hinweg aus. Als erledigt gilt die Aufgabe, wenn der Fall listener-without-password und client-with-password nicht mehr hängt, während die anderen gemeldeten Fälle ihre nachgewiesenen Ergebnisse beibehalten.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- distributed-systems, networking
- Issue-Typ
- Bug
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 45/100