package notify import ( "errors" "net" ) func (s *ServerCommon) stopClientSession(client *ClientConn, reason string, err error) { if client == nil { return } if runtime := s.getStreamRuntime(); runtime != nil { runtime.closeScope(serverFileScope(client), streamRuntimeCloseError(err)) } if runtime := s.getBulkRuntime(); runtime != nil { runtime.closeScope(serverFileScope(client), bulkRuntimeCloseError(err)) } if transfers := s.getTransferState(); transfers != nil { transfers.closeScope(serverFileScope(client), err) } client.stopServerOwnedSessionWith(s.removeClient, reason, err) } func (s *ServerCommon) stopLogicalSession(logical *LogicalConn, reason string, err error) { if logical == nil { return } if runtime := s.getStreamRuntime(); runtime != nil { runtime.closeScope(serverFileScope(logical), streamRuntimeCloseError(err)) } if runtime := s.getBulkRuntime(); runtime != nil { runtime.closeScope(serverFileScope(logical), bulkRuntimeCloseError(err)) } if transfers := s.getTransferState(); transfers != nil { transfers.closeScope(serverFileScope(logical), err) } logical.stopServerOwnedSessionWith(s.removeLogical, reason, err) } func (s *ServerCommon) detachClientSessionTransport(client *ClientConn, reason string, err error) { if s == nil || client == nil { return } if !client.clientConnTransportAttachedSnapshot() { return } client.markClientConnTransportDetached(reason, err) s.getPendingWaitPool().closeScope(serverTransportScope(client)) s.getPendingWaitPool().closeScope(serverFileScope(client)) s.getFileAckPool().closeScope(serverTransportScope(client)) s.getFileAckPool().closeScope(serverFileScope(client)) s.getSignalAckPool().closeScope(serverTransportScope(client)) s.getSignalAckPool().closeScope(serverFileScope(client)) if runtime := s.getStreamRuntime(); runtime != nil { runtime.closeScope(serverFileScope(client), errTransportDetached) } if runtime := s.getBulkRuntime(); runtime != nil { runtime.closeScope(serverFileScope(client), errTransportDetached) } s.closeServerDedicatedSidecar(logicalConnFromClient(client)) client.detachServerOwnedTransport() } func (s *ServerCommon) detachLogicalSessionTransport(logical *LogicalConn, reason string, err error) { if s == nil || logical == nil { return } if !logical.transportAttachedSnapshot() { return } logical.markTransportDetached(reason, err) s.getPendingWaitPool().closeScope(serverTransportScope(logical)) s.getPendingWaitPool().closeScope(serverFileScope(logical)) s.getFileAckPool().closeScope(serverTransportScope(logical)) s.getFileAckPool().closeScope(serverFileScope(logical)) s.getSignalAckPool().closeScope(serverTransportScope(logical)) s.getSignalAckPool().closeScope(serverFileScope(logical)) if runtime := s.getStreamRuntime(); runtime != nil { runtime.closeScope(serverFileScope(logical), errTransportDetached) } if runtime := s.getBulkRuntime(); runtime != nil { runtime.closeScope(serverFileScope(logical), errTransportDetached) } s.closeServerDedicatedSidecar(logical) logical.detachServerOwnedTransport() } func (s *ServerCommon) newAcceptedClient(id string, addr net.Addr) *ClientConn { logical := s.newAcceptedLogical(id, addr) if logical == nil { return nil } return logical.compatClientConn() } func (s *ServerCommon) newAcceptedLogical(id string, addr net.Addr) *LogicalConn { if s == nil { return nil } return newServerLogicalConn(s, id, addr) } func (s *ServerCommon) registerAcceptedClient(client *ClientConn) *LogicalConn { return s.registerAcceptedLogical(logicalConnFromClient(client)) } func (s *ServerCommon) registerAcceptedLogical(logical *LogicalConn) *LogicalConn { if s == nil || logical == nil { return nil } logical.setServer(s) logical.applyAttachmentProfile(s.maxReadTimeout, s.maxWriteTimeout, s.defaultMsgEn, s.defaultMsgDe, s.defaultFastStreamEncode, s.defaultFastBulkEncode, s.defaultFastPlainEncode, s.handshakeRsaKey, s.SecretKey) logical.updateAttachmentState(func(state *clientConnAttachmentState) { state.authMode = s.securityAuthMode state.peerAttached = false state.peerAttachFallback = false state.peerAttachAt = 0 }) if s.securityConfigured { logical.applyTransportProtectionProfile(s.securityBootstrap) } else { logical.setModernPSKRuntime(s.defaultModernPSKRuntime) } logical.markHeartbeatNow() return s.getPeerRegistry().registerLogical(logical) } func (s *ServerCommon) renameAcceptedLogical(logical *LogicalConn, id string) error { if s == nil { return errors.New("server is nil") } if logical == nil { return errors.New("logical conn is nil") } if id == "" { return errors.New("client id is empty") } if logical.ID() == id { return nil } return s.getPeerRegistry().renameLogical(logical, id) } func (s *ServerCommon) renameAcceptedClient(client *ClientConn, id string) error { return s.renameAcceptedLogical(logicalConnFromClient(client), id) } func (c *LogicalConn) inheritAcceptedLogicalTransportState(src *LogicalConn) { if c == nil || src == nil { return } c.inheritAttachmentProfile(src) if addr := src.RemoteAddr(); addr != nil { c.setRemoteAddr(addr) } } func (c *LogicalConn) attachAcceptedTransport(addr net.Addr, tuConn net.Conn) error { if c == nil { return errors.New("logical conn is nil") } if addr == nil && tuConn != nil { addr = tuConn.RemoteAddr() } if addr != nil { c.setRemoteAddr(addr) } if tuConn == nil { return nil } c.markHeartbeatNow() c.clearTransportDetachState() if c.sessionRuntimeSnapshot() == nil { c.startSessionTransport(tuConn, nil, nil) return nil } return c.attachSessionTransport(tuConn) } func (s *ServerCommon) attachAcceptedLogicalTransport(logical *LogicalConn, addr net.Addr, tuConn net.Conn) error { if s == nil { return errors.New("server is nil") } if logical == nil { return errors.New("logical conn is nil") } logical.setServer(s) return logical.attachAcceptedTransport(addr, tuConn) } func (s *ServerCommon) attachAcceptedClientTransport(client *ClientConn, addr net.Addr, tuConn net.Conn) error { return s.attachAcceptedLogicalTransport(logicalConnFromClient(client), addr, tuConn) } func (s *ServerCommon) handoffAcceptedLogicalTransport(dst *LogicalConn, src *LogicalConn) error { if s == nil { return errors.New("server is nil") } if dst == nil { return errors.New("destination logical conn is nil") } if src == nil { return errors.New("source logical conn is nil") } if dst == src { return nil } addr := src.RemoteAddr() conn, err := src.detachTransportForTransfer() if err != nil { return err } if err := s.attachAcceptedLogicalTransport(dst, addr, conn); err != nil { if conn != nil { _ = conn.Close() } return err } dst.inheritAcceptedLogicalTransportState(src) src.markSessionStopped("peer transport handed off", nil) s.removeLogical(src) return nil } func (s *ServerCommon) handoffAcceptedClientTransport(dst *ClientConn, src *ClientConn) error { return s.handoffAcceptedLogicalTransport(logicalConnFromClient(dst), logicalConnFromClient(src)) } func (s *ServerCommon) upsertAcceptedLogical(id string, addr net.Addr, tuConn net.Conn) (*LogicalConn, bool, error) { if s == nil { return nil, false, errors.New("server is nil") } if id == "" { return nil, false, errors.New("client id is empty") } if existing := s.GetLogicalConn(id); existing != nil { if err := s.attachAcceptedLogicalTransport(existing, addr, tuConn); err != nil { if tuConn != nil { _ = tuConn.Close() } return nil, true, err } return existing, true, nil } logical := s.newAcceptedLogical(id, addr) if logical == nil { return nil, false, errors.New("accepted logical is nil") } logical = s.registerAcceptedLogical(logical) if logical == nil { return nil, false, errors.New("accepted logical is nil") } if err := s.attachAcceptedLogicalTransport(logical, addr, tuConn); err != nil { if tuConn != nil { _ = tuConn.Close() } s.removeLogical(logical) return nil, false, err } if tuConn == nil { logical.startSession(nil, nil, nil) } return logical, false, nil } func (s *ServerCommon) upsertAcceptedClient(id string, addr net.Addr, tuConn net.Conn) (*ClientConn, bool, error) { logical, reused, err := s.upsertAcceptedLogical(id, addr, tuConn) if logical == nil { return nil, reused, err } return logical.compatClientConn(), reused, err } func (s *ServerCommon) bootstrapAcceptedLogical(id string, addr net.Addr, tuConn net.Conn) *LogicalConn { logical, _, err := s.upsertAcceptedLogical(id, addr, tuConn) if err != nil { return nil } return logical } func (s *ServerCommon) bootstrapAcceptedClient(id string, addr net.Addr, tuConn net.Conn) *ClientConn { logical := s.bootstrapAcceptedLogical(id, addr, tuConn) if logical == nil { return nil } return logical.compatClientConn() }