diff --git a/CHANGELOG.md b/CHANGELOG.md index b6adb62..e57686f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ All notable changes to this project will be documented in this file. - Added the `use_bundled_tls` build option. Applications can keep TLS enabled while replacing Dusty's pinned tls.zig dependency with a compatible module. +- Server and client connections now call `tls.Connection.deinit` on close + when the TLS module declares one, so an injected module backed by a C + library (one `SSL` object per connection) does not leak per connection. - `Listener.kernel_backlog` now defaults to the system's limit, `net.core.somaxconn` on Linux, instead of 1024. A full accept queue makes Linux drop new connections, which then wait a second or more to retry. diff --git a/src/client.zig b/src/client.zig index d74c280..70866ab 100644 --- a/src/client.zig +++ b/src/client.zig @@ -665,6 +665,14 @@ pub const Connection = struct { } pub fn deinit(self: *Connection) void { + if (build_options.use_tls) { + // See server.zig `Connection.deinit`: only a TLS module that owns + // per-connection state declares `deinit`. + if (@hasDecl(tls.Connection, "deinit")) { + if (self.tls_conn) |*c| c.deinit(); + } + self.tls_conn = null; + } self.stream.close(self.io); if (self.protocol == .https) { self.allocator.free(self.tls_tcp_read_buffer); diff --git a/src/server.zig b/src/server.zig index 6d59977..132e241 100644 --- a/src/server.zig +++ b/src/server.zig @@ -294,6 +294,15 @@ pub const Connection = struct { } pub fn deinit(self: *Connection) void { + if (build_options.use_tls) { + // tls.zig's Connection owns no memory and has no deinit; a TLS + // module backed by a C library (one SSL object per connection) + // frees it here. + if (@hasDecl(tls.Connection, "deinit")) { + if (self.tls_conn) |*c| c.deinit(); + } + self.tls_conn = null; + } self.allocator.free(self.buffers); }