2023-03-01 02:37:47 +00:00
|
|
|
package libbox
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"net"
|
|
|
|
"runtime"
|
|
|
|
"time"
|
|
|
|
|
2023-03-03 11:26:54 +00:00
|
|
|
"github.com/sagernet/sing-box/common/dialer/conntrack"
|
2023-03-01 02:37:47 +00:00
|
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
|
|
)
|
|
|
|
|
|
|
|
type StatusMessage struct {
|
2023-03-03 11:26:54 +00:00
|
|
|
Memory int64
|
|
|
|
Goroutines int32
|
|
|
|
Connections int32
|
2023-03-01 02:37:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func readStatus() StatusMessage {
|
|
|
|
var memStats runtime.MemStats
|
|
|
|
runtime.ReadMemStats(&memStats)
|
|
|
|
var message StatusMessage
|
2023-03-03 16:40:47 +00:00
|
|
|
message.Memory = int64(memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased)
|
2023-03-01 02:37:47 +00:00
|
|
|
message.Goroutines = int32(runtime.NumGoroutine())
|
2023-03-03 11:26:54 +00:00
|
|
|
message.Connections = int32(conntrack.Count())
|
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)
|
|
|
|
if err != nil {
|
|
|
|
return E.Cause(err, "read interval")
|
|
|
|
}
|
|
|
|
ticker := time.NewTicker(time.Duration(interval))
|
|
|
|
defer ticker.Stop()
|
|
|
|
ctx := connKeepAlive(conn)
|
|
|
|
for {
|
|
|
|
err = binary.Write(conn, binary.BigEndian, readStatus())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
return nil
|
|
|
|
case <-ticker.C:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CommandClient) handleStatusConn(conn net.Conn) {
|
|
|
|
for {
|
|
|
|
var message StatusMessage
|
|
|
|
err := binary.Read(conn, binary.BigEndian, &message)
|
|
|
|
if err != nil {
|
|
|
|
c.handler.Disconnected(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
c.handler.WriteStatus(&message)
|
|
|
|
}
|
|
|
|
}
|