avoid leaking sessions when no listener exists, or blocking if it's busy

This commit is contained in:
Arceliar 2019-08-12 18:22:30 -05:00
parent c15976e4dc
commit b2cb1d965c

View File

@ -348,40 +348,40 @@ func (ss *sessions) sendPingPong(sinfo *sessionInfo, isPong bool) {
func (ss *sessions) handlePing(ping *sessionPing) { func (ss *sessions) handlePing(ping *sessionPing) {
// Get the corresponding session (or create a new session) // Get the corresponding session (or create a new session)
sinfo, isIn := ss.getByTheirPerm(&ping.SendPermPub) sinfo, isIn := ss.getByTheirPerm(&ping.SendPermPub)
// Check if the session is allowed switch {
// TODO: this check may need to be moved case isIn: // Session already exists
if !isIn && !ss.isSessionAllowed(&ping.SendPermPub, false) { case !ss.isSessionAllowed(&ping.SendPermPub, false): // Session is not allowed
return case ping.IsPong: // This is a response, not an initial ping, so ignore it.
} default:
// Create the session if it doesn't already exist
if !isIn {
ss.createSession(&ping.SendPermPub)
sinfo, isIn = ss.getByTheirPerm(&ping.SendPermPub)
if !isIn {
panic("This should not happen")
}
ss.listenerMutex.Lock() ss.listenerMutex.Lock()
// Check and see if there's a Listener waiting to accept connections if ss.listener != nil {
// TODO: this should not block if nothing is accepting // This is a ping from an allowed node for which no session exists, and we have a listener ready to handle sessions.
if !ping.IsPong && ss.listener != nil { // We need to create a session and pass it to the listener.
sinfo = ss.createSession(&ping.SendPermPub)
if s, _ := ss.getByTheirPerm(&ping.SendPermPub); s != sinfo {
panic("This should not happen")
}
conn := newConn(ss.core, crypto.GetNodeID(&sinfo.theirPermPub), &crypto.NodeID{}, sinfo) conn := newConn(ss.core, crypto.GetNodeID(&sinfo.theirPermPub), &crypto.NodeID{}, sinfo)
for i := range conn.nodeMask { for i := range conn.nodeMask {
conn.nodeMask[i] = 0xFF conn.nodeMask[i] = 0xFF
} }
conn.session.startWorkers() conn.session.startWorkers()
ss.listener.conn <- conn c := ss.listener.conn
go func() { c <- conn }()
} }
ss.listenerMutex.Unlock() ss.listenerMutex.Unlock()
} }
sinfo.doFunc(func() { if sinfo != nil {
// Update the session sinfo.doFunc(func() {
if !sinfo.update(ping) { /*panic("Should not happen in testing")*/ // Update the session
return if !sinfo.update(ping) { /*panic("Should not happen in testing")*/
} return
if !ping.IsPong { }
ss.sendPingPong(sinfo, true) if !ping.IsPong {
} ss.sendPingPong(sinfo, true)
}) }
})
}
} }
// Get the MTU of the session. // Get the MTU of the session.