mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-08-26 03:57:36 +08:00
Compare commits
86 Commits
68386928b7
...
4d24b7198d
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4d24b7198d | ||
![]() |
8c1b03df4f | ||
![]() |
465bb41ace | ||
![]() |
284f10b296 | ||
![]() |
7a109569f9 | ||
![]() |
ea342f257a | ||
![]() |
8814994368 | ||
![]() |
20d338a06b | ||
![]() |
7527134ef2 | ||
![]() |
43230a89ef | ||
![]() |
967d84825f | ||
![]() |
c38000d94f | ||
![]() |
ff8e11dfe3 | ||
![]() |
eaaa70f118 | ||
![]() |
13870fb4b5 | ||
![]() |
961d586e47 | ||
![]() |
4f4b7def78 | ||
![]() |
4acb3065b8 | ||
![]() |
0ab2ef8c44 | ||
![]() |
56c144fc2b | ||
![]() |
7f0fec0bb3 | ||
![]() |
448d534d25 | ||
![]() |
f9f60bb9ea | ||
![]() |
9554908971 | ||
![]() |
74be568a93 | ||
![]() |
b37f4b68d5 | ||
![]() |
bbe6ded13c | ||
![]() |
9111cfa5d7 | ||
![]() |
546218c0f8 | ||
![]() |
680f8dd008 | ||
![]() |
13c251287b | ||
![]() |
8051bb4f3b | ||
![]() |
24c7b040c5 | ||
![]() |
ac74bbf5dd | ||
![]() |
2d72940096 | ||
![]() |
b2d6708f96 | ||
![]() |
5108103f3f | ||
![]() |
e875eebf9c | ||
![]() |
445eae88ab | ||
![]() |
3f4f804e3e | ||
![]() |
1347d92ebe | ||
![]() |
2819ec16f3 | ||
![]() |
aa5e7822a4 | ||
![]() |
fa7d03542d | ||
![]() |
dbbab063fe | ||
![]() |
ded7d45dee | ||
![]() |
96bf78ddc1 | ||
![]() |
5af81fa969 | ||
![]() |
a4ff6f2075 | ||
![]() |
3ea9468107 | ||
![]() |
a7c7703fd3 | ||
![]() |
db33a68eb2 | ||
![]() |
c3e4bf6a4c | ||
![]() |
3e455902c9 | ||
![]() |
aaba387a8a | ||
![]() |
4d1be802cb | ||
![]() |
83ccc72e2b | ||
![]() |
f9e850867a | ||
![]() |
342c2361f1 | ||
![]() |
ac4e30b190 | ||
![]() |
cf008519fd | ||
![]() |
91d9fc63b7 | ||
![]() |
7d054da0b1 | ||
![]() |
40d35829e1 | ||
![]() |
41ad180be1 | ||
![]() |
9cb07a2387 | ||
![]() |
086784baf3 | ||
![]() |
0e8cd7d3be | ||
![]() |
58f712d222 | ||
![]() |
dfb7569d11 | ||
![]() |
638179fd7c | ||
![]() |
69fff5591f | ||
![]() |
7c3c3ddbeb | ||
![]() |
d88e87b9a4 | ||
![]() |
1f529be0f1 | ||
![]() |
f87808f8c3 | ||
![]() |
11e3634a63 | ||
![]() |
c46f70a4c8 | ||
![]() |
4ed2e1ee1b | ||
![]() |
aa8a85b4bc | ||
![]() |
6103ecb771 | ||
![]() |
3dbe90c535 | ||
![]() |
0eac73a8fd | ||
![]() |
f9cb268ee7 | ||
![]() |
d7085167e7 | ||
![]() |
c80d62968c |
@ -341,16 +341,6 @@ 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,10 +268,13 @@ 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,9 +323,6 @@ 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)")
|
||||||
@ -334,15 +331,14 @@ 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 {
|
||||||
if err != nil {
|
panic("unexpected empty result")
|
||||||
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, E.New("lookup ", domain, ": empty result (cached)")
|
return nil, RcodeNameError
|
||||||
}
|
}
|
||||||
return responseAddrs, nil
|
return responseAddrs, nil
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ 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"
|
||||||
@ -91,9 +90,8 @@ 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 {
|
||||||
var addresses []netip.Addr
|
addresses, _ := dns.MessageToAddresses(response)
|
||||||
addresses, err = dns.MessageToAddresses(response)
|
if len(addresses) == 0 {
|
||||||
if err == nil && len(addresses) == 0 {
|
|
||||||
err = E.New(fqdn, ": empty result")
|
err = E.New(fqdn, ": empty result")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ 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,6 +37,8 @@ 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,6 +83,7 @@ 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 != "" && options.ListenPort != 0 {
|
if options.Detour == "" {
|
||||||
return nil, E.New("`listen_port` is conflict with `detour`")
|
options.IsWireGuardListener = true
|
||||||
}
|
}
|
||||||
outboundDialer, err := dialer.NewWithOptions(dialer.Options{
|
outboundDialer, err := dialer.NewWithOptions(dialer.Options{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
|
@ -46,7 +46,9 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
|||||||
logger: logger,
|
logger: logger,
|
||||||
localAddresses: options.LocalAddress,
|
localAddresses: options.LocalAddress,
|
||||||
}
|
}
|
||||||
if options.Detour != "" && options.GSO {
|
if options.Detour == "" {
|
||||||
|
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,7 +7,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -67,17 +66,7 @@ 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 {
|
||||||
var remoteString string
|
err = E.Cause(err, "open outbound connection")
|
||||||
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
|
||||||
@ -144,19 +133,8 @@ 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, err)
|
m.logger.ErrorContext(ctx, "open outbound packet connection: ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
remotePacketConn = bufio.NewUnbindPacketConn(remoteConn)
|
remotePacketConn = bufio.NewUnbindPacketConn(remoteConn)
|
||||||
@ -171,13 +149,8 @@ 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, err)
|
m.logger.ErrorContext(ctx, "listen outbound packet connection: ", 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 := common.Cast[conn.Listener](e.options.Dialer)
|
wgListener, isWgListener := e.options.Dialer.(conn.Listener)
|
||||||
if isWgListener {
|
if isWgListener {
|
||||||
bind = conn.NewStdNetBind(wgListener)
|
bind = conn.NewStdNetBind(wgListener)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user