github.com/sagernet/sing-box@v1.2.7/experimental/libbox/command_status.go (about) 1 package libbox 2 3 import ( 4 "encoding/binary" 5 "net" 6 "runtime" 7 "time" 8 9 "github.com/sagernet/sing-box/common/dialer/conntrack" 10 E "github.com/sagernet/sing/common/exceptions" 11 ) 12 13 type StatusMessage struct { 14 Memory int64 15 Goroutines int32 16 Connections int32 17 } 18 19 func readStatus() StatusMessage { 20 var memStats runtime.MemStats 21 runtime.ReadMemStats(&memStats) 22 var message StatusMessage 23 message.Memory = int64(memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased) 24 message.Goroutines = int32(runtime.NumGoroutine()) 25 message.Connections = int32(conntrack.Count()) 26 return message 27 } 28 29 func (s *CommandServer) handleStatusConn(conn net.Conn) error { 30 var interval int64 31 err := binary.Read(conn, binary.BigEndian, &interval) 32 if err != nil { 33 return E.Cause(err, "read interval") 34 } 35 ticker := time.NewTicker(time.Duration(interval)) 36 defer ticker.Stop() 37 ctx := connKeepAlive(conn) 38 for { 39 err = binary.Write(conn, binary.BigEndian, readStatus()) 40 if err != nil { 41 return err 42 } 43 select { 44 case <-ctx.Done(): 45 return ctx.Err() 46 case <-ticker.C: 47 } 48 } 49 } 50 51 func (c *CommandClient) handleStatusConn(conn net.Conn) { 52 for { 53 var message StatusMessage 54 err := binary.Read(conn, binary.BigEndian, &message) 55 if err != nil { 56 c.handler.Disconnected(err.Error()) 57 return 58 } 59 c.handler.WriteStatus(&message) 60 } 61 }