From 5d3e2b206bf97afb8fac4bb448947d77c5056564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Wed, 26 Oct 2022 19:20:34 +0800 Subject: [PATCH] Fix v2ray api --- experimental/trackerconn/conn.go | 87 +++++-------------------- experimental/trackerconn/packet_conn.go | 14 ++-- experimental/v2rayapi/stats.go | 47 +++++++------ test/go.mod | 20 +++--- test/go.sum | 48 +++++++------- test/v2ray_api_test.go | 55 ++++++++++++++++ 6 files changed, 145 insertions(+), 126 deletions(-) create mode 100644 test/v2ray_api_test.go diff --git a/experimental/trackerconn/conn.go b/experimental/trackerconn/conn.go index 8c04b2d4..0963c713 100644 --- a/experimental/trackerconn/conn.go +++ b/experimental/trackerconn/conn.go @@ -1,7 +1,6 @@ package trackerconn import ( - "io" "net" "github.com/sagernet/sing/common/buf" @@ -11,33 +10,25 @@ import ( "go.uber.org/atomic" ) -func New(conn net.Conn, readCounter *atomic.Int64, writeCounter *atomic.Int64, direct bool) N.ExtendedConn { - trackerConn := &Conn{bufio.NewExtendedConn(conn), readCounter, writeCounter} - if direct { - return (*DirectConn)(trackerConn) - } else { - return trackerConn - } +func New(conn net.Conn, readCounter []*atomic.Int64, writeCounter []*atomic.Int64, direct bool) *Conn { + return &Conn{bufio.NewExtendedConn(conn), readCounter, writeCounter} } -func NewHook(conn net.Conn, readCounter func(n int64), writeCounter func(n int64), direct bool) N.ExtendedConn { - trackerConn := &HookConn{bufio.NewExtendedConn(conn), readCounter, writeCounter} - if direct { - return (*DirectHookConn)(trackerConn) - } else { - return trackerConn - } +func NewHook(conn net.Conn, readCounter func(n int64), writeCounter func(n int64), direct bool) *HookConn { + return &HookConn{bufio.NewExtendedConn(conn), readCounter, writeCounter} } type Conn struct { N.ExtendedConn - readCounter *atomic.Int64 - writeCounter *atomic.Int64 + readCounter []*atomic.Int64 + writeCounter []*atomic.Int64 } func (c *Conn) Read(p []byte) (n int, err error) { n, err = c.ExtendedConn.Read(p) - c.readCounter.Add(int64(n)) + for _, counter := range c.readCounter { + counter.Add(int64(n)) + } return n, err } @@ -46,13 +37,17 @@ func (c *Conn) ReadBuffer(buffer *buf.Buffer) error { if err != nil { return err } - c.readCounter.Add(int64(buffer.Len())) + for _, counter := range c.readCounter { + counter.Add(int64(buffer.Len())) + } return nil } func (c *Conn) Write(p []byte) (n int, err error) { n, err = c.ExtendedConn.Write(p) - c.writeCounter.Add(int64(n)) + for _, counter := range c.writeCounter { + counter.Add(int64(n)) + } return n, err } @@ -62,7 +57,9 @@ func (c *Conn) WriteBuffer(buffer *buf.Buffer) error { if err != nil { return err } - c.writeCounter.Add(dataLen) + for _, counter := range c.writeCounter { + counter.Add(dataLen) + } return nil } @@ -110,51 +107,3 @@ func (c *HookConn) WriteBuffer(buffer *buf.Buffer) error { func (c *HookConn) Upstream() any { return c.ExtendedConn } - -type DirectConn Conn - -func (c *DirectConn) WriteTo(w io.Writer) (n int64, err error) { - reader := N.UnwrapReader(c.ExtendedConn) - if wt, ok := reader.(io.WriterTo); ok { - n, err = wt.WriteTo(w) - c.readCounter.Add(n) - return - } else { - return bufio.Copy(w, (*Conn)(c)) - } -} - -func (c *DirectConn) ReadFrom(r io.Reader) (n int64, err error) { - writer := N.UnwrapWriter(c.ExtendedConn) - if rt, ok := writer.(io.ReaderFrom); ok { - n, err = rt.ReadFrom(r) - c.writeCounter.Add(n) - return - } else { - return bufio.Copy((*Conn)(c), r) - } -} - -type DirectHookConn HookConn - -func (c *DirectHookConn) WriteTo(w io.Writer) (n int64, err error) { - reader := N.UnwrapReader(c.ExtendedConn) - if wt, ok := reader.(io.WriterTo); ok { - n, err = wt.WriteTo(w) - c.readCounter(n) - return - } else { - return bufio.Copy(w, (*HookConn)(c)) - } -} - -func (c *DirectHookConn) ReadFrom(r io.Reader) (n int64, err error) { - writer := N.UnwrapWriter(c.ExtendedConn) - if rt, ok := writer.(io.ReaderFrom); ok { - n, err = rt.ReadFrom(r) - c.writeCounter(n) - return - } else { - return bufio.Copy((*HookConn)(c), r) - } -} diff --git a/experimental/trackerconn/packet_conn.go b/experimental/trackerconn/packet_conn.go index 3aaccb84..f90f4b9b 100644 --- a/experimental/trackerconn/packet_conn.go +++ b/experimental/trackerconn/packet_conn.go @@ -8,7 +8,7 @@ import ( "go.uber.org/atomic" ) -func NewPacket(conn N.PacketConn, readCounter *atomic.Int64, writeCounter *atomic.Int64) *PacketConn { +func NewPacket(conn N.PacketConn, readCounter []*atomic.Int64, writeCounter []*atomic.Int64) *PacketConn { return &PacketConn{conn, readCounter, writeCounter} } @@ -18,14 +18,16 @@ func NewHookPacket(conn N.PacketConn, readCounter func(n int64), writeCounter fu type PacketConn struct { N.PacketConn - readCounter *atomic.Int64 - writeCounter *atomic.Int64 + readCounter []*atomic.Int64 + writeCounter []*atomic.Int64 } func (c *PacketConn) ReadPacket(buffer *buf.Buffer) (destination M.Socksaddr, err error) { destination, err = c.PacketConn.ReadPacket(buffer) if err == nil { - c.readCounter.Add(int64(buffer.Len())) + for _, counter := range c.readCounter { + counter.Add(int64(buffer.Len())) + } } return } @@ -36,7 +38,9 @@ func (c *PacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) er if err != nil { return err } - c.writeCounter.Add(dataLen) + for _, counter := range c.writeCounter { + counter.Add(dataLen) + } return nil } diff --git a/experimental/v2rayapi/stats.go b/experimental/v2rayapi/stats.go index d3d08cd5..ff711e74 100644 --- a/experimental/v2rayapi/stats.go +++ b/experimental/v2rayapi/stats.go @@ -58,8 +58,8 @@ func NewStatsService(options option.V2RayStatsServiceOptions) *StatsService { } func (s *StatsService) RoutedConnection(inbound string, outbound string, conn net.Conn) net.Conn { - var readCounter *atomic.Int64 - var writeCounter *atomic.Int64 + var readCounter []*atomic.Int64 + var writeCounter []*atomic.Int64 countInbound := inbound != "" && s.inbounds[inbound] countOutbound := outbound != "" && s.outbounds[outbound] if !countInbound && !countOutbound { @@ -67,20 +67,20 @@ func (s *StatsService) RoutedConnection(inbound string, outbound string, conn ne } s.access.Lock() if countInbound { - readCounter = s.loadOrCreateCounter("inbound>>>"+inbound+">>>traffic>>>uplink", readCounter) - writeCounter = s.loadOrCreateCounter("inbound>>>"+inbound+">>>traffic>>>downlink", writeCounter) + readCounter = append(readCounter, s.loadOrCreateCounter("inbound>>>"+inbound+">>>traffic>>>uplink")) + writeCounter = append(writeCounter, s.loadOrCreateCounter("inbound>>>"+inbound+">>>traffic>>>downlink")) } if countOutbound { - readCounter = s.loadOrCreateCounter("outbound>>>"+outbound+">>>traffic>>>uplink", readCounter) - writeCounter = s.loadOrCreateCounter("outbound>>>"+outbound+">>>traffic>>>downlink", writeCounter) + readCounter = append(readCounter, s.loadOrCreateCounter("outbound>>>"+outbound+">>>traffic>>>uplink")) + writeCounter = append(writeCounter, s.loadOrCreateCounter("outbound>>>"+outbound+">>>traffic>>>downlink")) } s.access.Unlock() return trackerconn.New(conn, readCounter, writeCounter, s.directIO) } func (s *StatsService) RoutedPacketConnection(inbound string, outbound string, conn N.PacketConn) N.PacketConn { - var readCounter *atomic.Int64 - var writeCounter *atomic.Int64 + var readCounter []*atomic.Int64 + var writeCounter []*atomic.Int64 countInbound := inbound != "" && s.inbounds[inbound] countOutbound := outbound != "" && s.outbounds[outbound] if !countInbound && !countOutbound { @@ -88,12 +88,12 @@ func (s *StatsService) RoutedPacketConnection(inbound string, outbound string, c } s.access.Lock() if countInbound { - readCounter = s.loadOrCreateCounter("inbound>>>"+inbound+">>>traffic>>>uplink", readCounter) - writeCounter = s.loadOrCreateCounter("inbound>>>"+inbound+">>>traffic>>>downlink", writeCounter) + readCounter = append(readCounter, s.loadOrCreateCounter("inbound>>>"+inbound+">>>traffic>>>uplink")) + writeCounter = append(writeCounter, s.loadOrCreateCounter("inbound>>>"+inbound+">>>traffic>>>downlink")) } if countOutbound { - readCounter = s.loadOrCreateCounter("outbound>>>"+outbound+">>>traffic>>>uplink", readCounter) - writeCounter = s.loadOrCreateCounter("outbound>>>"+outbound+">>>traffic>>>downlink", writeCounter) + readCounter = append(readCounter, s.loadOrCreateCounter("outbound>>>"+outbound+">>>traffic>>>uplink")) + writeCounter = append(writeCounter, s.loadOrCreateCounter("outbound>>>"+outbound+">>>traffic>>>downlink")) } s.access.Unlock() return trackerconn.NewPacket(conn, readCounter, writeCounter) @@ -119,7 +119,17 @@ func (s *StatsService) QueryStats(ctx context.Context, request *QueryStatsReques var response QueryStatsResponse s.access.Lock() defer s.access.Unlock() - if request.Regexp { + if len(request.Patterns) == 0 { + for name, counter := range s.counters { + var value int64 + if request.Reset_ { + value = counter.Swap(0) + } else { + value = counter.Load() + } + response.Stat = append(response.Stat, &Stat{Name: name, Value: value}) + } + } else if request.Regexp { matchers := make([]*regexp.Regexp, 0, len(request.Patterns)) for _, pattern := range request.Patterns { matcher, err := regexp.Compile(pattern) @@ -182,13 +192,12 @@ func (s *StatsService) mustEmbedUnimplementedStatsServiceServer() { } //nolint:staticcheck -func (s *StatsService) loadOrCreateCounter(name string, counter *atomic.Int64) *atomic.Int64 { +func (s *StatsService) loadOrCreateCounter(name string) *atomic.Int64 { counter, loaded := s.counters[name] - if !loaded { - if counter == nil { - counter = atomic.NewInt64(0) - } - s.counters[name] = counter + if loaded { + return counter } + counter = atomic.NewInt64(0) + s.counters[name] = counter return counter } diff --git a/test/go.mod b/test/go.mod index 17a9cd9b..426ac3f1 100644 --- a/test/go.mod +++ b/test/go.mod @@ -15,7 +15,7 @@ require ( github.com/spyzhov/ajson v0.7.1 github.com/stretchr/testify v1.8.0 go.uber.org/goleak v1.2.0 - golang.org/x/net v0.0.0-20221004154528-8021a29435af + golang.org/x/net v0.0.0-20221017152216-f25eb7ecb193 ) //replace github.com/sagernet/sing => ../../sing @@ -29,11 +29,11 @@ require ( github.com/caddyserver/certmagic v0.17.2 // indirect github.com/cloudflare/circl v1.2.1-0.20220831060716-4cf0150356fc // indirect github.com/cretz/bine v0.2.0 // indirect - github.com/database64128/tfo-go/v2 v2.0.1 // indirect + github.com/database64128/tfo-go/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/go-units v0.4.0 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-chi/chi/v5 v5.0.7 // indirect github.com/go-chi/cors v1.2.1 // indirect github.com/go-chi/render v1.0.2 // indirect @@ -43,7 +43,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/btree v1.0.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect - github.com/klauspost/compress v1.13.6 // indirect + github.com/klauspost/compress v1.15.9 // indirect github.com/klauspost/cpuid/v2 v2.1.1 // indirect github.com/libdns/libdns v0.2.1 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect @@ -62,13 +62,13 @@ require ( github.com/pires/go-proxyproto v0.6.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/refraction-networking/utls v1.1.2 // indirect + github.com/refraction-networking/utls v1.1.5 // indirect github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e // indirect github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb // indirect - github.com/sagernet/sing-dns v0.0.0-20220929010544-ee843807aae3 // indirect - github.com/sagernet/sing-tun v0.0.0-20221009132126-1ede22e6eb7e // indirect + github.com/sagernet/sing-dns v0.0.0-20221020030320-4c4e9d98314b // indirect + github.com/sagernet/sing-tun v0.0.0-20221012082254-488c3b75f6fd // indirect github.com/sagernet/sing-vmess v0.0.0-20220925083655-063bc85ea685 // indirect github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 // indirect github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect @@ -79,17 +79,17 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.23.0 // indirect go4.org/netipx v0.0.0-20220925034521-797b0c90d8ab // indirect - golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b // indirect + golang.org/x/crypto v0.0.0-20221012134737-56aed061732a // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect + golang.org/x/sys v0.1.0 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f // indirect golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b // indirect google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f // indirect - google.golang.org/grpc v1.49.0 // indirect + google.golang.org/grpc v1.50.1 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/test/go.sum b/test/go.sum index d21c096d..cdd828de 100644 --- a/test/go.sum +++ b/test/go.sum @@ -29,8 +29,8 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw= github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo= github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI= -github.com/database64128/tfo-go/v2 v2.0.1 h1:VFfturVoq6NmPGfhXO1K15x82KR19aAfw1RYtTzyVv4= -github.com/database64128/tfo-go/v2 v2.0.1/go.mod h1:FDdt4JaAsRU66wsYHxSVytYimPkKIHupVsxM+5DhvjY= +github.com/database64128/tfo-go/v2 v2.0.2 h1:5rGgkJeLEKlNaqredfrPQNLnctn1b+1fq/8tdKdOzJg= +github.com/database64128/tfo-go/v2 v2.0.2/go.mod h1:FDdt4JaAsRU66wsYHxSVytYimPkKIHupVsxM+5DhvjY= 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= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -50,8 +50,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= @@ -99,8 +99,8 @@ github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbg github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= @@ -152,8 +152,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/refraction-networking/utls v1.1.2 h1:a7GQauRt72VG+wtNm0lnrAaCGlyX47gEi1++dSsDBpw= -github.com/refraction-networking/utls v1.1.2/go.mod h1:+D89TUtA8+NKVFj1IXWr0p3tSdX1+SqUB7rL0QnGqyg= +github.com/refraction-networking/utls v1.1.5 h1:JtrojoNhbUQkBqEg05sP3gDgDj6hIEAAVKbI9lx4n6w= +github.com/refraction-networking/utls v1.1.5/go.mod h1:jRQxtYi7nkq1p28HF2lwOH5zQm9aC8rpK0O9lIIzGh8= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e h1:5CFRo8FJbCuf5s/eTBdZpmMbn8Fe2eSMLNAYfKanA34= github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e/go.mod h1:qbt0dWObotCfcjAJJ9AxtFPNSDUfZF+6dCpgKEOBn/g= @@ -167,12 +167,12 @@ github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2 github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.0.0-20221008120626-60a9910eefe4 h1:LO7xMvMGhYmjQg2vjhTzsODyzs9/WLYu5Per+/8jIeo= github.com/sagernet/sing v0.0.0-20221008120626-60a9910eefe4/go.mod h1:zvgDYKI+vCAW9RyfyrKTgleI+DOa8lzHMPC7VZo3OL4= -github.com/sagernet/sing-dns v0.0.0-20220929010544-ee843807aae3 h1:AEdyJxEDFq38z0pBX/0MpikQapGMIch+1ADe9k1bJqU= -github.com/sagernet/sing-dns v0.0.0-20220929010544-ee843807aae3/go.mod h1:SrvWLfOSlnFmH32CWXicfilAGgIXR0VjrH6yRbuXYww= +github.com/sagernet/sing-dns v0.0.0-20221020030320-4c4e9d98314b h1:GFAf2Cr/PRyF+u1ppgt3OWtxbpQYlW31Ij5yNK5EwWM= +github.com/sagernet/sing-dns v0.0.0-20221020030320-4c4e9d98314b/go.mod h1:SrvWLfOSlnFmH32CWXicfilAGgIXR0VjrH6yRbuXYww= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM= -github.com/sagernet/sing-tun v0.0.0-20221009132126-1ede22e6eb7e h1:UIE1wKIr92d2VUWox3On8JQknvewl7aeG+JfthISX0w= -github.com/sagernet/sing-tun v0.0.0-20221009132126-1ede22e6eb7e/go.mod h1:qbqV9lwcXJnj1Tw4we7oA6Z8zGE/kCXQBCzuhzRWVw8= +github.com/sagernet/sing-tun v0.0.0-20221012082254-488c3b75f6fd h1:TtoZDwg09Cpqi+gCmCtL6w4oEUZ5lHz+vHIjdr1UBNY= +github.com/sagernet/sing-tun v0.0.0-20221012082254-488c3b75f6fd/go.mod h1:1u3pjXA9HmH7kRiBJqM3C/zPxrxnCLd3svmqtub/RFU= github.com/sagernet/sing-vmess v0.0.0-20220925083655-063bc85ea685 h1:AZzFNRR/ZwMTceUQ1b/mxx6oyKqmFymdMn/yleJmoVM= github.com/sagernet/sing-vmess v0.0.0-20220925083655-063bc85ea685/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM= github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38= @@ -220,9 +220,9 @@ golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaE golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0= -golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20221012134737-56aed061732a h1:NmSIgad6KjE6VvHciPZuNRTKxGhlPfD6OA87W/PLkqg= +golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= @@ -255,10 +255,11 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211111160137-58aab5ef257a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4= -golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221017152216-f25eb7ecb193 h1:3Moaxt4TfzNcQH6DWvlYKraN1ozhBXQHcgvXjRGeim0= +golang.org/x/net v0.0.0-20221017152216-f25eb7ecb193/go.mod h1:RpDiru2p0u2F0lLpEoqnP2+7xs0ifAuOcJ442g6GU2s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -293,13 +294,14 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI= -golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -352,8 +354,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/test/v2ray_api_test.go b/test/v2ray_api_test.go new file mode 100644 index 00000000..ec560856 --- /dev/null +++ b/test/v2ray_api_test.go @@ -0,0 +1,55 @@ +package main + +import ( + "context" + "net/netip" + "testing" + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/experimental/v2rayapi" + "github.com/sagernet/sing-box/option" + + "github.com/stretchr/testify/require" +) + +func TestV2RayAPI(t *testing.T) { + i := startInstance(t, option.Options{ + Inbounds: []option.Inbound{ + { + Type: C.TypeMixed, + Tag: "in", + MixedOptions: option.HTTPMixedInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: option.ListenAddress(netip.IPv4Unspecified()), + ListenPort: clientPort, + }, + }, + }, + }, + Outbounds: []option.Outbound{ + { + Type: C.TypeDirect, + Tag: "out", + }, + }, + Experimental: &option.ExperimentalOptions{ + V2RayAPI: &option.V2RayAPIOptions{ + Listen: "127.0.0.1:8080", + Stats: &option.V2RayStatsServiceOptions{ + Enabled: true, + Inbounds: []string{"in"}, + Outbounds: []string{"out"}, + }, + }, + }, + }) + testSuit(t, clientPort, testPort) + statsService := i.Router().V2RayServer().StatsService() + require.NotNil(t, statsService) + response, err := statsService.(v2rayapi.StatsServiceServer).QueryStats(context.Background(), &v2rayapi.QueryStatsRequest{Regexp: true, Patterns: []string{".*"}}) + require.NoError(t, err) + count := response.Stat[0].Value + require.Equal(t, len(response.Stat), 4) + for _, stat := range response.Stat { + require.Equal(t, count, stat.Value) + } +}