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  }