mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 16:41:30 +00:00
Refactor platform command api
This commit is contained in:
parent
0ca344df5f
commit
5af8d001ae
|
@ -84,11 +84,12 @@ func buildiOS() {
|
||||||
"-libname=box",
|
"-libname=box",
|
||||||
}
|
}
|
||||||
if !debugEnabled {
|
if !debugEnabled {
|
||||||
args = append(args,
|
args = append(
|
||||||
"-trimpath", "-ldflags=-s -w -buildid=", "-tags", "with_gvisor,with_clash_api",
|
args, "-trimpath", "-ldflags=-s -w -buildid=",
|
||||||
|
"-tags", "with_gvisor,with_quic,with_wireguard,with_utls,with_clash_api",
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
args = append(args, "-tags", "with_gvisor,with_clash_api,debug")
|
args = append(args, "-tags", "with_gvisor,with_quic,with_wireguard,with_utls,with_clash_api,debug")
|
||||||
}
|
}
|
||||||
|
|
||||||
args = append(args, "./experimental/libbox")
|
args = append(args, "./experimental/libbox")
|
||||||
|
|
8
experimental/libbox/command.go
Normal file
8
experimental/libbox/command.go
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
|
package libbox
|
||||||
|
|
||||||
|
const (
|
||||||
|
CommandLog int32 = iota
|
||||||
|
CommandStatus
|
||||||
|
)
|
69
experimental/libbox/command_client.go
Normal file
69
experimental/libbox/command_client.go
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
|
package libbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"net"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommandClient struct {
|
||||||
|
sockPath string
|
||||||
|
handler CommandClientHandler
|
||||||
|
conn net.Conn
|
||||||
|
options CommandClientOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommandClientOptions struct {
|
||||||
|
Command int32
|
||||||
|
StatusInterval int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommandClientHandler interface {
|
||||||
|
Connected()
|
||||||
|
Disconnected(message string)
|
||||||
|
WriteLog(message string)
|
||||||
|
WriteStatus(message *StatusMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCommandClient(sharedDirectory string, handler CommandClientHandler, options *CommandClientOptions) *CommandClient {
|
||||||
|
return &CommandClient{
|
||||||
|
sockPath: filepath.Join(sharedDirectory, "command.sock"),
|
||||||
|
handler: handler,
|
||||||
|
options: common.PtrValueOrDefault(options),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandClient) Connect() error {
|
||||||
|
conn, err := net.DialUnix("unix", nil, &net.UnixAddr{
|
||||||
|
Name: c.sockPath,
|
||||||
|
Net: "unix",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.conn = conn
|
||||||
|
err = binary.Write(conn, binary.BigEndian, uint8(c.options.Command))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch c.options.Command {
|
||||||
|
case CommandLog:
|
||||||
|
go c.handleLogConn(conn)
|
||||||
|
case CommandStatus:
|
||||||
|
err = binary.Write(conn, binary.BigEndian, c.options.StatusInterval)
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "write interval")
|
||||||
|
}
|
||||||
|
go c.handleStatusConn(conn)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandClient) Disconnect() error {
|
||||||
|
return common.Close(c.conn)
|
||||||
|
}
|
104
experimental/libbox/command_log.go
Normal file
104
experimental/libbox/command_log.go
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
|
package libbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *CommandServer) WriteMessage(message string) {
|
||||||
|
s.subscriber.Emit(message)
|
||||||
|
s.access.Lock()
|
||||||
|
s.savedLines.PushBack(message)
|
||||||
|
if s.savedLines.Len() > 100 {
|
||||||
|
s.savedLines.Remove(s.savedLines.Front())
|
||||||
|
}
|
||||||
|
s.access.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func readLog(reader io.Reader) ([]byte, error) {
|
||||||
|
var messageLength uint16
|
||||||
|
err := binary.Read(reader, binary.BigEndian, &messageLength)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data := make([]byte, messageLength)
|
||||||
|
_, err = io.ReadFull(reader, data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeLog(writer io.Writer, message []byte) error {
|
||||||
|
err := binary.Write(writer, binary.BigEndian, uint16(len(message)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = writer.Write(message)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommandServer) handleLogConn(conn net.Conn) error {
|
||||||
|
var savedLines []string
|
||||||
|
s.access.Lock()
|
||||||
|
savedLines = make([]string, 0, s.savedLines.Len())
|
||||||
|
for element := s.savedLines.Front(); element != nil; element = element.Next() {
|
||||||
|
savedLines = append(savedLines, element.Value)
|
||||||
|
}
|
||||||
|
s.access.Unlock()
|
||||||
|
subscription, done, err := s.observer.Subscribe()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer s.observer.UnSubscribe(subscription)
|
||||||
|
for _, line := range savedLines {
|
||||||
|
err = writeLog(conn, []byte(line))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx := connKeepAlive(conn)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
case message := <-subscription:
|
||||||
|
err = writeLog(conn, []byte(message))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case <-done:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandClient) handleLogConn(conn net.Conn) {
|
||||||
|
c.handler.Connected()
|
||||||
|
for {
|
||||||
|
message, err := readLog(conn)
|
||||||
|
if err != nil {
|
||||||
|
c.handler.Disconnected(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.handler.WriteLog(string(message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func connKeepAlive(reader io.Reader) context.Context {
|
||||||
|
ctx, cancel := context.WithCancelCause(context.Background())
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
_, err := readLog(reader)
|
||||||
|
if err != nil {
|
||||||
|
cancel(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return ctx
|
||||||
|
}
|
85
experimental/libbox/command_server.go
Normal file
85
experimental/libbox/command_server.go
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
|
package libbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/log"
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
"github.com/sagernet/sing/common/observable"
|
||||||
|
"github.com/sagernet/sing/common/x/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommandServer struct {
|
||||||
|
sockPath string
|
||||||
|
listener net.Listener
|
||||||
|
|
||||||
|
access sync.Mutex
|
||||||
|
savedLines *list.List[string]
|
||||||
|
subscriber *observable.Subscriber[string]
|
||||||
|
observer *observable.Observer[string]
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCommandServer(sharedDirectory string) *CommandServer {
|
||||||
|
server := &CommandServer{
|
||||||
|
sockPath: filepath.Join(sharedDirectory, "command.sock"),
|
||||||
|
savedLines: new(list.List[string]),
|
||||||
|
subscriber: observable.NewSubscriber[string](128),
|
||||||
|
}
|
||||||
|
server.observer = observable.NewObserver[string](server.subscriber, 64)
|
||||||
|
return server
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommandServer) Start() error {
|
||||||
|
os.Remove(s.sockPath)
|
||||||
|
listener, err := net.ListenUnix("unix", &net.UnixAddr{
|
||||||
|
Name: s.sockPath,
|
||||||
|
Net: "unix",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go s.loopConnection(listener)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommandServer) Close() error {
|
||||||
|
return s.listener.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommandServer) loopConnection(listener net.Listener) {
|
||||||
|
for {
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
hErr := s.handleConnection(conn)
|
||||||
|
if hErr != nil && !E.IsClosed(err) {
|
||||||
|
log.Warn("log-server: process connection: ", hErr)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommandServer) handleConnection(conn net.Conn) error {
|
||||||
|
defer conn.Close()
|
||||||
|
var command uint8
|
||||||
|
err := binary.Read(conn, binary.BigEndian, &command)
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "read command")
|
||||||
|
}
|
||||||
|
switch int32(command) {
|
||||||
|
case CommandLog:
|
||||||
|
return s.handleLogConn(conn)
|
||||||
|
case CommandStatus:
|
||||||
|
return s.handleStatusConn(conn)
|
||||||
|
default:
|
||||||
|
return E.New("unknown command: ", command)
|
||||||
|
}
|
||||||
|
}
|
61
experimental/libbox/command_status.go
Normal file
61
experimental/libbox/command_status.go
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
|
package libbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"net"
|
||||||
|
"runtime"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StatusMessage struct {
|
||||||
|
Memory int64
|
||||||
|
Goroutines int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func readStatus() StatusMessage {
|
||||||
|
var memStats runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&memStats)
|
||||||
|
var message StatusMessage
|
||||||
|
message.Memory = int64(memStats.HeapInuse + memStats.StackInuse + memStats.MSpanInuse)
|
||||||
|
message.Goroutines = int32(runtime.NumGoroutine())
|
||||||
|
return message
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommandServer) handleStatusConn(conn net.Conn) error {
|
||||||
|
var interval int64
|
||||||
|
err := binary.Read(conn, binary.BigEndian, &interval)
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "read interval")
|
||||||
|
}
|
||||||
|
ticker := time.NewTicker(time.Duration(interval))
|
||||||
|
defer ticker.Stop()
|
||||||
|
ctx := connKeepAlive(conn)
|
||||||
|
for {
|
||||||
|
err = binary.Write(conn, binary.BigEndian, readStatus())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil
|
||||||
|
case <-ticker.C:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandClient) handleStatusConn(conn net.Conn) {
|
||||||
|
c.handler.Connected()
|
||||||
|
for {
|
||||||
|
var message StatusMessage
|
||||||
|
err := binary.Read(conn, binary.BigEndian, &message)
|
||||||
|
if err != nil {
|
||||||
|
c.handler.Disconnected(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.handler.WriteStatus(&message)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,59 +0,0 @@
|
||||||
//go:build darwin
|
|
||||||
|
|
||||||
package libbox
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/sagernet/sing/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LogClient struct {
|
|
||||||
sockPath string
|
|
||||||
handler LogClientHandler
|
|
||||||
conn net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
type LogClientHandler interface {
|
|
||||||
Connected()
|
|
||||||
Disconnected()
|
|
||||||
WriteLog(message string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLogClient(sharedDirectory string, handler LogClientHandler) *LogClient {
|
|
||||||
return &LogClient{
|
|
||||||
sockPath: filepath.Join(sharedDirectory, "log.sock"),
|
|
||||||
handler: handler,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *LogClient) Connect() error {
|
|
||||||
conn, err := net.DialUnix("unix", nil, &net.UnixAddr{
|
|
||||||
Name: c.sockPath,
|
|
||||||
Net: "unix",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.conn = conn
|
|
||||||
go c.loopConnection(&messageConn{conn})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *LogClient) Disconnect() error {
|
|
||||||
return common.Close(c.conn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *LogClient) loopConnection(conn *messageConn) {
|
|
||||||
c.handler.Connected()
|
|
||||||
defer c.handler.Disconnected()
|
|
||||||
for {
|
|
||||||
message, err := conn.Read()
|
|
||||||
if err != nil {
|
|
||||||
c.handler.WriteLog("(log client error) " + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.handler.WriteLog(string(message))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,139 +0,0 @@
|
||||||
//go:build darwin
|
|
||||||
|
|
||||||
package libbox
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/log"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
|
||||||
"github.com/sagernet/sing/common/observable"
|
|
||||||
"github.com/sagernet/sing/common/x/list"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LogServer struct {
|
|
||||||
sockPath string
|
|
||||||
listener net.Listener
|
|
||||||
|
|
||||||
access sync.Mutex
|
|
||||||
savedLines *list.List[string]
|
|
||||||
subscriber *observable.Subscriber[string]
|
|
||||||
observer *observable.Observer[string]
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLogServer(sharedDirectory string) *LogServer {
|
|
||||||
server := &LogServer{
|
|
||||||
sockPath: filepath.Join(sharedDirectory, "log.sock"),
|
|
||||||
savedLines: new(list.List[string]),
|
|
||||||
subscriber: observable.NewSubscriber[string](128),
|
|
||||||
}
|
|
||||||
server.observer = observable.NewObserver[string](server.subscriber, 64)
|
|
||||||
return server
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LogServer) Start() error {
|
|
||||||
os.Remove(s.sockPath)
|
|
||||||
listener, err := net.ListenUnix("unix", &net.UnixAddr{
|
|
||||||
Name: s.sockPath,
|
|
||||||
Net: "unix",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
go s.loopConnection(listener)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LogServer) Close() error {
|
|
||||||
return s.listener.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LogServer) WriteMessage(message string) {
|
|
||||||
s.subscriber.Emit(message)
|
|
||||||
s.access.Lock()
|
|
||||||
s.savedLines.PushBack(message)
|
|
||||||
if s.savedLines.Len() > 100 {
|
|
||||||
s.savedLines.Remove(s.savedLines.Front())
|
|
||||||
}
|
|
||||||
s.access.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LogServer) loopConnection(listener net.Listener) {
|
|
||||||
for {
|
|
||||||
conn, err := listener.Accept()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
hErr := s.handleConnection(&messageConn{conn})
|
|
||||||
if hErr != nil && !E.IsClosed(err) {
|
|
||||||
log.Warn("log-server: process connection: ", hErr)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LogServer) handleConnection(conn *messageConn) error {
|
|
||||||
var savedLines []string
|
|
||||||
s.access.Lock()
|
|
||||||
savedLines = make([]string, 0, s.savedLines.Len())
|
|
||||||
for element := s.savedLines.Front(); element != nil; element = element.Next() {
|
|
||||||
savedLines = append(savedLines, element.Value)
|
|
||||||
}
|
|
||||||
s.access.Unlock()
|
|
||||||
subscription, done, err := s.observer.Subscribe()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer s.observer.UnSubscribe(subscription)
|
|
||||||
for _, line := range savedLines {
|
|
||||||
err = conn.Write([]byte(line))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case message := <-subscription:
|
|
||||||
err = conn.Write([]byte(message))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case <-done:
|
|
||||||
conn.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type messageConn struct {
|
|
||||||
net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *messageConn) Read() ([]byte, error) {
|
|
||||||
var messageLength uint16
|
|
||||||
err := binary.Read(c.Conn, binary.BigEndian, &messageLength)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
data := make([]byte, messageLength)
|
|
||||||
_, err = io.ReadFull(c.Conn, data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *messageConn) Write(message []byte) error {
|
|
||||||
err := binary.Write(c.Conn, binary.BigEndian, uint16(len(message)))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = c.Conn.Write(message)
|
|
||||||
return err
|
|
||||||
}
|
|
|
@ -1,6 +1,10 @@
|
||||||
package libbox
|
package libbox
|
||||||
|
|
||||||
import C "github.com/sagernet/sing-box/constant"
|
import (
|
||||||
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
|
||||||
|
"github.com/dustin/go-humanize"
|
||||||
|
)
|
||||||
|
|
||||||
func SetBasePath(path string) {
|
func SetBasePath(path string) {
|
||||||
C.SetBasePath(path)
|
C.SetBasePath(path)
|
||||||
|
@ -9,3 +13,7 @@ func SetBasePath(path string) {
|
||||||
func Version() string {
|
func Version() string {
|
||||||
return C.Version
|
return C.Version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FormatBytes(length int64) string {
|
||||||
|
return humanize.Bytes(uint64(length))
|
||||||
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ func startInstance(t *testing.T, options option.Options) *box.Box {
|
||||||
var instance *box.Box
|
var instance *box.Box
|
||||||
var err error
|
var err error
|
||||||
for retry := 0; retry < 3; retry++ {
|
for retry := 0; retry < 3; retry++ {
|
||||||
instance, err = box.New(ctx, options)
|
instance, err = box.New(ctx, options, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = instance.Start()
|
err = instance.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -167,7 +167,7 @@ func testVLESSXray(t *testing.T, packetEncoding string, flow string) {
|
||||||
},
|
},
|
||||||
UUID: userID.String(),
|
UUID: userID.String(),
|
||||||
Flow: flow,
|
Flow: flow,
|
||||||
PacketEncoding: packetEncoding,
|
PacketEncoding: &packetEncoding,
|
||||||
TLS: &option.OutboundTLSOptions{
|
TLS: &option.OutboundTLSOptions{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
ServerName: "example.org",
|
ServerName: "example.org",
|
||||||
|
|
Loading…
Reference in a new issue