mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-19 17:50:12 +00:00
85 lines
3.7 KiB
Go
85 lines
3.7 KiB
Go
//go:build agentcompat
|
|
|
|
package rpc
|
|
|
|
func (s *NezhaHandler) ConsumeAgentCompatNATCapability(access AgentCompatCapabilityAccess) (AgentCompatNATPublishHandle, error) {
|
|
s.ioStreamMutex.Lock()
|
|
defer s.ioStreamMutex.Unlock()
|
|
registration, allowed := s.agentCompatRegistrationLocked(access)
|
|
if !allowed {
|
|
return AgentCompatNATPublishHandle{}, ErrAgentCompatCapabilityHidden
|
|
}
|
|
return s.consumeAgentCompatNATCapabilityLocked(registration, access.Capability.value)
|
|
}
|
|
|
|
func (s *NezhaHandler) ConsumeAgentCompatNATCapabilityForProfile(value string, targetServerID, resourceID uint64) (AgentCompatCapabilityAccess, AgentCompatNATPublishHandle, error) {
|
|
capability, err := ParseAgentCompatIOStreamCapability(value)
|
|
if err != nil {
|
|
return AgentCompatCapabilityAccess{}, AgentCompatNATPublishHandle{}, ErrAgentCompatCapabilityHidden
|
|
}
|
|
|
|
s.ioStreamMutex.Lock()
|
|
defer s.ioStreamMutex.Unlock()
|
|
registration, exists := s.agentCompatCapabilities.active[capability.value]
|
|
if !exists || registration.registration.Purpose != AgentCompatCapabilityNAT ||
|
|
registration.registration.TargetServerID != targetServerID || registration.registration.ResourceID != resourceID {
|
|
return AgentCompatCapabilityAccess{}, AgentCompatNATPublishHandle{}, ErrAgentCompatCapabilityHidden
|
|
}
|
|
handle, err := s.consumeAgentCompatNATCapabilityLocked(registration, capability.value)
|
|
if err != nil {
|
|
return AgentCompatCapabilityAccess{}, AgentCompatNATPublishHandle{}, err
|
|
}
|
|
stored := registration.registration
|
|
return AgentCompatCapabilityAccess{
|
|
Capability: capability, Owner: stored.Owner, Purpose: stored.Purpose,
|
|
TargetServerID: stored.TargetServerID, ResourceID: stored.ResourceID,
|
|
ServerAccessAllowed: stored.ServerAccessAllowed,
|
|
}, handle, nil
|
|
}
|
|
|
|
func (s *NezhaHandler) consumeAgentCompatNATCapabilityLocked(registration *agentCompatCapabilityRegistration, capability string) (AgentCompatNATPublishHandle, error) {
|
|
if registration == nil || registration.registration.Purpose != AgentCompatCapabilityNAT || registration.phase != agentCompatCapabilityRegistered {
|
|
return AgentCompatNATPublishHandle{}, ErrAgentCompatCapabilityHidden
|
|
}
|
|
registration.phase = agentCompatCapabilityConsumed
|
|
return AgentCompatNATPublishHandle{
|
|
registration: registration, generation: registration.generation,
|
|
capability: capability,
|
|
}, nil
|
|
}
|
|
|
|
func (s *NezhaHandler) PublishAgentCompatNATStream(handle AgentCompatNATPublishHandle, publication AgentCompatNATPublication) error {
|
|
s.ioStreamMutex.RLock()
|
|
publishObserver := s.agentCompatCapabilities.publishObserver
|
|
s.ioStreamMutex.RUnlock()
|
|
if publishObserver != nil {
|
|
publishObserver()
|
|
}
|
|
s.ioStreamMutex.Lock()
|
|
defer s.ioStreamMutex.Unlock()
|
|
registration := handle.registration
|
|
// Pointer identity plus generation makes a late publisher inert after unregister/cancel.
|
|
if registration == nil || registration.generation != handle.generation {
|
|
return nil
|
|
}
|
|
current, active := s.agentCompatCapabilities.active[handle.capability]
|
|
if !active || current != registration {
|
|
return nil
|
|
}
|
|
if registration.phase == agentCompatCapabilityPublished {
|
|
return nil
|
|
}
|
|
stored := registration.registration
|
|
stream := registration.stream
|
|
exists := publication.StreamID != "" && registration.streamID == publication.StreamID && stream != nil && s.ioStreams[publication.StreamID] == stream
|
|
if registration.phase != agentCompatCapabilityConsumed || publication.Purpose != stored.Purpose ||
|
|
publication.TargetServerID != stored.TargetServerID || publication.ResourceID != stored.ResourceID ||
|
|
!exists || stream.creatorUserID != 0 ||
|
|
stream.targetServerID != stored.TargetServerID || stream.purpose != PurposeNAT {
|
|
return ErrAgentCompatCapabilityHidden
|
|
}
|
|
registration.phase = agentCompatCapabilityPublished
|
|
registration.publishLocked()
|
|
return nil
|
|
}
|