mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 21:54:13 +08:00
feat: added sync.OnceValues for creating dialer when receiving a outbound dial context
This commit is contained in:
parent
5c05ed81fe
commit
654ae54f9e
@ -7,9 +7,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
otransport "github.com/Jigsaw-Code/outline-sdk/transport"
|
"github.com/Jigsaw-Code/outline-sdk/transport"
|
||||||
"github.com/Jigsaw-Code/outline-sdk/x/smart"
|
"github.com/Jigsaw-Code/outline-sdk/x/smart"
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/adapter/outbound"
|
"github.com/sagernet/sing-box/adapter/outbound"
|
||||||
@ -26,8 +27,10 @@ import (
|
|||||||
// Outbound implements the smart dialer outbound from outline sdk
|
// Outbound implements the smart dialer outbound from outline sdk
|
||||||
type Outbound struct {
|
type Outbound struct {
|
||||||
outbound.Adapter
|
outbound.Adapter
|
||||||
logger logger.ContextLogger
|
logger logger.ContextLogger
|
||||||
dialer otransport.StreamDialer
|
dialer transport.StreamDialer
|
||||||
|
dialerMutex *sync.Mutex
|
||||||
|
createDialer func() (transport.StreamDialer, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterOutbound registers the outline outbound to the registry
|
// RegisterOutbound registers the outline outbound to the registry
|
||||||
@ -65,22 +68,37 @@ func NewOutbound(ctx context.Context, router adapter.Router, log log.ContextLogg
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
outbound := &Outbound{
|
||||||
dialer, err := strategyFinder.NewDialer(ctx, options.Domains, yamlOptions)
|
Adapter: outbound.NewAdapterWithDialerOptions("outline", tag, []string{network.NetworkTCP}, options.DialerOptions),
|
||||||
if err != nil {
|
logger: log,
|
||||||
return nil, err
|
dialerMutex: &sync.Mutex{},
|
||||||
}
|
}
|
||||||
|
createDialer := sync.OnceValues(func() (transport.StreamDialer, error) {
|
||||||
|
dialer, err := strategyFinder.NewDialer(ctx, options.Domains, yamlOptions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dialer, nil
|
||||||
|
})
|
||||||
|
|
||||||
return &Outbound{
|
outbound.createDialer = createDialer
|
||||||
Adapter: outbound.NewAdapterWithDialerOptions("outline", tag, []string{network.NetworkTCP}, options.DialerOptions),
|
|
||||||
logger: log,
|
return outbound, nil
|
||||||
dialer: dialer,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialContext extracts the metadata domain, add the destination to the context
|
// DialContext extracts the metadata domain, add the destination to the context
|
||||||
// and use the proxyless dialer for sending the request
|
// and use the proxyless dialer for sending the request
|
||||||
func (o *Outbound) DialContext(ctx context.Context, network string, destination metadata.Socksaddr) (net.Conn, error) {
|
func (o *Outbound) DialContext(ctx context.Context, network string, destination metadata.Socksaddr) (net.Conn, error) {
|
||||||
|
o.dialerMutex.Lock()
|
||||||
|
if o.dialer == nil {
|
||||||
|
dialer, err := o.createDialer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
o.dialer = dialer
|
||||||
|
}
|
||||||
|
o.dialerMutex.Unlock()
|
||||||
|
|
||||||
ctx, metadata := adapter.ExtendContext(ctx)
|
ctx, metadata := adapter.ExtendContext(ctx)
|
||||||
metadata.Outbound = o.Tag()
|
metadata.Outbound = o.Tag()
|
||||||
metadata.Destination = destination
|
metadata.Destination = destination
|
||||||
@ -100,7 +118,7 @@ type outboundStreamDialer struct {
|
|||||||
logger log.ContextLogger
|
logger log.ContextLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *outboundStreamDialer) DialStream(ctx context.Context, addr string) (otransport.StreamConn, error) {
|
func (s *outboundStreamDialer) DialStream(ctx context.Context, addr string) (transport.StreamConn, error) {
|
||||||
destination := metadata.ParseSocksaddr(addr)
|
destination := metadata.ParseSocksaddr(addr)
|
||||||
conn, err := s.dialer.DialContext(ctx, network.NetworkTCP, destination)
|
conn, err := s.dialer.DialContext(ctx, network.NetworkTCP, destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user