| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 | 
							- package trafficontrol
 
- import (
 
- 	"runtime"
 
- 	"sync"
 
- 	"sync/atomic"
 
- 	"time"
 
- 	"github.com/sagernet/sing-box/common/compatible"
 
- 	C "github.com/sagernet/sing-box/constant"
 
- 	"github.com/sagernet/sing/common"
 
- 	"github.com/sagernet/sing/common/json"
 
- 	"github.com/sagernet/sing/common/x/list"
 
- 	"github.com/gofrs/uuid/v5"
 
- )
 
- type Manager struct {
 
- 	uploadTotal   atomic.Int64
 
- 	downloadTotal atomic.Int64
 
- 	connections             compatible.Map[uuid.UUID, Tracker]
 
- 	closedConnectionsAccess sync.Mutex
 
- 	closedConnections       list.List[TrackerMetadata]
 
- 	// process     *process.Process
 
- 	memory uint64
 
- }
 
- func NewManager() *Manager {
 
- 	return &Manager{}
 
- }
 
- func (m *Manager) Join(c Tracker) {
 
- 	m.connections.Store(c.Metadata().ID, c)
 
- }
 
- func (m *Manager) Leave(c Tracker) {
 
- 	metadata := c.Metadata()
 
- 	_, loaded := m.connections.LoadAndDelete(metadata.ID)
 
- 	if loaded {
 
- 		metadata.ClosedAt = time.Now()
 
- 		m.closedConnectionsAccess.Lock()
 
- 		defer m.closedConnectionsAccess.Unlock()
 
- 		if m.closedConnections.Len() >= 1000 {
 
- 			m.closedConnections.PopFront()
 
- 		}
 
- 		m.closedConnections.PushBack(metadata)
 
- 	}
 
- }
 
- func (m *Manager) PushUploaded(size int64) {
 
- 	m.uploadTotal.Add(size)
 
- }
 
- func (m *Manager) PushDownloaded(size int64) {
 
- 	m.downloadTotal.Add(size)
 
- }
 
- func (m *Manager) Total() (up int64, down int64) {
 
- 	return m.uploadTotal.Load(), m.downloadTotal.Load()
 
- }
 
- func (m *Manager) ConnectionsLen() int {
 
- 	return m.connections.Len()
 
- }
 
- func (m *Manager) Connections() []TrackerMetadata {
 
- 	var connections []TrackerMetadata
 
- 	m.connections.Range(func(_ uuid.UUID, value Tracker) bool {
 
- 		connections = append(connections, value.Metadata())
 
- 		return true
 
- 	})
 
- 	return connections
 
- }
 
- func (m *Manager) ClosedConnections() []TrackerMetadata {
 
- 	m.closedConnectionsAccess.Lock()
 
- 	defer m.closedConnectionsAccess.Unlock()
 
- 	return m.closedConnections.Array()
 
- }
 
- func (m *Manager) Connection(id uuid.UUID) Tracker {
 
- 	connection, loaded := m.connections.Load(id)
 
- 	if !loaded {
 
- 		return nil
 
- 	}
 
- 	return connection
 
- }
 
- func (m *Manager) Snapshot() *Snapshot {
 
- 	var connections []Tracker
 
- 	m.connections.Range(func(_ uuid.UUID, value Tracker) bool {
 
- 		if value.Metadata().OutboundType != C.TypeDNS {
 
- 			connections = append(connections, value)
 
- 		}
 
- 		return true
 
- 	})
 
- 	var memStats runtime.MemStats
 
- 	runtime.ReadMemStats(&memStats)
 
- 	m.memory = memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased
 
- 	return &Snapshot{
 
- 		Upload:      m.uploadTotal.Load(),
 
- 		Download:    m.downloadTotal.Load(),
 
- 		Connections: connections,
 
- 		Memory:      m.memory,
 
- 	}
 
- }
 
- func (m *Manager) ResetStatistic() {
 
- 	m.uploadTotal.Store(0)
 
- 	m.downloadTotal.Store(0)
 
- }
 
- type Snapshot struct {
 
- 	Download    int64
 
- 	Upload      int64
 
- 	Connections []Tracker
 
- 	Memory      uint64
 
- }
 
- func (s *Snapshot) MarshalJSON() ([]byte, error) {
 
- 	return json.Marshal(map[string]any{
 
- 		"downloadTotal": s.Download,
 
- 		"uploadTotal":   s.Upload,
 
- 		"connections":   common.Map(s.Connections, func(t Tracker) TrackerMetadata { return t.Metadata() }),
 
- 		"memory":        s.Memory,
 
- 	})
 
- }
 
 
  |