Leaking LIBSSH2_SESSION objects
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 35/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Ferma
- Stack tecnologico
- rust
- Ambito
- networking
Direzione di ricerca
Inizia dall’implementazione di Drop per SessionInner e traccia le relative chiamate a libssh2_session_free nelle modalità bloccante e non bloccante. Confronta le astrazioni di trasporto disponibili, incluso il percorso Windows, e determina come completare la pulizia senza una doppia ownership dello stream o un drop che si blocchi indefinitamente. Il lavoro è completato quando le risorse della sessione vengono rilasciate in sicurezza su tutte le piattaforme e modalità supportate.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
I'm using ssh2-rs in an async project (via async-ssh2), and I have stumbled across a problem with the way sessions are freed.
The Drop impl for SessionInner just calls libssh2_session_free and disregards the return value. This is a problem in both blocking and nonblocking modes:
- In non-blocking mode,
libssh2_session_freeis likely to returnLIBSSH2_ERROR_EAGAINand need to be called again when the socket is ready - In blocking mode, if the caller has set a timeout then it may return
LIBSSH2_ERROR_TIMEOUT(and in fact if the caller has not set a timeout, it may hang indefinitely if there is a network problem).
In both cases, if you don't repeatedly call it until you get a 0 returned, then the resources are not released.
In my experience so far, in case of network disturbance it can be pretty difficult to get libsshb2 to properly release the session. The only thing that has worked for me so far is this:
impl Drop for SessionInner {
fn drop(&mut self) {
self.set_blocking(true);
loop {
let rc = unsafe { raw::libssh2_session_free(self.raw) };
if rc == 0 {
break;
} else {
// Timeout - drop the transport,
// which will hopefully cause the socket to close so we can try again
if let Some(tcp) = self.tcp.take() {
let tcp = unsafe { std::net::TcpStream::from_raw_fd(tcp.as_raw_fd()) };
let _ = tcp.shutdown(std::net::Shutdown::Both);
}
}
}
}
}
So, if there is a timeout when calling libssh2_session_free, we shut down the socket and try again. The next time around libssh2 realizes the socket is shut down and finishes the cleanup.
This biggest problem with this is that since tcp is Box<dyn AsRawFd>, we can't call shutdown on it directly, all we can do is get the FD from it, and then create a new TcpStream around it - which is not sound, because then there are two TcpStreams with the same FD. In my testing this has not caused an issue yet, but the documentation explicitly states not to do that. Also, theoretically the the FD might be associated with some other stream type that implements AsRawFd, (eg. UnixStream).
The above is also not good from an async point of view, because the drop fn blocks the thread for potentially a long time. To make it work better in an async context some more work could be required, but that probably should be for another issue.
Finally - whatever approach is used here needs to be replicated for Windows also.
I'm happy to make a PR, if someone can suggest how to avoid the unsoundness described above.
- Lingua principale
- Rust
- Stelle
- 571
- Fork
- 166
- Merge medio
- 1g 18h
- PR unite (30g)
- 5
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
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.
Altre issue di rust-lang/ssh2-rs
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
-
enhancement help wanted
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
-
enhancement
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
-
enhancement
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
Tutte le issue di rust-lang/ssh2-rs
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno
-
good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 92/100
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
yunfie-twitter/Palleria#474 ·
I maintainer di solito rispondono entro 1 giorno
-
good first issue help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
servo/rust-smallvec#827 ·
I maintainer di solito rispondono entro 1 giorno