mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-08-26 03:57:36 +08:00
Compare commits
87 Commits
4d24b7198d
...
68386928b7
Author | SHA1 | Date | |
---|---|---|---|
![]() |
68386928b7 | ||
![]() |
7c62db5dbd | ||
![]() |
631abda983 | ||
![]() |
c6553b9579 | ||
![]() |
80013ab822 | ||
![]() |
f4eb5d1d37 | ||
![]() |
bac004a7db | ||
![]() |
1f6d91afac | ||
![]() |
5c90562ab4 | ||
![]() |
5e7bee2344 | ||
![]() |
88ad93ec68 | ||
![]() |
c5d056dccc | ||
![]() |
a5f0975f16 | ||
![]() |
12f708fc1b | ||
![]() |
ed2d228766 | ||
![]() |
2666d2422d | ||
![]() |
2d3cbcf3a6 | ||
![]() |
dc3a7dfff6 | ||
![]() |
ceff797cde | ||
![]() |
4bdda8e37c | ||
![]() |
02b4b87a2b | ||
![]() |
b3620d76a7 | ||
![]() |
e8a2c95f1c | ||
![]() |
b562536258 | ||
![]() |
768aa8fb4d | ||
![]() |
f44ed1c5f6 | ||
![]() |
b661886be9 | ||
![]() |
6f3ba8f895 | ||
![]() |
67736a27be | ||
![]() |
7e3ee707f8 | ||
![]() |
628e76098c | ||
![]() |
efb29260f3 | ||
![]() |
93bba2c835 | ||
![]() |
080e94c136 | ||
![]() |
a042a31fed | ||
![]() |
2ff596d1a2 | ||
![]() |
8a3f44f911 | ||
![]() |
69def3ca9c | ||
![]() |
908055c425 | ||
![]() |
510bc15f56 | ||
![]() |
8a8376b723 | ||
![]() |
890e48f892 | ||
![]() |
1ab3541973 | ||
![]() |
1e6f22d4a7 | ||
![]() |
035f8bae99 | ||
![]() |
cddb987365 | ||
![]() |
d4697de3a0 | ||
![]() |
9650bfd628 | ||
![]() |
78899b6a96 | ||
![]() |
2822d1c4a2 | ||
![]() |
e6a974f879 | ||
![]() |
2736dc1531 | ||
![]() |
5fde4b5be9 | ||
![]() |
3051698f69 | ||
![]() |
bd87fd7cdd | ||
![]() |
aa56698987 | ||
![]() |
4fef6a9845 | ||
![]() |
f3ebc3f532 | ||
![]() |
ee3069b83e | ||
![]() |
ba176cbf73 | ||
![]() |
c91b6cdf58 | ||
![]() |
49e4d3d5f5 | ||
![]() |
7d012c2c40 | ||
![]() |
4fed223ad9 | ||
![]() |
1e6fb9ac23 | ||
![]() |
c077840ba8 | ||
![]() |
7e1125d3a6 | ||
![]() |
1e02ad27e2 | ||
![]() |
eeeaf942e8 | ||
![]() |
fad6402a33 | ||
![]() |
9007333163 | ||
![]() |
f1343b8e2d | ||
![]() |
23786f4fc6 | ||
![]() |
56771b5341 | ||
![]() |
753048fec6 | ||
![]() |
389b7b1015 | ||
![]() |
f7edf03836 | ||
![]() |
d8b2d5142f | ||
![]() |
134802d1ee | ||
![]() |
e5e81b4de1 | ||
![]() |
300c961efa | ||
![]() |
7c7f512405 | ||
![]() |
03e8d029c2 | ||
![]() |
787b5f1931 | ||
![]() |
56a7624618 | ||
![]() |
3a84acf122 | ||
![]() |
f600e02e47 |
@ -341,6 +341,16 @@ func (d *DefaultDialer) ListenSerialInterfacePacket(ctx context.Context, destina
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DefaultDialer) ListenPacketCompat(network, address string) (net.PacketConn, error) {
|
func (d *DefaultDialer) ListenPacketCompat(network, address string) (net.PacketConn, error) {
|
||||||
|
udpListener := d.udpListener
|
||||||
|
udpListener.Control = control.Append(udpListener.Control, func(network, address string, conn syscall.RawConn) error {
|
||||||
|
for _, wgControlFn := range WgControlFns {
|
||||||
|
err := wgControlFn(network, address, conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
return d.udpListener.ListenPacket(context.Background(), network, address)
|
return d.udpListener.ListenPacket(context.Background(), network, address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,13 +268,10 @@ func (c *Client) Lookup(ctx context.Context, transport adapter.DNSTransport, dom
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
err := group.Run(ctx)
|
err := group.Run(ctx)
|
||||||
if len(response4) > 0 || len(response6) > 0 {
|
if len(response4) == 0 && len(response6) == 0 {
|
||||||
return sortAddresses(response4, response6, options.Strategy), nil
|
|
||||||
} else if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
|
||||||
return nil, RcodeError(dns.RcodeNameError)
|
|
||||||
}
|
}
|
||||||
|
return sortAddresses(response4, response6, options.Strategy), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ClearCache() {
|
func (c *Client) ClearCache() {
|
||||||
|
@ -323,6 +323,9 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
printResult := func() {
|
printResult := func() {
|
||||||
|
if err == nil && len(responseAddrs) == 0 {
|
||||||
|
err = E.New("empty result")
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, ErrResponseRejectedCached) {
|
if errors.Is(err, ErrResponseRejectedCached) {
|
||||||
r.logger.DebugContext(ctx, "response rejected for ", domain, " (cached)")
|
r.logger.DebugContext(ctx, "response rejected for ", domain, " (cached)")
|
||||||
@ -331,14 +334,15 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ
|
|||||||
} else {
|
} else {
|
||||||
r.logger.ErrorContext(ctx, E.Cause(err, "lookup failed for ", domain))
|
r.logger.ErrorContext(ctx, E.Cause(err, "lookup failed for ", domain))
|
||||||
}
|
}
|
||||||
} else if len(responseAddrs) == 0 {
|
}
|
||||||
panic("unexpected empty result")
|
if err != nil {
|
||||||
|
err = E.Cause(err, "lookup ", domain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
responseAddrs, cached = r.client.LookupCache(domain, options.Strategy)
|
responseAddrs, cached = r.client.LookupCache(domain, options.Strategy)
|
||||||
if cached {
|
if cached {
|
||||||
if len(responseAddrs) == 0 {
|
if len(responseAddrs) == 0 {
|
||||||
return nil, RcodeNameError
|
return nil, E.New("lookup ", domain, ": empty result (cached)")
|
||||||
}
|
}
|
||||||
return responseAddrs, nil
|
return responseAddrs, nil
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package local
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
@ -90,8 +91,9 @@ func (t *Transport) exchangeParallel(ctx context.Context, systemConfig *dnsConfi
|
|||||||
startRacer := func(ctx context.Context, fqdn string) {
|
startRacer := func(ctx context.Context, fqdn string) {
|
||||||
response, err := t.tryOneName(ctx, systemConfig, fqdn, message)
|
response, err := t.tryOneName(ctx, systemConfig, fqdn, message)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
addresses, _ := dns.MessageToAddresses(response)
|
var addresses []netip.Addr
|
||||||
if len(addresses) == 0 {
|
addresses, err = dns.MessageToAddresses(response)
|
||||||
|
if err == nil && len(addresses) == 0 {
|
||||||
err = E.New(fqdn, ": empty result")
|
err = E.New(fqdn, ": empty result")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -50,7 +49,6 @@ type Server struct {
|
|||||||
httpServer *http.Server
|
httpServer *http.Server
|
||||||
trafficManager *trafficontrol.Manager
|
trafficManager *trafficontrol.Manager
|
||||||
urlTestHistory adapter.URLTestHistoryStorage
|
urlTestHistory adapter.URLTestHistoryStorage
|
||||||
uiUpdateAccess sync.Mutex
|
|
||||||
logDebug bool
|
logDebug bool
|
||||||
|
|
||||||
mode string
|
mode string
|
||||||
|
@ -37,8 +37,6 @@ func (s *Server) checkAndDownloadExternalUI() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) downloadExternalUI() error {
|
func (s *Server) downloadExternalUI() error {
|
||||||
s.uiUpdateAccess.Lock()
|
|
||||||
defer s.uiUpdateAccess.Unlock()
|
|
||||||
var downloadURL string
|
var downloadURL string
|
||||||
if s.externalUIDownloadURL != "" {
|
if s.externalUIDownloadURL != "" {
|
||||||
downloadURL = s.externalUIDownloadURL
|
downloadURL = s.externalUIDownloadURL
|
||||||
|
@ -83,7 +83,6 @@ type DialerOptions struct {
|
|||||||
NetworkType badoption.Listable[InterfaceType] `json:"network_type,omitempty"`
|
NetworkType badoption.Listable[InterfaceType] `json:"network_type,omitempty"`
|
||||||
FallbackNetworkType badoption.Listable[InterfaceType] `json:"fallback_network_type,omitempty"`
|
FallbackNetworkType badoption.Listable[InterfaceType] `json:"fallback_network_type,omitempty"`
|
||||||
FallbackDelay badoption.Duration `json:"fallback_delay,omitempty"`
|
FallbackDelay badoption.Duration `json:"fallback_delay,omitempty"`
|
||||||
IsWireGuardListener bool `json:"-"`
|
|
||||||
|
|
||||||
// Deprecated: migrated to domain resolver
|
// Deprecated: migrated to domain resolver
|
||||||
DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
|
DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
|
||||||
|
@ -45,8 +45,8 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
|
|||||||
logger: logger,
|
logger: logger,
|
||||||
localAddresses: options.Address,
|
localAddresses: options.Address,
|
||||||
}
|
}
|
||||||
if options.Detour == "" {
|
if options.Detour != "" && options.ListenPort != 0 {
|
||||||
options.IsWireGuardListener = true
|
return nil, E.New("`listen_port` is conflict with `detour`")
|
||||||
}
|
}
|
||||||
outboundDialer, err := dialer.NewWithOptions(dialer.Options{
|
outboundDialer, err := dialer.NewWithOptions(dialer.Options{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
|
@ -46,9 +46,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
|||||||
logger: logger,
|
logger: logger,
|
||||||
localAddresses: options.LocalAddress,
|
localAddresses: options.LocalAddress,
|
||||||
}
|
}
|
||||||
if options.Detour == "" {
|
if options.Detour != "" && options.GSO {
|
||||||
options.IsWireGuardListener = true
|
|
||||||
} else if options.GSO {
|
|
||||||
return nil, E.New("gso is conflict with detour")
|
return nil, E.New("gso is conflict with detour")
|
||||||
}
|
}
|
||||||
outboundDialer, err := dialer.NewWithOptions(dialer.Options{
|
outboundDialer, err := dialer.NewWithOptions(dialer.Options{
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -66,7 +67,17 @@ func (m *ConnectionManager) NewConnection(ctx context.Context, this N.Dialer, co
|
|||||||
remoteConn, err = this.DialContext(ctx, N.NetworkTCP, metadata.Destination)
|
remoteConn, err = this.DialContext(ctx, N.NetworkTCP, metadata.Destination)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = E.Cause(err, "open outbound connection")
|
var remoteString string
|
||||||
|
if len(metadata.DestinationAddresses) > 0 {
|
||||||
|
remoteString = "[" + strings.Join(common.Map(metadata.DestinationAddresses, netip.Addr.String), ",") + "]"
|
||||||
|
} else {
|
||||||
|
remoteString = metadata.Destination.String()
|
||||||
|
}
|
||||||
|
var dialerString string
|
||||||
|
if outbound, isOutbound := this.(adapter.Outbound); isOutbound {
|
||||||
|
dialerString = " using outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
|
||||||
|
}
|
||||||
|
err = E.Cause(err, "open connection to ", remoteString, dialerString)
|
||||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||||
m.logger.ErrorContext(ctx, err)
|
m.logger.ErrorContext(ctx, err)
|
||||||
return
|
return
|
||||||
@ -133,8 +144,19 @@ func (m *ConnectionManager) NewPacketConnection(ctx context.Context, this N.Dial
|
|||||||
remoteConn, err = this.DialContext(ctx, N.NetworkUDP, metadata.Destination)
|
remoteConn, err = this.DialContext(ctx, N.NetworkUDP, metadata.Destination)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
var remoteString string
|
||||||
|
if len(metadata.DestinationAddresses) > 0 {
|
||||||
|
remoteString = "[" + strings.Join(common.Map(metadata.DestinationAddresses, netip.Addr.String), ",") + "]"
|
||||||
|
} else {
|
||||||
|
remoteString = metadata.Destination.String()
|
||||||
|
}
|
||||||
|
var dialerString string
|
||||||
|
if outbound, isOutbound := this.(adapter.Outbound); isOutbound {
|
||||||
|
dialerString = " using outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
|
||||||
|
}
|
||||||
|
err = E.Cause(err, "open packet connection to ", remoteString, dialerString)
|
||||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||||
m.logger.ErrorContext(ctx, "open outbound packet connection: ", err)
|
m.logger.ErrorContext(ctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
remotePacketConn = bufio.NewUnbindPacketConn(remoteConn)
|
remotePacketConn = bufio.NewUnbindPacketConn(remoteConn)
|
||||||
@ -149,8 +171,13 @@ func (m *ConnectionManager) NewPacketConnection(ctx context.Context, this N.Dial
|
|||||||
remotePacketConn, err = this.ListenPacket(ctx, metadata.Destination)
|
remotePacketConn, err = this.ListenPacket(ctx, metadata.Destination)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
var dialerString string
|
||||||
|
if outbound, isOutbound := this.(adapter.Outbound); isOutbound {
|
||||||
|
dialerString = " using outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
|
||||||
|
}
|
||||||
|
err = E.Cause(err, "listen packet connection using ", dialerString)
|
||||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||||
m.logger.ErrorContext(ctx, "listen outbound packet connection: ", err)
|
m.logger.ErrorContext(ctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ func (e *Endpoint) Start(resolve bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var bind conn.Bind
|
var bind conn.Bind
|
||||||
wgListener, isWgListener := e.options.Dialer.(conn.Listener)
|
wgListener, isWgListener := common.Cast[conn.Listener](e.options.Dialer)
|
||||||
if isWgListener {
|
if isWgListener {
|
||||||
bind = conn.NewStdNetBind(wgListener)
|
bind = conn.NewStdNetBind(wgListener)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user