mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-08-07 14:25:17 +03:00
159 lines
4.3 KiB
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)
|
|
}
|