2021-11-08 15:43:36 +00:00
|
|
|
package tunnelstate
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/rs/zerolog"
|
|
|
|
|
|
|
|
"github.com/cloudflare/cloudflared/connection"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ConnTracker struct {
|
|
|
|
sync.RWMutex
|
2022-08-11 20:31:36 +00:00
|
|
|
// int is the connection Index
|
|
|
|
connectionInfo map[uint8]ConnectionInfo
|
|
|
|
log *zerolog.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
type ConnectionInfo struct {
|
|
|
|
IsConnected bool
|
|
|
|
Protocol connection.Protocol
|
2021-11-08 15:43:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewConnTracker(log *zerolog.Logger) *ConnTracker {
|
|
|
|
return &ConnTracker{
|
2022-08-11 20:31:36 +00:00
|
|
|
connectionInfo: make(map[uint8]ConnectionInfo, 0),
|
|
|
|
log: log,
|
2021-11-08 15:43:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-11 20:31:36 +00:00
|
|
|
func MockedConnTracker(mocked map[uint8]ConnectionInfo) *ConnTracker {
|
2021-11-08 15:43:36 +00:00
|
|
|
return &ConnTracker{
|
2022-08-11 20:31:36 +00:00
|
|
|
connectionInfo: mocked,
|
2021-11-08 15:43:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ct *ConnTracker) OnTunnelEvent(c connection.Event) {
|
|
|
|
switch c.EventType {
|
|
|
|
case connection.Connected:
|
|
|
|
ct.Lock()
|
2022-08-11 20:31:36 +00:00
|
|
|
ci := ConnectionInfo{
|
|
|
|
IsConnected: true,
|
|
|
|
Protocol: c.Protocol,
|
|
|
|
}
|
|
|
|
ct.connectionInfo[c.Index] = ci
|
2021-11-08 15:43:36 +00:00
|
|
|
ct.Unlock()
|
|
|
|
case connection.Disconnected, connection.Reconnecting, connection.RegisteringTunnel, connection.Unregistering:
|
|
|
|
ct.Lock()
|
2022-08-11 20:31:36 +00:00
|
|
|
ci := ct.connectionInfo[c.Index]
|
|
|
|
ci.IsConnected = false
|
|
|
|
ct.connectionInfo[c.Index] = ci
|
2021-11-08 15:43:36 +00:00
|
|
|
ct.Unlock()
|
|
|
|
default:
|
|
|
|
ct.log.Error().Msgf("Unknown connection event case %v", c)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ct *ConnTracker) CountActiveConns() uint {
|
|
|
|
ct.RLock()
|
|
|
|
defer ct.RUnlock()
|
|
|
|
active := uint(0)
|
2022-08-11 20:31:36 +00:00
|
|
|
for _, ci := range ct.connectionInfo {
|
|
|
|
if ci.IsConnected {
|
2021-11-08 15:43:36 +00:00
|
|
|
active++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return active
|
|
|
|
}
|
2022-08-11 20:31:36 +00:00
|
|
|
|
|
|
|
// HasConnectedWith checks if we've ever had a successful connection to the edge
|
|
|
|
// with said protocol.
|
|
|
|
func (ct *ConnTracker) HasConnectedWith(protocol connection.Protocol) bool {
|
|
|
|
ct.RLock()
|
|
|
|
defer ct.RUnlock()
|
|
|
|
for _, ci := range ct.connectionInfo {
|
|
|
|
if ci.Protocol == protocol {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|