mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-16 03:39:07 +02:00
57 lines
2.0 KiB
Go
57 lines
2.0 KiB
Go
package server
|
|
|
|
import "context"
|
|
|
|
// sessionAgent abstracts the per-platform manager that spawns and tracks
|
|
// the user-session VNC agent. Resolve returns the agent's Unix-socket
|
|
// path, the shared per-spawn token, and the uid the agent was spawned
|
|
// under (used to validate peer credentials before the daemon hands the
|
|
// token to whoever is on the other end of the socket). Resolve may spawn
|
|
// the agent lazily.
|
|
type sessionAgent interface {
|
|
Resolve(ctx context.Context) (socketPath, token string, peerUID uint32, err error)
|
|
}
|
|
|
|
// serviceAgent returns the one agent manager this server shares across every
|
|
// service-mode accept loop, constructing it on first use.
|
|
//
|
|
// One per server, not one per listener: the manager owns the agent process for
|
|
// the active session, so a second manager spawns a second agent on its own
|
|
// socket path, and each accept loop then proxies to a different one. Only one of
|
|
// those agents ends up serving, so connections arriving on the other listener
|
|
// are refused with the agent socket actively refusing the dial. A dual-stack
|
|
// server has two accept loops, since the v6 overlay listener is added after
|
|
// Start, which is how that happened.
|
|
//
|
|
// Returns nil once the server has stopped, and on platforms with no service
|
|
// mode.
|
|
func (s *Server) serviceAgent() sessionAgent {
|
|
s.serviceAgentMu.Lock()
|
|
defer s.serviceAgentMu.Unlock()
|
|
|
|
if s.serviceAgentStopped {
|
|
return nil
|
|
}
|
|
if s.serviceAgentMgr == nil {
|
|
s.serviceAgentMgr, s.serviceAgentStop = s.newServiceAgentManager()
|
|
}
|
|
return s.serviceAgentMgr
|
|
}
|
|
|
|
// stopServiceAgent tears down the shared manager, if one was ever built, and
|
|
// latches the server so a still-draining accept loop cannot build another.
|
|
// Owned by Stop rather than by an accept loop: the loops share the manager, so
|
|
// the first one to exit must not take it away from the others.
|
|
func (s *Server) stopServiceAgent() {
|
|
s.serviceAgentMu.Lock()
|
|
stop := s.serviceAgentStop
|
|
s.serviceAgentStop = nil
|
|
s.serviceAgentMgr = nil
|
|
s.serviceAgentStopped = true
|
|
s.serviceAgentMu.Unlock()
|
|
|
|
if stop != nil {
|
|
stop()
|
|
}
|
|
}
|