2023-03-01 02:37:47 +00:00
|
|
|
package libbox
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"net"
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
"github.com/sagernet/sing/common"
|
|
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
|
|
)
|
|
|
|
|
|
|
|
type CommandClient struct {
|
2023-03-03 11:26:54 +00:00
|
|
|
sharedDirectory string
|
|
|
|
handler CommandClientHandler
|
|
|
|
conn net.Conn
|
|
|
|
options CommandClientOptions
|
2023-03-01 02:37:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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{
|
2023-03-03 11:26:54 +00:00
|
|
|
sharedDirectory: sharedDirectory,
|
|
|
|
handler: handler,
|
|
|
|
options: common.PtrValueOrDefault(options),
|
2023-03-01 02:37:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-03 11:26:54 +00:00
|
|
|
func clientConnect(sharedDirectory string) (net.Conn, error) {
|
|
|
|
return net.DialUnix("unix", nil, &net.UnixAddr{
|
|
|
|
Name: filepath.Join(sharedDirectory, "command.sock"),
|
2023-03-01 02:37:47 +00:00
|
|
|
Net: "unix",
|
|
|
|
})
|
2023-03-03 11:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CommandClient) Connect() error {
|
2023-04-04 20:38:56 +00:00
|
|
|
common.Close(c.conn)
|
2023-03-03 11:26:54 +00:00
|
|
|
conn, err := clientConnect(c.sharedDirectory)
|
2023-03-01 02:37:47 +00:00
|
|
|
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:
|
2023-03-02 08:40:28 +00:00
|
|
|
c.handler.Connected()
|
2023-03-01 02:37:47 +00:00
|
|
|
go c.handleLogConn(conn)
|
|
|
|
case CommandStatus:
|
|
|
|
err = binary.Write(conn, binary.BigEndian, c.options.StatusInterval)
|
|
|
|
if err != nil {
|
|
|
|
return E.Cause(err, "write interval")
|
|
|
|
}
|
2023-03-02 08:40:28 +00:00
|
|
|
c.handler.Connected()
|
2023-03-01 02:37:47 +00:00
|
|
|
go c.handleStatusConn(conn)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CommandClient) Disconnect() error {
|
|
|
|
return common.Close(c.conn)
|
|
|
|
}
|