From b6b094413596cd8319c3dc71c9d7f286b9745ddb Mon Sep 17 00:00:00 2001
From: M03ED <50927468+M03ED@users.noreply.github.com>
Date: Fri, 14 Mar 2025 22:37:27 +0330
Subject: [PATCH 1/3] fix: keep alive bug
---
controller/controller.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/controller/controller.go b/controller/controller.go
index 897275a..0cb53aa 100644
--- a/controller/controller.go
+++ b/controller/controller.go
@@ -65,6 +65,8 @@ func (c *Controller) Disconnect() {
c.mu.Lock()
defer c.mu.Unlock()
+ c.aliveCancel()
+
if c.backend != nil {
c.backend.Shutdown()
}
@@ -75,7 +77,6 @@ func (c *Controller) Disconnect() {
c.sessionID = uuid.Nil
- c.aliveCancel()
}
func (c *Controller) NewRequest() {
From 070fc24521d2db15c89ea358105c0cc5c8da1933 Mon Sep 17 00:00:00 2001
From: M03ED <50927468+M03ED@users.noreply.github.com>
Date: Sat, 15 Mar 2025 05:38:56 +0330
Subject: [PATCH 2/3] fix: prevent race condition's and remove unnecessary
methods
---
backend/xray/xray.go | 53 ++++++++++++++-----------
controller/controller.go | 70 ++++++++++++++------------------
controller/rest/base.go | 18 ++++-----
controller/rest/log.go | 2 +-
controller/rest/middleware.go | 4 +-
controller/rest/rest_test.go | 2 +-
controller/rest/service.go | 75 ++++-------------------------------
controller/rest/stats.go | 18 ++++-----
controller/rest/user.go | 4 +-
controller/rpc/base.go | 30 +++++++++++---
controller/rpc/log.go | 4 +-
controller/rpc/middleware.go | 8 ++--
controller/rpc/rpc_test.go | 2 +-
controller/rpc/service.go | 28 +++----------
controller/rpc/stats.go | 18 ++++-----
controller/rpc/user.go | 11 ++---
main.go | 2 +-
17 files changed, 142 insertions(+), 207 deletions(-)
diff --git a/backend/xray/xray.go b/backend/xray/xray.go
index d3fcca0..47f853a 100644
--- a/backend/xray/xray.go
+++ b/backend/xray/xray.go
@@ -25,9 +25,8 @@ type Xray struct {
core *Core
handler *api.XrayHandler
configPath string
- ctx context.Context
cancelFunc context.CancelFunc
- mu sync.Mutex
+ mu sync.RWMutex
}
func NewXray(ctx context.Context, port int, executablePath, assetsPath, configPath string) (*Xray, error) {
@@ -48,7 +47,7 @@ func NewXray(ctx context.Context, port int, executablePath, assetsPath, configPa
xCtx, xCancel := context.WithCancel(context.Background())
- xray := &Xray{configPath: configAbsolutePath, ctx: xCtx, cancelFunc: xCancel}
+ xray := &Xray{configPath: configAbsolutePath, cancelFunc: xCancel}
start := time.Now()
@@ -94,7 +93,7 @@ func NewXray(ctx context.Context, port int, executablePath, assetsPath, configPa
return nil, err
}
xray.setHandler(handler)
- go xray.checkXrayHealth()
+ go xray.checkXrayHealth(xCtx)
return xray, nil
}
@@ -106,8 +105,8 @@ func (x *Xray) setConfig(config *Config) {
}
func (x *Xray) getConfig() *Config {
- x.mu.Lock()
- defer x.mu.Unlock()
+ x.mu.RLock()
+ defer x.mu.RUnlock()
return x.config
}
@@ -118,26 +117,26 @@ func (x *Xray) setCore(core *Core) {
}
func (x *Xray) getCore() *Core {
- x.mu.Lock()
- defer x.mu.Unlock()
+ x.mu.RLock()
+ defer x.mu.RUnlock()
return x.core
}
func (x *Xray) GetCore() backend.Core {
- x.mu.Lock()
- defer x.mu.Unlock()
+ x.mu.RLock()
+ defer x.mu.RUnlock()
return x.core
}
func (x *Xray) GetLogs() chan string {
- x.mu.Lock()
- defer x.mu.Unlock()
+ x.mu.RLock()
+ defer x.mu.RUnlock()
return x.core.GetLogs()
}
func (x *Xray) GetVersion() string {
- x.mu.Lock()
- defer x.mu.Unlock()
+ x.mu.RLock()
+ defer x.mu.RUnlock()
return x.core.GetVersion()
}
@@ -148,8 +147,8 @@ func (x *Xray) setHandler(handler *api.XrayHandler) {
}
func (x *Xray) getHandler() *api.XrayHandler {
- x.mu.Lock()
- defer x.mu.Unlock()
+ x.mu.RLock()
+ defer x.mu.RUnlock()
return x.handler
}
@@ -213,8 +212,8 @@ func (x *Xray) GetInboundStats(ctx context.Context, tag string, reset bool) (*co
}
func (x *Xray) GenerateConfigFile() error {
- x.mu.Lock()
- defer x.mu.Unlock()
+ x.mu.RLock()
+ defer x.mu.RUnlock()
var prettyJSON bytes.Buffer
@@ -271,21 +270,29 @@ Loop:
return nil
}
-func (x *Xray) checkXrayHealth() {
+func (x *Xray) checkXrayHealth(baseCtx context.Context) {
for {
select {
- case <-x.ctx.Done():
+ case <-baseCtx.Done():
return
default:
- ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
- if _, err := x.GetSysStats(ctx); err != nil {
+ ctx, cancel := context.WithTimeout(baseCtx, time.Second*2)
+ _, err := x.GetSysStats(ctx)
+ cancel() // Always call cancel to avoid context leak
+
+ if err != nil {
+ if errors.Is(err, context.Canceled) {
+ // Context was canceled due to x.ctx cancellation
+ return // Exit gracefully
+ }
+
+ // Handle other errors by attempting restart
if err = x.Restart(); err != nil {
nodeLogger.Log(nodeLogger.LogError, err.Error())
} else {
nodeLogger.Log(nodeLogger.LogInfo, "xray restarted")
}
}
- cancel()
}
time.Sleep(time.Second * 2)
}
diff --git a/controller/controller.go b/controller/controller.go
index 0cb53aa..081932a 100644
--- a/controller/controller.go
+++ b/controller/controller.go
@@ -19,54 +19,55 @@ import (
const NodeVersion = "1.0.0"
type Service interface {
- StopService()
+ Disconnect()
}
type Controller struct {
backend backend.Backend
sessionID uuid.UUID
apiPort int
+ clientIP string
lastRequest time.Time
stats *common.SystemStatsResponse
- aliveCancel context.CancelFunc
- statsCancel context.CancelFunc
- mu sync.Mutex
+ cancelFunc context.CancelFunc
+ mu sync.RWMutex
}
-func NewController() *Controller {
- c := &Controller{
- sessionID: uuid.Nil,
- apiPort: tools.FindFreePort(),
- }
- c.startJobs()
- return c
+func (c *Controller) Init() {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.sessionID = uuid.Nil
+ c.apiPort = tools.FindFreePort()
+ _, c.cancelFunc = context.WithCancel(context.Background())
}
func (c *Controller) GetSessionID() uuid.UUID {
- c.mu.Lock()
- defer c.mu.Unlock()
+ c.mu.RLock()
+ defer c.mu.RUnlock()
return c.sessionID
}
-func (c *Controller) Connect(keepAlive uint64) {
+func (c *Controller) Connect(ip string, keepAlive uint64) {
c.mu.Lock()
defer c.mu.Unlock()
c.sessionID = uuid.New()
c.lastRequest = time.Now()
+ c.clientIP = ip
ctx, cancel := context.WithCancel(context.Background())
- c.aliveCancel = cancel
+ c.cancelFunc = cancel
+ go c.recordSystemStats(ctx)
if keepAlive > 0 {
go c.keepAliveTracker(ctx, time.Duration(keepAlive)*time.Second)
}
}
func (c *Controller) Disconnect() {
+ c.cancelFunc()
+
c.mu.Lock()
defer c.mu.Unlock()
- c.aliveCancel()
-
if c.backend != nil {
c.backend.Shutdown()
}
@@ -76,7 +77,13 @@ func (c *Controller) Disconnect() {
c.apiPort = apiPort
c.sessionID = uuid.Nil
+ c.clientIP = ""
+}
+func (c *Controller) GetIP() string {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+ return c.clientIP
}
func (c *Controller) NewRequest() {
@@ -105,8 +112,8 @@ func (c *Controller) StartBackend(ctx context.Context, backendType common.Backen
}
func (c *Controller) GetBackend() backend.Backend {
- c.mu.Lock()
- defer c.mu.Unlock()
+ c.mu.RLock()
+ defer c.mu.RUnlock()
return c.backend
}
@@ -116,9 +123,9 @@ func (c *Controller) keepAliveTracker(ctx context.Context, keepAlive time.Durati
case <-ctx.Done():
break
default:
- c.mu.Lock()
+ c.mu.RLock()
lastRequest := c.lastRequest
- c.mu.Unlock()
+ c.mu.RUnlock()
if time.Since(lastRequest) >= keepAlive {
log.Println("disconnect automatically due to keep alive timeout")
c.Disconnect()
@@ -148,8 +155,8 @@ func (c *Controller) recordSystemStats(ctx context.Context) {
}
func (c *Controller) GetStats() *common.SystemStatsResponse {
- c.mu.Lock()
- defer c.mu.Unlock()
+ c.mu.RLock()
+ defer c.mu.RUnlock()
return c.stats
}
@@ -174,20 +181,3 @@ func (c *Controller) BaseInfoResponse(includeID bool, extra string) *common.Base
return response
}
-
-func (c *Controller) startJobs() {
- ctx, cancel := context.WithCancel(context.Background())
- c.mu.Lock()
- defer c.mu.Unlock()
- c.statsCancel = cancel
- go c.recordSystemStats(ctx)
-}
-
-func (c *Controller) StopJobs() {
- c.mu.Lock()
- c.statsCancel()
- c.mu.Unlock()
-
- c.Disconnect()
-
-}
diff --git a/controller/rest/base.go b/controller/rest/base.go
index 9b49d74..a04d475 100644
--- a/controller/rest/base.go
+++ b/controller/rest/base.go
@@ -13,7 +13,7 @@ import (
)
func (s *Service) Base(w http.ResponseWriter, _ *http.Request) {
- common.SendProtoResponse(w, s.controller.BaseInfoResponse(false, ""))
+ common.SendProtoResponse(w, s.BaseInfoResponse(false, ""))
}
func (s *Service) Start(w http.ResponseWriter, r *http.Request) {
@@ -29,26 +29,26 @@ func (s *Service) Start(w http.ResponseWriter, r *http.Request) {
return
}
- if s.controller.GetBackend() != nil {
+ if s.GetBackend() != nil {
log.Println("New connection from ", ip, " core control access was taken away from previous client.")
- s.disconnect()
+ s.Disconnect()
}
- s.connect(ip, keepAlive)
+ s.Connect(ip, keepAlive)
- log.Println(ip, " connected, Session ID = ", s.controller.GetSessionID())
+ log.Println(ip, " connected, Session ID = ", s.GetSessionID())
- if err = s.controller.StartBackend(ctx, backendType); err != nil {
+ if err = s.StartBackend(ctx, backendType); err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
- common.SendProtoResponse(w, s.controller.BaseInfoResponse(true, ""))
+ common.SendProtoResponse(w, s.BaseInfoResponse(true, ""))
}
func (s *Service) Stop(w http.ResponseWriter, _ *http.Request) {
- log.Println(s.GetIP(), " disconnected, Session ID = ", s.controller.GetSessionID())
- s.disconnect()
+ log.Println(s.GetIP(), " disconnected, Session ID = ", s.GetSessionID())
+ s.Disconnect()
common.SendProtoResponse(w, &common.Empty{})
}
diff --git a/controller/rest/log.go b/controller/rest/log.go
index 8a97f17..02a7a12 100644
--- a/controller/rest/log.go
+++ b/controller/rest/log.go
@@ -16,7 +16,7 @@ func (s *Service) GetLogs(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
- logChan := s.controller.GetBackend().GetLogs()
+ logChan := s.GetBackend().GetLogs()
for {
select {
diff --git a/controller/rest/middleware.go b/controller/rest/middleware.go
index cd0caf0..766dd3a 100644
--- a/controller/rest/middleware.go
+++ b/controller/rest/middleware.go
@@ -15,7 +15,7 @@ func (s *Service) checkSessionIDMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// check ip
clientIP := s.GetIP()
- clientID := s.controller.GetSessionID()
+ clientID := s.GetSessionID()
if clientIP == "" || clientID == uuid.Nil {
http.Error(w, "please connect first", http.StatusTooEarly)
return
@@ -61,7 +61,7 @@ func (s *Service) checkSessionIDMiddleware(next http.Handler) http.Handler {
func (s *Service) checkBackendMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- back := s.controller.GetBackend()
+ back := s.GetBackend()
if back == nil {
http.Error(w, "backend not initialized", http.StatusInternalServerError)
return
diff --git a/controller/rest/rest_test.go b/controller/rest/rest_test.go
index c1d9d29..fe515d2 100644
--- a/controller/rest/rest_test.go
+++ b/controller/rest/rest_test.go
@@ -79,7 +79,7 @@ func TestRESTConnection(t *testing.T) {
if err != nil {
t.Fatalf("Failed to start HTTP listener: %v", err)
}
- defer s.StopService()
+ defer s.Disconnect()
creds, err := tools.LoadTLSCredentials(sslClientCertFile, sslClientKeyFile, sslCertFile, true)
if err != nil {
diff --git a/controller/rest/service.go b/controller/rest/service.go
index 9837a1f..105a63e 100644
--- a/controller/rest/service.go
+++ b/controller/rest/service.go
@@ -4,20 +4,15 @@ import (
"context"
"crypto/tls"
"errors"
- "log"
- "net/http"
- "sync"
-
"github.com/go-chi/chi/v5"
- "github.com/m03ed/gozargah-node/common"
"github.com/m03ed/gozargah-node/controller"
+ "log"
+ "net/http"
)
func NewService() *Service {
- s := &Service{
- controller: controller.NewController(),
- clientIP: "",
- }
+ s := &Service{}
+ s.Init()
s.setRouter()
return s
}
@@ -59,68 +54,12 @@ func (s *Service) setRouter() {
})
})
- s.mu.Lock()
- defer s.mu.Unlock()
s.Router = router
}
type Service struct {
- Router chi.Router
- clientIP string
- controller *controller.Controller
- mu sync.Mutex
-}
-
-func (s *Service) connect(ip string, keepAlive uint64) {
- s.mu.Lock()
- defer s.mu.Unlock()
- s.clientIP = ip
- s.controller.Connect(keepAlive)
-}
-
-func (s *Service) disconnect() {
- s.controller.Disconnect()
-
- s.mu.Lock()
- defer s.mu.Unlock()
-
- s.clientIP = ""
-}
-
-func (s *Service) StopService() {
- s.mu.Lock()
- defer s.mu.Unlock()
- s.controller.StopJobs()
-}
-
-func (s *Service) GetIP() string {
- s.mu.Lock()
- defer s.mu.Unlock()
- return s.clientIP
-}
-
-func (s *Service) response(includeID bool, extra string) *common.BaseInfoResponse {
- response := &common.BaseInfoResponse{
- Started: false,
- CoreVersion: "",
- NodeVersion: controller.NodeVersion,
- Extra: extra,
- }
-
- s.mu.Lock()
- defer s.mu.Unlock()
-
- back := s.controller.GetBackend()
- if back != nil {
- response.Started = back.Started()
- response.CoreVersion = back.GetVersion()
- }
-
- if includeID {
- response.SessionId = s.controller.GetSessionID().String()
- }
-
- return response
+ controller.Controller
+ Router chi.Router
}
func StartHttpListener(tlsConfig *tls.Config, addr string) (func(ctx context.Context) error, controller.Service, error) {
@@ -141,5 +80,5 @@ func StartHttpListener(tlsConfig *tls.Config, addr string) (func(ctx context.Con
}()
// Return a shutdown function for HTTP server
- return httpServer.Shutdown, controller.Service(s), nil
+ return httpServer.Shutdown, s, nil
}
diff --git a/controller/rest/stats.go b/controller/rest/stats.go
index c4c878f..bb913aa 100644
--- a/controller/rest/stats.go
+++ b/controller/rest/stats.go
@@ -13,7 +13,7 @@ func (s *Service) GetOutboundsStats(w http.ResponseWriter, r *http.Request) {
return
}
- stats, err := s.controller.GetBackend().GetOutboundsStats(r.Context(), request.GetReset_())
+ stats, err := s.GetBackend().GetOutboundsStats(r.Context(), request.GetReset_())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -34,7 +34,7 @@ func (s *Service) GetOutboundStats(w http.ResponseWriter, r *http.Request) {
return
}
- stats, err := s.controller.GetBackend().GetOutboundStats(r.Context(), request.GetName(), request.GetReset_())
+ stats, err := s.GetBackend().GetOutboundStats(r.Context(), request.GetName(), request.GetReset_())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -50,7 +50,7 @@ func (s *Service) GetInboundsStats(w http.ResponseWriter, r *http.Request) {
return
}
- stats, err := s.controller.GetBackend().GetInboundsStats(r.Context(), request.GetReset_())
+ stats, err := s.GetBackend().GetInboundsStats(r.Context(), request.GetReset_())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -71,7 +71,7 @@ func (s *Service) GetInboundStats(w http.ResponseWriter, r *http.Request) {
return
}
- stats, err := s.controller.GetBackend().GetInboundStats(r.Context(), request.GetName(), request.GetReset_())
+ stats, err := s.GetBackend().GetInboundStats(r.Context(), request.GetName(), request.GetReset_())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -87,7 +87,7 @@ func (s *Service) GetUsersStats(w http.ResponseWriter, r *http.Request) {
return
}
- stats, err := s.controller.GetBackend().GetUsersStats(r.Context(), request.GetReset_())
+ stats, err := s.GetBackend().GetUsersStats(r.Context(), request.GetReset_())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -108,7 +108,7 @@ func (s *Service) GetUserStats(w http.ResponseWriter, r *http.Request) {
return
}
- stats, err := s.controller.GetBackend().GetUserStats(r.Context(), request.GetName(), request.GetReset_())
+ stats, err := s.GetBackend().GetUserStats(r.Context(), request.GetName(), request.GetReset_())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -129,7 +129,7 @@ func (s *Service) GetUserOnlineStat(w http.ResponseWriter, r *http.Request) {
return
}
- stats, err := s.controller.GetBackend().GetStatOnline(r.Context(), request.GetName())
+ stats, err := s.GetBackend().GetStatOnline(r.Context(), request.GetName())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -139,7 +139,7 @@ func (s *Service) GetUserOnlineStat(w http.ResponseWriter, r *http.Request) {
}
func (s *Service) GetBackendStats(w http.ResponseWriter, r *http.Request) {
- stats, err := s.controller.GetBackend().GetSysStats(r.Context())
+ stats, err := s.GetBackend().GetSysStats(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -149,5 +149,5 @@ func (s *Service) GetBackendStats(w http.ResponseWriter, r *http.Request) {
}
func (s *Service) GetSystemStats(w http.ResponseWriter, _ *http.Request) {
- common.SendProtoResponse(w, s.controller.GetStats())
+ common.SendProtoResponse(w, s.GetStats())
}
diff --git a/controller/rest/user.go b/controller/rest/user.go
index 7c91c2f..5781b10 100644
--- a/controller/rest/user.go
+++ b/controller/rest/user.go
@@ -28,7 +28,7 @@ func (s *Service) SyncUser(w http.ResponseWriter, r *http.Request) {
return
}
- if err = s.controller.GetBackend().SyncUser(r.Context(), user); err != nil {
+ if err = s.GetBackend().SyncUser(r.Context(), user); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -56,7 +56,7 @@ func (s *Service) SyncUsers(w http.ResponseWriter, r *http.Request) {
return
}
- if err = s.controller.GetBackend().SyncUsers(r.Context(), users.GetUsers()); err != nil {
+ if err = s.GetBackend().SyncUsers(r.Context(), users.GetUsers()); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
diff --git a/controller/rpc/base.go b/controller/rpc/base.go
index c2dfbe0..46388f7 100644
--- a/controller/rpc/base.go
+++ b/controller/rpc/base.go
@@ -3,9 +3,12 @@ package rpc
import (
"context"
"errors"
+ "net"
+
"github.com/m03ed/gozargah-node/backend"
"github.com/m03ed/gozargah-node/backend/xray"
"github.com/m03ed/gozargah-node/common"
+ "google.golang.org/grpc/peer"
)
func (s *Service) Start(ctx context.Context, detail *common.Backend) (*common.BaseInfoResponse, error) {
@@ -14,17 +17,34 @@ func (s *Service) Start(ctx context.Context, detail *common.Backend) (*common.Ba
return nil, err
}
- if err = s.controller.StartBackend(ctx, detail.GetType()); err != nil {
+ if err = s.StartBackend(ctx, detail.GetType()); err != nil {
return nil, err
}
- s.connect(detail.GetKeepAlive())
+ clientIP := ""
+ if p, ok := peer.FromContext(ctx); ok {
+ // Extract IP address from peer address
+ if tcpAddr, ok := p.Addr.(*net.TCPAddr); ok {
+ clientIP = tcpAddr.IP.String()
+ } else {
+ // For other address types, extract just the IP without the port
+ addr := p.Addr.String()
+ if host, _, err := net.SplitHostPort(addr); err == nil {
+ clientIP = host
+ } else {
+ // If SplitHostPort fails, use the whole address
+ clientIP = addr
+ }
+ }
+ }
+
+ s.Connect(clientIP, detail.GetKeepAlive())
- return s.controller.BaseInfoResponse(true, ""), nil
+ return s.BaseInfoResponse(true, ""), nil
}
func (s *Service) Stop(_ context.Context, _ *common.Empty) (*common.Empty, error) {
- s.disconnect()
+ s.Disconnect()
return nil, nil
}
@@ -45,5 +65,5 @@ func (s *Service) detectBackend(ctx context.Context, detail *common.Backend) (co
}
func (s *Service) GetBaseInfo(_ context.Context, _ *common.Empty) (*common.BaseInfoResponse, error) {
- return s.controller.BaseInfoResponse(false, ""), nil
+ return s.BaseInfoResponse(false, ""), nil
}
diff --git a/controller/rpc/log.go b/controller/rpc/log.go
index 6042455..3369ebd 100644
--- a/controller/rpc/log.go
+++ b/controller/rpc/log.go
@@ -8,7 +8,7 @@ import (
)
func (s *Service) GetLogs(_ *common.Empty, stream common.NodeService_GetLogsServer) error {
- logChan := s.controller.GetBackend().GetLogs()
+ logChan := s.GetBackend().GetLogs()
for {
select {
@@ -23,7 +23,7 @@ func (s *Service) GetLogs(_ *common.Empty, stream common.NodeService_GetLogsServ
case <-stream.Context().Done():
// Client has disconnected or cancelled the request
- return stream.Context().Err()
+ return nil
}
}
}
diff --git a/controller/rpc/middleware.go b/controller/rpc/middleware.go
index c0c2bae..3f47212 100644
--- a/controller/rpc/middleware.go
+++ b/controller/rpc/middleware.go
@@ -23,7 +23,7 @@ func validateSessionID(ctx context.Context, s *Service) error {
}
// Check session ID
- sessionID := s.controller.GetSessionID()
+ sessionID := s.GetSessionID()
if sessionID == uuid.Nil {
return status.Errorf(codes.Unauthenticated, "please connect first")
}
@@ -51,8 +51,8 @@ func validateSessionID(ctx context.Context, s *Service) error {
if token != sessionID {
return status.Errorf(codes.PermissionDenied, "session ID mismatch")
}
-
- s.controller.NewRequest()
+
+ s.NewRequest()
return nil
}
@@ -90,7 +90,7 @@ func CheckSessionIDStreamMiddleware(s *Service) grpc.StreamServerInterceptor {
}
func checkBackendStatus(s *Service) error {
- back := s.controller.GetBackend()
+ back := s.GetBackend()
if back == nil {
return status.Errorf(codes.Internal, "backend not initialized")
}
diff --git a/controller/rpc/rpc_test.go b/controller/rpc/rpc_test.go
index 6623503..13c634c 100644
--- a/controller/rpc/rpc_test.go
+++ b/controller/rpc/rpc_test.go
@@ -66,7 +66,7 @@ func TestGRPCConnection(t *testing.T) {
}
shutdownFunc, s, err := StartGRPCListener(tlsConfig, addr)
- defer s.StopService()
+ defer s.Disconnect()
if err != nil {
t.Fatal(err)
}
diff --git a/controller/rpc/service.go b/controller/rpc/service.go
index 7d08e32..f2bb131 100644
--- a/controller/rpc/service.go
+++ b/controller/rpc/service.go
@@ -4,41 +4,25 @@ import (
"context"
"crypto/tls"
"fmt"
+ "github.com/m03ed/gozargah-node/common"
+ "github.com/m03ed/gozargah-node/controller"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"log"
"net"
- "sync"
-
- "github.com/m03ed/gozargah-node/common"
- "github.com/m03ed/gozargah-node/controller"
)
type Service struct {
common.UnimplementedNodeServiceServer
- controller *controller.Controller
- mu sync.Mutex
+ controller.Controller
}
func NewService() *Service {
- s := &Service{controller: controller.NewController()}
+ s := &Service{}
+ s.Init()
return s
}
-func (s *Service) StopService() {
- s.mu.Lock()
- defer s.mu.Unlock()
- s.controller.StopJobs()
-}
-
-func (s *Service) connect(keepAlive uint64) {
- s.controller.Connect(keepAlive)
-}
-
-func (s *Service) disconnect() {
- s.controller.Disconnect()
-}
-
func StartGRPCListener(tlsConfig *tls.Config, addr string) (func(ctx context.Context) error, controller.Service, error) {
s := NewService()
@@ -84,5 +68,5 @@ func StartGRPCListener(tlsConfig *tls.Config, addr string) (func(ctx context.Con
grpcServer.Stop() // Force stop if graceful stop times out
return ctx.Err()
}
- }, controller.Service(s), nil
+ }, s, nil
}
diff --git a/controller/rpc/stats.go b/controller/rpc/stats.go
index 40e3738..cc67c6f 100644
--- a/controller/rpc/stats.go
+++ b/controller/rpc/stats.go
@@ -8,49 +8,49 @@ import (
)
func (s *Service) GetOutboundsStats(ctx context.Context, request *common.StatRequest) (*common.StatResponse, error) {
- return s.controller.GetBackend().GetOutboundsStats(ctx, request.GetReset_())
+ return s.GetBackend().GetOutboundsStats(ctx, request.GetReset_())
}
func (s *Service) GetOutboundStats(ctx context.Context, request *common.StatRequest) (*common.StatResponse, error) {
if request.GetName() == "" {
return nil, errors.New("name is required")
}
- return s.controller.GetBackend().GetOutboundStats(ctx, request.GetName(), request.GetReset_())
+ return s.GetBackend().GetOutboundStats(ctx, request.GetName(), request.GetReset_())
}
func (s *Service) GetInboundsStats(ctx context.Context, request *common.StatRequest) (*common.StatResponse, error) {
- return s.controller.GetBackend().GetInboundsStats(ctx, request.GetReset_())
+ return s.GetBackend().GetInboundsStats(ctx, request.GetReset_())
}
func (s *Service) GetInboundStats(ctx context.Context, request *common.StatRequest) (*common.StatResponse, error) {
if request.GetName() == "" {
return nil, errors.New("name is required")
}
- return s.controller.GetBackend().GetInboundStats(ctx, request.GetName(), request.GetReset_())
+ return s.GetBackend().GetInboundStats(ctx, request.GetName(), request.GetReset_())
}
func (s *Service) GetUsersStats(ctx context.Context, request *common.StatRequest) (*common.StatResponse, error) {
- return s.controller.GetBackend().GetUsersStats(ctx, request.GetReset_())
+ return s.GetBackend().GetUsersStats(ctx, request.GetReset_())
}
func (s *Service) GetUserStats(ctx context.Context, request *common.StatRequest) (*common.StatResponse, error) {
if request.GetName() == "" {
return nil, errors.New("name is required")
}
- return s.controller.GetBackend().GetUserStats(ctx, request.GetName(), request.GetReset_())
+ return s.GetBackend().GetUserStats(ctx, request.GetName(), request.GetReset_())
}
func (s *Service) GetUserOnlineStats(ctx context.Context, request *common.StatRequest) (*common.OnlineStatResponse, error) {
if request.GetName() == "" {
return nil, errors.New("name is required")
}
- return s.controller.GetBackend().GetStatOnline(ctx, request.GetName())
+ return s.GetBackend().GetStatOnline(ctx, request.GetName())
}
func (s *Service) GetBackendStats(ctx context.Context, _ *common.Empty) (*common.BackendStatsResponse, error) {
- return s.controller.GetBackend().GetSysStats(ctx)
+ return s.GetBackend().GetSysStats(ctx)
}
func (s *Service) GetSystemStats(_ context.Context, _ *common.Empty) (*common.SystemStatsResponse, error) {
- return s.controller.GetStats(), nil
+ return s.GetStats(), nil
}
diff --git a/controller/rpc/user.go b/controller/rpc/user.go
index 8d83bd2..2f7185e 100644
--- a/controller/rpc/user.go
+++ b/controller/rpc/user.go
@@ -3,8 +3,6 @@ package rpc
import (
"context"
"errors"
- "io"
-
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -15,25 +13,22 @@ import (
func (s *Service) SyncUser(stream grpc.ClientStreamingServer[common.User, common.Empty]) error {
for {
user, err := stream.Recv()
- if err == io.EOF {
- return stream.SendAndClose(&common.Empty{})
- }
if err != nil {
- return status.Errorf(codes.Internal, "failed to receive user: %v", err)
+ return stream.SendAndClose(&common.Empty{})
}
if user.GetEmail() == "" {
return errors.New("email is required")
}
- if err = s.controller.GetBackend().SyncUser(stream.Context(), user); err != nil {
+ if err = s.GetBackend().SyncUser(stream.Context(), user); err != nil {
return status.Errorf(codes.Internal, "failed to update user: %v", err)
}
}
}
func (s *Service) SyncUsers(ctx context.Context, users *common.Users) (*common.Empty, error) {
- if err := s.controller.GetBackend().SyncUsers(ctx, users.GetUsers()); err != nil {
+ if err := s.GetBackend().SyncUsers(ctx, users.GetUsers()); err != nil {
return nil, err
}
diff --git a/main.go b/main.go
index f258fb1..168af63 100644
--- a/main.go
+++ b/main.go
@@ -39,7 +39,7 @@ func main() {
shutdownFunc, service, err = rpc.StartGRPCListener(tlsConfig, addr)
}
- defer service.StopService()
+ defer service.Disconnect()
stopChan := make(chan os.Signal, 1)
signal.Notify(stopChan, os.Interrupt, syscall.SIGTERM)
From 6bb2d76e3dc7e155f15284d514c6dfec871c24d7 Mon Sep 17 00:00:00 2001
From: M03ED <50927468+M03ED@users.noreply.github.com>
Date: Sat, 15 Mar 2025 19:47:51 +0330
Subject: [PATCH 3/3] feat: add GetUserOnlineIpListStats
---
README.md | 38 +--
backend/backend.go | 3 +-
backend/xray/api/stats.go | 14 +-
backend/xray/xray.go | 8 +-
common/service.pb.go | 516 +++++++++++++++++++++----------------
common/service.proto | 8 +-
common/service_grpc.pb.go | 68 +++--
controller/rest/service.go | 1 +
controller/rest/stats.go | 23 +-
controller/rpc/stats.go | 9 +-
go.mod | 32 +--
go.sum | 38 +++
12 files changed, 480 insertions(+), 278 deletions(-)
diff --git a/README.md b/README.md
index b1d5d76..0288f4f 100644
--- a/README.md
+++ b/README.md
@@ -89,7 +89,8 @@ The node uses the `common/service.proto` file messages for both protocols.
| `Stat` | Contains:
- `name` (string): Stat name.
- `type` (string): Stat type.
- `link` (string): Link associated with the stat.
- `value` (int64): Stat value. |
| `StatResponse` | Contains:
- `stats` ([]Stat): List of stats. |
| `StatRequest` | Contains:
- `name` (string): Name of the stat to request, user email or inbound \ outbound tag.
- `reset` (bool) Whether to reset traffic stats. |
-| `OnlineStatResponse` | Contains:
- `email` (string): User's email.
- `value` (int64): Online stat value. |
+| `OnlineStatResponse` | Contains:
- `name` (string): User's email.
- `value` (int64): Online connection number. |
+| `OnlineStatResponse` | Contains:
- `name` (string): User's email.
- `value` (map): Online stat value. |
| `BackendStatsResponse` | Contains:
- `num_goroutine` (uint32): Number of goroutines.
- `num_gc` (uint32): Number of garbage collections.
- `alloc` (uint64): Allocated memory.
- `total_alloc` (uint64): Total allocated memory.
- `sys` (uint64): System memory.
- `mallocs` (uint64): Number of mallocs.
- `frees` (uint64): Number of frees.
- `live_objects` (uint64): Number of live objects.
- `pause_total_ns` (uint64): Total pause time in nanoseconds.
- `uptime` (uint32): Uptime in seconds. |
| `SystemStatsResponse` | Contains:
- `mem_total` (uint64): Total memory.
- `mem_used` (uint64): Used memory.
- `cpu_cores` (uint64): Number of CPU cores.
- `cpu_usage` (double): CPU usage percentage.
- `incoming_bandwidth_speed` (uint64): Incoming bandwidth speed.
- `outgoing_bandwidth_speed` (uint64): Outgoing bandwidth speed. |
| `Users` | Contains:
- `users` ([]User): List of users. |
@@ -102,23 +103,24 @@ The node uses the `common/service.proto` file messages for both protocols.
- Use `Authorization Bearer ` in the header for authentication with the **REST API**.
- Use `authorization Bearer ` in metadata for authentication with **gRPC**.
-| gRPC | REST | Input | Output | Description |
-|:-----------------------|:---------------------------|---------------|--------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `Start()` | `POST`,`/start` | `Backend` | `BaseInfoResponse` | This is the only method called before creating a connection. |
-| `Stop()` | `PUT`,`/stop` | `Empty` | `Empty` | Stops the backend and deactivates the connection with the client. |
-| `GetBaseInfo()` | `GET`,`/info` | `Empty` | `BaseInfoResponse` | Returns base info; can be used to check the connection between the node and client. |
-| `GetLogs()` | `GET`,`/logs` | `Empty` | gRPC: (stream `Log`)
REST API: (`SSE`) | This method is a `SSE` connection in the REST protocol, but in gRPC, it provides a stream connection. |
-| `GetSystemStats()` | `GET`,`/stats/system` | `Empty` | `SystemStatsResponse` | Retrieves system statistics. |
-| `GetBackendStats()` | `GET`,`/stats/backend` | `Empty` | `BackendStatsResponse` | Retrieves backend statistics. |
-| `GetOutboundsStats()` | `GET`, `/stats/outbounds` | `StatRequest` | `StatResponse` | Retrieves outbound statistics. The `name` field in the request will be ignored. |
-| `GetOutboundStats()` | `GET`,`/stats/outbound` | `StatRequest` | `StatResponse` | Retrieves statistics for a specific outbound. |
-| `GetInboundsStats()` | `GET`,`/stats/inbounds` | `StatRequest` | `StatResponse` | Retrieves inbound statistics. The `name` field in the request will be ignored. |
-| `GetInboundStats()` | `GET`,`/stats/inbound` | `StatRequest` | `StatResponse` | Retrieves statistics for a specific inbound. |
-| `GetUsersStats()` | `GET`,`/stats/users` | `StatRequest` | `StatResponse` | Retrieves user statistics and resets traffic stats. The `name` field in the request will be ignored. |
-| `GetUserStats()` | `GET`,`/stats/user` | `StatRequest` | `StatResponse` | Retrieves statistics for a specific user. |
-| `GetUserOnlineStats()` | `GET`,`/stats/user/online` | `StatRequest` | `StatResponse` | Retrieves online statistics for a specific user. The `reset` field in the request will be ignored |
-| `SyncUser()` | `PUT`,`/user/sync` | `User` | `Empty` | Adds/updates/removes a user in the core. To remove a user, ensure you send empty inbounds. Provides a stream in `gRPC` but must be called for each user in the `REST API`. |
-| `SyncUsers()` | `PUT`,`/users/sync` | `Users` | `Empty` | Removes all old users and replaces them with the provided users. |
+| gRPC | REST | Input | Output | Description |
+|:-----------------------------|:------------------------------|---------------|--------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `Start()` | `POST`,`/start` | `Backend` | `BaseInfoResponse` | This is the only method called before creating a connection. |
+| `Stop()` | `PUT`,`/stop` | `Empty` | `Empty` | Stops the backend and deactivates the connection with the client. |
+| `GetBaseInfo()` | `GET`,`/info` | `Empty` | `BaseInfoResponse` | Returns base info; can be used to check the connection between the node and client. |
+| `GetLogs()` | `GET`,`/logs` | `Empty` | gRPC: (stream `Log`)
REST API: (`SSE`) | This method is a `SSE` connection in the REST protocol, but in gRPC, it provides a stream connection. |
+| `GetSystemStats()` | `GET`,`/stats/system` | `Empty` | `SystemStatsResponse` | Retrieves system statistics. |
+| `GetBackendStats()` | `GET`,`/stats/backend` | `Empty` | `BackendStatsResponse` | Retrieves backend statistics. |
+| `GetOutboundsStats()` | `GET`, `/stats/outbounds` | `StatRequest` | `StatResponse` | Retrieves outbound statistics. The `name` field in the request will be ignored. |
+| `GetOutboundStats()` | `GET`,`/stats/outbound` | `StatRequest` | `StatResponse` | Retrieves statistics for a specific outbound. |
+| `GetInboundsStats()` | `GET`,`/stats/inbounds` | `StatRequest` | `StatResponse` | Retrieves inbound statistics. The `name` field in the request will be ignored. |
+| `GetInboundStats()` | `GET`,`/stats/inbound` | `StatRequest` | `StatResponse` | Retrieves statistics for a specific inbound. |
+| `GetUsersStats()` | `GET`,`/stats/users` | `StatRequest` | `StatResponse` | Retrieves user statistics and resets traffic stats. The `name` field in the request will be ignored. |
+| `GetUserStats()` | `GET`,`/stats/user` | `StatRequest` | `StatResponse` | Retrieves statistics for a specific user. |
+| `GetUserOnlineStats()` | `GET`,`/stats/user/online` | `StatRequest` | `OnlineStatResponse` | Retrieves online statistics for a specific user. The `reset` field in the request will be ignored |
+| `GetUserOnlineIpListStats()` | `GET`,`/stats/user/online_ip` | `StatRequest` | `StatsOnlineIpListResponse` | Retrieves ip list statistics for a specific user. The `reset` field in the request will be ignored |
+| `SyncUser()` | `PUT`,`/user/sync` | `User` | `Empty` | Adds/updates/removes a user in the core. To remove a user, ensure you send empty inbounds. Provides a stream in `gRPC` but must be called for each user in the `REST API`. |
+| `SyncUsers()` | `PUT`,`/users/sync` | `Users` | `Empty` | Removes all old users and replaces them with the provided users. |
# Official library
We create some library's for you so make your job easier
diff --git a/backend/backend.go b/backend/backend.go
index 723470d..6a996c5 100644
--- a/backend/backend.go
+++ b/backend/backend.go
@@ -18,7 +18,8 @@ type Backend interface {
GetSysStats(context.Context) (*common.BackendStatsResponse, error)
GetUsersStats(context.Context, bool) (*common.StatResponse, error)
GetUserStats(context.Context, string, bool) (*common.StatResponse, error)
- GetStatOnline(context.Context, string) (*common.OnlineStatResponse, error)
+ GetUserOnlineStats(context.Context, string) (*common.OnlineStatResponse, error)
+ GetUserOnlineIpListStats(context.Context, string) (*common.StatsOnlineIpListResponse, error)
GetOutboundsStats(context.Context, bool) (*common.StatResponse, error)
GetOutboundStats(context.Context, string, bool) (*common.StatResponse, error)
GetInboundsStats(context.Context, bool) (*common.StatResponse, error)
diff --git a/backend/xray/api/stats.go b/backend/xray/api/stats.go
index 8f07a4c..85b27b0 100644
--- a/backend/xray/api/stats.go
+++ b/backend/xray/api/stats.go
@@ -43,14 +43,24 @@ func (x *XrayHandler) QueryStats(ctx context.Context, pattern string, reset bool
return resp, nil
}
-func (x *XrayHandler) GetStatOnline(ctx context.Context, email string) (*common.OnlineStatResponse, error) {
+func (x *XrayHandler) GetUserOnlineStats(ctx context.Context, email string) (*common.OnlineStatResponse, error) {
client := *x.StatsServiceClient
resp, err := client.GetStatsOnline(ctx, &command.GetStatsRequest{Name: email})
if err != nil {
return nil, err
}
- return &common.OnlineStatResponse{Email: email, Value: resp.GetStat().Value}, nil
+ return &common.OnlineStatResponse{Name: email, Value: resp.GetStat().GetValue()}, nil
+}
+
+func (x *XrayHandler) GetUserOnlineIpListStats(ctx context.Context, email string) (*common.StatsOnlineIpListResponse, error) {
+ client := *x.StatsServiceClient
+ resp, err := client.GetStatsOnlineIpList(ctx, &command.GetStatsRequest{Name: email})
+ if err != nil {
+ return nil, err
+ }
+
+ return &common.StatsOnlineIpListResponse{Name: email, Ips: resp.GetIps()}, nil
}
func (x *XrayHandler) GetUsersStats(ctx context.Context, reset bool) (*common.StatResponse, error) {
diff --git a/backend/xray/xray.go b/backend/xray/xray.go
index 47f853a..6bbe547 100644
--- a/backend/xray/xray.go
+++ b/backend/xray/xray.go
@@ -191,8 +191,12 @@ func (x *Xray) GetUserStats(ctx context.Context, email string, reset bool) (*com
return x.handler.GetUserStats(ctx, email, reset)
}
-func (x *Xray) GetStatOnline(ctx context.Context, email string) (*common.OnlineStatResponse, error) {
- return x.handler.GetStatOnline(ctx, email)
+func (x *Xray) GetUserOnlineStats(ctx context.Context, email string) (*common.OnlineStatResponse, error) {
+ return x.handler.GetUserOnlineStats(ctx, email)
+}
+
+func (x *Xray) GetUserOnlineIpListStats(ctx context.Context, email string) (*common.StatsOnlineIpListResponse, error) {
+ return x.handler.GetUserOnlineIpListStats(ctx, email)
}
func (x *Xray) GetOutboundsStats(ctx context.Context, reset bool) (*common.StatResponse, error) {
diff --git a/common/service.pb.go b/common/service.pb.go
index a703821..88be547 100644
--- a/common/service.pb.go
+++ b/common/service.pb.go
@@ -465,7 +465,7 @@ type OnlineStatResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"`
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"`
}
@@ -499,9 +499,9 @@ func (*OnlineStatResponse) Descriptor() ([]byte, []int) {
return file_common_service_proto_rawDescGZIP(), []int{7}
}
-func (x *OnlineStatResponse) GetEmail() string {
+func (x *OnlineStatResponse) GetName() string {
if x != nil {
- return x.Email
+ return x.Name
}
return ""
}
@@ -513,6 +513,59 @@ func (x *OnlineStatResponse) GetValue() int64 {
return 0
}
+type StatsOnlineIpListResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ Ips map[string]int64 `protobuf:"bytes,2,rep,name=ips,proto3" json:"ips,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
+}
+
+func (x *StatsOnlineIpListResponse) Reset() {
+ *x = StatsOnlineIpListResponse{}
+ mi := &file_common_service_proto_msgTypes[8]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *StatsOnlineIpListResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*StatsOnlineIpListResponse) ProtoMessage() {}
+
+func (x *StatsOnlineIpListResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_common_service_proto_msgTypes[8]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use StatsOnlineIpListResponse.ProtoReflect.Descriptor instead.
+func (*StatsOnlineIpListResponse) Descriptor() ([]byte, []int) {
+ return file_common_service_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *StatsOnlineIpListResponse) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *StatsOnlineIpListResponse) GetIps() map[string]int64 {
+ if x != nil {
+ return x.Ips
+ }
+ return nil
+}
+
type BackendStatsResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -532,7 +585,7 @@ type BackendStatsResponse struct {
func (x *BackendStatsResponse) Reset() {
*x = BackendStatsResponse{}
- mi := &file_common_service_proto_msgTypes[8]
+ mi := &file_common_service_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -544,7 +597,7 @@ func (x *BackendStatsResponse) String() string {
func (*BackendStatsResponse) ProtoMessage() {}
func (x *BackendStatsResponse) ProtoReflect() protoreflect.Message {
- mi := &file_common_service_proto_msgTypes[8]
+ mi := &file_common_service_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -557,7 +610,7 @@ func (x *BackendStatsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use BackendStatsResponse.ProtoReflect.Descriptor instead.
func (*BackendStatsResponse) Descriptor() ([]byte, []int) {
- return file_common_service_proto_rawDescGZIP(), []int{8}
+ return file_common_service_proto_rawDescGZIP(), []int{9}
}
func (x *BackendStatsResponse) GetNumGoroutine() uint32 {
@@ -645,7 +698,7 @@ type SystemStatsResponse struct {
func (x *SystemStatsResponse) Reset() {
*x = SystemStatsResponse{}
- mi := &file_common_service_proto_msgTypes[9]
+ mi := &file_common_service_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -657,7 +710,7 @@ func (x *SystemStatsResponse) String() string {
func (*SystemStatsResponse) ProtoMessage() {}
func (x *SystemStatsResponse) ProtoReflect() protoreflect.Message {
- mi := &file_common_service_proto_msgTypes[9]
+ mi := &file_common_service_proto_msgTypes[10]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -670,7 +723,7 @@ func (x *SystemStatsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use SystemStatsResponse.ProtoReflect.Descriptor instead.
func (*SystemStatsResponse) Descriptor() ([]byte, []int) {
- return file_common_service_proto_rawDescGZIP(), []int{9}
+ return file_common_service_proto_rawDescGZIP(), []int{10}
}
func (x *SystemStatsResponse) GetMemTotal() uint64 {
@@ -726,7 +779,7 @@ type Vmess struct {
func (x *Vmess) Reset() {
*x = Vmess{}
- mi := &file_common_service_proto_msgTypes[10]
+ mi := &file_common_service_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -738,7 +791,7 @@ func (x *Vmess) String() string {
func (*Vmess) ProtoMessage() {}
func (x *Vmess) ProtoReflect() protoreflect.Message {
- mi := &file_common_service_proto_msgTypes[10]
+ mi := &file_common_service_proto_msgTypes[11]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -751,7 +804,7 @@ func (x *Vmess) ProtoReflect() protoreflect.Message {
// Deprecated: Use Vmess.ProtoReflect.Descriptor instead.
func (*Vmess) Descriptor() ([]byte, []int) {
- return file_common_service_proto_rawDescGZIP(), []int{10}
+ return file_common_service_proto_rawDescGZIP(), []int{11}
}
func (x *Vmess) GetId() string {
@@ -772,7 +825,7 @@ type Vless struct {
func (x *Vless) Reset() {
*x = Vless{}
- mi := &file_common_service_proto_msgTypes[11]
+ mi := &file_common_service_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -784,7 +837,7 @@ func (x *Vless) String() string {
func (*Vless) ProtoMessage() {}
func (x *Vless) ProtoReflect() protoreflect.Message {
- mi := &file_common_service_proto_msgTypes[11]
+ mi := &file_common_service_proto_msgTypes[12]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -797,7 +850,7 @@ func (x *Vless) ProtoReflect() protoreflect.Message {
// Deprecated: Use Vless.ProtoReflect.Descriptor instead.
func (*Vless) Descriptor() ([]byte, []int) {
- return file_common_service_proto_rawDescGZIP(), []int{11}
+ return file_common_service_proto_rawDescGZIP(), []int{12}
}
func (x *Vless) GetId() string {
@@ -824,7 +877,7 @@ type Trojan struct {
func (x *Trojan) Reset() {
*x = Trojan{}
- mi := &file_common_service_proto_msgTypes[12]
+ mi := &file_common_service_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -836,7 +889,7 @@ func (x *Trojan) String() string {
func (*Trojan) ProtoMessage() {}
func (x *Trojan) ProtoReflect() protoreflect.Message {
- mi := &file_common_service_proto_msgTypes[12]
+ mi := &file_common_service_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -849,7 +902,7 @@ func (x *Trojan) ProtoReflect() protoreflect.Message {
// Deprecated: Use Trojan.ProtoReflect.Descriptor instead.
func (*Trojan) Descriptor() ([]byte, []int) {
- return file_common_service_proto_rawDescGZIP(), []int{12}
+ return file_common_service_proto_rawDescGZIP(), []int{13}
}
func (x *Trojan) GetPassword() string {
@@ -870,7 +923,7 @@ type Shadowsocks struct {
func (x *Shadowsocks) Reset() {
*x = Shadowsocks{}
- mi := &file_common_service_proto_msgTypes[13]
+ mi := &file_common_service_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -882,7 +935,7 @@ func (x *Shadowsocks) String() string {
func (*Shadowsocks) ProtoMessage() {}
func (x *Shadowsocks) ProtoReflect() protoreflect.Message {
- mi := &file_common_service_proto_msgTypes[13]
+ mi := &file_common_service_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -895,7 +948,7 @@ func (x *Shadowsocks) ProtoReflect() protoreflect.Message {
// Deprecated: Use Shadowsocks.ProtoReflect.Descriptor instead.
func (*Shadowsocks) Descriptor() ([]byte, []int) {
- return file_common_service_proto_rawDescGZIP(), []int{13}
+ return file_common_service_proto_rawDescGZIP(), []int{14}
}
func (x *Shadowsocks) GetPassword() string {
@@ -925,7 +978,7 @@ type Proxy struct {
func (x *Proxy) Reset() {
*x = Proxy{}
- mi := &file_common_service_proto_msgTypes[14]
+ mi := &file_common_service_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -937,7 +990,7 @@ func (x *Proxy) String() string {
func (*Proxy) ProtoMessage() {}
func (x *Proxy) ProtoReflect() protoreflect.Message {
- mi := &file_common_service_proto_msgTypes[14]
+ mi := &file_common_service_proto_msgTypes[15]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -950,7 +1003,7 @@ func (x *Proxy) ProtoReflect() protoreflect.Message {
// Deprecated: Use Proxy.ProtoReflect.Descriptor instead.
func (*Proxy) Descriptor() ([]byte, []int) {
- return file_common_service_proto_rawDescGZIP(), []int{14}
+ return file_common_service_proto_rawDescGZIP(), []int{15}
}
func (x *Proxy) GetVmess() *Vmess {
@@ -993,7 +1046,7 @@ type User struct {
func (x *User) Reset() {
*x = User{}
- mi := &file_common_service_proto_msgTypes[15]
+ mi := &file_common_service_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1005,7 +1058,7 @@ func (x *User) String() string {
func (*User) ProtoMessage() {}
func (x *User) ProtoReflect() protoreflect.Message {
- mi := &file_common_service_proto_msgTypes[15]
+ mi := &file_common_service_proto_msgTypes[16]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1018,7 +1071,7 @@ func (x *User) ProtoReflect() protoreflect.Message {
// Deprecated: Use User.ProtoReflect.Descriptor instead.
func (*User) Descriptor() ([]byte, []int) {
- return file_common_service_proto_rawDescGZIP(), []int{15}
+ return file_common_service_proto_rawDescGZIP(), []int{16}
}
func (x *User) GetEmail() string {
@@ -1052,7 +1105,7 @@ type Users struct {
func (x *Users) Reset() {
*x = Users{}
- mi := &file_common_service_proto_msgTypes[16]
+ mi := &file_common_service_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1064,7 +1117,7 @@ func (x *Users) String() string {
func (*Users) ProtoMessage() {}
func (x *Users) ProtoReflect() protoreflect.Message {
- mi := &file_common_service_proto_msgTypes[16]
+ mi := &file_common_service_proto_msgTypes[17]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1077,7 +1130,7 @@ func (x *Users) ProtoReflect() protoreflect.Message {
// Deprecated: Use Users.ProtoReflect.Descriptor instead.
func (*Users) Descriptor() ([]byte, []int) {
- return file_common_service_proto_rawDescGZIP(), []int{16}
+ return file_common_service_proto_rawDescGZIP(), []int{17}
}
func (x *Users) GetUsers() []*User {
@@ -1126,139 +1179,155 @@ var file_common_service_proto_rawDesc = []byte{
0x74, 0x73, 0x22, 0x37, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x73, 0x65, 0x74, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x65, 0x73, 0x65, 0x74, 0x22, 0x40, 0x0a, 0x12, 0x4f,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x65, 0x73, 0x65, 0x74, 0x22, 0x3e, 0x0a, 0x12, 0x4f,
0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xac, 0x02,
- 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x75, 0x6d, 0x5f, 0x67, 0x6f,
- 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6e,
- 0x75, 0x6d, 0x47, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6e,
- 0x75, 0x6d, 0x5f, 0x67, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6e, 0x75, 0x6d,
- 0x47, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x04, 0x52, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61,
- 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74,
- 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x79, 0x73,
- 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x73, 0x79, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d,
- 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61,
- 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x72, 0x65, 0x65, 0x73, 0x18, 0x07,
- 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x66, 0x72, 0x65, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6c,
- 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28,
- 0x04, 0x52, 0x0b, 0x6c, 0x69, 0x76, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x24,
- 0x0a, 0x0e, 0x70, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6e, 0x73,
- 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, 0x61, 0x75, 0x73, 0x65, 0x54, 0x6f, 0x74,
- 0x61, 0x6c, 0x4e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x22, 0xfb, 0x01, 0x0a,
- 0x13, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x5f, 0x74, 0x6f, 0x74, 0x61,
- 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x54, 0x6f, 0x74, 0x61,
- 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x65, 0x6d, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09,
- 0x63, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52,
- 0x08, 0x63, 0x70, 0x75, 0x43, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x70, 0x75,
- 0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x63, 0x70,
- 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x18, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69,
- 0x6e, 0x67, 0x5f, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x73, 0x70, 0x65,
- 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69,
- 0x6e, 0x67, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x53, 0x70, 0x65, 0x65, 0x64,
- 0x12, 0x38, 0x0a, 0x18, 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x61, 0x6e,
- 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01,
- 0x28, 0x04, 0x52, 0x16, 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x42, 0x61, 0x6e, 0x64,
- 0x77, 0x69, 0x64, 0x74, 0x68, 0x53, 0x70, 0x65, 0x65, 0x64, 0x22, 0x17, 0x0a, 0x05, 0x56, 0x6d,
+ 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa6, 0x01, 0x0a, 0x19,
+ 0x53, 0x74, 0x61, 0x74, 0x73, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x49, 0x70, 0x4c, 0x69, 0x73,
+ 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+ 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a,
+ 0x03, 0x69, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65,
+ 0x49, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49,
+ 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x69, 0x70, 0x73, 0x1a, 0x36, 0x0a, 0x08,
+ 0x49, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x3a, 0x02, 0x38, 0x01, 0x22, 0xac, 0x02, 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
+ 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a,
+ 0x0d, 0x6e, 0x75, 0x6d, 0x5f, 0x67, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6e, 0x75, 0x6d, 0x47, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69,
+ 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x5f, 0x67, 0x63, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x05, 0x6e, 0x75, 0x6d, 0x47, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x6c,
+ 0x6f, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x12,
+ 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63,
+ 0x12, 0x10, 0x0a, 0x03, 0x73, 0x79, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x73,
+ 0x79, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x18, 0x06, 0x20,
+ 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x12, 0x14, 0x0a, 0x05,
+ 0x66, 0x72, 0x65, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x66, 0x72, 0x65,
+ 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63,
+ 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6c, 0x69, 0x76, 0x65, 0x4f, 0x62,
+ 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x74,
+ 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70,
+ 0x61, 0x75, 0x73, 0x65, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x75,
+ 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74,
+ 0x69, 0x6d, 0x65, 0x22, 0xfb, 0x01, 0x0a, 0x13, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x74,
+ 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d,
+ 0x65, 0x6d, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08,
+ 0x6d, 0x65, 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x65, 0x6d, 0x5f,
+ 0x75, 0x73, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x55,
+ 0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x73,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x63, 0x70, 0x75, 0x43, 0x6f, 0x72, 0x65, 0x73,
+ 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x70, 0x75, 0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x01, 0x52, 0x08, 0x63, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a,
+ 0x18, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69,
+ 0x64, 0x74, 0x68, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52,
+ 0x16, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64,
+ 0x74, 0x68, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x18, 0x6f, 0x75, 0x74, 0x67, 0x6f,
+ 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x73, 0x70,
+ 0x65, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x6f, 0x75, 0x74, 0x67, 0x6f,
+ 0x69, 0x6e, 0x67, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x53, 0x70, 0x65, 0x65,
+ 0x64, 0x22, 0x17, 0x0a, 0x05, 0x56, 0x6d, 0x65, 0x73, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2b, 0x0a, 0x05, 0x56, 0x6c,
0x65, 0x73, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x02, 0x69, 0x64, 0x22, 0x2b, 0x0a, 0x05, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x12, 0x0e, 0x0a, 0x02,
- 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04,
- 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x6c, 0x6f, 0x77,
- 0x22, 0x24, 0x0a, 0x06, 0x54, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61,
- 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61,
- 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x41, 0x0a, 0x0b, 0x53, 0x68, 0x61, 0x64, 0x6f, 0x77,
- 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
- 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
- 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0xb4, 0x01, 0x0a, 0x05, 0x50, 0x72,
- 0x6f, 0x78, 0x79, 0x12, 0x24, 0x0a, 0x05, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x6d, 0x65,
- 0x73, 0x73, 0x52, 0x05, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x12, 0x24, 0x0a, 0x05, 0x76, 0x6c, 0x65,
- 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
- 0x63, 0x65, 0x2e, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x52, 0x05, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x12,
- 0x27, 0x0a, 0x06, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x72, 0x6f, 0x6a, 0x61, 0x6e,
- 0x52, 0x06, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x64,
- 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
- 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f,
- 0x63, 0x6b, 0x73, 0x52, 0x0b, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73,
- 0x22, 0x62, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69,
- 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x28,
- 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x52,
- 0x07, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x62, 0x6f,
- 0x75, 0x6e, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x62, 0x6f,
- 0x75, 0x6e, 0x64, 0x73, 0x22, 0x2c, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x23, 0x0a,
- 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x73,
- 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65,
- 0x72, 0x73, 0x2a, 0x17, 0x0a, 0x0b, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x79, 0x70,
- 0x65, 0x12, 0x08, 0x0a, 0x04, 0x58, 0x52, 0x41, 0x59, 0x10, 0x00, 0x32, 0x92, 0x07, 0x0a, 0x0b,
- 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x53,
- 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42,
- 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x1a, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x2e, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x22, 0x00, 0x12, 0x28, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x0e, 0x2e, 0x73, 0x65,
- 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0e, 0x2e, 0x73, 0x65,
- 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3a, 0x0a,
- 0x0b, 0x47, 0x65, 0x74, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x2e, 0x73,
- 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x73,
- 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2b, 0x0a, 0x07, 0x47, 0x65, 0x74,
- 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45,
- 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c,
- 0x6f, 0x67, 0x22, 0x00, 0x30, 0x01, 0x12, 0x40, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73,
- 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
- 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
- 0x63, 0x65, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42,
- 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x0e, 0x2e, 0x73, 0x65,
- 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x73, 0x65,
- 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61,
- 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x11,
- 0x47, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x53, 0x74, 0x61, 0x74,
- 0x73, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
- 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
- 0x12, 0x41, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53,
- 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53,
- 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x72,
- 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e,
- 0x64, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
- 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e,
- 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x62,
- 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76,
- 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
- 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x55,
- 0x73, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76,
- 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
- 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x55,
- 0x73, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
+ 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x04, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0x24, 0x0a, 0x06, 0x54, 0x72, 0x6f, 0x6a, 0x61,
+ 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x41, 0x0a,
+ 0x0b, 0x53, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x1a, 0x0a, 0x08,
+ 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
+ 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68,
+ 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
+ 0x22, 0xb4, 0x01, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x24, 0x0a, 0x05, 0x76, 0x6d,
+ 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76,
+ 0x69, 0x63, 0x65, 0x2e, 0x56, 0x6d, 0x65, 0x73, 0x73, 0x52, 0x05, 0x76, 0x6d, 0x65, 0x73, 0x73,
+ 0x12, 0x24, 0x0a, 0x05, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x52,
+ 0x05, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x12, 0x27, 0x0a, 0x06, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x2e, 0x54, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x52, 0x06, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x12,
+ 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53,
+ 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x0b, 0x73, 0x68, 0x61, 0x64,
+ 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x22, 0x62, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12,
+ 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
+ 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x28, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x73,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x73, 0x12,
+ 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x08, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x22, 0x2c, 0x0a, 0x05, 0x55,
+ 0x73, 0x65, 0x72, 0x73, 0x12, 0x23, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x55, 0x73,
+ 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2a, 0x17, 0x0a, 0x0b, 0x42, 0x61, 0x63,
+ 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x58, 0x52, 0x41, 0x59,
+ 0x10, 0x00, 0x32, 0xea, 0x07, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69,
+ 0x63, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x2e, 0x73, 0x65,
+ 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x1a, 0x19, 0x2e,
+ 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x28, 0x0a, 0x04, 0x53, 0x74,
+ 0x6f, 0x70, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70,
+ 0x74, 0x79, 0x1a, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70,
+ 0x74, 0x79, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, 0x61, 0x73, 0x65, 0x49,
+ 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d,
+ 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61,
+ 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
+ 0x12, 0x2b, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x0e, 0x2e, 0x73, 0x65,
+ 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0c, 0x2e, 0x73, 0x65,
+ 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x22, 0x00, 0x30, 0x01, 0x12, 0x40, 0x0a,
+ 0x0e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12,
+ 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
+ 0x1c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
+ 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
+ 0x42, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61,
+ 0x74, 0x73, 0x12, 0x0e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70,
+ 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x63,
+ 0x6b, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75,
+ 0x6e, 0x64, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15,
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73,
- 0x65, 0x72, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x2e,
- 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4f, 0x6e,
- 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x22, 0x00, 0x12, 0x2d, 0x0a, 0x08, 0x53, 0x79, 0x6e, 0x63, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0d,
- 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, 0x0e, 0x2e,
- 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x28,
- 0x01, 0x12, 0x2d, 0x0a, 0x09, 0x53, 0x79, 0x6e, 0x63, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x0e,
- 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x0e,
- 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00,
- 0x42, 0x18, 0x5a, 0x16, 0x6d, 0x61, 0x72, 0x7a, 0x62, 0x61, 0x6e, 0x5f, 0x6e, 0x6f, 0x64, 0x65,
- 0x5f, 0x67, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x33,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4f, 0x75,
+ 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x65,
+ 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x10, 0x47, 0x65,
+ 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14,
+ 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53,
+ 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a,
+ 0x0f, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x73,
+ 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
+ 0x3e, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73,
+ 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
+ 0x3d, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12,
+ 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+ 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49,
+ 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53,
+ 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53,
+ 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x18, 0x47, 0x65, 0x74,
+ 0x55, 0x73, 0x65, 0x72, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x49, 0x70, 0x4c, 0x69, 0x73, 0x74,
+ 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+ 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x65,
+ 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x4f, 0x6e, 0x6c, 0x69, 0x6e,
+ 0x65, 0x49, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+ 0x00, 0x12, 0x2d, 0x0a, 0x08, 0x53, 0x79, 0x6e, 0x63, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0d, 0x2e,
+ 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, 0x0e, 0x2e, 0x73,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x28, 0x01,
+ 0x12, 0x2d, 0x0a, 0x09, 0x53, 0x79, 0x6e, 0x63, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x0e, 0x2e,
+ 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x0e, 0x2e,
+ 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42,
+ 0x18, 0x5a, 0x16, 0x6d, 0x61, 0x72, 0x7a, 0x62, 0x61, 0x6e, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f,
+ 0x67, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x33,
}
var (
@@ -1274,72 +1343,77 @@ func file_common_service_proto_rawDescGZIP() []byte {
}
var file_common_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_common_service_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
+var file_common_service_proto_msgTypes = make([]protoimpl.MessageInfo, 19)
var file_common_service_proto_goTypes = []any{
- (BackendType)(0), // 0: service.BackendType
- (*Empty)(nil), // 1: service.Empty
- (*BaseInfoResponse)(nil), // 2: service.BaseInfoResponse
- (*Backend)(nil), // 3: service.Backend
- (*Log)(nil), // 4: service.Log
- (*Stat)(nil), // 5: service.Stat
- (*StatResponse)(nil), // 6: service.StatResponse
- (*StatRequest)(nil), // 7: service.StatRequest
- (*OnlineStatResponse)(nil), // 8: service.OnlineStatResponse
- (*BackendStatsResponse)(nil), // 9: service.BackendStatsResponse
- (*SystemStatsResponse)(nil), // 10: service.SystemStatsResponse
- (*Vmess)(nil), // 11: service.Vmess
- (*Vless)(nil), // 12: service.Vless
- (*Trojan)(nil), // 13: service.Trojan
- (*Shadowsocks)(nil), // 14: service.Shadowsocks
- (*Proxy)(nil), // 15: service.Proxy
- (*User)(nil), // 16: service.User
- (*Users)(nil), // 17: service.Users
+ (BackendType)(0), // 0: service.BackendType
+ (*Empty)(nil), // 1: service.Empty
+ (*BaseInfoResponse)(nil), // 2: service.BaseInfoResponse
+ (*Backend)(nil), // 3: service.Backend
+ (*Log)(nil), // 4: service.Log
+ (*Stat)(nil), // 5: service.Stat
+ (*StatResponse)(nil), // 6: service.StatResponse
+ (*StatRequest)(nil), // 7: service.StatRequest
+ (*OnlineStatResponse)(nil), // 8: service.OnlineStatResponse
+ (*StatsOnlineIpListResponse)(nil), // 9: service.StatsOnlineIpListResponse
+ (*BackendStatsResponse)(nil), // 10: service.BackendStatsResponse
+ (*SystemStatsResponse)(nil), // 11: service.SystemStatsResponse
+ (*Vmess)(nil), // 12: service.Vmess
+ (*Vless)(nil), // 13: service.Vless
+ (*Trojan)(nil), // 14: service.Trojan
+ (*Shadowsocks)(nil), // 15: service.Shadowsocks
+ (*Proxy)(nil), // 16: service.Proxy
+ (*User)(nil), // 17: service.User
+ (*Users)(nil), // 18: service.Users
+ nil, // 19: service.StatsOnlineIpListResponse.IpsEntry
}
var file_common_service_proto_depIdxs = []int32{
0, // 0: service.Backend.type:type_name -> service.BackendType
- 16, // 1: service.Backend.users:type_name -> service.User
+ 17, // 1: service.Backend.users:type_name -> service.User
5, // 2: service.StatResponse.stats:type_name -> service.Stat
- 11, // 3: service.Proxy.vmess:type_name -> service.Vmess
- 12, // 4: service.Proxy.vless:type_name -> service.Vless
- 13, // 5: service.Proxy.trojan:type_name -> service.Trojan
- 14, // 6: service.Proxy.shadowsocks:type_name -> service.Shadowsocks
- 15, // 7: service.User.proxies:type_name -> service.Proxy
- 16, // 8: service.Users.users:type_name -> service.User
- 3, // 9: service.NodeService.Start:input_type -> service.Backend
- 1, // 10: service.NodeService.Stop:input_type -> service.Empty
- 1, // 11: service.NodeService.GetBaseInfo:input_type -> service.Empty
- 1, // 12: service.NodeService.GetLogs:input_type -> service.Empty
- 1, // 13: service.NodeService.GetSystemStats:input_type -> service.Empty
- 1, // 14: service.NodeService.GetBackendStats:input_type -> service.Empty
- 7, // 15: service.NodeService.GetOutboundsStats:input_type -> service.StatRequest
- 7, // 16: service.NodeService.GetOutboundStats:input_type -> service.StatRequest
- 7, // 17: service.NodeService.GetInboundsStats:input_type -> service.StatRequest
- 7, // 18: service.NodeService.GetInboundStats:input_type -> service.StatRequest
- 7, // 19: service.NodeService.GetUsersStats:input_type -> service.StatRequest
- 7, // 20: service.NodeService.GetUserStats:input_type -> service.StatRequest
- 7, // 21: service.NodeService.GetUserOnlineStats:input_type -> service.StatRequest
- 16, // 22: service.NodeService.SyncUser:input_type -> service.User
- 17, // 23: service.NodeService.SyncUsers:input_type -> service.Users
- 2, // 24: service.NodeService.Start:output_type -> service.BaseInfoResponse
- 1, // 25: service.NodeService.Stop:output_type -> service.Empty
- 2, // 26: service.NodeService.GetBaseInfo:output_type -> service.BaseInfoResponse
- 4, // 27: service.NodeService.GetLogs:output_type -> service.Log
- 10, // 28: service.NodeService.GetSystemStats:output_type -> service.SystemStatsResponse
- 9, // 29: service.NodeService.GetBackendStats:output_type -> service.BackendStatsResponse
- 6, // 30: service.NodeService.GetOutboundsStats:output_type -> service.StatResponse
- 6, // 31: service.NodeService.GetOutboundStats:output_type -> service.StatResponse
- 6, // 32: service.NodeService.GetInboundsStats:output_type -> service.StatResponse
- 6, // 33: service.NodeService.GetInboundStats:output_type -> service.StatResponse
- 6, // 34: service.NodeService.GetUsersStats:output_type -> service.StatResponse
- 6, // 35: service.NodeService.GetUserStats:output_type -> service.StatResponse
- 8, // 36: service.NodeService.GetUserOnlineStats:output_type -> service.OnlineStatResponse
- 1, // 37: service.NodeService.SyncUser:output_type -> service.Empty
- 1, // 38: service.NodeService.SyncUsers:output_type -> service.Empty
- 24, // [24:39] is the sub-list for method output_type
- 9, // [9:24] is the sub-list for method input_type
- 9, // [9:9] is the sub-list for extension type_name
- 9, // [9:9] is the sub-list for extension extendee
- 0, // [0:9] is the sub-list for field type_name
+ 19, // 3: service.StatsOnlineIpListResponse.ips:type_name -> service.StatsOnlineIpListResponse.IpsEntry
+ 12, // 4: service.Proxy.vmess:type_name -> service.Vmess
+ 13, // 5: service.Proxy.vless:type_name -> service.Vless
+ 14, // 6: service.Proxy.trojan:type_name -> service.Trojan
+ 15, // 7: service.Proxy.shadowsocks:type_name -> service.Shadowsocks
+ 16, // 8: service.User.proxies:type_name -> service.Proxy
+ 17, // 9: service.Users.users:type_name -> service.User
+ 3, // 10: service.NodeService.Start:input_type -> service.Backend
+ 1, // 11: service.NodeService.Stop:input_type -> service.Empty
+ 1, // 12: service.NodeService.GetBaseInfo:input_type -> service.Empty
+ 1, // 13: service.NodeService.GetLogs:input_type -> service.Empty
+ 1, // 14: service.NodeService.GetSystemStats:input_type -> service.Empty
+ 1, // 15: service.NodeService.GetBackendStats:input_type -> service.Empty
+ 7, // 16: service.NodeService.GetOutboundsStats:input_type -> service.StatRequest
+ 7, // 17: service.NodeService.GetOutboundStats:input_type -> service.StatRequest
+ 7, // 18: service.NodeService.GetInboundsStats:input_type -> service.StatRequest
+ 7, // 19: service.NodeService.GetInboundStats:input_type -> service.StatRequest
+ 7, // 20: service.NodeService.GetUsersStats:input_type -> service.StatRequest
+ 7, // 21: service.NodeService.GetUserStats:input_type -> service.StatRequest
+ 7, // 22: service.NodeService.GetUserOnlineStats:input_type -> service.StatRequest
+ 7, // 23: service.NodeService.GetUserOnlineIpListStats:input_type -> service.StatRequest
+ 17, // 24: service.NodeService.SyncUser:input_type -> service.User
+ 18, // 25: service.NodeService.SyncUsers:input_type -> service.Users
+ 2, // 26: service.NodeService.Start:output_type -> service.BaseInfoResponse
+ 1, // 27: service.NodeService.Stop:output_type -> service.Empty
+ 2, // 28: service.NodeService.GetBaseInfo:output_type -> service.BaseInfoResponse
+ 4, // 29: service.NodeService.GetLogs:output_type -> service.Log
+ 11, // 30: service.NodeService.GetSystemStats:output_type -> service.SystemStatsResponse
+ 10, // 31: service.NodeService.GetBackendStats:output_type -> service.BackendStatsResponse
+ 6, // 32: service.NodeService.GetOutboundsStats:output_type -> service.StatResponse
+ 6, // 33: service.NodeService.GetOutboundStats:output_type -> service.StatResponse
+ 6, // 34: service.NodeService.GetInboundsStats:output_type -> service.StatResponse
+ 6, // 35: service.NodeService.GetInboundStats:output_type -> service.StatResponse
+ 6, // 36: service.NodeService.GetUsersStats:output_type -> service.StatResponse
+ 6, // 37: service.NodeService.GetUserStats:output_type -> service.StatResponse
+ 8, // 38: service.NodeService.GetUserOnlineStats:output_type -> service.OnlineStatResponse
+ 9, // 39: service.NodeService.GetUserOnlineIpListStats:output_type -> service.StatsOnlineIpListResponse
+ 1, // 40: service.NodeService.SyncUser:output_type -> service.Empty
+ 1, // 41: service.NodeService.SyncUsers:output_type -> service.Empty
+ 26, // [26:42] is the sub-list for method output_type
+ 10, // [10:26] is the sub-list for method input_type
+ 10, // [10:10] is the sub-list for extension type_name
+ 10, // [10:10] is the sub-list for extension extendee
+ 0, // [0:10] is the sub-list for field type_name
}
func init() { file_common_service_proto_init() }
@@ -1353,7 +1427,7 @@ func file_common_service_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_common_service_proto_rawDesc,
NumEnums: 1,
- NumMessages: 17,
+ NumMessages: 19,
NumExtensions: 0,
NumServices: 1,
},
diff --git a/common/service.proto b/common/service.proto
index f5e69d2..21e289d 100644
--- a/common/service.proto
+++ b/common/service.proto
@@ -49,10 +49,15 @@ message StatRequest {
}
message OnlineStatResponse {
- string email = 1;
+ string name = 1;
int64 value = 2;
}
+message StatsOnlineIpListResponse {
+ string name = 1;
+ map ips = 2;
+}
+
message BackendStatsResponse {
uint32 num_goroutine = 1;
uint32 num_gc = 2;
@@ -128,6 +133,7 @@ service NodeService {
rpc GetUsersStats (StatRequest) returns (StatResponse) {}
rpc GetUserStats (StatRequest) returns (StatResponse) {}
rpc GetUserOnlineStats (StatRequest) returns (OnlineStatResponse) {}
+ rpc GetUserOnlineIpListStats(StatRequest) returns (StatsOnlineIpListResponse) {}
rpc SyncUser (stream User) returns (Empty) {}
rpc SyncUsers (Users) returns (Empty) {}
diff --git a/common/service_grpc.pb.go b/common/service_grpc.pb.go
index 3de7df4..5141984 100644
--- a/common/service_grpc.pb.go
+++ b/common/service_grpc.pb.go
@@ -19,21 +19,22 @@ import (
const _ = grpc.SupportPackageIsVersion9
const (
- NodeService_Start_FullMethodName = "/service.NodeService/Start"
- NodeService_Stop_FullMethodName = "/service.NodeService/Stop"
- NodeService_GetBaseInfo_FullMethodName = "/service.NodeService/GetBaseInfo"
- NodeService_GetLogs_FullMethodName = "/service.NodeService/GetLogs"
- NodeService_GetSystemStats_FullMethodName = "/service.NodeService/GetSystemStats"
- NodeService_GetBackendStats_FullMethodName = "/service.NodeService/GetBackendStats"
- NodeService_GetOutboundsStats_FullMethodName = "/service.NodeService/GetOutboundsStats"
- NodeService_GetOutboundStats_FullMethodName = "/service.NodeService/GetOutboundStats"
- NodeService_GetInboundsStats_FullMethodName = "/service.NodeService/GetInboundsStats"
- NodeService_GetInboundStats_FullMethodName = "/service.NodeService/GetInboundStats"
- NodeService_GetUsersStats_FullMethodName = "/service.NodeService/GetUsersStats"
- NodeService_GetUserStats_FullMethodName = "/service.NodeService/GetUserStats"
- NodeService_GetUserOnlineStats_FullMethodName = "/service.NodeService/GetUserOnlineStats"
- NodeService_SyncUser_FullMethodName = "/service.NodeService/SyncUser"
- NodeService_SyncUsers_FullMethodName = "/service.NodeService/SyncUsers"
+ NodeService_Start_FullMethodName = "/service.NodeService/Start"
+ NodeService_Stop_FullMethodName = "/service.NodeService/Stop"
+ NodeService_GetBaseInfo_FullMethodName = "/service.NodeService/GetBaseInfo"
+ NodeService_GetLogs_FullMethodName = "/service.NodeService/GetLogs"
+ NodeService_GetSystemStats_FullMethodName = "/service.NodeService/GetSystemStats"
+ NodeService_GetBackendStats_FullMethodName = "/service.NodeService/GetBackendStats"
+ NodeService_GetOutboundsStats_FullMethodName = "/service.NodeService/GetOutboundsStats"
+ NodeService_GetOutboundStats_FullMethodName = "/service.NodeService/GetOutboundStats"
+ NodeService_GetInboundsStats_FullMethodName = "/service.NodeService/GetInboundsStats"
+ NodeService_GetInboundStats_FullMethodName = "/service.NodeService/GetInboundStats"
+ NodeService_GetUsersStats_FullMethodName = "/service.NodeService/GetUsersStats"
+ NodeService_GetUserStats_FullMethodName = "/service.NodeService/GetUserStats"
+ NodeService_GetUserOnlineStats_FullMethodName = "/service.NodeService/GetUserOnlineStats"
+ NodeService_GetUserOnlineIpListStats_FullMethodName = "/service.NodeService/GetUserOnlineIpListStats"
+ NodeService_SyncUser_FullMethodName = "/service.NodeService/SyncUser"
+ NodeService_SyncUsers_FullMethodName = "/service.NodeService/SyncUsers"
)
// NodeServiceClient is the client API for NodeService service.
@@ -55,6 +56,7 @@ type NodeServiceClient interface {
GetUsersStats(ctx context.Context, in *StatRequest, opts ...grpc.CallOption) (*StatResponse, error)
GetUserStats(ctx context.Context, in *StatRequest, opts ...grpc.CallOption) (*StatResponse, error)
GetUserOnlineStats(ctx context.Context, in *StatRequest, opts ...grpc.CallOption) (*OnlineStatResponse, error)
+ GetUserOnlineIpListStats(ctx context.Context, in *StatRequest, opts ...grpc.CallOption) (*StatsOnlineIpListResponse, error)
SyncUser(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[User, Empty], error)
SyncUsers(ctx context.Context, in *Users, opts ...grpc.CallOption) (*Empty, error)
}
@@ -206,6 +208,16 @@ func (c *nodeServiceClient) GetUserOnlineStats(ctx context.Context, in *StatRequ
return out, nil
}
+func (c *nodeServiceClient) GetUserOnlineIpListStats(ctx context.Context, in *StatRequest, opts ...grpc.CallOption) (*StatsOnlineIpListResponse, error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ out := new(StatsOnlineIpListResponse)
+ err := c.cc.Invoke(ctx, NodeService_GetUserOnlineIpListStats_FullMethodName, in, out, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
func (c *nodeServiceClient) SyncUser(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[User, Empty], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &NodeService_ServiceDesc.Streams[1], NodeService_SyncUser_FullMethodName, cOpts...)
@@ -248,6 +260,7 @@ type NodeServiceServer interface {
GetUsersStats(context.Context, *StatRequest) (*StatResponse, error)
GetUserStats(context.Context, *StatRequest) (*StatResponse, error)
GetUserOnlineStats(context.Context, *StatRequest) (*OnlineStatResponse, error)
+ GetUserOnlineIpListStats(context.Context, *StatRequest) (*StatsOnlineIpListResponse, error)
SyncUser(grpc.ClientStreamingServer[User, Empty]) error
SyncUsers(context.Context, *Users) (*Empty, error)
mustEmbedUnimplementedNodeServiceServer()
@@ -299,6 +312,9 @@ func (UnimplementedNodeServiceServer) GetUserStats(context.Context, *StatRequest
func (UnimplementedNodeServiceServer) GetUserOnlineStats(context.Context, *StatRequest) (*OnlineStatResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUserOnlineStats not implemented")
}
+func (UnimplementedNodeServiceServer) GetUserOnlineIpListStats(context.Context, *StatRequest) (*StatsOnlineIpListResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method GetUserOnlineIpListStats not implemented")
+}
func (UnimplementedNodeServiceServer) SyncUser(grpc.ClientStreamingServer[User, Empty]) error {
return status.Errorf(codes.Unimplemented, "method SyncUser not implemented")
}
@@ -553,6 +569,24 @@ func _NodeService_GetUserOnlineStats_Handler(srv interface{}, ctx context.Contex
return interceptor(ctx, in, info, handler)
}
+func _NodeService_GetUserOnlineIpListStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(StatRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(NodeServiceServer).GetUserOnlineIpListStats(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: NodeService_GetUserOnlineIpListStats_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(NodeServiceServer).GetUserOnlineIpListStats(ctx, req.(*StatRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
func _NodeService_SyncUser_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(NodeServiceServer).SyncUser(&grpc.GenericServerStream[User, Empty]{ServerStream: stream})
}
@@ -633,6 +667,10 @@ var NodeService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetUserOnlineStats",
Handler: _NodeService_GetUserOnlineStats_Handler,
},
+ {
+ MethodName: "GetUserOnlineIpListStats",
+ Handler: _NodeService_GetUserOnlineIpListStats_Handler,
+ },
{
MethodName: "SyncUsers",
Handler: _NodeService_SyncUsers_Handler,
diff --git a/controller/rest/service.go b/controller/rest/service.go
index 105a63e..4e3c509 100644
--- a/controller/rest/service.go
+++ b/controller/rest/service.go
@@ -47,6 +47,7 @@ func (s *Service) setRouter() {
statsGroup.Get("/users", s.GetUsersStats)
statsGroup.Get("/user", s.GetUserStats)
statsGroup.Get("/user/online", s.GetUserOnlineStat)
+ statsGroup.Get("/user/online_ip", s.GetUserOnlineIpListStats)
statsGroup.Get("/backend", s.GetBackendStats)
})
private.Put("/user/sync", s.SyncUser)
diff --git a/controller/rest/stats.go b/controller/rest/stats.go
index bb913aa..af5c8b6 100644
--- a/controller/rest/stats.go
+++ b/controller/rest/stats.go
@@ -129,7 +129,28 @@ func (s *Service) GetUserOnlineStat(w http.ResponseWriter, r *http.Request) {
return
}
- stats, err := s.GetBackend().GetStatOnline(r.Context(), request.GetName())
+ stats, err := s.GetBackend().GetUserOnlineStats(r.Context(), request.GetName())
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ common.SendProtoResponse(w, stats)
+}
+
+func (s *Service) GetUserOnlineIpListStats(w http.ResponseWriter, r *http.Request) {
+ var request common.StatRequest
+ if err := common.ReadProtoBody(r.Body, &request); err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ if request.GetName() == "" {
+ http.Error(w, "name is required", http.StatusBadRequest)
+ return
+ }
+
+ stats, err := s.GetBackend().GetUserOnlineIpListStats(r.Context(), request.GetName())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/controller/rpc/stats.go b/controller/rpc/stats.go
index cc67c6f..a754ed4 100644
--- a/controller/rpc/stats.go
+++ b/controller/rpc/stats.go
@@ -44,7 +44,14 @@ func (s *Service) GetUserOnlineStats(ctx context.Context, request *common.StatRe
if request.GetName() == "" {
return nil, errors.New("name is required")
}
- return s.GetBackend().GetStatOnline(ctx, request.GetName())
+ return s.GetBackend().GetUserOnlineStats(ctx, request.GetName())
+}
+
+func (s *Service) GetUserOnlineIpListStats(ctx context.Context, request *common.StatRequest) (*common.StatsOnlineIpListResponse, error) {
+ if request.GetName() == "" {
+ return nil, errors.New("name is required")
+ }
+ return s.GetBackend().GetUserOnlineIpListStats(ctx, request.GetName())
}
func (s *Service) GetBackendStats(ctx context.Context, _ *common.Empty) (*common.BackendStatsResponse, error) {
diff --git a/go.mod b/go.mod
index 52cba30..16ebc68 100644
--- a/go.mod
+++ b/go.mod
@@ -8,14 +8,14 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/joho/godotenv v1.5.1
github.com/shirou/gopsutil v3.21.11+incompatible
- github.com/xtls/xray-core v1.8.25-0.20241130041635-98a72b6fb49b
- google.golang.org/grpc v1.70.0
+ github.com/xtls/xray-core v1.250306.0
+ google.golang.org/grpc v1.71.0
google.golang.org/protobuf v1.36.5
)
require (
github.com/andybalholm/brotli v1.1.0 // indirect
- github.com/cloudflare/circl v1.4.0 // indirect
+ github.com/cloudflare/circl v1.6.0 // indirect
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
@@ -26,8 +26,8 @@ require (
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/onsi/ginkgo/v2 v2.19.0 // indirect
github.com/pires/go-proxyproto v0.8.0 // indirect
- github.com/quic-go/qpack v0.4.0 // indirect
- github.com/quic-go/quic-go v0.46.0 // indirect
+ github.com/quic-go/qpack v0.5.1 // indirect
+ github.com/quic-go/quic-go v0.50.0 // indirect
github.com/refraction-networking/utls v1.6.7 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
github.com/sagernet/sing v0.5.1 // indirect
@@ -40,19 +40,19 @@ require (
github.com/vishvananda/netns v0.0.4 // indirect
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
- go.uber.org/mock v0.4.0 // indirect
+ go.uber.org/mock v0.5.0 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
- golang.org/x/crypto v0.35.0 // indirect
+ golang.org/x/crypto v0.36.0 // indirect
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
- golang.org/x/mod v0.18.0 // indirect
- golang.org/x/net v0.36.0 // indirect
- golang.org/x/sys v0.30.0 // indirect
- golang.org/x/text v0.22.0 // indirect
- golang.org/x/time v0.5.0 // indirect
- golang.org/x/tools v0.22.0 // indirect
+ golang.org/x/mod v0.21.0 // indirect
+ golang.org/x/net v0.37.0 // indirect
+ golang.org/x/sys v0.31.0 // indirect
+ golang.org/x/text v0.23.0 // indirect
+ golang.org/x/time v0.7.0 // indirect
+ golang.org/x/tools v0.26.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect
- gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect
- lukechampine.com/blake3 v1.3.0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
+ gvisor.dev/gvisor v0.0.0-20240320123526-dc6abceb7ff0 // indirect
+ lukechampine.com/blake3 v1.4.0 // indirect
)
diff --git a/go.sum b/go.sum
index 660636b..c512e75 100644
--- a/go.sum
+++ b/go.sum
@@ -9,6 +9,8 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.4.0 h1:BV7h5MgrktNzytKmWjpOtdYrf0lkkbF8YMlBGPhJQrY=
github.com/cloudflare/circl v1.4.0/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
+github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
+github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -51,6 +53,7 @@ github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl76
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba h1:ql1qNgCyOB7iAEk8JTNM+zJrgIbnyCKX/wdlyPufP5g=
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -73,6 +76,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
+github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
@@ -88,8 +92,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
+github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
+github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y=
github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
+github.com/quic-go/quic-go v0.50.0 h1:3H/ld1pa3CYhkcc20TPIyG1bNsdhn9qZBGN3b9/UyUo=
+github.com/quic-go/quic-go v0.50.0/go.mod h1:Vim6OmUvlYdwBhXP9ZVrtGmCMWa3wEqhq3NgYrI8b4E=
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
@@ -126,24 +134,33 @@ github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhig
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE=
github.com/xtls/xray-core v1.8.25-0.20241130041635-98a72b6fb49b h1:h8DhM+nmPMo4yKqNnxQ7TZ3e8YiESKm9h0gE45UiNmA=
github.com/xtls/xray-core v1.8.25-0.20241130041635-98a72b6fb49b/go.mod h1:BCeSy6P4xz8vSk46ziVkg0iby82W2Mmqvz2ub5kfYrc=
+github.com/xtls/xray-core v1.250306.0 h1:XZyZvSgcpAoVEGnFnxNdoHbSF7Kp77A/0TPk4lhv6rM=
+github.com/xtls/xray-core v1.250306.0/go.mod h1:clXnUOnX6CKWBGgJY4ePYhb/EtTdSrUC7vPfT6m5p4c=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
+go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
+go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
+go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
+go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
+go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
+go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
+go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
@@ -153,6 +170,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
+golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
+golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
@@ -164,6 +183,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -174,6 +194,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
+golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
+golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -182,6 +204,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -195,12 +218,18 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
+golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -212,6 +241,7 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
+golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -227,6 +257,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a h1:hgh8P4EuoxpsuKMXX/To36nOFD7vixReXgn8lPGnt+o=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
@@ -234,6 +266,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
+google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
+google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -249,7 +283,11 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 h1:ze1vwAdliUAr68RQ5NtufWaXaOg8WUO2OACzEV+TNdE=
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk=
+gvisor.dev/gvisor v0.0.0-20240320123526-dc6abceb7ff0 h1:P+U/06iIKPQ3DLcg+zBfSCia1luZ2msPZrJ8jYDFPs0=
+gvisor.dev/gvisor v0.0.0-20240320123526-dc6abceb7ff0/go.mod h1:NQHVAzMwvZ+Qe3ElSiHmq9RUm1MdNHpUZ52fiEqvn+0=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
+lukechampine.com/blake3 v1.4.0 h1:xDbKOZCVbnZsfzM6mHSYcGRHZ3YrLDzqz8XnV4uaD5w=
+lukechampine.com/blake3 v1.4.0/go.mod h1:MQJNQCTnR+kwOP/JEZSxj3MaQjp80FOFSNMMHXcSeX0=