command_types.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. package libbox
  2. import (
  3. "slices"
  4. "strings"
  5. "github.com/sagernet/sing-box/daemon"
  6. M "github.com/sagernet/sing/common/metadata"
  7. )
  8. type StatusMessage struct {
  9. Memory int64
  10. Goroutines int32
  11. ConnectionsIn int32
  12. ConnectionsOut int32
  13. TrafficAvailable bool
  14. Uplink int64
  15. Downlink int64
  16. UplinkTotal int64
  17. DownlinkTotal int64
  18. }
  19. type SystemProxyStatus struct {
  20. Available bool
  21. Enabled bool
  22. }
  23. type OutboundGroup struct {
  24. Tag string
  25. Type string
  26. Selectable bool
  27. Selected string
  28. IsExpand bool
  29. ItemList []*OutboundGroupItem
  30. }
  31. func (g *OutboundGroup) GetItems() OutboundGroupItemIterator {
  32. return newIterator(g.ItemList)
  33. }
  34. type OutboundGroupIterator interface {
  35. Next() *OutboundGroup
  36. HasNext() bool
  37. }
  38. type OutboundGroupItem struct {
  39. Tag string
  40. Type string
  41. URLTestTime int64
  42. URLTestDelay int32
  43. }
  44. type OutboundGroupItemIterator interface {
  45. Next() *OutboundGroupItem
  46. HasNext() bool
  47. }
  48. const (
  49. ConnectionStateAll = iota
  50. ConnectionStateActive
  51. ConnectionStateClosed
  52. )
  53. type Connections struct {
  54. input []Connection
  55. filtered []Connection
  56. }
  57. func (c *Connections) FilterState(state int32) {
  58. c.filtered = c.filtered[:0]
  59. switch state {
  60. case ConnectionStateAll:
  61. c.filtered = append(c.filtered, c.input...)
  62. case ConnectionStateActive:
  63. for _, connection := range c.input {
  64. if connection.ClosedAt == 0 {
  65. c.filtered = append(c.filtered, connection)
  66. }
  67. }
  68. case ConnectionStateClosed:
  69. for _, connection := range c.input {
  70. if connection.ClosedAt != 0 {
  71. c.filtered = append(c.filtered, connection)
  72. }
  73. }
  74. }
  75. }
  76. func (c *Connections) SortByDate() {
  77. slices.SortStableFunc(c.filtered, func(x, y Connection) int {
  78. if x.CreatedAt < y.CreatedAt {
  79. return 1
  80. } else if x.CreatedAt > y.CreatedAt {
  81. return -1
  82. } else {
  83. return strings.Compare(y.ID, x.ID)
  84. }
  85. })
  86. }
  87. func (c *Connections) SortByTraffic() {
  88. slices.SortStableFunc(c.filtered, func(x, y Connection) int {
  89. xTraffic := x.Uplink + x.Downlink
  90. yTraffic := y.Uplink + y.Downlink
  91. if xTraffic < yTraffic {
  92. return 1
  93. } else if xTraffic > yTraffic {
  94. return -1
  95. } else {
  96. return strings.Compare(y.ID, x.ID)
  97. }
  98. })
  99. }
  100. func (c *Connections) SortByTrafficTotal() {
  101. slices.SortStableFunc(c.filtered, func(x, y Connection) int {
  102. xTraffic := x.UplinkTotal + x.DownlinkTotal
  103. yTraffic := y.UplinkTotal + y.DownlinkTotal
  104. if xTraffic < yTraffic {
  105. return 1
  106. } else if xTraffic > yTraffic {
  107. return -1
  108. } else {
  109. return strings.Compare(y.ID, x.ID)
  110. }
  111. })
  112. }
  113. func (c *Connections) Iterator() ConnectionIterator {
  114. return newPtrIterator(c.filtered)
  115. }
  116. type Connection struct {
  117. ID string
  118. Inbound string
  119. InboundType string
  120. IPVersion int32
  121. Network string
  122. Source string
  123. Destination string
  124. Domain string
  125. Protocol string
  126. User string
  127. FromOutbound string
  128. CreatedAt int64
  129. ClosedAt int64
  130. Uplink int64
  131. Downlink int64
  132. UplinkTotal int64
  133. DownlinkTotal int64
  134. Rule string
  135. Outbound string
  136. OutboundType string
  137. ChainList []string
  138. }
  139. func (c *Connection) Chain() StringIterator {
  140. return newIterator(c.ChainList)
  141. }
  142. func (c *Connection) DisplayDestination() string {
  143. destination := M.ParseSocksaddr(c.Destination)
  144. if destination.IsIP() && c.Domain != "" {
  145. destination = M.Socksaddr{
  146. Fqdn: c.Domain,
  147. Port: destination.Port,
  148. }
  149. return destination.String()
  150. }
  151. return c.Destination
  152. }
  153. type ConnectionIterator interface {
  154. Next() *Connection
  155. HasNext() bool
  156. }
  157. func StatusMessageFromGRPC(status *daemon.Status) *StatusMessage {
  158. if status == nil {
  159. return nil
  160. }
  161. return &StatusMessage{
  162. Memory: int64(status.Memory),
  163. Goroutines: status.Goroutines,
  164. ConnectionsIn: status.ConnectionsIn,
  165. ConnectionsOut: status.ConnectionsOut,
  166. TrafficAvailable: status.TrafficAvailable,
  167. Uplink: status.Uplink,
  168. Downlink: status.Downlink,
  169. UplinkTotal: status.UplinkTotal,
  170. DownlinkTotal: status.DownlinkTotal,
  171. }
  172. }
  173. func OutboundGroupIteratorFromGRPC(groups *daemon.Groups) OutboundGroupIterator {
  174. if groups == nil || len(groups.Group) == 0 {
  175. return newIterator([]*OutboundGroup{})
  176. }
  177. var libboxGroups []*OutboundGroup
  178. for _, g := range groups.Group {
  179. libboxGroup := &OutboundGroup{
  180. Tag: g.Tag,
  181. Type: g.Type,
  182. Selectable: g.Selectable,
  183. Selected: g.Selected,
  184. IsExpand: g.IsExpand,
  185. }
  186. for _, item := range g.Items {
  187. libboxGroup.ItemList = append(libboxGroup.ItemList, &OutboundGroupItem{
  188. Tag: item.Tag,
  189. Type: item.Type,
  190. URLTestTime: item.UrlTestTime,
  191. URLTestDelay: item.UrlTestDelay,
  192. })
  193. }
  194. libboxGroups = append(libboxGroups, libboxGroup)
  195. }
  196. return newIterator(libboxGroups)
  197. }
  198. func ConnectionFromGRPC(conn *daemon.Connection) Connection {
  199. return Connection{
  200. ID: conn.Id,
  201. Inbound: conn.Inbound,
  202. InboundType: conn.InboundType,
  203. IPVersion: conn.IpVersion,
  204. Network: conn.Network,
  205. Source: conn.Source,
  206. Destination: conn.Destination,
  207. Domain: conn.Domain,
  208. Protocol: conn.Protocol,
  209. User: conn.User,
  210. FromOutbound: conn.FromOutbound,
  211. CreatedAt: conn.CreatedAt,
  212. ClosedAt: conn.ClosedAt,
  213. Uplink: conn.Uplink,
  214. Downlink: conn.Downlink,
  215. UplinkTotal: conn.UplinkTotal,
  216. DownlinkTotal: conn.DownlinkTotal,
  217. Rule: conn.Rule,
  218. Outbound: conn.Outbound,
  219. OutboundType: conn.OutboundType,
  220. ChainList: conn.ChainList,
  221. }
  222. }
  223. func ConnectionsFromGRPC(connections *daemon.Connections) []Connection {
  224. if connections == nil || len(connections.Connections) == 0 {
  225. return nil
  226. }
  227. var libboxConnections []Connection
  228. for _, conn := range connections.Connections {
  229. libboxConnections = append(libboxConnections, ConnectionFromGRPC(conn))
  230. }
  231. return libboxConnections
  232. }
  233. func SystemProxyStatusFromGRPC(status *daemon.SystemProxyStatus) *SystemProxyStatus {
  234. if status == nil {
  235. return nil
  236. }
  237. return &SystemProxyStatus{
  238. Available: status.Available,
  239. Enabled: status.Enabled,
  240. }
  241. }
  242. func SystemProxyStatusToGRPC(status *SystemProxyStatus) *daemon.SystemProxyStatus {
  243. if status == nil {
  244. return nil
  245. }
  246. return &daemon.SystemProxyStatus{
  247. Available: status.Available,
  248. Enabled: status.Enabled,
  249. }
  250. }