Rewrite flood limiting for new time behaviour.

This commit is contained in:
Alex Bramley 2012-02-04 01:13:07 +00:00
parent dfb6f94b56
commit 1c62354cb8
1 changed files with 9 additions and 12 deletions

View File

@ -13,10 +13,6 @@ import (
"time" "time"
) )
const (
second = int64(1e9)
)
// An IRC connection is represented by this struct. // An IRC connection is represented by this struct.
type Conn struct { type Conn struct {
// Connection Hostname and Nickname // Connection Hostname and Nickname
@ -58,7 +54,8 @@ type Conn struct {
Flood bool Flood bool
// Internal counters for flood protection // Internal counters for flood protection
badness, lastsent int64 badness time.Duration
lastsent time.Time
} }
// Creates a new IRC connection object, but doesn't connect to anything so // Creates a new IRC connection object, but doesn't connect to anything so
@ -96,7 +93,7 @@ func Client(nick, ident, name string,
SSLConfig: nil, SSLConfig: nil,
Flood: false, Flood: false,
badness: 0, badness: 0,
lastsent: 0, lastsent: time.Now(),
} }
conn.addIntHandlers() conn.addIntHandlers()
conn.Me = state.NewNick(nick, l) conn.Me = state.NewNick(nick, l)
@ -248,10 +245,10 @@ func (conn *Conn) runLoop() {
// using Hybrid's algorithm to rate limit if conn.Flood is false. // using Hybrid's algorithm to rate limit if conn.Flood is false.
func (conn *Conn) write(line string) { func (conn *Conn) write(line string) {
if !conn.Flood { if !conn.Flood {
if t := conn.rateLimit(int64(len(line))); t != 0 { if t := conn.rateLimit(len(line)); t != 0 {
// sleep for the current line's time value before sending it // sleep for the current line's time value before sending it
conn.l.Debug("irc.rateLimit(): Flood! Sleeping for %.2f secs.", conn.l.Debug("irc.rateLimit(): Flood! Sleeping for %.2f secs.",
float64(t)/float64(second)) t.Seconds())
<-time.After(t) <-time.After(t)
} }
} }
@ -270,19 +267,19 @@ func (conn *Conn) write(line string) {
} }
// Implement Hybrid's flood control algorithm to rate-limit outgoing lines. // Implement Hybrid's flood control algorithm to rate-limit outgoing lines.
func (conn *Conn) rateLimit(chars int64) int64 { func (conn *Conn) rateLimit(chars int) time.Duration {
// Hybrid's algorithm allows for 2 seconds per line and an additional // Hybrid's algorithm allows for 2 seconds per line and an additional
// 1/120 of a second per character on that line. // 1/120 of a second per character on that line.
linetime := 2*second + chars*second/120 linetime := 2*time.Second + time.Duration(chars)*time.Second/120
elapsed := time.Now().Sub(conn.lastsent) elapsed := time.Now().Sub(conn.lastsent)
if conn.badness += linetime - elapsed; conn.badness < 0 { if conn.badness += linetime - elapsed; conn.badness < 0 {
// negative badness times are badness... // negative badness times are badness...
conn.badness = int64(0) conn.badness = 0
} }
conn.lastsent = time.Now() conn.lastsent = time.Now()
// If we've sent more than 10 second's worth of lines according to the // If we've sent more than 10 second's worth of lines according to the
// calculation above, then we're at risk of "Excess Flood". // calculation above, then we're at risk of "Excess Flood".
if conn.badness > 10*second { if conn.badness > 10*time.Second {
return linetime return linetime
} }
return 0 return 0