diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index 5a6eb45..d2a8c43 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -101,6 +101,8 @@ func (r *router) mainLoop() { // Any periodic maintenance stuff goes here r.core.switchTable.doMaintenance() r.core.dht.doMaintenance() + r.core.sessions.cleanup() + r.core.sigs.cleanup() util_getBytes() // To slowly drain things } case f := <-r.admin: diff --git a/src/yggdrasil/session.go b/src/yggdrasil/session.go index b36349a..8631ff2 100644 --- a/src/yggdrasil/session.go +++ b/src/yggdrasil/session.go @@ -89,7 +89,8 @@ func (s *sessionInfo) timedout() bool { // Sessions are indexed by handle. // Additionally, stores maps of address/subnet onto keys, and keys onto handles. type sessions struct { - core *Core + core *Core + lastCleanup time.Time // Maps known permanent keys to their shared key, used by DHT a lot permShared map[boxPubKey]*boxSharedKey // Maps (secret) handle onto session info @@ -111,6 +112,7 @@ func (ss *sessions) init(core *Core) { ss.byTheirPerm = make(map[boxPubKey]*handle) ss.addrToPerm = make(map[address]*boxPubKey) ss.subnetToPerm = make(map[subnet]*boxPubKey) + ss.lastCleanup = time.Now() } // Gets the session corresponding to a given handle. @@ -202,13 +204,6 @@ func (ss *sessions) createSession(theirPermKey *boxPubKey) *sessionInfo { sinfo.send = make(chan []byte, 32) sinfo.recv = make(chan *wire_trafficPacket, 32) go sinfo.doWorker() - // Do some cleanup - // Time thresholds almost certainly could use some adjusting - for _, s := range ss.sinfos { - if s.timedout() { - s.close() - } - } ss.sinfos[sinfo.myHandle] = &sinfo ss.byMySes[sinfo.mySesPub] = &sinfo.myHandle ss.byTheirPerm[sinfo.theirPermPub] = &sinfo.myHandle @@ -217,6 +212,19 @@ func (ss *sessions) createSession(theirPermKey *boxPubKey) *sessionInfo { return &sinfo } +func (ss *sessions) cleanup() { + // Time thresholds almost certainly could use some adjusting + if time.Since(ss.lastCleanup) < time.Minute { + return + } + for _, s := range ss.sinfos { + if s.timedout() { + s.close() + } + } + ss.lastCleanup = time.Now() +} + // Closes a session, removing it from sessions maps and killing the worker goroutine. func (sinfo *sessionInfo) close() { delete(sinfo.core.sessions.sinfos, sinfo.myHandle) diff --git a/src/yggdrasil/signature.go b/src/yggdrasil/signature.go index 374183a..203c9ad 100644 --- a/src/yggdrasil/signature.go +++ b/src/yggdrasil/signature.go @@ -71,16 +71,20 @@ func (m *sigManager) isChecked(key *sigPubKey, sig *sigBytes, bs []byte) bool { func (m *sigManager) putChecked(key *sigPubKey, newsig *sigBytes, bs []byte) { m.mutex.Lock() defer m.mutex.Unlock() - now := time.Now() - if time.Since(m.lastCleaned) > 60*time.Second { - // Since we have the write lock anyway, do some cleanup - for s, k := range m.checked { - if time.Since(k.time) > 60*time.Second { - delete(m.checked, s) - } - } - m.lastCleaned = now - } - k := knownSig{key: *key, sig: *newsig, bs: bs, time: now} + k := knownSig{key: *key, sig: *newsig, bs: bs, time: time.Now()} m.checked[*newsig] = k } + +func (m *sigManager) cleanup() { + m.mutex.Lock() + defer m.mutex.Unlock() + if time.Since(m.lastCleaned) < time.Minute { + return + } + for s, k := range m.checked { + if time.Since(k.time) > time.Minute { + delete(m.checked, s) + } + } + m.lastCleaned = time.Now() +}