mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-16 11:32:21 +08:00
89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
package libbox
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"net"
|
|
"path/filepath"
|
|
|
|
"github.com/sagernet/sing/common"
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
)
|
|
|
|
type CommandClient struct {
|
|
sharedDirectory 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)
|
|
WriteGroups(message OutboundGroupIterator)
|
|
}
|
|
|
|
func NewStandaloneCommandClient(sharedDirectory string) *CommandClient {
|
|
return &CommandClient{
|
|
sharedDirectory: sharedDirectory,
|
|
}
|
|
}
|
|
|
|
func NewCommandClient(sharedDirectory string, handler CommandClientHandler, options *CommandClientOptions) *CommandClient {
|
|
return &CommandClient{
|
|
sharedDirectory: sharedDirectory,
|
|
handler: handler,
|
|
options: common.PtrValueOrDefault(options),
|
|
}
|
|
}
|
|
|
|
func (c *CommandClient) directConnect() (net.Conn, error) {
|
|
return net.DialUnix("unix", nil, &net.UnixAddr{
|
|
Name: filepath.Join(c.sharedDirectory, "command.sock"),
|
|
Net: "unix",
|
|
})
|
|
}
|
|
|
|
func (c *CommandClient) Connect() error {
|
|
common.Close(c.conn)
|
|
conn, err := c.directConnect()
|
|
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:
|
|
c.handler.Connected()
|
|
go c.handleLogConn(conn)
|
|
case CommandStatus:
|
|
err = binary.Write(conn, binary.BigEndian, c.options.StatusInterval)
|
|
if err != nil {
|
|
return E.Cause(err, "write interval")
|
|
}
|
|
c.handler.Connected()
|
|
go c.handleStatusConn(conn)
|
|
case CommandGroup:
|
|
err = binary.Write(conn, binary.BigEndian, c.options.StatusInterval)
|
|
if err != nil {
|
|
return E.Cause(err, "write interval")
|
|
}
|
|
c.handler.Connected()
|
|
go c.handleGroupConn(conn)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *CommandClient) Disconnect() error {
|
|
return common.Close(c.conn)
|
|
}
|