5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-29 21:21:35 +00:00

periodically clean up timed-out sessions and old signatures, instead of trying to do it when creating new sessions or adding new signatures

This commit is contained in:
Arceliar 2018-06-21 20:31:30 -05:00
parent 8e7edf566c
commit 5dfa01a0e8
3 changed files with 33 additions and 19 deletions

View File

@ -101,6 +101,8 @@ func (r *router) mainLoop() {
// Any periodic maintenance stuff goes here // Any periodic maintenance stuff goes here
r.core.switchTable.doMaintenance() r.core.switchTable.doMaintenance()
r.core.dht.doMaintenance() r.core.dht.doMaintenance()
r.core.sessions.cleanup()
r.core.sigs.cleanup()
util_getBytes() // To slowly drain things util_getBytes() // To slowly drain things
} }
case f := <-r.admin: case f := <-r.admin:

View File

@ -90,6 +90,7 @@ func (s *sessionInfo) timedout() bool {
// Additionally, stores maps of address/subnet onto keys, and keys onto handles. // Additionally, stores maps of address/subnet onto keys, and keys onto handles.
type sessions struct { type sessions struct {
core *Core core *Core
lastCleanup time.Time
// Maps known permanent keys to their shared key, used by DHT a lot // Maps known permanent keys to their shared key, used by DHT a lot
permShared map[boxPubKey]*boxSharedKey permShared map[boxPubKey]*boxSharedKey
// Maps (secret) handle onto session info // Maps (secret) handle onto session info
@ -111,6 +112,7 @@ func (ss *sessions) init(core *Core) {
ss.byTheirPerm = make(map[boxPubKey]*handle) ss.byTheirPerm = make(map[boxPubKey]*handle)
ss.addrToPerm = make(map[address]*boxPubKey) ss.addrToPerm = make(map[address]*boxPubKey)
ss.subnetToPerm = make(map[subnet]*boxPubKey) ss.subnetToPerm = make(map[subnet]*boxPubKey)
ss.lastCleanup = time.Now()
} }
// Gets the session corresponding to a given handle. // 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.send = make(chan []byte, 32)
sinfo.recv = make(chan *wire_trafficPacket, 32) sinfo.recv = make(chan *wire_trafficPacket, 32)
go sinfo.doWorker() 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.sinfos[sinfo.myHandle] = &sinfo
ss.byMySes[sinfo.mySesPub] = &sinfo.myHandle ss.byMySes[sinfo.mySesPub] = &sinfo.myHandle
ss.byTheirPerm[sinfo.theirPermPub] = &sinfo.myHandle ss.byTheirPerm[sinfo.theirPermPub] = &sinfo.myHandle
@ -217,6 +212,19 @@ func (ss *sessions) createSession(theirPermKey *boxPubKey) *sessionInfo {
return &sinfo 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. // Closes a session, removing it from sessions maps and killing the worker goroutine.
func (sinfo *sessionInfo) close() { func (sinfo *sessionInfo) close() {
delete(sinfo.core.sessions.sinfos, sinfo.myHandle) delete(sinfo.core.sessions.sinfos, sinfo.myHandle)

View File

@ -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) { func (m *sigManager) putChecked(key *sigPubKey, newsig *sigBytes, bs []byte) {
m.mutex.Lock() m.mutex.Lock()
defer m.mutex.Unlock() defer m.mutex.Unlock()
now := time.Now() k := knownSig{key: *key, sig: *newsig, bs: bs, time: time.Now()}
if time.Since(m.lastCleaned) > 60*time.Second { m.checked[*newsig] = k
// Since we have the write lock anyway, do some cleanup }
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 { for s, k := range m.checked {
if time.Since(k.time) > 60*time.Second { if time.Since(k.time) > time.Minute {
delete(m.checked, s) delete(m.checked, s)
} }
} }
m.lastCleaned = now m.lastCleaned = time.Now()
}
k := knownSig{key: *key, sig: *newsig, bs: bs, time: now}
m.checked[*newsig] = k
} }