mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-07-23 15:53:28 +03:00
Fix tailscale crash at start
This commit is contained in:
@@ -111,6 +111,7 @@ type Endpoint struct {
|
|||||||
systemInterfaceName string
|
systemInterfaceName string
|
||||||
systemInterfaceMTU uint32
|
systemInterfaceMTU uint32
|
||||||
serverStarted bool
|
serverStarted bool
|
||||||
|
started atomic.Bool
|
||||||
systemTun tun.Tun
|
systemTun tun.Tun
|
||||||
systemDialer *dialer.DefaultDialer
|
systemDialer *dialer.DefaultDialer
|
||||||
fallbackTCPCloser func()
|
fallbackTCPCloser func()
|
||||||
@@ -422,6 +423,7 @@ func (t *Endpoint) postStart() error {
|
|||||||
}
|
}
|
||||||
t.filter = localBackend.ExportFilter()
|
t.filter = localBackend.ExportFilter()
|
||||||
go t.watchState()
|
go t.watchState()
|
||||||
|
t.started.Store(true)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,6 +487,7 @@ func (t *Endpoint) watchState() {
|
|||||||
|
|
||||||
func (t *Endpoint) Close() error {
|
func (t *Endpoint) Close() error {
|
||||||
var err error
|
var err error
|
||||||
|
t.started.Store(false)
|
||||||
if t.serverStarted {
|
if t.serverStarted {
|
||||||
err = common.Close(common.PtrOrNil(t.server))
|
err = common.Close(common.PtrOrNil(t.server))
|
||||||
t.serverStarted = false
|
t.serverStarted = false
|
||||||
@@ -509,6 +512,9 @@ func (t *Endpoint) DialContext(ctx context.Context, network string, destination
|
|||||||
case N.NetworkUDP:
|
case N.NetworkUDP:
|
||||||
t.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
t.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||||
}
|
}
|
||||||
|
if !t.started.Load() {
|
||||||
|
return nil, E.New("Tailscale is not ready yet")
|
||||||
|
}
|
||||||
if destination.IsDomain() {
|
if destination.IsDomain() {
|
||||||
destinationAddresses, err := t.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
|
destinationAddresses, err := t.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -565,6 +571,9 @@ func (t *Endpoint) DialContext(ctx context.Context, network string, destination
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Endpoint) listenPacketWithAddress(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
func (t *Endpoint) listenPacketWithAddress(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||||
|
if !t.started.Load() {
|
||||||
|
return nil, E.New("Tailscale is not ready yet")
|
||||||
|
}
|
||||||
if t.systemDialer != nil {
|
if t.systemDialer != nil {
|
||||||
return t.systemDialer.ListenPacket(ctx, destination)
|
return t.systemDialer.ListenPacket(ctx, destination)
|
||||||
}
|
}
|
||||||
@@ -632,6 +641,9 @@ func (t *Endpoint) ListenPacket(ctx context.Context, destination M.Socksaddr) (n
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Endpoint) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
|
func (t *Endpoint) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
|
||||||
|
if !t.started.Load() {
|
||||||
|
return nil, E.New("Tailscale is not ready yet")
|
||||||
|
}
|
||||||
tsFilter := t.filter.Load()
|
tsFilter := t.filter.Load()
|
||||||
if tsFilter != nil {
|
if tsFilter != nil {
|
||||||
var ipProto ipproto.Proto
|
var ipProto ipproto.Proto
|
||||||
@@ -725,6 +737,9 @@ func (t *Endpoint) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Endpoint) NewDirectRouteConnection(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
|
func (t *Endpoint) NewDirectRouteConnection(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
|
||||||
|
if !t.started.Load() {
|
||||||
|
return nil, E.New("Tailscale is not ready yet")
|
||||||
|
}
|
||||||
ctx := log.ContextWithNewID(t.ctx)
|
ctx := log.ContextWithNewID(t.ctx)
|
||||||
var destination tun.DirectRouteDestination
|
var destination tun.DirectRouteDestination
|
||||||
var err error
|
var err error
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
@@ -41,6 +42,7 @@ type Endpoint struct {
|
|||||||
logger logger.ContextLogger
|
logger logger.ContextLogger
|
||||||
localAddresses []netip.Prefix
|
localAddresses []netip.Prefix
|
||||||
endpoint *wireguard.Endpoint
|
endpoint *wireguard.Endpoint
|
||||||
|
started atomic.Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WireGuardEndpointOptions) (adapter.Endpoint, error) {
|
func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WireGuardEndpointOptions) (adapter.Endpoint, error) {
|
||||||
@@ -120,16 +122,24 @@ func (w *Endpoint) Start(stage adapter.StartStage) error {
|
|||||||
case adapter.StartStateStart:
|
case adapter.StartStateStart:
|
||||||
return w.endpoint.Start(false)
|
return w.endpoint.Start(false)
|
||||||
case adapter.StartStatePostStart:
|
case adapter.StartStatePostStart:
|
||||||
return w.endpoint.Start(true)
|
err := w.endpoint.Start(true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.started.Store(true)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Endpoint) Close() error {
|
func (w *Endpoint) Close() error {
|
||||||
|
w.started.Store(false)
|
||||||
return w.endpoint.Close()
|
return w.endpoint.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Endpoint) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
|
func (w *Endpoint) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
|
||||||
|
if !w.started.Load() {
|
||||||
|
return nil, E.New("WireGuard is not ready yet")
|
||||||
|
}
|
||||||
var ipVersion uint8
|
var ipVersion uint8
|
||||||
if !destination.IsIPv6() {
|
if !destination.IsIPv6() {
|
||||||
ipVersion = 4
|
ipVersion = 4
|
||||||
@@ -210,6 +220,9 @@ func (w *Endpoint) DialContext(ctx context.Context, network string, destination
|
|||||||
case N.NetworkUDP:
|
case N.NetworkUDP:
|
||||||
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||||
}
|
}
|
||||||
|
if !w.started.Load() {
|
||||||
|
return nil, E.New("WireGuard is not ready yet")
|
||||||
|
}
|
||||||
if destination.IsDomain() {
|
if destination.IsDomain() {
|
||||||
destinationAddresses, err := w.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
|
destinationAddresses, err := w.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -224,6 +237,9 @@ func (w *Endpoint) DialContext(ctx context.Context, network string, destination
|
|||||||
|
|
||||||
func (w *Endpoint) ListenPacketWithDestination(ctx context.Context, destination M.Socksaddr) (net.PacketConn, netip.Addr, error) {
|
func (w *Endpoint) ListenPacketWithDestination(ctx context.Context, destination M.Socksaddr) (net.PacketConn, netip.Addr, error) {
|
||||||
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||||
|
if !w.started.Load() {
|
||||||
|
return nil, netip.Addr{}, E.New("WireGuard is not ready yet")
|
||||||
|
}
|
||||||
if destination.IsDomain() {
|
if destination.IsDomain() {
|
||||||
destinationAddresses, err := w.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
|
destinationAddresses, err := w.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -257,9 +273,15 @@ func (w *Endpoint) PreferredDomain(domain string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Endpoint) PreferredAddress(address netip.Addr) bool {
|
func (w *Endpoint) PreferredAddress(address netip.Addr) bool {
|
||||||
|
if !w.started.Load() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return w.endpoint.Lookup(address) != nil
|
return w.endpoint.Lookup(address) != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Endpoint) NewDirectRouteConnection(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
|
func (w *Endpoint) NewDirectRouteConnection(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
|
||||||
|
if !w.started.Load() {
|
||||||
|
return nil, E.New("WireGuard is not ready yet")
|
||||||
|
}
|
||||||
return w.endpoint.NewDirectRouteConnection(metadata, routeContext, timeout)
|
return w.endpoint.NewDirectRouteConnection(metadata, routeContext, timeout)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user