mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-08-07 06:15:15 +03:00
Update sing-box core
This commit is contained in:
64
protocol/anytls/client_metadata.go
Normal file
64
protocol/anytls/client_metadata.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package anytls
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/sagernet/sing/common"
|
||||
|
||||
anytls "github.com/anytls/sing-anytls"
|
||||
"github.com/anytls/sing-anytls/session"
|
||||
)
|
||||
|
||||
const (
|
||||
commandSettings = 4
|
||||
frameHeaderSize = 7
|
||||
)
|
||||
|
||||
var (
|
||||
clientSessionField, _ = reflect.TypeFor[anytls.Client]().FieldByName("sessionClient")
|
||||
streamSessionField, _ = reflect.TypeFor[session.Stream]().FieldByName("sess")
|
||||
sessionConnLockField, _ = reflect.TypeFor[session.Session]().FieldByName("connLock")
|
||||
sessionBufferField, _ = reflect.TypeFor[session.Session]().FieldByName("buffer")
|
||||
)
|
||||
|
||||
func sessionClientOf(client *anytls.Client) *session.Client {
|
||||
return *(**session.Client)(unsafe.Add(unsafe.Pointer(client), clientSessionField.Offset))
|
||||
}
|
||||
|
||||
func (h *Outbound) rewriteClientMetadata(conn net.Conn) {
|
||||
sess := *(**session.Session)(unsafe.Add(unsafe.Pointer(conn.(*session.Stream)), streamSessionField.Offset))
|
||||
connLock := (*sync.Mutex)(unsafe.Add(unsafe.Pointer(sess), sessionConnLockField.Offset))
|
||||
bufferPointer := (*[]byte)(unsafe.Add(unsafe.Pointer(sess), sessionBufferField.Offset))
|
||||
connLock.Lock()
|
||||
defer connLock.Unlock()
|
||||
buffer := *bufferPointer
|
||||
offset := 0
|
||||
for offset+frameHeaderSize <= len(buffer) {
|
||||
dataLength := int(binary.BigEndian.Uint16(buffer[offset+5 : offset+7]))
|
||||
frameEnd := offset + frameHeaderSize + dataLength
|
||||
if frameEnd > len(buffer) {
|
||||
return
|
||||
}
|
||||
if buffer[offset] == commandSettings {
|
||||
data := []byte(strings.Join(common.Map(strings.Split(string(buffer[offset+frameHeaderSize:frameEnd]), "\n"), func(line string) string {
|
||||
if strings.HasPrefix(line, "client=") {
|
||||
return "client=" + h.clientMetadata
|
||||
}
|
||||
return line
|
||||
}), "\n"))
|
||||
newBuffer := make([]byte, 0, offset+frameHeaderSize+len(data)+len(buffer)-frameEnd)
|
||||
newBuffer = append(newBuffer, buffer[:offset+5]...)
|
||||
newBuffer = binary.BigEndian.AppendUint16(newBuffer, uint16(len(data)))
|
||||
newBuffer = append(newBuffer, data...)
|
||||
newBuffer = append(newBuffer, buffer[frameEnd:]...)
|
||||
*bufferPointer = newBuffer
|
||||
return
|
||||
}
|
||||
offset = frameEnd
|
||||
}
|
||||
}
|
||||
@@ -19,20 +19,25 @@ import (
|
||||
"github.com/sagernet/sing/common/uot"
|
||||
|
||||
anytls "github.com/anytls/sing-anytls"
|
||||
"github.com/anytls/sing-anytls/session"
|
||||
)
|
||||
|
||||
func RegisterOutbound(registry *outbound.Registry) {
|
||||
outbound.Register[option.AnyTLSOutboundOptions](registry, C.TypeAnyTLS, NewOutbound)
|
||||
}
|
||||
|
||||
var _ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
|
||||
type Outbound struct {
|
||||
outbound.Adapter
|
||||
dialer tls.Dialer
|
||||
server M.Socksaddr
|
||||
tlsConfig tls.Config
|
||||
client *anytls.Client
|
||||
uotClient *uot.Client
|
||||
logger log.ContextLogger
|
||||
dialer tls.Dialer
|
||||
server M.Socksaddr
|
||||
tlsConfig tls.Config
|
||||
clientMetadata string
|
||||
client *anytls.Client
|
||||
sessionClient *session.Client
|
||||
uotClient *uot.Client
|
||||
logger log.ContextLogger
|
||||
}
|
||||
|
||||
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.AnyTLSOutboundOptions) (adapter.Outbound, error) {
|
||||
@@ -81,14 +86,30 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound.client = client
|
||||
outbound.clientMetadata = options.ClientMetadata
|
||||
outbound.sessionClient = sessionClientOf(client)
|
||||
|
||||
outbound.uotClient = &uot.Client{
|
||||
Dialer: anytlsDialer(client.CreateProxy),
|
||||
Dialer: (anytlsDialer)(outbound.createProxy),
|
||||
Version: uot.Version,
|
||||
}
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
func (h *Outbound) createProxy(ctx context.Context, destination M.Socksaddr) (net.Conn, error) {
|
||||
conn, err := h.sessionClient.CreateStream(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h.rewriteClientMetadata(conn)
|
||||
err = M.SocksaddrSerializer.WriteAddrPort(conn, destination)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
type anytlsDialer func(ctx context.Context, destination M.Socksaddr) (net.Conn, error)
|
||||
|
||||
func (d anytlsDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
@@ -103,6 +124,10 @@ func (h *Outbound) dialOut(ctx context.Context) (net.Conn, error) {
|
||||
return h.dialer.DialTLSContext(ctx, h.server)
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
ctx, metadata := adapter.ExtendContext(ctx)
|
||||
metadata.Outbound = h.Tag()
|
||||
@@ -110,7 +135,7 @@ func (h *Outbound) DialContext(ctx context.Context, network string, destination
|
||||
switch N.NetworkName(network) {
|
||||
case N.NetworkTCP:
|
||||
h.logger.InfoContext(ctx, "outbound connection to ", destination)
|
||||
return h.client.CreateProxy(ctx, destination)
|
||||
return h.createProxy(ctx, destination)
|
||||
case N.NetworkUDP:
|
||||
h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
|
||||
return h.uotClient.DialContext(ctx, network, destination)
|
||||
|
||||
@@ -108,7 +108,10 @@ func (h *Outbound) fetchMyAddresses() {
|
||||
func (h *Outbound) isMyLoopbackAddress(addresses ...netip.Addr) bool {
|
||||
for _, prefix := range h.myAddresses.Load() {
|
||||
for _, address := range addresses {
|
||||
if prefix.Addr() != address && prefix.Contains(address) {
|
||||
if !C.IsDarwin && prefix.Addr() == address {
|
||||
continue
|
||||
}
|
||||
if prefix.Contains(address) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ func (n *Inbound) newConnection(ctx context.Context, waitForClose bool, conn net
|
||||
} else {
|
||||
done := make(chan struct{})
|
||||
wrapper := v2rayhttp.NewHTTP2Wrapper(conn)
|
||||
n.router.RouteConnectionEx(ctx, conn, metadata, N.OnceClose(func(it error) {
|
||||
n.router.RouteConnectionEx(ctx, wrapper, metadata, N.OnceClose(func(it error) {
|
||||
close(done)
|
||||
}))
|
||||
<-done
|
||||
|
||||
@@ -26,6 +26,8 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
outbound.Register[option.ShadowsocksOutboundOptions](registry, C.TypeShadowsocks, NewOutbound)
|
||||
}
|
||||
|
||||
var _ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
|
||||
type Outbound struct {
|
||||
outbound.Adapter
|
||||
logger logger.ContextLogger
|
||||
@@ -124,6 +126,10 @@ func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (n
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return h.multiplexDialer != nil
|
||||
}
|
||||
|
||||
func (h *Outbound) InterfaceUpdated() {
|
||||
if h.multiplexDialer != nil {
|
||||
h.multiplexDialer.Reset()
|
||||
|
||||
@@ -103,7 +103,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
for _, hostKey := range options.HostKey {
|
||||
key, _, _, _, err := ssh.ParseAuthorizedKey([]byte(hostKey))
|
||||
if err != nil {
|
||||
return nil, E.New("parse host key ", key)
|
||||
return nil, E.Cause(err, "parse host key: ", hostKey)
|
||||
}
|
||||
outbound.hostKey = append(outbound.hostKey, key)
|
||||
}
|
||||
|
||||
@@ -161,8 +161,9 @@ func (t *DNSTransport) updateDNSServers(routeConfig *router.Config, dnsConfig *n
|
||||
|
||||
func (t *DNSTransport) createResolver(directDialer func() N.Dialer, resolver *dnstype.Resolver) (adapter.DNSTransport, error) {
|
||||
serverURL, parseURLErr := url.Parse(resolver.Addr)
|
||||
isHTTPScheme := parseURLErr == nil && (serverURL.Scheme == "http" || serverURL.Scheme == "https")
|
||||
var myDialer N.Dialer
|
||||
if parseURLErr == nil && serverURL.Scheme == "http" {
|
||||
if isHTTPScheme && serverURL.Scheme == "http" {
|
||||
myDialer = t.endpoint
|
||||
} else {
|
||||
myDialer = directDialer()
|
||||
@@ -170,36 +171,39 @@ func (t *DNSTransport) createResolver(directDialer func() N.Dialer, resolver *dn
|
||||
if len(resolver.BootstrapResolution) > 0 {
|
||||
bootstrapTransport := transport.NewUDPRaw(t.logger, t.TransportAdapter, myDialer, M.SocksaddrFrom(resolver.BootstrapResolution[0], 53))
|
||||
myDialer = dialer.NewResolveDialer(t.ctx, myDialer, false, "", adapter.DNSQueryOptions{Transport: bootstrapTransport}, 0)
|
||||
}
|
||||
if serverAddr := M.ParseSocksaddr(resolver.Addr); serverAddr.IsValid() {
|
||||
if serverAddr.Port == 0 {
|
||||
serverAddr.Port = 53
|
||||
}
|
||||
return transport.NewUDPRaw(t.logger, t.TransportAdapter, myDialer, serverAddr), nil
|
||||
} else if parseURLErr != nil {
|
||||
return nil, E.Cause(parseURLErr, "parse resolver address")
|
||||
} else {
|
||||
myDialer = dialer.NewResolveDialer(t.ctx, myDialer, false, "", t.endpoint.queryOptions, 0)
|
||||
}
|
||||
if isHTTPScheme {
|
||||
serverAddr := M.ParseSocksaddrHostPortStr(serverURL.Hostname(), serverURL.Port())
|
||||
switch serverURL.Scheme {
|
||||
case "https":
|
||||
serverAddr = M.ParseSocksaddrHostPortStr(serverURL.Hostname(), serverURL.Port())
|
||||
if serverAddr.Port == 0 {
|
||||
serverAddr.Port = 443
|
||||
}
|
||||
tlsConfig := common.Must1(tls.NewClient(t.ctx, t.logger, serverAddr.AddrString(), option.OutboundTLSOptions{
|
||||
ALPN: []string{http2.NextProtoTLS, "http/1.1"},
|
||||
Enabled: true,
|
||||
ALPN: []string{http2.NextProtoTLS, "http/1.1"},
|
||||
}))
|
||||
return transport.NewHTTPSRaw(t.TransportAdapter, t.logger, myDialer, serverURL, http.Header{}, serverAddr, tlsConfig), nil
|
||||
case "http":
|
||||
serverAddr = M.ParseSocksaddrHostPortStr(serverURL.Hostname(), serverURL.Port())
|
||||
if serverAddr.Port == 0 {
|
||||
serverAddr.Port = 80
|
||||
}
|
||||
return transport.NewHTTPSRaw(t.TransportAdapter, t.logger, myDialer, serverURL, http.Header{}, serverAddr, nil), nil
|
||||
// case "tls":
|
||||
default:
|
||||
return nil, E.New("unknown resolver scheme: ", serverURL.Scheme)
|
||||
}
|
||||
}
|
||||
serverAddr := M.ParseSocksaddr(resolver.Addr)
|
||||
if !serverAddr.IsValid() {
|
||||
if parseURLErr != nil {
|
||||
return nil, E.Cause(parseURLErr, "parse resolver address")
|
||||
}
|
||||
return nil, E.New("invalid resolver address: ", resolver.Addr)
|
||||
}
|
||||
if serverAddr.Port == 0 {
|
||||
serverAddr.Port = 53
|
||||
}
|
||||
return transport.NewUDPRaw(t.logger, t.TransportAdapter, myDialer, serverAddr), nil
|
||||
}
|
||||
|
||||
func buildRoutePrefixes(routeConfig *router.Config) []netip.Prefix {
|
||||
@@ -279,7 +283,7 @@ func (t *DNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.M
|
||||
}
|
||||
}
|
||||
for domainSuffix, transports := range routes {
|
||||
if strings.HasSuffix(question.Name, domainSuffix) {
|
||||
if mDNS.IsSubDomain(domainSuffix, question.Name) {
|
||||
if len(transports) == 0 {
|
||||
return &mDNS.Msg{
|
||||
MsgHdr: mDNS.MsgHdr{
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -71,7 +70,7 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
version.SetVersion(tailscaleroot.VersionDotTxt + " (sing-box " + C.Version + ")")
|
||||
version.SetVersion(strings.TrimSpace(tailscaleroot.VersionDotTxt) + "-0-(sing-box " + C.Version + ")")
|
||||
}
|
||||
|
||||
func RegisterEndpoint(registry *endpoint.Registry) {
|
||||
@@ -83,6 +82,7 @@ type Endpoint struct {
|
||||
ctx context.Context
|
||||
router adapter.Router
|
||||
logger logger.ContextLogger
|
||||
queryOptions adapter.DNSQueryOptions
|
||||
dnsRouter adapter.DNSRouter
|
||||
network adapter.NetworkManager
|
||||
platformInterface adapter.PlatformInterface
|
||||
@@ -93,6 +93,7 @@ type Endpoint struct {
|
||||
onReconfigHook wgengine.ReconfigListener
|
||||
|
||||
cfg *wgcfg.Config
|
||||
routerCfg *router.Config
|
||||
dnsCfg *tsDNS.Config
|
||||
routeDomains common.TypedValue[map[string]bool]
|
||||
routePrefixes atomic.Pointer[netipx.IPSet]
|
||||
@@ -188,27 +189,17 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
} else {
|
||||
udpTimeout = C.UDPTimeout
|
||||
}
|
||||
var remoteIsDomain bool
|
||||
if options.ControlURL != "" {
|
||||
controlURL, err := url.Parse(options.ControlURL)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "parse control URL")
|
||||
}
|
||||
remoteIsDomain = M.ParseSocksaddr(controlURL.Hostname()).IsDomain()
|
||||
} else {
|
||||
// controlplane.tailscale.com
|
||||
remoteIsDomain = true
|
||||
}
|
||||
outboundDialer, err := dialer.NewWithOptions(dialer.Options{
|
||||
Context: ctx,
|
||||
Options: options.DialerOptions,
|
||||
RemoteIsDomain: remoteIsDomain,
|
||||
RemoteIsDomain: true,
|
||||
ResolverOnDetour: true,
|
||||
NewDialer: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dialerQueryOptions := outboundDialer.(dialer.ResolveDialer).QueryOptions()
|
||||
dnsRouter := service.FromContext[adapter.DNSRouter](ctx)
|
||||
server := &tsnet.Server{
|
||||
Dir: stateDirectory,
|
||||
@@ -225,7 +216,7 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
AdvertiseTags: options.AdvertiseTags,
|
||||
Dialer: &endpointDialer{Dialer: outboundDialer, logger: logger},
|
||||
LookupHook: func(ctx context.Context, host string) ([]netip.Addr, error) {
|
||||
return dnsRouter.Lookup(ctx, host, outboundDialer.(dialer.ResolveDialer).QueryOptions())
|
||||
return dnsRouter.Lookup(ctx, host, dialerQueryOptions)
|
||||
},
|
||||
DNS: &dnsConfigurtor{},
|
||||
HTTPClient: &http.Client{
|
||||
@@ -242,10 +233,11 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
},
|
||||
}
|
||||
return &Endpoint{
|
||||
Adapter: endpoint.NewAdapter(C.TypeTailscale, tag, []string{N.NetworkTCP, N.NetworkUDP, N.NetworkICMP}, nil),
|
||||
Adapter: endpoint.NewAdapterWithDialerOptions(C.TypeTailscale, tag, []string{N.NetworkTCP, N.NetworkUDP, N.NetworkICMP}, options.DialerOptions),
|
||||
ctx: ctx,
|
||||
router: router,
|
||||
logger: logger,
|
||||
queryOptions: dialerQueryOptions,
|
||||
dnsRouter: dnsRouter,
|
||||
network: service.FromContext[adapter.NetworkManager](ctx),
|
||||
platformInterface: service.FromContext[adapter.PlatformInterface](ctx),
|
||||
@@ -704,12 +696,17 @@ func (t *Endpoint) NewConnectionEx(ctx context.Context, conn net.Conn, source M.
|
||||
metadata.Inbound = t.Tag()
|
||||
metadata.InboundType = t.Type()
|
||||
metadata.Source = source
|
||||
addr4, addr6 := t.server.TailscaleIPs()
|
||||
switch destination.Addr {
|
||||
case addr4:
|
||||
destination.Addr = netip.AddrFrom4([4]uint8{127, 0, 0, 1})
|
||||
case addr6:
|
||||
destination.Addr = netip.IPv6Loopback()
|
||||
destinationAddress := tsaddr.UnmapVia(destination.Addr)
|
||||
if destinationAddress != destination.Addr {
|
||||
destination.Addr = destinationAddress
|
||||
} else {
|
||||
addr4, addr6 := t.server.TailscaleIPs()
|
||||
switch destination.Addr {
|
||||
case addr4:
|
||||
destination.Addr = netip.AddrFrom4([4]uint8{127, 0, 0, 1})
|
||||
case addr6:
|
||||
destination.Addr = netip.IPv6Loopback()
|
||||
}
|
||||
}
|
||||
metadata.Destination = destination
|
||||
t.logger.InfoContext(ctx, "inbound connection from ", source)
|
||||
@@ -722,16 +719,22 @@ func (t *Endpoint) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
|
||||
metadata.Inbound = t.Tag()
|
||||
metadata.InboundType = t.Type()
|
||||
metadata.Source = source
|
||||
addr4, addr6 := t.server.TailscaleIPs()
|
||||
switch destination.Addr {
|
||||
case addr4:
|
||||
metadata.OriginDestination = destination
|
||||
destination.Addr = netip.AddrFrom4([4]uint8{127, 0, 0, 1})
|
||||
conn = bufio.NewNATPacketConn(bufio.NewNetPacketConn(conn), metadata.OriginDestination, destination)
|
||||
case addr6:
|
||||
metadata.OriginDestination = destination
|
||||
destination.Addr = netip.IPv6Loopback()
|
||||
conn = bufio.NewNATPacketConn(bufio.NewNetPacketConn(conn), metadata.OriginDestination, destination)
|
||||
originDestination := destination
|
||||
destinationAddress := tsaddr.UnmapVia(destination.Addr)
|
||||
if destinationAddress != destination.Addr {
|
||||
destination.Addr = destinationAddress
|
||||
} else {
|
||||
addr4, addr6 := t.server.TailscaleIPs()
|
||||
switch destination.Addr {
|
||||
case addr4:
|
||||
destination.Addr = netip.AddrFrom4([4]uint8{127, 0, 0, 1})
|
||||
case addr6:
|
||||
destination.Addr = netip.IPv6Loopback()
|
||||
}
|
||||
}
|
||||
if destination != originDestination {
|
||||
metadata.OriginDestination = originDestination
|
||||
conn = bufio.NewNATPacketConn(bufio.NewNetPacketConn(conn), originDestination, destination)
|
||||
}
|
||||
metadata.Destination = destination
|
||||
t.logger.InfoContext(ctx, "inbound packet connection from ", source)
|
||||
@@ -797,7 +800,9 @@ func (t *Endpoint) onReconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCf
|
||||
if cfg == nil || dnsCfg == nil {
|
||||
return
|
||||
}
|
||||
if (t.cfg != nil && reflect.DeepEqual(t.cfg, cfg)) && (t.dnsCfg != nil && reflect.DeepEqual(t.dnsCfg, dnsCfg)) {
|
||||
if t.cfg != nil && reflect.DeepEqual(t.cfg, cfg) &&
|
||||
t.routerCfg != nil && reflect.DeepEqual(t.routerCfg, routerCfg) &&
|
||||
t.dnsCfg != nil && reflect.DeepEqual(t.dnsCfg, dnsCfg) {
|
||||
return
|
||||
}
|
||||
var inet4Address, inet6Address netip.Addr
|
||||
@@ -810,6 +815,7 @@ func (t *Endpoint) onReconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCf
|
||||
}
|
||||
t.icmpForwarder.SetLocalAddresses(inet4Address, inet6Address)
|
||||
t.cfg = cfg
|
||||
t.routerCfg = routerCfg
|
||||
t.dnsCfg = dnsCfg
|
||||
|
||||
routeDomains := make(map[string]bool)
|
||||
|
||||
@@ -11,6 +11,9 @@ import (
|
||||
singTun "github.com/sagernet/sing-tun"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
wgTun "github.com/sagernet/wireguard-go/tun"
|
||||
|
||||
"github.com/dblohm7/wingoes/com"
|
||||
"golang.org/x/sys/windows/svc"
|
||||
)
|
||||
|
||||
type tunDeviceAdapter struct {
|
||||
@@ -21,7 +24,23 @@ type tunDeviceAdapter struct {
|
||||
closeOnce sync.Once
|
||||
}
|
||||
|
||||
func newTunDeviceAdapter(tun singTun.Tun, mtu int, _ logger.ContextLogger) (wgTun.Device, error) {
|
||||
var comRuntimeOnce sync.Once
|
||||
|
||||
func newTunDeviceAdapter(tun singTun.Tun, mtu int, contextLogger logger.ContextLogger) (wgTun.Device, error) {
|
||||
// wgengine/router/osrouter/ifconfig_windows.go setPrivateNetwork assumes COM
|
||||
// is initialized process-wide, which upstream performs only in tailscaled's
|
||||
// main package; library consumers must do it themselves.
|
||||
comRuntimeOnce.Do(func() {
|
||||
processType := com.ConsoleApp
|
||||
isService, serviceErr := svc.IsWindowsService()
|
||||
if serviceErr == nil && isService {
|
||||
processType = com.Service
|
||||
}
|
||||
err := com.StartRuntime(processType)
|
||||
if err != nil {
|
||||
contextLogger.Warn("initialize COM runtime: ", err)
|
||||
}
|
||||
})
|
||||
winTun, ok := tun.(singTun.WinTun)
|
||||
if !ok {
|
||||
return nil, errors.New("not a windows tun device")
|
||||
|
||||
@@ -26,6 +26,8 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
outbound.Register[option.TrojanOutboundOptions](registry, C.TypeTrojan, NewOutbound)
|
||||
}
|
||||
|
||||
var _ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
|
||||
type Outbound struct {
|
||||
outbound.Adapter
|
||||
logger logger.ContextLogger
|
||||
@@ -107,6 +109,10 @@ func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (n
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return h.multiplexDialer != nil
|
||||
}
|
||||
|
||||
func (h *Outbound) InterfaceUpdated() {
|
||||
if h.transport != nil {
|
||||
h.transport.Close()
|
||||
|
||||
@@ -198,6 +198,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
IncludePackage: options.IncludePackage,
|
||||
ExcludePackage: options.ExcludePackage,
|
||||
InterfaceMonitor: networkManager.InterfaceMonitor(),
|
||||
Logger: logger,
|
||||
EXP_MultiPendingPackets: multiPendingPackets,
|
||||
},
|
||||
udpTimeout: udpTimeout,
|
||||
|
||||
@@ -33,6 +33,8 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
outbound.Register[option.VLESSOutboundOptions](registry, C.TypeVLESS, NewOutbound)
|
||||
}
|
||||
|
||||
var _ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
|
||||
type Outbound struct {
|
||||
outbound.Adapter
|
||||
logger logger.ContextLogger
|
||||
@@ -152,6 +154,10 @@ func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (n
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return h.multiplexDialer != nil
|
||||
}
|
||||
|
||||
func (h *Outbound) InterfaceUpdated() {
|
||||
if h.transport != nil {
|
||||
h.transport.Close()
|
||||
|
||||
@@ -27,6 +27,8 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
outbound.Register[option.VMessOutboundOptions](registry, C.TypeVMess, NewOutbound)
|
||||
}
|
||||
|
||||
var _ adapter.OutboundWithMultiplex = (*Outbound)(nil)
|
||||
|
||||
type Outbound struct {
|
||||
outbound.Adapter
|
||||
logger logger.ContextLogger
|
||||
@@ -105,6 +107,10 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
func (h *Outbound) MultiplexEnabled() bool {
|
||||
return h.multiplexDialer != nil
|
||||
}
|
||||
|
||||
func (h *Outbound) InterfaceUpdated() {
|
||||
if h.transport != nil {
|
||||
h.transport.Close()
|
||||
|
||||
Reference in New Issue
Block a user