multiprocessing.connection.Client deadlocks when trying to connect to a listener without a password
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 77.2k
- Fork
- 35.9k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
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
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia con multiprocessing.connection.Client e il percorso answer_challenge identificato nel report, quindi esegui il reproducer fornito con le relative combinazioni di autenticazione. Il lavoro è completato quando il caso listener-without-password e client-with-password non rimane più bloccato, mentre gli altri casi segnalati mantengono i risultati dimostrati.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- distributed-systems, networking
- Tipo di issue
- Bug
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 45/100