Skip to content

Commit

Permalink
Fix session leave + termination deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
Joerger authored Apr 7, 2022
1 parent 85d7e8a commit 76be6d7
Showing 1 changed file with 10 additions and 12 deletions.
22 changes: 10 additions & 12 deletions lib/srv/sess.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,15 +300,15 @@ func (s *SessionRegistry) emitSessionLeaveEvent(party *party) {
for _, p := range party.s.getParties() {
eventPayload, err := utils.FastMarshal(sessionLeaveEvent)
if err != nil {
s.log.Warnf("Unable to marshal %v for %v: %v.", events.SessionJoinEvent, p.sconn.RemoteAddr(), err)
s.log.Warnf("Unable to marshal %v for %v: %v.", events.SessionLeaveEvent, p.sconn.RemoteAddr(), err)
continue
}
_, _, err = p.sconn.SendRequest(teleport.SessionEvent, false, eventPayload)
if err != nil {
s.log.Warnf("Unable to send %v to %v: %v.", events.SessionJoinEvent, p.sconn.RemoteAddr(), err)
s.log.Warnf("Unable to send %v to %v: %v.", events.SessionLeaveEvent, p.sconn.RemoteAddr(), err)
continue
}
s.log.Debugf("Sent %v to %v.", events.SessionJoinEvent, p.sconn.RemoteAddr())
s.log.Debugf("Sent %v to %v.", events.SessionLeaveEvent, p.sconn.RemoteAddr())
}
}

Expand Down Expand Up @@ -346,21 +346,16 @@ func (s *SessionRegistry) ForceTerminate(ctx *ServerContext) error {
// leaveSession removes the given party from this session.
func (s *SessionRegistry) leaveSession(party *party) error {
sess := party.s
s.mu.Lock()
defer s.mu.Unlock()

// Emit session leave event to both the Audit Log as well as over the
// "x-teleport-event" channel in the SSH connection.
s.emitSessionLeaveEvent(party)

sess.mu.Lock()
defer sess.mu.Unlock()

// Remove member from in-members representation of party.
if err := sess.removeParty(party); err != nil {
return trace.Wrap(err)
}

// Emit session leave event to both the Audit Log as well as over the
// "x-teleport-event" channel in the SSH connection.
s.emitSessionLeaveEvent(party)

// this goroutine runs for a short amount of time only after a session
// becomes empty (no parties). It allows session to "linger" for a bit
// allowing parties to reconnect if they lost connection momentarily
Expand Down Expand Up @@ -1289,6 +1284,9 @@ func (s *session) removePartyMember(party *party) {
// removeParty removes the party from the in-memory map that holds all party
// members.
func (s *session) removeParty(p *party) error {
s.mu.Lock()
defer s.mu.Unlock()

p.ctx.Infof("Removing party %v from session %v", p, s.id)

// Removes participant from in-memory map of party members.
Expand Down

0 comments on commit 76be6d7

Please sign in to comment.