This commit is contained in:
John Donaldson 2019-05-21 16:00:32 +01:00
commit 810dd3f19a
4 changed files with 46 additions and 8 deletions

View File

@ -1 +1 @@
3.2
3.3

16
contrib/smash Executable file
View File

@ -0,0 +1,16 @@
#! /bin/sh
## Run two of these to trigger the race condition from
BASEURL=http://localhost:8080
URL=$BASEURL/answer
while true; do
curl \
-X POST \
-F "cat=byobf" \
-F "points=10" \
-F "id=test" \
-F "answer=6" \
$URL
done

View File

@ -11,6 +11,7 @@ import (
"os"
"path"
"strings"
"sync"
"time"
)
@ -21,12 +22,13 @@ type Instance struct {
ThemeDir string
AttemptInterval time.Duration
categories map[string]*Mothball
update chan bool
jPuzzleList []byte
jPointsLog []byte
nextAttempt map[string]time.Time
mux *http.ServeMux
categories map[string]*Mothball
update chan bool
jPuzzleList []byte
jPointsLog []byte
nextAttempt map[string]time.Time
nextAttemptMutex *sync.RWMutex
mux *http.ServeMux
}
func (ctx *Instance) Initialize() error {
@ -42,6 +44,7 @@ func (ctx *Instance) Initialize() error {
ctx.categories = map[string]*Mothball{}
ctx.update = make(chan bool, 10)
ctx.nextAttempt = map[string]time.Time{}
ctx.nextAttemptMutex = new(sync.RWMutex)
ctx.mux = http.NewServeMux()
ctx.BindHandlers()
@ -129,8 +132,15 @@ func (ctx *Instance) ThemePath(parts ...string) string {
func (ctx *Instance) TooFast(teamId string) bool {
now := time.Now()
ctx.nextAttemptMutex.RLock()
next, _ := ctx.nextAttempt[teamId]
ctx.nextAttemptMutex.RUnlock()
ctx.nextAttemptMutex.Lock()
ctx.nextAttempt[teamId] = now.Add(ctx.AttemptInterval)
ctx.nextAttemptMutex.Unlock()
return now.Before(next)
}
@ -212,7 +222,10 @@ func (ctx *Instance) OpenCategoryFile(category string, parts ...string) (io.Read
}
func (ctx *Instance) ValidTeamId(teamId string) bool {
ctx.nextAttemptMutex.RLock()
_, ok := ctx.nextAttempt[teamId]
ctx.nextAttemptMutex.RUnlock()
return ok
}

View File

@ -186,19 +186,28 @@ func (ctx *Instance) readTeams() {
now := time.Now()
added := 0
for k, _ := range newList {
if _, ok := ctx.nextAttempt[k]; !ok {
ctx.nextAttemptMutex.RLock()
_, ok := ctx.nextAttempt[k]
ctx.nextAttemptMutex.RUnlock()
if !ok {
ctx.nextAttemptMutex.Lock()
ctx.nextAttempt[k] = now
ctx.nextAttemptMutex.Unlock()
added += 1
}
}
// For any removed team IDs, remove them
removed := 0
ctx.nextAttemptMutex.Lock() // XXX: This could be less of a cludgel
for k, _ := range ctx.nextAttempt {
if _, ok := newList[k]; !ok {
delete(ctx.nextAttempt, k)
}
}
ctx.nextAttemptMutex.Unlock()
if (added > 0) || (removed > 0) {
log.Printf("Team IDs updated: %d added, %d removed", added, removed)