Skip to content

Commit

Permalink
Fix session handling and kill a race
Browse files Browse the repository at this point in the history
  • Loading branch information
marcopeereboom committed Feb 27, 2024
1 parent 90c4d2f commit 4ee8899
Showing 1 changed file with 10 additions and 20 deletions.
30 changes: 10 additions & 20 deletions service/bfg/bfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -704,9 +704,6 @@ func (s *Server) handleWebsocketPrivateRead(ctx context.Context, bws *bfgWs) {
if err != nil {
log.Errorf("handleWebsocketRead %v %v %v: %v",
bws.addr, cmd, id, err)
// XXX this needs to be handled by the caller
bws.conn.CloseStatus(websocket.StatusProtocolError,
err.Error())
return
}

Expand Down Expand Up @@ -781,9 +778,6 @@ func (s *Server) handleWebsocketPublicRead(ctx context.Context, bws *bfgWs) {
if err != nil {
log.Errorf("handleWebsocketRead %v %v %v: %v",
bws.addr, cmd, id, err)
// XXX this needs to be handled by the caller
bws.conn.CloseStatus(websocket.StatusProtocolError,
err.Error())
return
}

Expand Down Expand Up @@ -815,21 +809,19 @@ func (s *Server) newSession(bws *bfgWs) (string, error) {
}
}

func (s *Server) killSession(id string, why websocket.StatusCode) {
func (s *Server) deleteSession(id string) {
log.Tracef("deleteSession")
defer log.Tracef("deleteSession exit")

s.mtx.Lock()
bws, ok := s.sessions[id]
_, ok := s.sessions[id]
if ok {
delete(s.sessions, id)
}
s.mtx.Unlock()

if !ok {
log.Errorf("killSession: id not found in sessions %s", id)
} else {
if err := bws.conn.CloseStatus(why, ""); err != nil {
// XXX this is too noisy.
log.Debugf("session close %v: %v", id, err)
}
log.Errorf("deleteSession: id not found in sessions %s", id)
}
}

Expand All @@ -848,6 +840,7 @@ func (s *Server) handleWebsocketPrivate(w http.ResponseWriter, r *http.Request)
r.RemoteAddr, err)
return
}
defer conn.Close(websocket.StatusProtocolError, "")

bws := &bfgWs{
addr: r.RemoteAddr,
Expand All @@ -865,7 +858,7 @@ func (s *Server) handleWebsocketPrivate(w http.ResponseWriter, r *http.Request)
}

defer func() {
s.killSession(bws.sessionId, websocket.StatusNormalClosure)
s.deleteSession(bws.sessionId)
}()

bws.wg.Add(1)
Expand Down Expand Up @@ -956,7 +949,7 @@ func (s *Server) handleWebsocketPublic(w http.ResponseWriter, r *http.Request) {
return
}
defer func() {
s.killSession(bws.sessionId, websocket.StatusNormalClosure)
s.deleteSession(bws.sessionId)
}()

// Always ping, required by protocol.
Expand Down Expand Up @@ -1300,8 +1293,6 @@ func (s *Server) handleAccessPublicKeys(table string, action string, payload, pa
return
}

// XXX this is racing with killSession but protected. We should
// create a killSessions that takes an encoded PublicKey
s.mtx.Lock()
for _, v := range s.sessions {
// if public key does not exist on session, it's not an authenticated
Expand All @@ -1314,8 +1305,7 @@ func (s *Server) handleAccessPublicKeys(table string, action string, payload, pa
// encoding, ensure that the session string does for an equal comparison
sessionPublicKeyEncoded := fmt.Sprintf("\\x%s", hex.EncodeToString(v.publicKey))
if sessionPublicKeyEncoded == accessPublicKey.PublicKeyEncoded {
sessionId := v.sessionId
go s.killSession(sessionId, protocol.StatusHandshakeErr)
v.conn.CloseStatus(websocket.StatusProtocolError, "killed")
}
}
s.mtx.Unlock()
Expand Down

0 comments on commit 4ee8899

Please sign in to comment.