tls: send a close_notify on close for established TLS sessions instead of just dropping the socket, so clients see a clean shutdown not a truncation error
This commit is contained in:
parent
59e18b0205
commit
d8d57511ab
2 changed files with 14 additions and 0 deletions
|
|
@ -154,6 +154,13 @@ impl Sock {
|
||||||
Sock::Tls(t) => t.write(buf),
|
Sock::Tls(t) => t.write(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Best-effort graceful close. TLS sends a close_notify alert; plaintext relies on
|
||||||
|
/// the socket's own FIN when the stream drops.
|
||||||
|
fn shutdown(&mut self) {
|
||||||
|
if let Sock::Tls(t) = self {
|
||||||
|
t.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Conn {
|
struct Conn {
|
||||||
|
|
@ -816,6 +823,10 @@ fn flush_conn(poll: &mut Poll, conns: &mut HashMap<usize, Conn>, t: usize, core:
|
||||||
fn close_conn(poll: &mut Poll, conns: &mut HashMap<usize, Conn>, t: usize, core: &Sender<Event>) {
|
fn close_conn(poll: &mut Poll, conns: &mut HashMap<usize, Conn>, t: usize, core: &Sender<Event>) {
|
||||||
if let Some(mut c) = conns.remove(&t) {
|
if let Some(mut c) = conns.remove(&t) {
|
||||||
let _ = poll.registry().deregister(c.sock.source());
|
let _ = poll.registry().deregister(c.sock.source());
|
||||||
|
// send a TLS close_notify for an established session (not a half-done handshake)
|
||||||
|
if !c.handshaking {
|
||||||
|
c.sock.shutdown();
|
||||||
|
}
|
||||||
let uid = c.uid;
|
let uid = c.uid;
|
||||||
// a conn whose Connect was never emitted — a still-pending PROXY header or an
|
// a conn whose Connect was never emitted — a still-pending PROXY header or an
|
||||||
// unfinished TLS handshake — must not send the core a Disconnect for a uid it
|
// unfinished TLS handshake — must not send the core a Disconnect for a uid it
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,9 @@ impl TlsSession for OpensslSession {
|
||||||
Some(digest.iter().map(|b| format!("{b:02x}")).collect())
|
Some(digest.iter().map(|b| format!("{b:02x}")).collect())
|
||||||
}
|
}
|
||||||
fn shutdown(&mut self) {
|
fn shutdown(&mut self) {
|
||||||
|
// best-effort TLS close_notify, then close the socket. Non-blocking, so a
|
||||||
|
// WouldBlock just means the alert is queued — we don't wait for the peer's.
|
||||||
|
let _ = self.0.shutdown();
|
||||||
let _ = self.0.get_ref().shutdown(Shutdown::Both);
|
let _ = self.0.get_ref().shutdown(Shutdown::Both);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue