From a3386f6254cb1192d7b59831dfc81e6c0b1c548c Mon Sep 17 00:00:00 2001 From: sinku Date: Mon, 2 Mar 2026 13:04:12 -0500 Subject: [PATCH] Add ConnectionMetrics to expose session ticket/PSK usage Add a ConnectionMetrics struct and Conn.ConnectionMetrics() method that allows consumers to determine whether the client sent a TLS 1.2 session ticket or a TLS 1.3 PSK in the ClientHello. This is useful for metrics and diagnostics around session resumption behavior. Changes: - Add ConnectionMetrics struct in common.go - Add clientSentTicket field to Conn in conn.go - Add ConnectionMetrics() method on Conn in conn.go - Set clientSentTicket after writeHandshakeRecord in u_handshake_client.go --- common.go | 7 +++++++ conn.go | 10 ++++++++++ u_handshake_client.go | 5 +++++ 3 files changed, 22 insertions(+) diff --git a/common.go b/common.go index 73b6dad5..81d35b46 100644 --- a/common.go +++ b/common.go @@ -235,6 +235,13 @@ const ( // include downgrade canaries even if it's using its highers supported version. var testingOnlyForceDowngradeCanary bool +// ConnectionMetrics contains basic metrics about the connection. +type ConnectionMetrics struct { + // ClientSentTicket is true if the client has sent a TLS 1.2 session ticket + // or a TLS 1.3 PSK in the ClientHello successfully. + ClientSentTicket bool +} + // ConnectionState records basic TLS details about the connection. type ConnectionState struct { // Version is the TLS version used by the connection (e.g. VersionTLS12). diff --git a/conn.go b/conn.go index f761ccae..3c4b1ad1 100644 --- a/conn.go +++ b/conn.go @@ -46,6 +46,7 @@ type Conn struct { // zero or one. handshakes int extMasterSecret bool + clientSentTicket bool // whether the client sent a session ticket or a PSK in the Client Hello didResume bool // whether this connection was a session resumption didHRR bool // whether a HelloRetryRequest was sent/received cipherSuite uint16 @@ -1699,3 +1700,12 @@ func (c *Conn) VerifyHostname(host string) error { } return c.peerCertificates[0].VerifyHostname(host) } + +// ConnectionMetrics returns basic metrics about the connection. +func (c *Conn) ConnectionMetrics() ConnectionMetrics { + c.handshakeMutex.Lock() + defer c.handshakeMutex.Unlock() + var metrics ConnectionMetrics + metrics.ClientSentTicket = c.clientSentTicket + return metrics +} diff --git a/u_handshake_client.go b/u_handshake_client.go index 9928f0c3..b7aaeb6a 100644 --- a/u_handshake_client.go +++ b/u_handshake_client.go @@ -494,6 +494,11 @@ func (c *UConn) clientHandshake(ctx context.Context) (err error) { return err } + // Client sent a session ticket or PSK. + if session != nil { + c.clientSentTicket = true + } + if hello.earlyData { suite := cipherSuiteTLS13ByID(session.cipherSuite) transcript := suite.hash.New()