Skip to content

Commit

Permalink
Add support for session tickets
Browse files Browse the repository at this point in the history
Closes #533

Signed-off-by: Tomás Senart <tsenart@gmail.com>
  • Loading branch information
hjongh authored and tsenart committed Jul 16, 2023
1 parent 5c9d86f commit a1f293f
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 1 deletion.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ attack command:
List of addresses (ip:port) to use for DNS resolution. Disables use of local system DNS. (comma separated list)
-root-certs value
TLS root certificate files (comma separated list)
-session-tickets
Enable TLS session resumption support using session tickets (default false)
-targets string
Targets file (default "stdin")
-timeout duration
Expand Down Expand Up @@ -384,6 +386,10 @@ the ones configured by the operating system. Works only on non Windows systems.
Specifies the trusted TLS root CAs certificate files as a comma separated
list. If unspecified, the default system CAs certificates will be used.

#### `-session-tickets`

Specifies whether to support TLS session resumption using session tickets.

#### `-targets`

Specifies the file from which to read targets, defaulting to stdin.
Expand Down
3 changes: 3 additions & 0 deletions attack.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func attackCmd() command {
fs.BoolVar(&opts.keepalive, "keepalive", true, "Use persistent connections")
fs.StringVar(&opts.unixSocket, "unix-socket", "", "Connect over a unix socket. This overrides the host address in target URLs")
fs.Var(&dnsTTLFlag{&opts.dnsTTL}, "dns-ttl", "Cache DNS lookups for the given duration [-1 = disabled, 0 = forever]")
fs.BoolVar(&opts.sessionTickets, "session-tickets", false, "Support TLS session resumption using session tickets")
systemSpecificFlags(fs, opts)

return command{fs, func(args []string) error {
Expand Down Expand Up @@ -101,6 +102,7 @@ type attackOpts struct {
resolvers csl
unixSocket string
dnsTTL time.Duration
sessionTickets bool
}

// attack validates the attack arguments, sets up the
Expand Down Expand Up @@ -193,6 +195,7 @@ func attack(opts *attackOpts) (err error) {
vegeta.ProxyHeader(proxyHdr),
vegeta.ChunkedBody(opts.chunked),
vegeta.DNSCaching(opts.dnsTTL),
vegeta.SessionTickets(opts.sessionTickets),
)

res := atk.Attack(tr, opts.rate, opts.duration, opts.name)
Expand Down
12 changes: 12 additions & 0 deletions lib/attack.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,18 @@ func UnixSocket(socket string) func(*Attacker) {
}
}

// SessionTickets returns a functional option which configures usage of session
// tickets for TLS session resumption.
func SessionTickets(enabled bool) func(*Attacker) {
return func(a *Attacker) {
if enabled {
cf := a.client.Transport.(*http.Transport).TLSClientConfig
cf.SessionTicketsDisabled = false
cf.ClientSessionCache = tls.NewLRUClientSessionCache(0)
}
}
}

// Client returns a functional option that allows you to bring your own http.Client
func Client(c *http.Client) func(*Attacker) {
return func(a *Attacker) { a.client = *c }
Expand Down
15 changes: 14 additions & 1 deletion lib/attack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ func TestAttackDuration(t *testing.T) {
}

func TestTLSConfig(t *testing.T) {
t.Parallel()
atk := NewAttacker()
got := atk.client.Transport.(*http.Transport).TLSClientConfig
if want := (&tls.Config{InsecureSkipVerify: true}); !reflect.DeepEqual(got, want) {
Expand Down Expand Up @@ -164,6 +163,20 @@ func TestKeepAlive(t *testing.T) {
}
}

// This test cannot be run in parallel with TestTLSConfig() because ClientSessionCache
// is designed to be called concurrently from different goroutines.
func TestSessionTickets(t *testing.T) {
atk := NewAttacker(SessionTickets(true))
cf := atk.client.Transport.(*http.Transport).TLSClientConfig
got, want := cf.SessionTicketsDisabled, false
if got != want {
t.Fatalf("got: %v, want: %v", got, want)
}
if cf.ClientSessionCache == nil {
t.Fatalf("ClientSessionCache is nil")
}
}

func TestConnections(t *testing.T) {
t.Parallel()
atk := NewAttacker(Connections(23))
Expand Down

0 comments on commit a1f293f

Please sign in to comment.