github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/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/inazumav/sing-box/common/dialer/conntrack" 10 "github.com/inazumav/sing-box/experimental/clashapi" 11 E "github.com/sagernet/sing/common/exceptions" 12 ) 13 14 type StatusMessage struct { 15 Memory int64 16 Goroutines int32 17 ConnectionsIn int32 18 ConnectionsOut int32 19 TrafficAvailable bool 20 Uplink int64 21 Downlink int64 22 UplinkTotal int64 23 DownlinkTotal int64 24 } 25 26 func (s *CommandServer) readStatus() StatusMessage { 27 var memStats runtime.MemStats 28 runtime.ReadMemStats(&memStats) 29 var message StatusMessage 30 message.Memory = int64(memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased) 31 message.Goroutines = int32(runtime.NumGoroutine()) 32 message.ConnectionsOut = int32(conntrack.Count()) 33 34 if s.service != nil { 35 if clashServer := s.service.instance.Router().ClashServer(); clashServer != nil { 36 message.TrafficAvailable = true 37 trafficManager := clashServer.(*clashapi.Server).TrafficManager() 38 message.Uplink, message.Downlink = trafficManager.Now() 39 message.UplinkTotal, message.DownlinkTotal = trafficManager.Total() 40 message.ConnectionsIn = int32(trafficManager.Connections()) 41 } 42 } 43 44 return message 45 } 46 47 func (s *CommandServer) handleStatusConn(conn net.Conn) error { 48 var interval int64 49 err := binary.Read(conn, binary.BigEndian, &interval) 50 if err != nil { 51 return E.Cause(err, "read interval") 52 } 53 ticker := time.NewTicker(time.Duration(interval)) 54 defer ticker.Stop() 55 ctx := connKeepAlive(conn) 56 for { 57 err = binary.Write(conn, binary.BigEndian, s.readStatus()) 58 if err != nil { 59 return err 60 } 61 select { 62 case <-ctx.Done(): 63 return ctx.Err() 64 case <-ticker.C: 65 } 66 } 67 } 68 69 func (c *CommandClient) handleStatusConn(conn net.Conn) { 70 for { 71 var message StatusMessage 72 err := binary.Read(conn, binary.BigEndian, &message) 73 if err != nil { 74 c.handler.Disconnected(err.Error()) 75 return 76 } 77 c.handler.WriteStatus(&message) 78 } 79 }