sing-box/experimental/libbox/command_status.go

88 lines
2 KiB
Go
Raw Normal View History

2023-03-01 02:37:47 +00:00
package libbox
import (
"encoding/binary"
"net"
"runtime"
"time"
2023-09-20 06:12:08 +00:00
"github.com/sagernet/sing-box/common/conntrack"
2023-07-16 06:08:45 +00:00
"github.com/sagernet/sing-box/experimental/clashapi"
2023-03-01 02:37:47 +00:00
E "github.com/sagernet/sing/common/exceptions"
2023-09-20 06:12:08 +00:00
"github.com/sagernet/sing/common/memory"
2023-03-01 02:37:47 +00:00
)
type StatusMessage struct {
2023-07-16 06:08:45 +00:00
Memory int64
Goroutines int32
ConnectionsIn int32
ConnectionsOut int32
TrafficAvailable bool
Uplink int64
Downlink int64
UplinkTotal int64
DownlinkTotal int64
2023-03-01 02:37:47 +00:00
}
2023-07-16 06:08:45 +00:00
func (s *CommandServer) readStatus() StatusMessage {
2023-03-01 02:37:47 +00:00
var message StatusMessage
2023-09-20 06:12:08 +00:00
message.Memory = int64(memory.Inuse())
2023-03-01 02:37:47 +00:00
message.Goroutines = int32(runtime.NumGoroutine())
2023-07-16 06:08:45 +00:00
message.ConnectionsOut = int32(conntrack.Count())
if s.service != nil {
2024-11-10 08:46:59 +00:00
message.TrafficAvailable = true
trafficManager := s.service.clashServer.(*clashapi.Server).TrafficManager()
message.UplinkTotal, message.DownlinkTotal = trafficManager.Total()
message.ConnectionsIn = int32(trafficManager.ConnectionsLen())
2023-07-16 06:08:45 +00:00
}
2023-03-01 02:37:47 +00:00
return message
}
func (s *CommandServer) handleStatusConn(conn net.Conn) error {
var interval int64
err := binary.Read(conn, binary.BigEndian, &interval)
2023-03-01 02:37:47 +00:00
if err != nil {
return E.Cause(err, "read interval")
}
ticker := time.NewTicker(time.Duration(interval))
defer ticker.Stop()
ctx := connKeepAlive(conn)
2024-11-27 10:05:30 +00:00
var (
status StatusMessage
uploadTotal int64
downloadTotal int64
)
for {
2024-11-27 10:05:30 +00:00
status = s.readStatus()
upload := status.UplinkTotal - uploadTotal
download := status.DownlinkTotal - downloadTotal
uploadTotal = status.UplinkTotal
downloadTotal = status.DownlinkTotal
status.Uplink = upload
status.Downlink = download
err = binary.Write(conn, binary.BigEndian, status)
if err != nil {
return err
2023-03-01 02:37:47 +00:00
}
select {
case <-ctx.Done():
return ctx.Err()
case <-ticker.C:
2023-03-01 02:37:47 +00:00
}
}
}
func (c *CommandClient) handleStatusConn(conn net.Conn) {
for {
var message StatusMessage
err := binary.Read(conn, binary.BigEndian, &message)
2023-03-01 02:37:47 +00:00
if err != nil {
c.handler.Disconnected(err.Error())
return
}
c.handler.WriteStatus(&message)
}
}