Refactor struct & Add override dialer options
This commit is contained in:
33 files changed
+282
-166
No files matched your search
+1
-1
@@ -22,5 +22,5 @@ type InboundContext struct {
|
|||||||
|
|
||||||
SourceGeoIPCode string
|
SourceGeoIPCode string
|
||||||
GeoIPCode string
|
GeoIPCode string
|
||||||
ProcessPath string
|
// ProcessPath string
|
||||||
}
|
}
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
package outbound
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/database64128/tfo-go"
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
|
||||||
"github.com/sagernet/sing-box/log"
|
|
||||||
"github.com/sagernet/sing-box/option"
|
|
||||||
"github.com/sagernet/sing/common"
|
|
||||||
"github.com/sagernet/sing/common/buf"
|
|
||||||
"github.com/sagernet/sing/common/bufio"
|
|
||||||
"github.com/sagernet/sing/common/control"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
|
||||||
N "github.com/sagernet/sing/common/network"
|
|
||||||
)
|
|
||||||
|
|
||||||
type myOutboundAdapter struct {
|
|
||||||
protocol string
|
|
||||||
logger log.Logger
|
|
||||||
tag string
|
|
||||||
dialer N.Dialer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *myOutboundAdapter) Type() string {
|
|
||||||
return a.protocol
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *myOutboundAdapter) Tag() string {
|
|
||||||
return a.tag
|
|
||||||
}
|
|
||||||
|
|
||||||
type defaultDialer struct {
|
|
||||||
tfo.Dialer
|
|
||||||
net.ListenConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDialer) DialContext(ctx context.Context, network string, address M.Socksaddr) (net.Conn, error) {
|
|
||||||
return d.Dialer.DialContext(ctx, network, address.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *defaultDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
|
||||||
return d.ListenConfig.ListenPacket(ctx, "udp", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDialer(options option.DialerOptions) N.Dialer {
|
|
||||||
var dialer net.Dialer
|
|
||||||
var listener net.ListenConfig
|
|
||||||
if options.BindInterface != "" {
|
|
||||||
dialer.Control = control.Append(dialer.Control, control.BindToInterface(options.BindInterface))
|
|
||||||
listener.Control = control.Append(listener.Control, control.BindToInterface(options.BindInterface))
|
|
||||||
}
|
|
||||||
if options.RoutingMark != 0 {
|
|
||||||
dialer.Control = control.Append(dialer.Control, control.RoutingMark(options.RoutingMark))
|
|
||||||
listener.Control = control.Append(listener.Control, control.RoutingMark(options.RoutingMark))
|
|
||||||
}
|
|
||||||
if options.ReuseAddr {
|
|
||||||
listener.Control = control.Append(listener.Control, control.ReuseAddr())
|
|
||||||
}
|
|
||||||
if options.ConnectTimeout != 0 {
|
|
||||||
dialer.Timeout = time.Duration(options.ConnectTimeout) * time.Second
|
|
||||||
}
|
|
||||||
return &defaultDialer{tfo.Dialer{Dialer: dialer, DisableTFO: !options.TCPFastOpen}, listener}
|
|
||||||
}
|
|
||||||
|
|
||||||
type lazyDialer struct {
|
|
||||||
router adapter.Router
|
|
||||||
options option.DialerOptions
|
|
||||||
dialer N.Dialer
|
|
||||||
initOnce sync.Once
|
|
||||||
initErr error
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDialer(router adapter.Router, options option.DialerOptions) N.Dialer {
|
|
||||||
if options.Detour == "" {
|
|
||||||
return newDialer(options)
|
|
||||||
}
|
|
||||||
return &lazyDialer{
|
|
||||||
router: router,
|
|
||||||
options: options,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *lazyDialer) Dialer() (N.Dialer, error) {
|
|
||||||
d.initOnce.Do(func() {
|
|
||||||
var loaded bool
|
|
||||||
d.dialer, loaded = d.router.Outbound(d.options.Detour)
|
|
||||||
if !loaded {
|
|
||||||
d.initErr = E.New("outbound detour not found: ", d.options.Detour)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return d.dialer, d.initErr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *lazyDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
|
||||||
dialer, err := d.Dialer()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return dialer.DialContext(ctx, network, destination)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *lazyDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
|
||||||
dialer, err := d.Dialer()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return dialer.ListenPacket(ctx, destination)
|
|
||||||
}
|
|
||||||
|
|
||||||
func CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) error {
|
|
||||||
_payload := buf.StackNew()
|
|
||||||
payload := common.Dup(_payload)
|
|
||||||
err := conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = payload.ReadFrom(conn)
|
|
||||||
if err != nil && !E.IsTimeout(err) {
|
|
||||||
return E.Cause(err, "read payload")
|
|
||||||
}
|
|
||||||
err = conn.SetReadDeadline(time.Time{})
|
|
||||||
if err != nil {
|
|
||||||
payload.Release()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = serverConn.Write(payload.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return E.Cause(err, "client handshake")
|
|
||||||
}
|
|
||||||
runtime.KeepAlive(_payload)
|
|
||||||
return bufio.CopyConn(ctx, conn, serverConn)
|
|
||||||
}
|
|
||||||
File renamed without changes.
@@ -59,9 +59,9 @@ func (a *myInboundAdapter) Start() error {
|
|||||||
var tcpListener *net.TCPListener
|
var tcpListener *net.TCPListener
|
||||||
var err error
|
var err error
|
||||||
if !a.listenOptions.TCPFastOpen {
|
if !a.listenOptions.TCPFastOpen {
|
||||||
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr("tcp", bindAddr.Addr), bindAddr.TCPAddr())
|
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(C.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
|
||||||
} else {
|
} else {
|
||||||
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr("tcp", bindAddr.Addr), bindAddr.TCPAddr())
|
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr(C.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -71,7 +71,7 @@ func (a *myInboundAdapter) Start() error {
|
|||||||
listenAddr = tcpListener.Addr()
|
listenAddr = tcpListener.Addr()
|
||||||
}
|
}
|
||||||
if common.Contains(a.network, C.NetworkUDP) {
|
if common.Contains(a.network, C.NetworkUDP) {
|
||||||
udpConn, err := net.ListenUDP(M.NetworkFromNetAddr("udp", bindAddr.Addr), bindAddr.UDPAddr())
|
udpConn, err := net.ListenUDP(M.NetworkFromNetAddr(C.NetworkUDP, bindAddr.Addr), bindAddr.UDPAddr())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ func (a *myInboundAdapter) loopTCPIn() {
|
|||||||
ctx := log.ContextWithID(a.ctx)
|
ctx := log.ContextWithID(a.ctx)
|
||||||
var metadata adapter.InboundContext
|
var metadata adapter.InboundContext
|
||||||
metadata.Inbound = a.tag
|
metadata.Inbound = a.tag
|
||||||
metadata.Network = "tcp"
|
metadata.Network = C.NetworkTCP
|
||||||
metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr())
|
metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr())
|
||||||
a.logger.WithContext(ctx).Info("inbound connection from ", metadata.Source)
|
a.logger.WithContext(ctx).Info("inbound connection from ", metadata.Source)
|
||||||
hErr := a.connHandler.NewConnection(ctx, conn, metadata)
|
hErr := a.connHandler.NewConnection(ctx, conn, metadata)
|
||||||
@@ -165,7 +165,7 @@ func (a *myInboundAdapter) loopUDPIn() {
|
|||||||
buffer.Truncate(n)
|
buffer.Truncate(n)
|
||||||
var metadata adapter.InboundContext
|
var metadata adapter.InboundContext
|
||||||
metadata.Inbound = a.tag
|
metadata.Inbound = a.tag
|
||||||
metadata.Network = "udp"
|
metadata.Network = C.NetworkUDP
|
||||||
metadata.Source = M.SocksaddrFromNetIP(addr)
|
metadata.Source = M.SocksaddrFromNetIP(addr)
|
||||||
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
|
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -187,7 +187,7 @@ func (a *myInboundAdapter) loopUDPInThreadSafe() {
|
|||||||
buffer.Truncate(n)
|
buffer.Truncate(n)
|
||||||
var metadata adapter.InboundContext
|
var metadata adapter.InboundContext
|
||||||
metadata.Inbound = a.tag
|
metadata.Inbound = a.tag
|
||||||
metadata.Network = "udp"
|
metadata.Network = C.NetworkUDP
|
||||||
metadata.Source = M.SocksaddrFromNetIP(addr)
|
metadata.Source = M.SocksaddrFromNetIP(addr)
|
||||||
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
|
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -235,7 +235,7 @@ func (a *myInboundAdapter) NewError(ctx context.Context, err error) {
|
|||||||
func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
||||||
defer buffer.Release()
|
defer buffer.Release()
|
||||||
if destination.IsFqdn() {
|
if destination.IsFqdn() {
|
||||||
udpAddr, err := net.ResolveUDPAddr("udp", destination.String())
|
udpAddr, err := net.ResolveUDPAddr(C.NetworkUDP, destination.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
-1
@@ -21,7 +21,8 @@ func (v *NetworkList) UnmarshalJSON(data []byte) error {
|
|||||||
}
|
}
|
||||||
for _, networkName := range networkList {
|
for _, networkName := range networkList {
|
||||||
switch networkName {
|
switch networkName {
|
||||||
case "tcp", "udp":
|
case C.NetworkTCP, C.NetworkUDP:
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
return E.New("unknown network: " + networkName)
|
return E.New("unknown network: " + networkName)
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-6
@@ -55,12 +55,20 @@ func (h *Outbound) UnmarshalJSON(bytes []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DialerOptions struct {
|
type DialerOptions struct {
|
||||||
Detour string `json:"detour,omitempty"`
|
Detour string `json:"detour,omitempty"`
|
||||||
BindInterface string `json:"bind_interface,omitempty"`
|
BindInterface string `json:"bind_interface,omitempty"`
|
||||||
RoutingMark int `json:"routing_mark,omitempty"`
|
RoutingMark int `json:"routing_mark,omitempty"`
|
||||||
ReuseAddr bool `json:"reuse_addr,omitempty"`
|
ReuseAddr bool `json:"reuse_addr,omitempty"`
|
||||||
ConnectTimeout int `json:"connect_timeout,omitempty"`
|
ConnectTimeout int `json:"connect_timeout,omitempty"`
|
||||||
TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
|
TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
|
||||||
|
OverrideOptions *OverrideStreamOptions `json:"override,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OverrideStreamOptions struct {
|
||||||
|
TLS bool `json:"tls,omitempty"`
|
||||||
|
TLSServerName string `json:"tls_servername,omitempty"`
|
||||||
|
TLSInsecure bool `json:"tls_insecure,omitempty"`
|
||||||
|
UDPOverTCP bool `json:"udp_over_tcp,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DirectOutboundOptions struct {
|
type DirectOutboundOptions struct {
|
||||||
|
|||||||
File renamed without changes.
@@ -0,0 +1,54 @@
|
|||||||
|
package outbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
"runtime"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/log"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/buf"
|
||||||
|
"github.com/sagernet/sing/common/bufio"
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
type myOutboundAdapter struct {
|
||||||
|
protocol string
|
||||||
|
logger log.Logger
|
||||||
|
tag string
|
||||||
|
dialer N.Dialer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *myOutboundAdapter) Type() string {
|
||||||
|
return a.protocol
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *myOutboundAdapter) Tag() string {
|
||||||
|
return a.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
func CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) error {
|
||||||
|
_payload := buf.StackNew()
|
||||||
|
payload := common.Dup(_payload)
|
||||||
|
err := conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = payload.ReadFrom(conn)
|
||||||
|
if err != nil && !E.IsTimeout(err) {
|
||||||
|
return E.Cause(err, "read payload")
|
||||||
|
}
|
||||||
|
err = conn.SetReadDeadline(time.Time{})
|
||||||
|
if err != nil {
|
||||||
|
payload.Release()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = serverConn.Write(payload.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "client handshake")
|
||||||
|
}
|
||||||
|
runtime.KeepAlive(_payload)
|
||||||
|
return bufio.CopyConn(ctx, conn, serverConn)
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package dialer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/database64128/tfo-go"
|
||||||
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common/control"
|
||||||
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
type defaultDialer struct {
|
||||||
|
tfo.Dialer
|
||||||
|
net.ListenConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDefault(options option.DialerOptions) N.Dialer {
|
||||||
|
var dialer net.Dialer
|
||||||
|
var listener net.ListenConfig
|
||||||
|
if options.BindInterface != "" {
|
||||||
|
dialer.Control = control.Append(dialer.Control, control.BindToInterface(options.BindInterface))
|
||||||
|
listener.Control = control.Append(listener.Control, control.BindToInterface(options.BindInterface))
|
||||||
|
}
|
||||||
|
if options.RoutingMark != 0 {
|
||||||
|
dialer.Control = control.Append(dialer.Control, control.RoutingMark(options.RoutingMark))
|
||||||
|
listener.Control = control.Append(listener.Control, control.RoutingMark(options.RoutingMark))
|
||||||
|
}
|
||||||
|
if options.ReuseAddr {
|
||||||
|
listener.Control = control.Append(listener.Control, control.ReuseAddr())
|
||||||
|
}
|
||||||
|
if options.ConnectTimeout != 0 {
|
||||||
|
dialer.Timeout = time.Duration(options.ConnectTimeout) * time.Second
|
||||||
|
}
|
||||||
|
return &defaultDialer{tfo.Dialer{Dialer: dialer, DisableTFO: !options.TCPFastOpen}, listener}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *defaultDialer) DialContext(ctx context.Context, network string, address M.Socksaddr) (net.Conn, error) {
|
||||||
|
return d.Dialer.DialContext(ctx, network, address.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *defaultDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||||
|
return d.ListenConfig.ListenPacket(ctx, C.NetworkUDP, "")
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package dialer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing-box/option"
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
type detourDialer struct {
|
||||||
|
router adapter.Router
|
||||||
|
options option.DialerOptions
|
||||||
|
dialer N.Dialer
|
||||||
|
initOnce sync.Once
|
||||||
|
initErr error
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDetour(router adapter.Router, options option.DialerOptions) N.Dialer {
|
||||||
|
return &detourDialer{router: router, options: options}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *detourDialer) Dialer() (N.Dialer, error) {
|
||||||
|
d.initOnce.Do(func() {
|
||||||
|
var loaded bool
|
||||||
|
d.dialer, loaded = d.router.Outbound(d.options.Detour)
|
||||||
|
if !loaded {
|
||||||
|
d.initErr = E.New("outbound detour not found: ", d.options.Detour)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return d.dialer, d.initErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *detourDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||||
|
dialer, err := d.Dialer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dialer.DialContext(ctx, network, destination)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *detourDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||||
|
dialer, err := d.Dialer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dialer.ListenPacket(ctx, destination)
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package dialer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
func New(router adapter.Router, options option.DialerOptions) N.Dialer {
|
||||||
|
var dialer N.Dialer
|
||||||
|
if options.Detour == "" {
|
||||||
|
dialer = newDefault(options)
|
||||||
|
} else {
|
||||||
|
dialer = newDetour(router, options)
|
||||||
|
}
|
||||||
|
if options.OverrideOptions != nil {
|
||||||
|
dialer = newOverride(dialer, common.PtrValueOrDefault(options.OverrideOptions))
|
||||||
|
}
|
||||||
|
return dialer
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package dialer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
"github.com/sagernet/sing-box/option"
|
||||||
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
"github.com/sagernet/sing/common/uot"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ N.Dialer = (*overrideDialer)(nil)
|
||||||
|
|
||||||
|
type overrideDialer struct {
|
||||||
|
upstream N.Dialer
|
||||||
|
tlsEnabled bool
|
||||||
|
tlsConfig tls.Config
|
||||||
|
uotEnabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newOverride(upstream N.Dialer, options option.OverrideStreamOptions) N.Dialer {
|
||||||
|
if !options.TLS && !options.UDPOverTCP {
|
||||||
|
return upstream
|
||||||
|
}
|
||||||
|
return &overrideDialer{
|
||||||
|
upstream,
|
||||||
|
options.TLS,
|
||||||
|
tls.Config{
|
||||||
|
ServerName: options.TLSServerName,
|
||||||
|
InsecureSkipVerify: options.TLSInsecure,
|
||||||
|
},
|
||||||
|
options.UDPOverTCP,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *overrideDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||||
|
switch network {
|
||||||
|
case C.NetworkTCP:
|
||||||
|
conn, err := d.upstream.DialContext(ctx, C.NetworkTCP, destination)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tls.Client(conn, &d.tlsConfig), nil
|
||||||
|
case C.NetworkUDP:
|
||||||
|
if d.uotEnabled {
|
||||||
|
tcpConn, err := d.upstream.DialContext(ctx, C.NetworkTCP, destination)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return uot.NewClientConn(tcpConn), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d.upstream.DialContext(ctx, network, destination)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *overrideDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||||
|
if d.uotEnabled {
|
||||||
|
tcpConn, err := d.upstream.DialContext(ctx, C.NetworkTCP, destination)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return uot.NewClientConn(tcpConn), nil
|
||||||
|
}
|
||||||
|
return d.upstream.ListenPacket(ctx, destination)
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing-box/outbound/dialer"
|
||||||
"github.com/sagernet/sing/common/bufio"
|
"github.com/sagernet/sing/common/bufio"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
@@ -27,7 +28,7 @@ func NewDirect(router adapter.Router, logger log.Logger, tag string, options opt
|
|||||||
protocol: C.TypeDirect,
|
protocol: C.TypeDirect,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
dialer: NewDialer(router, options.DialerOptions),
|
dialer: dialer.New(router, options.DialerOptions),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if options.OverrideAddress != "" && options.OverridePort != 0 {
|
if options.OverrideAddress != "" && options.OverridePort != 0 {
|
||||||
@@ -69,7 +70,7 @@ func (d *Direct) ListenPacket(ctx context.Context, destination M.Socksaddr) (net
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Direct) NewConnection(ctx context.Context, conn net.Conn, destination M.Socksaddr) error {
|
func (d *Direct) NewConnection(ctx context.Context, conn net.Conn, destination M.Socksaddr) error {
|
||||||
outConn, err := d.DialContext(ctx, "tcp", destination)
|
outConn, err := d.DialContext(ctx, C.NetworkTCP, destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing-box/outbound/dialer"
|
||||||
"github.com/sagernet/sing-shadowsocks"
|
"github.com/sagernet/sing-shadowsocks"
|
||||||
"github.com/sagernet/sing-shadowsocks/shadowimpl"
|
"github.com/sagernet/sing-shadowsocks/shadowimpl"
|
||||||
"github.com/sagernet/sing/common/bufio"
|
"github.com/sagernet/sing/common/bufio"
|
||||||
@@ -30,7 +31,7 @@ func NewShadowsocks(router adapter.Router, logger log.Logger, tag string, option
|
|||||||
protocol: C.TypeDirect,
|
protocol: C.TypeDirect,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
dialer: NewDialer(router, options.DialerOptions),
|
dialer: dialer.New(router, options.DialerOptions),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
@@ -51,14 +52,14 @@ func (o *Shadowsocks) DialContext(ctx context.Context, network string, destinati
|
|||||||
switch network {
|
switch network {
|
||||||
case C.NetworkTCP:
|
case C.NetworkTCP:
|
||||||
o.logger.WithContext(ctx).Info("outbound connection to ", destination)
|
o.logger.WithContext(ctx).Info("outbound connection to ", destination)
|
||||||
outConn, err := o.dialer.DialContext(ctx, "tcp", o.serverAddr)
|
outConn, err := o.dialer.DialContext(ctx, C.NetworkTCP, o.serverAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return o.method.DialEarlyConn(outConn, destination), nil
|
return o.method.DialEarlyConn(outConn, destination), nil
|
||||||
case C.NetworkUDP:
|
case C.NetworkUDP:
|
||||||
o.logger.WithContext(ctx).Info("outbound packet connection to ", destination)
|
o.logger.WithContext(ctx).Info("outbound packet connection to ", destination)
|
||||||
outConn, err := o.dialer.DialContext(ctx, "udp", o.serverAddr)
|
outConn, err := o.dialer.DialContext(ctx, C.NetworkUDP, o.serverAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -78,7 +79,7 @@ func (o *Shadowsocks) ListenPacket(ctx context.Context, destination M.Socksaddr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *Shadowsocks) NewConnection(ctx context.Context, conn net.Conn, destination M.Socksaddr) error {
|
func (o *Shadowsocks) NewConnection(ctx context.Context, conn net.Conn, destination M.Socksaddr) error {
|
||||||
serverConn, err := o.DialContext(ctx, "tcp", destination)
|
serverConn, err := o.DialContext(ctx, C.NetworkTCP, destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing-box/outbound/dialer"
|
||||||
"github.com/sagernet/sing/common/bufio"
|
"github.com/sagernet/sing/common/bufio"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
@@ -22,7 +23,7 @@ type Socks struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewSocks(router adapter.Router, logger log.Logger, tag string, options option.SocksOutboundOptions) (*Socks, error) {
|
func NewSocks(router adapter.Router, logger log.Logger, tag string, options option.SocksOutboundOptions) (*Socks, error) {
|
||||||
dialer := NewDialer(router, options.DialerOptions)
|
dialer := dialer.New(router, options.DialerOptions)
|
||||||
var version socks.Version
|
var version socks.Version
|
||||||
var err error
|
var err error
|
||||||
if options.Version != "" {
|
if options.Version != "" {
|
||||||
@@ -62,7 +63,7 @@ func (h *Socks) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Socks) NewConnection(ctx context.Context, conn net.Conn, destination M.Socksaddr) error {
|
func (h *Socks) NewConnection(ctx context.Context, conn net.Conn, destination M.Socksaddr) error {
|
||||||
outConn, err := h.DialContext(ctx, "tcp", destination)
|
outConn, err := h.DialContext(ctx, C.NetworkTCP, destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+5
-5
@@ -4,11 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/adapter/inbound"
|
"github.com/sagernet/sing-box/inbound"
|
||||||
"github.com/sagernet/sing-box/adapter/outbound"
|
|
||||||
"github.com/sagernet/sing-box/adapter/route"
|
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
outbound2 "github.com/sagernet/sing-box/outbound"
|
||||||
|
"github.com/sagernet/sing-box/route"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
)
|
)
|
||||||
@@ -43,14 +43,14 @@ func NewService(ctx context.Context, options option.Options) (*Service, error) {
|
|||||||
}
|
}
|
||||||
for i, outboundOptions := range options.Outbounds {
|
for i, outboundOptions := range options.Outbounds {
|
||||||
var outboundService adapter.Outbound
|
var outboundService adapter.Outbound
|
||||||
outboundService, err = outbound.New(router, logger, i, outboundOptions)
|
outboundService, err = outbound2.New(router, logger, i, outboundOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, E.Cause(err, "parse outbound[", i, "]")
|
return nil, E.Cause(err, "parse outbound[", i, "]")
|
||||||
}
|
}
|
||||||
outbounds = append(outbounds, outboundService)
|
outbounds = append(outbounds, outboundService)
|
||||||
}
|
}
|
||||||
if len(outbounds) == 0 {
|
if len(outbounds) == 0 {
|
||||||
outbounds = append(outbounds, outbound.NewDirect(nil, logger, "direct", option.DirectOutboundOptions{}))
|
outbounds = append(outbounds, outbound2.NewDirect(nil, logger, "direct", option.DirectOutboundOptions{}))
|
||||||
}
|
}
|
||||||
router.UpdateOutbounds(outbounds)
|
router.UpdateOutbounds(outbounds)
|
||||||
return &Service{
|
return &Service{
|
||||||
|
|||||||
Reference in new issue
Block a user