mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 08:31:30 +00:00
parent
1d517b6ca5
commit
f504fb0d46
|
@ -20,7 +20,6 @@ type CommandClient struct {
|
||||||
type CommandClientOptions struct {
|
type CommandClientOptions struct {
|
||||||
Command int32
|
Command int32
|
||||||
StatusInterval int64
|
StatusInterval int64
|
||||||
IsMainClient bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommandClientHandler interface {
|
type CommandClientHandler interface {
|
||||||
|
@ -29,7 +28,6 @@ type CommandClientHandler interface {
|
||||||
ClearLogs()
|
ClearLogs()
|
||||||
WriteLogs(messageList StringIterator)
|
WriteLogs(messageList StringIterator)
|
||||||
WriteStatus(message *StatusMessage)
|
WriteStatus(message *StatusMessage)
|
||||||
OpenURL(url string)
|
|
||||||
WriteGroups(message OutboundGroupIterator)
|
WriteGroups(message OutboundGroupIterator)
|
||||||
InitializeClashMode(modeList StringIterator, currentMode string)
|
InitializeClashMode(modeList StringIterator, currentMode string)
|
||||||
UpdateClashMode(newMode string)
|
UpdateClashMode(newMode string)
|
||||||
|
@ -93,13 +91,9 @@ func (c *CommandClient) Connect() error {
|
||||||
c.handler.Connected()
|
c.handler.Connected()
|
||||||
go c.handleLogConn(conn)
|
go c.handleLogConn(conn)
|
||||||
case CommandStatus:
|
case CommandStatus:
|
||||||
err = binary.Write(conn, binary.BigEndian, c.options.IsMainClient)
|
|
||||||
if err != nil {
|
|
||||||
return E.Cause(err, "write is main client")
|
|
||||||
}
|
|
||||||
err = binary.Write(conn, binary.BigEndian, c.options.StatusInterval)
|
err = binary.Write(conn, binary.BigEndian, c.options.StatusInterval)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return E.Cause(err, "write header")
|
return E.Cause(err, "write interval")
|
||||||
}
|
}
|
||||||
c.handler.Connected()
|
c.handler.Connected()
|
||||||
go c.handleStatusConn(conn)
|
go c.handleStatusConn(conn)
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
package libbox
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
|
||||||
"github.com/sagernet/sing/common/varbin"
|
|
||||||
)
|
|
||||||
|
|
||||||
type myEvent interface {
|
|
||||||
writeTo(writer varbin.Writer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func readEvent(reader varbin.Reader) (myEvent, error) {
|
|
||||||
eventType, err := reader.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch eventType {
|
|
||||||
case eventTypeEmpty:
|
|
||||||
return nil, nil
|
|
||||||
case eventTypeOpenURL:
|
|
||||||
url, err := varbin.ReadValue[string](reader, binary.BigEndian)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &eventOpenURL{URL: url}, nil
|
|
||||||
default:
|
|
||||||
return nil, E.New("unknown event type: ", eventType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type eventOpenURL struct {
|
|
||||||
URL string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *eventOpenURL) writeTo(writer varbin.Writer) {
|
|
||||||
writer.WriteByte(eventTypeOpenURL)
|
|
||||||
varbin.Write(writer, binary.BigEndian, e.URL)
|
|
||||||
}
|
|
|
@ -33,7 +33,6 @@ type CommandServer struct {
|
||||||
urlTestUpdate chan struct{}
|
urlTestUpdate chan struct{}
|
||||||
modeUpdate chan struct{}
|
modeUpdate chan struct{}
|
||||||
logReset chan struct{}
|
logReset chan struct{}
|
||||||
events chan myEvent
|
|
||||||
|
|
||||||
closedConnections []Connection
|
closedConnections []Connection
|
||||||
}
|
}
|
||||||
|
@ -53,7 +52,6 @@ func NewCommandServer(handler CommandServerHandler, maxLines int32) *CommandServ
|
||||||
urlTestUpdate: make(chan struct{}, 1),
|
urlTestUpdate: make(chan struct{}, 1),
|
||||||
modeUpdate: make(chan struct{}, 1),
|
modeUpdate: make(chan struct{}, 1),
|
||||||
logReset: make(chan struct{}, 1),
|
logReset: make(chan struct{}, 1),
|
||||||
events: make(chan myEvent, 8),
|
|
||||||
}
|
}
|
||||||
server.observer = observable.NewObserver[string](server.subscriber, 64)
|
server.observer = observable.NewObserver[string](server.subscriber, 64)
|
||||||
return server
|
return server
|
||||||
|
@ -63,12 +61,6 @@ func (s *CommandServer) SetService(newService *BoxService) {
|
||||||
if newService != nil {
|
if newService != nil {
|
||||||
service.PtrFromContext[urltest.HistoryStorage](newService.ctx).SetHook(s.urlTestUpdate)
|
service.PtrFromContext[urltest.HistoryStorage](newService.ctx).SetHook(s.urlTestUpdate)
|
||||||
newService.instance.Router().ClashServer().(*clashapi.Server).SetModeUpdateHook(s.modeUpdate)
|
newService.instance.Router().ClashServer().(*clashapi.Server).SetModeUpdateHook(s.modeUpdate)
|
||||||
newService.platformInterface.openURLFunc = func(url string) {
|
|
||||||
select {
|
|
||||||
case s.events <- &eventOpenURL{URL: url}:
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
s.service = newService
|
s.service = newService
|
||||||
s.notifyURLTestUpdate()
|
s.notifyURLTestUpdate()
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package libbox
|
package libbox
|
||||||
|
|
||||||
import (
|
import (
|
||||||
std_bufio "bufio"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
@ -10,15 +9,9 @@ import (
|
||||||
"github.com/sagernet/sing-box/common/conntrack"
|
"github.com/sagernet/sing-box/common/conntrack"
|
||||||
"github.com/sagernet/sing-box/experimental/clashapi"
|
"github.com/sagernet/sing-box/experimental/clashapi"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
F "github.com/sagernet/sing/common/format"
|
|
||||||
"github.com/sagernet/sing/common/memory"
|
"github.com/sagernet/sing/common/memory"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
eventTypeEmpty byte = iota
|
|
||||||
eventTypeOpenURL
|
|
||||||
)
|
|
||||||
|
|
||||||
type StatusMessage struct {
|
type StatusMessage struct {
|
||||||
Memory int64
|
Memory int64
|
||||||
Goroutines int32
|
Goroutines int32
|
||||||
|
@ -51,73 +44,31 @@ func (s *CommandServer) readStatus() StatusMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CommandServer) handleStatusConn(conn net.Conn) error {
|
func (s *CommandServer) handleStatusConn(conn net.Conn) error {
|
||||||
var isMainClient bool
|
|
||||||
err := binary.Read(conn, binary.BigEndian, &isMainClient)
|
|
||||||
if err != nil {
|
|
||||||
return E.Cause(err, "read is main client")
|
|
||||||
}
|
|
||||||
var interval int64
|
var interval int64
|
||||||
err = binary.Read(conn, binary.BigEndian, &interval)
|
err := binary.Read(conn, binary.BigEndian, &interval)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return E.Cause(err, "read interval")
|
return E.Cause(err, "read interval")
|
||||||
}
|
}
|
||||||
ticker := time.NewTicker(time.Duration(interval))
|
ticker := time.NewTicker(time.Duration(interval))
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
ctx := connKeepAlive(conn)
|
ctx := connKeepAlive(conn)
|
||||||
writer := std_bufio.NewWriter(conn)
|
for {
|
||||||
if isMainClient {
|
err = binary.Write(conn, binary.BigEndian, s.readStatus())
|
||||||
for {
|
if err != nil {
|
||||||
writer.WriteByte(eventTypeEmpty)
|
return err
|
||||||
err = binary.Write(writer, binary.BigEndian, s.readStatus())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
writer.Flush()
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
case <-ticker.C:
|
|
||||||
case event := <-s.events:
|
|
||||||
event.writeTo(writer)
|
|
||||||
writer.Flush()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
select {
|
||||||
for {
|
case <-ctx.Done():
|
||||||
err = binary.Write(writer, binary.BigEndian, s.readStatus())
|
return ctx.Err()
|
||||||
if err != nil {
|
case <-ticker.C:
|
||||||
return err
|
|
||||||
}
|
|
||||||
writer.Flush()
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
case <-ticker.C:
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommandClient) handleStatusConn(conn net.Conn) {
|
func (c *CommandClient) handleStatusConn(conn net.Conn) {
|
||||||
reader := std_bufio.NewReader(conn)
|
|
||||||
for {
|
for {
|
||||||
if c.options.IsMainClient {
|
|
||||||
rawEvent, err := readEvent(reader)
|
|
||||||
if err != nil {
|
|
||||||
c.handler.Disconnected(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch event := rawEvent.(type) {
|
|
||||||
case *eventOpenURL:
|
|
||||||
c.handler.OpenURL(event.URL)
|
|
||||||
continue
|
|
||||||
case nil:
|
|
||||||
default:
|
|
||||||
panic(F.ToString("unexpected event type: ", event))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var message StatusMessage
|
var message StatusMessage
|
||||||
err := binary.Read(reader, binary.BigEndian, &message)
|
err := binary.Read(conn, binary.BigEndian, &message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.handler.Disconnected(err.Error())
|
c.handler.Disconnected(err.Error())
|
||||||
return
|
return
|
||||||
|
|
|
@ -134,9 +134,6 @@ func (s *interfaceMonitorStub) RegisterCallback(callback tun.DefaultInterfaceUpd
|
||||||
func (s *interfaceMonitorStub) UnregisterCallback(element *list.Element[tun.DefaultInterfaceUpdateCallback]) {
|
func (s *interfaceMonitorStub) UnregisterCallback(element *list.Element[tun.DefaultInterfaceUpdateCallback]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *platformInterfaceStub) OpenURL(url string) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func FormatConfig(configContent string) (string, error) {
|
func FormatConfig(configContent string) (string, error) {
|
||||||
options, err := parseConfig(configContent)
|
options, err := parseConfig(configContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -25,5 +25,4 @@ type Interface interface {
|
||||||
ClearDNSCache()
|
ClearDNSCache()
|
||||||
ReadWIFIState() adapter.WIFIState
|
ReadWIFIState() adapter.WIFIState
|
||||||
process.Searcher
|
process.Searcher
|
||||||
OpenURL(url string)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,9 @@ type BoxService struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
instance *box.Box
|
instance *box.Box
|
||||||
platformInterface *platformInterfaceWrapper
|
|
||||||
pauseManager pause.Manager
|
pauseManager pause.Manager
|
||||||
urlTestHistoryStorage *urltest.HistoryStorage
|
urlTestHistoryStorage *urltest.HistoryStorage
|
||||||
|
|
||||||
servicePauseFields
|
servicePauseFields
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,6 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
instance: instance,
|
instance: instance,
|
||||||
platformInterface: platformWrapper,
|
|
||||||
urlTestHistoryStorage: urlTestHistoryStorage,
|
urlTestHistoryStorage: urlTestHistoryStorage,
|
||||||
pauseManager: service.FromContext[pause.Manager](ctx),
|
pauseManager: service.FromContext[pause.Manager](ctx),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -103,10 +102,9 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type platformInterfaceWrapper struct {
|
type platformInterfaceWrapper struct {
|
||||||
iif PlatformInterface
|
iif PlatformInterface
|
||||||
useProcFS bool
|
useProcFS bool
|
||||||
router adapter.Router
|
router adapter.Router
|
||||||
openURLFunc func(url string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *platformInterfaceWrapper) Initialize(ctx context.Context, router adapter.Router) error {
|
func (w *platformInterfaceWrapper) Initialize(ctx context.Context, router adapter.Router) error {
|
||||||
|
@ -241,9 +239,3 @@ func (w *platformInterfaceWrapper) DisableColors() bool {
|
||||||
func (w *platformInterfaceWrapper) WriteMessage(level log.Level, message string) {
|
func (w *platformInterfaceWrapper) WriteMessage(level log.Level, message string) {
|
||||||
w.iif.WriteLog(message)
|
w.iif.WriteLog(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *platformInterfaceWrapper) OpenURL(url string) {
|
|
||||||
if w.openURLFunc != nil {
|
|
||||||
w.openURLFunc(url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue