Skip to content

Commit 89f8aa1

Browse files
committed
feat: add TLS session cache for conn resumption
Automatically configure TLS `ClientSessionCache` on HTTP transports to enable session ticket reuse. This reduces TLS handshake overhead from 2-RTT to 1-RTT on reconnection and avoids repeated asymmetric crypto ops. Default cache size is 1024 entries per transport. Configurable via `Options.TLSSessionCacheSize`. Closes #506. Signed-off-by: Dwi Siswanto <[email protected]>
1 parent c769437 commit 89f8aa1

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

client.go

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,30 +63,36 @@ type Options struct {
6363
HttpClient *http.Client
6464
// Trace enables tracing of the HTTP request
6565
Trace bool
66+
// TLSSessionCacheSize specifies the size of the TLS session cache.
67+
//
68+
// If less than or equal to zero, defaults to 1024.
69+
TLSSessionCacheSize int
6670
}
6771

6872
// DefaultOptionsSpraying contains the default options for host spraying
6973
// scenarios where lots of requests need to be sent to different hosts.
7074
var DefaultOptionsSpraying = Options{
71-
RetryWaitMin: 1 * time.Second,
72-
RetryWaitMax: 30 * time.Second,
73-
Timeout: 30 * time.Second,
74-
RetryMax: 5,
75-
RespReadLimit: 4096,
76-
KillIdleConn: true,
77-
NoAdjustTimeout: true,
75+
RetryWaitMin: 1 * time.Second,
76+
RetryWaitMax: 30 * time.Second,
77+
Timeout: 30 * time.Second,
78+
RetryMax: 5,
79+
RespReadLimit: 4096,
80+
KillIdleConn: true,
81+
NoAdjustTimeout: true,
82+
TLSSessionCacheSize: 1024,
7883
}
7984

8085
// DefaultOptionsSingle contains the default options for host bruteforce
8186
// scenarios where lots of requests need to be sent to a single host.
8287
var DefaultOptionsSingle = Options{
83-
RetryWaitMin: 1 * time.Second,
84-
RetryWaitMax: 30 * time.Second,
85-
Timeout: 30 * time.Second,
86-
RetryMax: 5,
87-
RespReadLimit: 4096,
88-
KillIdleConn: false,
89-
NoAdjustTimeout: true,
88+
RetryWaitMin: 1 * time.Second,
89+
RetryWaitMax: 30 * time.Second,
90+
Timeout: 30 * time.Second,
91+
RetryMax: 5,
92+
RespReadLimit: 4096,
93+
KillIdleConn: false,
94+
NoAdjustTimeout: true,
95+
TLSSessionCacheSize: 1024,
9096
}
9197

9298
// NewClient creates a new Client with default settings.
@@ -105,6 +111,11 @@ func NewClient(options Options) *Client {
105111
return nil
106112
}
107113

114+
if options.HttpClient == nil && options.TLSSessionCacheSize > 0 {
115+
applyTLSSessionCache(httpclient, options.TLSSessionCacheSize)
116+
applyTLSSessionCache(httpclient2, options.TLSSessionCacheSize)
117+
}
118+
108119
var retryPolicy CheckRetry
109120
var backoff Backoff
110121

http.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func DefaultReusePooledTransport() *http.Transport {
4141
MaxIdleConnsPerHost: 100,
4242
MaxResponseHeaderBytes: 4096, // net/http default is 10Mb
4343
TLSClientConfig: &tls.Config{
44+
ClientSessionCache: tls.NewLRUClientSessionCache(1024),
4445
Renegotiation: tls.RenegotiateOnceAsClient, // Renegotiation is not supported in TLS 1.3 as per docs
4546
InsecureSkipVerify: true,
4647
MinVersion: tls.VersionTLS10,
@@ -76,6 +77,19 @@ func DefaultPooledClient() *http.Client {
7677
}
7778
}
7879

80+
// applyTLSSessionCache configures the TLS session cache size for an
81+
// [http.Client].
82+
//
83+
// It only applies if the client has an [http.Transport] with a
84+
// TLSClientConfig.
85+
func applyTLSSessionCache(client *http.Client, size int) {
86+
if transport, ok := client.Transport.(*http.Transport); ok {
87+
if transport.TLSClientConfig != nil {
88+
transport.TLSClientConfig.ClientSessionCache = tls.NewLRUClientSessionCache(size)
89+
}
90+
}
91+
}
92+
7993
var (
8094
fdInit = &sync.Once{}
8195
fd *fastdialer.Dialer

0 commit comments

Comments
 (0)