diff --git a/server/keystore.go b/server/keystore.go index 8a94197d7788b943a2727ad7652ed0f110240711..02ca79a8e937955ee98608534746195d5673802d 100644 --- a/server/keystore.go +++ b/server/keystore.go @@ -217,12 +217,6 @@ func (s *KeyStore) Close(username, sessionID string) bool { return s.userKeys.deleteSession(nsSessionID(username, sessionID)) } -func wipeBytes(b []byte) { - for i := 0; i < len(b); i++ { - b[i] = 0 - } -} - // Combine usernames and session IDs so that every user gets its own // session namespace. This allows for backwards compatibility for // clients that do not set a session_id (in which case the service diff --git a/server/map.go b/server/map.go index 3db45432fd69cafd0bd02861c7d3975b81776084..83afcf07fd62c677f7b30431bbfd052d436df96f 100644 --- a/server/map.go +++ b/server/map.go @@ -5,6 +5,8 @@ import ( "time" ) +// Priority queue of userSession objects, kept ordered by expiration +// time so that periodic expire() is fast even with lots of objects. type sessionPQ []*userSession func (pq sessionPQ) Len() int { @@ -69,8 +71,8 @@ func (m *sessionMap) del(sessionID string) *userSession { return sess } +// Peek at the oldest entry and pop it if expired. func (m *sessionMap) expireNext(deadline time.Time) *userSession { - // Peek and return first expired session. if len(m.pq) > 0 && m.pq[0].expiry.Before(deadline) { sess := heap.Pop(&m.pq).(*userSession) delete(m.sessions, sess.id) @@ -80,6 +82,9 @@ func (m *sessionMap) expireNext(deadline time.Time) *userSession { return nil } +// Maintain association between sessions (that may expire) and user +// keys. Enforces the constraint that keys will be removed once they +// have no sessions attached. type userKeyMap struct { sessions *sessionMap userKeys map[string]*userKey @@ -145,3 +150,9 @@ func (u *userKeyMap) cleanupSession(sess *userSession) { u.userSessions[sess.username] = ids } } + +func wipeBytes(b []byte) { + for i := 0; i < len(b); i++ { + b[i] = 0 + } +}