Commit 9bd5bf62 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Add session expiry ticker

parent fb498c65
......@@ -85,6 +85,7 @@ func HandleProtocolMessage(
return failSession(nil, irmaserver.ErrorInvalidRequest, "")
}
// Fetch the session
token := matches[1]
verb := matches[2]
session := sessions.get(token)
......
......@@ -4,6 +4,7 @@ import (
"math/big"
"math/rand"
"sync"
"time"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
......@@ -12,12 +13,16 @@ import (
)
type session struct {
sync.Mutex
action irma.Action
token string
version *irma.ProtocolVersion
request irma.SessionRequest
status irmaserver.Status
active time.Time
proofStatus irma.ProofStatus
disclosed []*irma.DisclosedAttribute
signature *irma.SignedMessage
......@@ -28,6 +33,7 @@ type session struct {
type sessionStore interface {
get(token string) *session
add(token string, session *session)
deleteExpired()
}
type memorySessionStore struct {
......@@ -35,6 +41,11 @@ type memorySessionStore struct {
m map[string]*session
}
const (
maxSessionLifetime = 5 * time.Minute // After this a session is cancelled
expiryTicker = 10 * time.Second // Every so often we check if any session has expired
)
const sessionChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var (
......@@ -46,6 +57,10 @@ var (
}
)
func init() {
go sessions.deleteExpired()
}
func (s *memorySessionStore) get(token string) *session {
s.RLock()
defer s.RUnlock()
......@@ -58,6 +73,32 @@ func (s *memorySessionStore) add(token string, session *session) {
s.m[token] = session
}
func (s memorySessionStore) deleteExpired() {
// First check which sessions have expired
// We don't need a write lock for this yet, so postpone that for actual deleting
s.RLock()
expired := make([]string, 0, len(s.m))
for token, session := range s.m {
if session.active.Add(5 * time.Minute).Before(time.Now()) {
conf.Logger.Infof("Session %s expired, deleting", token)
expired = append(expired, token)
}
}
s.RUnlock()
// Using a write lock, delete the expired sessions
s.Lock()
for _, token := range expired {
delete(s.m, token)
}
s.Unlock()
// Schedule next run
time.AfterFunc(expiryTicker, func() {
s.deleteExpired()
})
}
var one *big.Int = big.NewInt(1)
func newSession(action irma.Action, request irma.SessionRequest) *session {
......@@ -65,6 +106,7 @@ func newSession(action irma.Action, request irma.SessionRequest) *session {
action: action,
request: request,
status: irmaserver.StatusInitialized,
active: time.Now(),
token: newSessionToken(),
}
nonce, _ := gabi.RandomBigInt(gabi.DefaultSystemParameters[2048].Lstatzk)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment