mirror of https://github.com/coder/coder.git
102 lines
2.3 KiB
Go
102 lines
2.3 KiB
Go
package tailnet
|
|
|
|
import "github.com/google/uuid"
|
|
|
|
type TunnelAuth interface {
|
|
Authorize(dst uuid.UUID) bool
|
|
}
|
|
|
|
// SingleTailnetTunnelAuth allows all tunnels, since Coderd and wsproxy are allowed to initiate a tunnel to any agent
|
|
type SingleTailnetTunnelAuth struct{}
|
|
|
|
func (SingleTailnetTunnelAuth) Authorize(uuid.UUID) bool {
|
|
return true
|
|
}
|
|
|
|
// ClientTunnelAuth allows connecting to a single, given agent
|
|
type ClientTunnelAuth struct {
|
|
AgentID uuid.UUID
|
|
}
|
|
|
|
func (c ClientTunnelAuth) Authorize(dst uuid.UUID) bool {
|
|
return c.AgentID == dst
|
|
}
|
|
|
|
// AgentTunnelAuth disallows all tunnels, since agents are not allowed to initiate their own tunnels
|
|
type AgentTunnelAuth struct{}
|
|
|
|
func (AgentTunnelAuth) Authorize(uuid.UUID) bool {
|
|
return false
|
|
}
|
|
|
|
// tunnelStore contains tunnel information and allows querying it. It is not threadsafe and all
|
|
// methods must be serialized by holding, e.g. the core mutex.
|
|
type tunnelStore struct {
|
|
bySrc map[uuid.UUID]map[uuid.UUID]struct{}
|
|
byDst map[uuid.UUID]map[uuid.UUID]struct{}
|
|
}
|
|
|
|
func newTunnelStore() *tunnelStore {
|
|
return &tunnelStore{
|
|
bySrc: make(map[uuid.UUID]map[uuid.UUID]struct{}),
|
|
byDst: make(map[uuid.UUID]map[uuid.UUID]struct{}),
|
|
}
|
|
}
|
|
|
|
func (s *tunnelStore) add(src, dst uuid.UUID) {
|
|
srcM, ok := s.bySrc[src]
|
|
if !ok {
|
|
srcM = make(map[uuid.UUID]struct{})
|
|
s.bySrc[src] = srcM
|
|
}
|
|
srcM[dst] = struct{}{}
|
|
dstM, ok := s.byDst[dst]
|
|
if !ok {
|
|
dstM = make(map[uuid.UUID]struct{})
|
|
s.byDst[dst] = dstM
|
|
}
|
|
dstM[src] = struct{}{}
|
|
}
|
|
|
|
func (s *tunnelStore) remove(src, dst uuid.UUID) {
|
|
delete(s.bySrc[src], dst)
|
|
if len(s.bySrc[src]) == 0 {
|
|
delete(s.bySrc, src)
|
|
}
|
|
delete(s.byDst[dst], src)
|
|
if len(s.byDst[dst]) == 0 {
|
|
delete(s.byDst, dst)
|
|
}
|
|
}
|
|
|
|
func (s *tunnelStore) removeAll(src uuid.UUID) {
|
|
for dst := range s.bySrc[src] {
|
|
s.remove(src, dst)
|
|
}
|
|
}
|
|
|
|
func (s *tunnelStore) findTunnelPeers(id uuid.UUID) []uuid.UUID {
|
|
set := make(map[uuid.UUID]struct{})
|
|
for dst := range s.bySrc[id] {
|
|
set[dst] = struct{}{}
|
|
}
|
|
for src := range s.byDst[id] {
|
|
set[src] = struct{}{}
|
|
}
|
|
out := make([]uuid.UUID, 0, len(set))
|
|
for id := range set {
|
|
out = append(out, id)
|
|
}
|
|
return out
|
|
}
|
|
|
|
func (s *tunnelStore) htmlDebug() []HTMLTunnel {
|
|
out := make([]HTMLTunnel, 0)
|
|
for src, dsts := range s.bySrc {
|
|
for dst := range dsts {
|
|
out = append(out, HTMLTunnel{Src: src, Dst: dst})
|
|
}
|
|
}
|
|
return out
|
|
}
|