diff --git a/irc/client.go b/irc/client.go index 240763f7..58ba6777 100644 --- a/irc/client.go +++ b/irc/client.go @@ -158,7 +158,7 @@ func (client *Client) resetFakelag() { return nil } - return NewFakelag(flc.Window, flc.BurstLimit, flc.MessagesPerWindow) + return NewFakelag(flc.Window, flc.BurstLimit, flc.MessagesPerWindow, flc.Cooldown) }() client.stateMutex.Lock() diff --git a/irc/config.go b/irc/config.go index 84a565b2..09c0bb82 100644 --- a/irc/config.go +++ b/irc/config.go @@ -194,6 +194,7 @@ type FakelagConfig struct { Window time.Duration BurstLimit uint `yaml:"burst-limit"` MessagesPerWindow uint `yaml:"messages-per-window"` + Cooldown time.Duration } // Config defines the overall configuration. diff --git a/irc/fakelag.go b/irc/fakelag.go index 2b13b9f5..a3ed64b2 100644 --- a/irc/fakelag.go +++ b/irc/fakelag.go @@ -27,6 +27,7 @@ type Fakelag struct { window time.Duration burstLimit uint throttleMessagesPerWindow uint + cooldown time.Duration nowFunc func() time.Time sleepFunc func(time.Duration) @@ -35,11 +36,12 @@ type Fakelag struct { lastTouch time.Time } -func NewFakelag(window time.Duration, burstLimit uint, throttleMessagesPerWindow uint) *Fakelag { +func NewFakelag(window time.Duration, burstLimit uint, throttleMessagesPerWindow uint, cooldown time.Duration) *Fakelag { return &Fakelag{ window: window, burstLimit: burstLimit, throttleMessagesPerWindow: throttleMessagesPerWindow, + cooldown: cooldown, nowFunc: time.Now, sleepFunc: time.Sleep, state: FakelagBursting, @@ -59,8 +61,7 @@ func (fl *Fakelag) Touch() { if fl.state == FakelagBursting { // determine if the previous burst is over - // (we could use 2*window instead) - if elapsed > fl.window { + if elapsed > fl.cooldown { fl.burstCount = 0 } @@ -77,8 +78,8 @@ func (fl *Fakelag) Touch() { } if fl.state == FakelagThrottled { - if elapsed > fl.window { - // let them burst again (as above, we could use 2*window instead) + if elapsed > fl.cooldown { + // let them burst again fl.state = FakelagBursting return } diff --git a/irc/fakelag_test.go b/irc/fakelag_test.go index 957ee595..b2141039 100644 --- a/irc/fakelag_test.go +++ b/irc/fakelag_test.go @@ -39,8 +39,8 @@ func (mt *mockTime) lastSleep() (slept bool, duration time.Duration) { return } -func newFakelagForTesting(window time.Duration, burstLimit uint, throttleMessagesPerWindow uint) (*Fakelag, *mockTime) { - fl := NewFakelag(window, burstLimit, throttleMessagesPerWindow) +func newFakelagForTesting(window time.Duration, burstLimit uint, throttleMessagesPerWindow uint, cooldown time.Duration) (*Fakelag, *mockTime) { + fl := NewFakelag(window, burstLimit, throttleMessagesPerWindow, cooldown) mt := new(mockTime) mt.now, _ = time.Parse("Mon Jan 2 15:04:05 -0700 MST 2006", "Mon Jan 2 15:04:05 -0700 MST 2006") mt.lastCheckedSleep = -1 @@ -51,7 +51,7 @@ func newFakelagForTesting(window time.Duration, burstLimit uint, throttleMessage func TestFakelag(t *testing.T) { window, _ := time.ParseDuration("1s") - fl, mt := newFakelagForTesting(window, 3, 2) + fl, mt := newFakelagForTesting(window, 3, 2, window) fl.Touch() slept, _ := mt.lastSleep() diff --git a/oragono.yaml b/oragono.yaml index bf027489..2a438b1e 100644 --- a/oragono.yaml +++ b/oragono.yaml @@ -392,15 +392,18 @@ limits: # fakelag: prevents clients from spamming commands too rapidly fakelag: # whether to enforce fakelag - enabled: true + enabled: false # time unit for counting command rates window: 1s # clients can send this many commands without fakelag being imposed - # (resets after a period of `window` elapses without any commands) burst-limit: 5 # once clients have exceeded their burst allowance, they can send only # this many commands per `window`: messages-per-window: 2 + + # client status resets to the default state if they go this long without + # sending any commands: + cooldown: 1s