Files
sing-box-extended/transport/call/config.go

159 lines
4.3 KiB
Go

package call
import (
"context"
"fmt"
"net"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/transport/call/dion"
"github.com/sagernet/sing-box/transport/call/telemost"
"github.com/sagernet/sing-box/transport/call/tunnel"
"github.com/sagernet/sing-box/transport/call/vk"
"github.com/sagernet/sing-box/transport/call/wbstream"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
N "github.com/sagernet/sing/common/network"
)
type Role int
const (
RoleCreator Role = iota
RoleJoiner
)
type Config struct {
Platform string
Mode string
JoinLink string
Cookies string
CookieString string
Email string
Password string
ReadBuffer int
Role Role
Dialer N.Dialer
DNSRouter adapter.DNSRouter
Logger logger.ContextLogger
}
func Connect(ctx context.Context, cfg Config) (*Bridge, error) {
readBuf := cfg.ReadBuffer
if readBuf <= 0 {
readBuf = 32768
}
log := cfg.Logger
if log == nil {
log = logger.NOP()
}
cookieStr := cfg.CookieString
if cookieStr == "" {
cookieStr = cfg.Cookies
}
switch cfg.Platform {
case "telemost":
switch cfg.Role {
case RoleCreator:
relay, joinLink, err := telemost.ConnectCreator(ctx, cookieStr, cfg.JoinLink, readBuf, cfg.Dialer, log)
if err != nil {
return nil, err
}
log.Notice(fmt.Sprintf("call[telemost]: join_link=%s", joinLink))
return &Bridge{relay: relay}, nil
case RoleJoiner:
tun, err := telemost.ConnectJoiner(ctx, cfg.JoinLink, "", readBuf, cfg.Dialer, cfg.DNSRouter, log)
if err != nil {
return nil, err
}
relay := tunnel.NewRelayBridge(tun, "joiner", readBuf, cfg.Dialer, log)
relay.MarkReady()
return &Bridge{relay: relay}, nil
}
case "wbstream":
switch cfg.Role {
case RoleCreator:
relay, joinLink, err := wbstream.ConnectCreator(ctx, cookieStr, cfg.JoinLink, cfg.Mode, readBuf, cfg.Dialer, log)
if err != nil {
return nil, err
}
log.Notice(fmt.Sprintf("call[wbstream]: join_link=%s", joinLink))
return &Bridge{relay: relay}, nil
case RoleJoiner:
tun, err := wbstream.ConnectJoiner(ctx, cfg.JoinLink, "", cfg.Mode, readBuf, cfg.Dialer, cfg.DNSRouter, log)
if err != nil {
return nil, err
}
relay := tunnel.NewRelayBridge(tun, "joiner", readBuf, cfg.Dialer, log)
relay.MarkReady()
return &Bridge{relay: relay}, nil
}
case "vk":
switch cfg.Role {
case RoleCreator:
relay, joinLink, err := vk.ConnectCreator(ctx, cookieStr, cfg.JoinLink, readBuf, cfg.Dialer, log)
if err != nil {
return nil, err
}
log.Notice(fmt.Sprintf("call[vk]: join_link=%s", joinLink))
return &Bridge{relay: relay}, nil
case RoleJoiner:
tun, err := vk.ConnectJoiner(ctx, cfg.JoinLink, "", readBuf, cfg.Dialer, cfg.DNSRouter, log)
if err != nil {
return nil, err
}
relay := tunnel.NewRelayBridge(tun, "joiner", readBuf, cfg.Dialer, log)
relay.MarkReady()
return &Bridge{relay: relay}, nil
}
case "dion":
switch cfg.Role {
case RoleCreator:
relay, joinLink, err := dion.ConnectCreator(ctx, cookieStr, cfg.JoinLink, cfg.Email, cfg.Password, readBuf, cfg.Dialer, log)
if err != nil {
return nil, err
}
log.Notice(fmt.Sprintf("call[dion]: join_link=%s", joinLink))
return &Bridge{relay: relay}, nil
case RoleJoiner:
tun, err := dion.ConnectJoiner(ctx, cfg.JoinLink, "", readBuf, cfg.Dialer, log)
if err != nil {
return nil, err
}
relay := tunnel.NewRelayBridge(tun, "joiner", readBuf, cfg.Dialer, log)
relay.MarkReady()
return &Bridge{relay: relay}, nil
}
}
return nil, E.New("call: unsupported platform ", cfg.Platform)
}
type Bridge struct {
relay *tunnel.RelayBridge
}
func NewBridge(relay *tunnel.RelayBridge) *Bridge {
return &Bridge{relay: relay}
}
func (b *Bridge) Close() error {
b.relay.Close()
return nil
}
func (b *Bridge) DialContext(ctx context.Context, destination string) (net.Conn, error) {
return b.relay.DialContext(ctx, destination)
}
func (b *Bridge) ListenPacket(ctx context.Context, destination string) (net.Conn, error) {
return b.relay.ListenPacket(ctx, destination)
}
func (b *Bridge) SetAcceptHandler(fn func(conn net.Conn, destination string)) {
b.relay.SetAcceptHandler(fn)
}
func (b *Bridge) SetUDPAcceptHandler(fn func(conn net.Conn, destination string)) {
b.relay.SetUDPAcceptHandler(fn)
}