Skip to content

Commit

Permalink
attack: Same order of timestamps and seq numbers
Browse files Browse the repository at this point in the history
This commit makes timestamps and sequence numbers maintain the exact
same ordering.
  • Loading branch information
tsenart committed Aug 11, 2018
1 parent 4be48a3 commit b274d1f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 16 deletions.
23 changes: 15 additions & 8 deletions lib/attack.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type Attacker struct {
stopch chan struct{}
workers uint64
redirects int
seqmu sync.Mutex
seq uint64
}

const (
Expand Down Expand Up @@ -204,13 +206,13 @@ func (a *Attacker) Attack(tr Targeter, rate uint64, du time.Duration, name strin
defer close(ticks)
interval := 1e9 / rate
hits := rate * uint64(du.Seconds())
began, seq := time.Now(), uint64(0)
began, count := time.Now(), uint64(0)
for {
now, next := time.Now(), began.Add(time.Duration(seq*interval))
now, next := time.Now(), began.Add(time.Duration(count*interval))
time.Sleep(next.Sub(now))
select {
case ticks <- seq:
if seq++; seq == hits {
case ticks <- count:
if count++; count == hits {
return
}
case <-a.stopch:
Expand All @@ -237,14 +239,14 @@ func (a *Attacker) Stop() {

func (a *Attacker) attack(tr Targeter, name string, workers *sync.WaitGroup, ticks <-chan uint64, results chan<- *Result) {
defer workers.Done()
for seq := range ticks {
results <- a.hit(tr, name, seq)
for range ticks {
results <- a.hit(tr, name)
}
}

func (a *Attacker) hit(tr Targeter, name string, seq uint64) *Result {
func (a *Attacker) hit(tr Targeter, name string) *Result {
var (
res = Result{Attack: name, Seq: seq}
res = Result{Attack: name}
tgt Target
err error
)
Expand All @@ -265,7 +267,12 @@ func (a *Attacker) hit(tr Targeter, name string, seq uint64) *Result {
return &res
}

a.seqmu.Lock()
res.Timestamp = time.Now()
res.Seq = a.seq
a.seq++
a.seqmu.Unlock()

r, err := a.client.Do(req)
if err != nil {
return &res
Expand Down
16 changes: 8 additions & 8 deletions lib/attack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func TestRedirects(t *testing.T) {
redirects := 2
atk := NewAttacker(Redirects(redirects))
tr := NewStaticTargeter(Target{Method: "GET", URL: server.URL})
res := atk.hit(tr, "", 0)
res := atk.hit(tr, "")
want := fmt.Sprintf("stopped after %d redirects", redirects)
if got := res.Error; !strings.HasSuffix(got, want) {
t.Fatalf("want: '%v' in '%v'", want, got)
Expand All @@ -93,7 +93,7 @@ func TestNoFollow(t *testing.T) {
defer server.Close()
atk := NewAttacker(Redirects(NoFollow))
tr := NewStaticTargeter(Target{Method: "GET", URL: server.URL})
res := atk.hit(tr, "", 0)
res := atk.hit(tr, "")
if res.Error != "" {
t.Fatalf("got err: %v", res.Error)
}
Expand All @@ -112,7 +112,7 @@ func TestTimeout(t *testing.T) {
defer server.Close()
atk := NewAttacker(Timeout(10 * time.Millisecond))
tr := NewStaticTargeter(Target{Method: "GET", URL: server.URL})
res := atk.hit(tr, "", 0)
res := atk.hit(tr, "")
want := "net/http: timeout awaiting response headers"
if got := res.Error; !strings.HasSuffix(got, want) {
t.Fatalf("want: '%v' in '%v'", want, got)
Expand All @@ -137,7 +137,7 @@ func TestLocalAddr(t *testing.T) {
defer server.Close()
atk := NewAttacker(LocalAddr(*addr))
tr := NewStaticTargeter(Target{Method: "GET", URL: server.URL})
atk.hit(tr, "", 0)
atk.hit(tr, "")
}

func TestKeepAlive(t *testing.T) {
Expand Down Expand Up @@ -171,7 +171,7 @@ func TestStatusCodeErrors(t *testing.T) {
defer server.Close()
atk := NewAttacker()
tr := NewStaticTargeter(Target{Method: "GET", URL: server.URL})
res := atk.hit(tr, "", 0)
res := atk.hit(tr, "")
if got, want := res.Error, "400 Bad Request"; got != want {
t.Fatalf("got: %v, want: %v", got, want)
}
Expand All @@ -181,7 +181,7 @@ func TestBadTargeterError(t *testing.T) {
t.Parallel()
atk := NewAttacker()
tr := func(*Target) error { return io.EOF }
res := atk.hit(tr, "", 0)
res := atk.hit(tr, "")
if got, want := res.Error, io.EOF.Error(); got != want {
t.Fatalf("got: %v, want: %v", got, want)
}
Expand All @@ -199,7 +199,7 @@ func TestResponseBodyCapture(t *testing.T) {
defer server.Close()
atk := NewAttacker()
tr := NewStaticTargeter(Target{Method: "GET", URL: server.URL})
res := atk.hit(tr, "", 0)
res := atk.hit(tr, "")
if got := res.Body; !bytes.Equal(got, want) {
t.Fatalf("got: %v, want: %v", got, want)
}
Expand All @@ -226,7 +226,7 @@ func TestProxyOption(t *testing.T) {
}))

tr := NewStaticTargeter(Target{Method: "GET", URL: "http://127.0.0.2"})
res := atk.hit(tr, "", 0)
res := atk.hit(tr, "")
if got, want := res.Error, ""; got != want {
t.Errorf("got error: %q, want %q", got, want)
}
Expand Down

0 comments on commit b274d1f

Please sign in to comment.