mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-21 16:11:32 +00:00
platform: Add support for tvOS
This commit is contained in:
parent
1e31d26e03
commit
b054441f34
4
Makefile
4
Makefile
|
@ -89,8 +89,8 @@ lib:
|
|||
|
||||
lib_install:
|
||||
go get -v -d
|
||||
go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.0.0-20230701084532-493ee2e45182
|
||||
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.0.0-20230701084532-493ee2e45182
|
||||
go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.0.0-20230728014906-3de089147f59
|
||||
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.0.0-20230728014906-3de089147f59
|
||||
|
||||
clean:
|
||||
rm -rf bin dist sing-box
|
||||
|
|
|
@ -107,7 +107,7 @@ func buildiOS() {
|
|||
args := []string{
|
||||
"bind",
|
||||
"-v",
|
||||
"-target", "ios,iossimulator,macos",
|
||||
"-target", "ios,iossimulator,tvos,tvossimulator,macos",
|
||||
"-libname=box",
|
||||
}
|
||||
if !debugEnabled {
|
||||
|
|
|
@ -10,10 +10,9 @@ import (
|
|||
)
|
||||
|
||||
type CommandClient struct {
|
||||
sharedDirectory string
|
||||
handler CommandClientHandler
|
||||
conn net.Conn
|
||||
options CommandClientOptions
|
||||
handler CommandClientHandler
|
||||
conn net.Conn
|
||||
options CommandClientOptions
|
||||
}
|
||||
|
||||
type CommandClientOptions struct {
|
||||
|
@ -29,25 +28,26 @@ type CommandClientHandler interface {
|
|||
WriteGroups(message OutboundGroupIterator)
|
||||
}
|
||||
|
||||
func NewStandaloneCommandClient(sharedDirectory string) *CommandClient {
|
||||
return &CommandClient{
|
||||
sharedDirectory: sharedDirectory,
|
||||
}
|
||||
func NewStandaloneCommandClient() *CommandClient {
|
||||
return new(CommandClient)
|
||||
}
|
||||
|
||||
func NewCommandClient(sharedDirectory string, handler CommandClientHandler, options *CommandClientOptions) *CommandClient {
|
||||
return &CommandClient{
|
||||
sharedDirectory: sharedDirectory,
|
||||
handler: handler,
|
||||
options: common.PtrValueOrDefault(options),
|
||||
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",
|
||||
})
|
||||
if !sTVOS {
|
||||
return net.DialUnix("unix", nil, &net.UnixAddr{
|
||||
Name: filepath.Join(sBasePath, "command.sock"),
|
||||
Net: "unix",
|
||||
})
|
||||
} else {
|
||||
return net.Dial("tcp", "127.0.0.1:8964")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommandClient) Connect() error {
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
)
|
||||
|
||||
type CommandServer struct {
|
||||
sockPath string
|
||||
listener net.Listener
|
||||
handler CommandServerHandler
|
||||
|
||||
|
@ -37,9 +36,8 @@ type CommandServerHandler interface {
|
|||
ServiceReload() error
|
||||
}
|
||||
|
||||
func NewCommandServer(sharedDirectory string, handler CommandServerHandler, maxLines int32) *CommandServer {
|
||||
func NewCommandServer(handler CommandServerHandler, maxLines int32) *CommandServer {
|
||||
server := &CommandServer{
|
||||
sockPath: filepath.Join(sharedDirectory, "command.sock"),
|
||||
handler: handler,
|
||||
savedLines: new(list.List[string]),
|
||||
maxLines: int(maxLines),
|
||||
|
@ -70,20 +68,29 @@ func (s *CommandServer) notifyURLTestUpdate() {
|
|||
}
|
||||
|
||||
func (s *CommandServer) Start() error {
|
||||
os.Remove(s.sockPath)
|
||||
if !sTVOS {
|
||||
return s.listenUNIX()
|
||||
} else {
|
||||
return s.listenTCP()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CommandServer) listenUNIX() error {
|
||||
sockPath := filepath.Join(sBasePath, "command.sock")
|
||||
os.Remove(sockPath)
|
||||
listener, err := net.ListenUnix("unix", &net.UnixAddr{
|
||||
Name: s.sockPath,
|
||||
Name: sockPath,
|
||||
Net: "unix",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return E.Cause(err, "listen")
|
||||
}
|
||||
if sUserID > 0 {
|
||||
err = os.Chown(s.sockPath, sUserID, sGroupID)
|
||||
err = os.Chown(sockPath, sUserID, sGroupID)
|
||||
if err != nil {
|
||||
listener.Close()
|
||||
os.Remove(s.sockPath)
|
||||
return err
|
||||
os.Remove(sockPath)
|
||||
return E.Cause(err, "chown")
|
||||
}
|
||||
}
|
||||
s.listener = listener
|
||||
|
@ -91,6 +98,16 @@ func (s *CommandServer) Start() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *CommandServer) listenTCP() error {
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:8964")
|
||||
if err != nil {
|
||||
return E.Cause(err, "listen")
|
||||
}
|
||||
s.listener = listener
|
||||
go s.loopConnection(listener)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *CommandServer) Close() error {
|
||||
return common.Close(
|
||||
s.listener,
|
||||
|
|
219
experimental/libbox/profile_import.go
Normal file
219
experimental/libbox/profile_import.go
Normal file
|
@ -0,0 +1,219 @@
|
|||
package libbox
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
)
|
||||
|
||||
func EncodeChunkedMessage(data []byte) []byte {
|
||||
var buffer bytes.Buffer
|
||||
binary.Write(&buffer, binary.BigEndian, uint16(len(data)))
|
||||
buffer.Write(data)
|
||||
return buffer.Bytes()
|
||||
}
|
||||
|
||||
func DecodeLengthChunk(data []byte) int32 {
|
||||
return int32(binary.BigEndian.Uint16(data))
|
||||
}
|
||||
|
||||
const (
|
||||
MessageTypeError = iota
|
||||
MessageTypeProfileList
|
||||
MessageTypeProfileContentRequest
|
||||
MessageTypeProfileContent
|
||||
)
|
||||
|
||||
type ErrorMessage struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *ErrorMessage) Encode() []byte {
|
||||
var buffer bytes.Buffer
|
||||
buffer.WriteByte(MessageTypeError)
|
||||
rw.WriteVString(&buffer, e.Message)
|
||||
return buffer.Bytes()
|
||||
}
|
||||
|
||||
func DecodeErrorMessage(data []byte) (*ErrorMessage, error) {
|
||||
reader := bytes.NewReader(data)
|
||||
messageType, err := rw.ReadByte(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if messageType != MessageTypeError {
|
||||
return nil, E.New("invalid message")
|
||||
}
|
||||
var message ErrorMessage
|
||||
message.Message, err = rw.ReadVString(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &message, nil
|
||||
}
|
||||
|
||||
const (
|
||||
ProfileTypeLocal int32 = iota
|
||||
ProfileTypeiCloud
|
||||
ProfileTypeRemote
|
||||
)
|
||||
|
||||
type ProfilePreview struct {
|
||||
ProfileID int64
|
||||
Name string
|
||||
Type int32
|
||||
}
|
||||
|
||||
type ProfilePreviewIterator interface {
|
||||
Next() *ProfilePreview
|
||||
HasNext() bool
|
||||
}
|
||||
|
||||
type ProfileEncoder struct {
|
||||
profiles []ProfilePreview
|
||||
}
|
||||
|
||||
func (e *ProfileEncoder) Append(profile *ProfilePreview) {
|
||||
e.profiles = append(e.profiles, *profile)
|
||||
}
|
||||
|
||||
func (e *ProfileEncoder) Encode() []byte {
|
||||
var buffer bytes.Buffer
|
||||
buffer.WriteByte(MessageTypeProfileList)
|
||||
binary.Write(&buffer, binary.BigEndian, uint16(len(e.profiles)))
|
||||
for _, preview := range e.profiles {
|
||||
binary.Write(&buffer, binary.BigEndian, preview.ProfileID)
|
||||
rw.WriteVString(&buffer, preview.Name)
|
||||
binary.Write(&buffer, binary.BigEndian, preview.Type)
|
||||
}
|
||||
return buffer.Bytes()
|
||||
}
|
||||
|
||||
type ProfileDecoder struct {
|
||||
profiles []*ProfilePreview
|
||||
}
|
||||
|
||||
func (d *ProfileDecoder) Decode(data []byte) error {
|
||||
reader := bytes.NewReader(data)
|
||||
messageType, err := reader.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if messageType != MessageTypeProfileList {
|
||||
return E.New("invalid message")
|
||||
}
|
||||
var profileCount uint16
|
||||
err = binary.Read(reader, binary.BigEndian, &profileCount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < int(profileCount); i++ {
|
||||
var profile ProfilePreview
|
||||
err = binary.Read(reader, binary.BigEndian, &profile.ProfileID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
profile.Name, err = rw.ReadVString(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(reader, binary.BigEndian, &profile.Type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.profiles = append(d.profiles, &profile)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *ProfileDecoder) Iterator() ProfilePreviewIterator {
|
||||
return newIterator(d.profiles)
|
||||
}
|
||||
|
||||
type ProfileContentRequest struct {
|
||||
ProfileID int64
|
||||
}
|
||||
|
||||
func (r *ProfileContentRequest) Encode() []byte {
|
||||
var buffer bytes.Buffer
|
||||
buffer.WriteByte(MessageTypeProfileContentRequest)
|
||||
binary.Write(&buffer, binary.BigEndian, r.ProfileID)
|
||||
return buffer.Bytes()
|
||||
}
|
||||
|
||||
func DecodeProfileContentRequest(data []byte) (*ProfileContentRequest, error) {
|
||||
reader := bytes.NewReader(data)
|
||||
messageType, err := rw.ReadByte(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if messageType != MessageTypeProfileContentRequest {
|
||||
return nil, E.New("invalid message")
|
||||
}
|
||||
var request ProfileContentRequest
|
||||
err = binary.Read(reader, binary.BigEndian, &request.ProfileID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &request, nil
|
||||
}
|
||||
|
||||
type ProfileContent struct {
|
||||
Name string
|
||||
Type int32
|
||||
Config string
|
||||
RemotePath string
|
||||
AutoUpdate bool
|
||||
LastUpdated int64
|
||||
}
|
||||
|
||||
func (c *ProfileContent) Encode() []byte {
|
||||
var buffer bytes.Buffer
|
||||
buffer.WriteByte(MessageTypeProfileContent)
|
||||
rw.WriteVString(&buffer, c.Name)
|
||||
binary.Write(&buffer, binary.BigEndian, c.Type)
|
||||
rw.WriteVString(&buffer, c.Config)
|
||||
rw.WriteVString(&buffer, c.RemotePath)
|
||||
binary.Write(&buffer, binary.BigEndian, c.AutoUpdate)
|
||||
binary.Write(&buffer, binary.BigEndian, c.LastUpdated)
|
||||
return buffer.Bytes()
|
||||
}
|
||||
|
||||
func DecodeProfileContent(data []byte) (*ProfileContent, error) {
|
||||
reader := bytes.NewReader(data)
|
||||
messageType, err := rw.ReadByte(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if messageType != MessageTypeProfileContent {
|
||||
return nil, E.New("invalid message")
|
||||
}
|
||||
var content ProfileContent
|
||||
content.Name, err = rw.ReadVString(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Read(reader, binary.BigEndian, &content.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content.Config, err = rw.ReadVString(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content.RemotePath, err = rw.ReadVString(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Read(reader, binary.BigEndian, &content.AutoUpdate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Read(reader, binary.BigEndian, &content.LastUpdated)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &content, nil
|
||||
}
|
|
@ -33,7 +33,7 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box
|
|||
return nil, err
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx = filemanager.WithDefault(ctx, sBasePath, sTempPath, sUserID, sGroupID)
|
||||
ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID)
|
||||
ctx = service.ContextWithPtr(ctx, urltest.NewHistoryStorage())
|
||||
instance, err := box.New(box.Options{
|
||||
Context: ctx,
|
||||
|
|
|
@ -11,21 +11,26 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
sBasePath string
|
||||
sTempPath string
|
||||
sUserID int
|
||||
sGroupID int
|
||||
sBasePath string
|
||||
sWorkingPath string
|
||||
sTempPath string
|
||||
sUserID int
|
||||
sGroupID int
|
||||
sTVOS bool
|
||||
)
|
||||
|
||||
func Setup(basePath string, tempPath string) {
|
||||
func Setup(basePath string, workingPath string, tempPath string, isTVOS bool) {
|
||||
sBasePath = basePath
|
||||
sWorkingPath = workingPath
|
||||
sTempPath = tempPath
|
||||
sUserID = os.Getuid()
|
||||
sGroupID = os.Getgid()
|
||||
sTVOS = isTVOS
|
||||
}
|
||||
|
||||
func SetupWithUsername(basePath string, tempPath string, username string) error {
|
||||
func SetupWithUsername(basePath string, workingPath string, tempPath string, username string) error {
|
||||
sBasePath = basePath
|
||||
sWorkingPath = workingPath
|
||||
sTempPath = tempPath
|
||||
sUser, err := user.Lookup(username)
|
||||
if err != nil {
|
||||
|
|
2
go.mod
2
go.mod
|
@ -21,7 +21,7 @@ require (
|
|||
github.com/oschwald/maxminddb-golang v1.11.0
|
||||
github.com/pires/go-proxyproto v0.7.0
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0
|
||||
github.com/sagernet/gomobile v0.0.0-20230701084532-493ee2e45182
|
||||
github.com/sagernet/gomobile v0.0.0-20230728014906-3de089147f59
|
||||
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2
|
||||
github.com/sagernet/quic-go v0.0.0-20230615020047-10f05c797c02
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
||||
|
|
4
go.sum
4
go.sum
|
@ -105,8 +105,8 @@ github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt
|
|||
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I=
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
|
||||
github.com/sagernet/gomobile v0.0.0-20230701084532-493ee2e45182 h1:sD5g92IO15RAX2DvA4Cq3Uc7tcgqNWVi8K3VTCI6sEo=
|
||||
github.com/sagernet/gomobile v0.0.0-20230701084532-493ee2e45182/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU=
|
||||
github.com/sagernet/gomobile v0.0.0-20230728014906-3de089147f59 h1:vN4divY6LYHcYmiTsCHNPmGZtEsEKJzh81LyvgAQfEQ=
|
||||
github.com/sagernet/gomobile v0.0.0-20230728014906-3de089147f59/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU=
|
||||
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 h1:dnkKrzapqtAwjTSWt6hdPrARORfoYvuUczynvRLrueo=
|
||||
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2/go.mod h1:1JUiV7nGuf++YFm9eWZ8q2lrwHmhcUGzptMl/vL1+LA=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
|
||||
|
|
Loading…
Reference in a new issue