mirror of
https://github.com/daeuniverse/dae.git
synced 2024-12-23 01:24:45 +07:00
feat: support to dial domain for udp and support udp for ssr (#17)
This commit is contained in:
parent
663fbb2a59
commit
e495ee1b7c
@ -7,12 +7,11 @@ package netutils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"golang.org/x/net/proxy"
|
||||
"net"
|
||||
)
|
||||
|
||||
type ContextDialer struct {
|
||||
Dialer proxy.Dialer
|
||||
Dialer net.Dialer
|
||||
}
|
||||
|
||||
func (d *ContextDialer) DialContext(ctx context.Context, network, addr string) (c net.Conn, err error) {
|
||||
|
@ -9,10 +9,10 @@ import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/mzz2017/softwind/pkg/fastrand"
|
||||
"github.com/mzz2017/softwind/pool"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
"golang.org/x/net/proxy"
|
||||
"io"
|
||||
"math"
|
||||
"net/netip"
|
||||
@ -70,7 +70,7 @@ func SystemDns() (dns netip.AddrPort, err error) {
|
||||
return systemDns, nil
|
||||
}
|
||||
|
||||
func ResolveNetip(ctx context.Context, d proxy.Dialer, dns netip.AddrPort, host string, typ dnsmessage.Type, tcp bool) (addrs []netip.Addr, err error) {
|
||||
func ResolveNetip(ctx context.Context, d netproxy.Dialer, dns netip.AddrPort, host string, typ dnsmessage.Type, tcp bool) (addrs []netip.Addr, err error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
if addr, err := netip.ParseAddr(host); err == nil {
|
||||
@ -122,14 +122,13 @@ func ResolveNetip(ctx context.Context, d proxy.Dialer, dns netip.AddrPort, host
|
||||
}
|
||||
|
||||
// Dial and write.
|
||||
var network string
|
||||
cd := &netproxy.ContextDialer{Dialer: d}
|
||||
var c netproxy.Conn
|
||||
if tcp {
|
||||
network = "tcp"
|
||||
c, err = cd.DialTcpContext(ctx, dns.String())
|
||||
} else {
|
||||
network = "udp"
|
||||
c, err = cd.DialUdpContext(ctx, dns.String())
|
||||
}
|
||||
cd := ContextDialer{d}
|
||||
c, err := cd.DialContext(ctx, network, dns.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ package netutils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
"golang.org/x/net/proxy"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
@ -17,7 +17,7 @@ type Ip46 struct {
|
||||
Ip6 netip.Addr
|
||||
}
|
||||
|
||||
func ParseIp46(ctx context.Context, dialer proxy.Dialer, dns netip.AddrPort, host string, tcp bool) (ipv46 *Ip46, err error) {
|
||||
func ParseIp46(ctx context.Context, dialer netproxy.Dialer, dns netip.AddrPort, host string, tcp bool) (ipv46 *Ip46, err error) {
|
||||
addrs4, err := ResolveNetip(ctx, dialer, dns, host, dnsmessage.TypeA, tcp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -127,6 +127,10 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
|
||||
// This dialer is already alive.
|
||||
} else {
|
||||
// Dialer: not alive -> alive.
|
||||
a.log.WithFields(logrus.Fields{
|
||||
"dialer": dialer.Name(),
|
||||
"network": a.CheckTyp.StringWithoutDns(),
|
||||
}).Infoln("NOT ALIVE -> ALIVE:")
|
||||
a.dialerToIndex[dialer] = len(a.inorderedAliveDialerSet)
|
||||
a.inorderedAliveDialerSet = append(a.inorderedAliveDialerSet, dialer)
|
||||
}
|
||||
@ -134,6 +138,10 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
|
||||
index := a.dialerToIndex[dialer]
|
||||
if index >= 0 {
|
||||
// Dialer: alive -> not alive.
|
||||
a.log.WithFields(logrus.Fields{
|
||||
"dialer": dialer.Name(),
|
||||
"network": a.CheckTyp.StringWithoutDns(),
|
||||
}).Infoln("ALIVE -> NOT ALIVE:")
|
||||
// Remove the dialer from inorderedAliveDialerSet.
|
||||
if index >= len(a.inorderedAliveDialerSet) {
|
||||
a.log.Panicf("index:%v >= len(a.inorderedAliveDialerSet):%v", index, len(a.inorderedAliveDialerSet))
|
||||
|
@ -6,6 +6,7 @@
|
||||
package dialer
|
||||
|
||||
import (
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"net"
|
||||
)
|
||||
|
||||
@ -13,7 +14,11 @@ type blockDialer struct {
|
||||
DialCallback func()
|
||||
}
|
||||
|
||||
func (d *blockDialer) Dial(network string, addr string) (c net.Conn, err error) {
|
||||
func (d *blockDialer) DialTcp(addr string) (c netproxy.Conn, err error) {
|
||||
d.DialCallback()
|
||||
return nil, net.ErrClosed
|
||||
}
|
||||
func (d *blockDialer) DialUdp(addr string) (c netproxy.PacketConn, err error) {
|
||||
d.DialCallback()
|
||||
return nil, net.ErrClosed
|
||||
}
|
||||
|
@ -9,7 +9,9 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/mzz2017/softwind/pkg/fastrand"
|
||||
"github.com/mzz2017/softwind/protocol/direct"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/v2rayA/dae/common/consts"
|
||||
"github.com/v2rayA/dae/common/netutils"
|
||||
@ -119,7 +121,7 @@ func ParseTcpCheckOption(ctx context.Context, rawURL string) (opt *TcpCheckOptio
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ip46, err := netutils.ParseIp46(ctx, SymmetricDirect, systemDns, u.Hostname(), false)
|
||||
ip46, err := netutils.ParseIp46(ctx, direct.SymmetricDirect, systemDns, u.Hostname(), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -154,7 +156,7 @@ func ParseCheckDnsOption(ctx context.Context, dnsHostPort string) (opt *CheckDns
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bad port: %v", err)
|
||||
}
|
||||
ip46, err := netutils.ParseIp46(ctx, SymmetricDirect, systemDns, host, false)
|
||||
ip46, err := netutils.ParseIp46(ctx, direct.SymmetricDirect, systemDns, host, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -491,12 +493,20 @@ func (d *Dialer) Check(timeout time.Duration,
|
||||
|
||||
func (d *Dialer) HttpCheck(ctx context.Context, u *netutils.URL, ip netip.Addr) (ok bool, err error) {
|
||||
// HTTP(S) check.
|
||||
cd := netutils.ContextDialer{d.Dialer}
|
||||
cd := &netproxy.ContextDialer{Dialer: d.Dialer}
|
||||
cli := http.Client{
|
||||
Transport: &http.Transport{
|
||||
DialContext: func(ctx context.Context, network, addr string) (c net.Conn, err error) {
|
||||
// Force to dial "ip".
|
||||
return cd.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), u.Port()))
|
||||
conn, err := cd.DialTcpContext(ctx, net.JoinHostPort(ip.String(), u.Port()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &netproxy.FakeNetConn{
|
||||
Conn: conn,
|
||||
LAddr: nil,
|
||||
RAddr: nil,
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package dialer
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/proxy"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@ -17,7 +17,7 @@ var (
|
||||
type Dialer struct {
|
||||
*GlobalOption
|
||||
instanceOption InstanceOption
|
||||
proxy.Dialer
|
||||
netproxy.Dialer
|
||||
name string
|
||||
protocol string
|
||||
link string
|
||||
@ -43,13 +43,13 @@ type GlobalOption struct {
|
||||
}
|
||||
|
||||
type InstanceOption struct {
|
||||
CheckEnabled bool
|
||||
CheckEnabled bool
|
||||
}
|
||||
|
||||
type AliveDialerSetSet map[*AliveDialerSet]int
|
||||
|
||||
// NewDialer is for register in general.
|
||||
func NewDialer(dialer proxy.Dialer, option *GlobalOption, iOption InstanceOption, name string, protocol string, link string) *Dialer {
|
||||
func NewDialer(dialer netproxy.Dialer, option *GlobalOption, iOption InstanceOption, name string, protocol string, link string) *Dialer {
|
||||
var collections [6]*collection
|
||||
for i := range collections {
|
||||
collections[i] = newCollection()
|
||||
|
@ -1,82 +1,13 @@
|
||||
package dialer
|
||||
|
||||
import (
|
||||
"golang.org/x/net/proxy"
|
||||
"net"
|
||||
softwindDirect "github.com/mzz2017/softwind/protocol/direct"
|
||||
)
|
||||
|
||||
var SymmetricDirect = newDirect(false)
|
||||
var FullconeDirect = newDirect(true)
|
||||
|
||||
func NewDirectDialer(option *GlobalOption, fullcone bool) *Dialer {
|
||||
if fullcone {
|
||||
return NewDialer(FullconeDirect, option, InstanceOption{CheckEnabled: false}, "direct", "direct", "")
|
||||
return NewDialer(softwindDirect.FullconeDirect, option, InstanceOption{CheckEnabled: false}, "direct", "direct", "")
|
||||
} else {
|
||||
return NewDialer(SymmetricDirect, option, InstanceOption{CheckEnabled: false}, "direct", "direct", "")
|
||||
return NewDialer(softwindDirect.SymmetricDirect, option, InstanceOption{CheckEnabled: false}, "direct", "direct", "")
|
||||
}
|
||||
}
|
||||
|
||||
type direct struct {
|
||||
proxy.Dialer
|
||||
netDialer *net.Dialer
|
||||
fullCone bool
|
||||
}
|
||||
|
||||
func newDirect(fullCone bool) proxy.Dialer {
|
||||
return &direct{
|
||||
netDialer: &net.Dialer{},
|
||||
fullCone: fullCone,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *direct) Dial(network, addr string) (c net.Conn, err error) {
|
||||
switch network {
|
||||
case "tcp":
|
||||
conn, err := d.netDialer.Dial(network, addr)
|
||||
return conn, err
|
||||
case "udp":
|
||||
if d.fullCone {
|
||||
conn, err := net.ListenUDP(network, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &directUDPConn{UDPConn: conn, FullCone: true}, nil
|
||||
} else {
|
||||
conn, err := d.netDialer.Dial(network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &directUDPConn{UDPConn: conn.(*net.UDPConn), FullCone: false}, nil
|
||||
}
|
||||
default:
|
||||
return nil, net.UnknownNetworkError(network)
|
||||
}
|
||||
}
|
||||
|
||||
type directUDPConn struct {
|
||||
*net.UDPConn
|
||||
FullCone bool
|
||||
}
|
||||
|
||||
func (c *directUDPConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||
if !c.FullCone {
|
||||
// FIXME: check the addr
|
||||
return c.Write(b)
|
||||
}
|
||||
return c.UDPConn.WriteTo(b, addr)
|
||||
}
|
||||
|
||||
func (c *directUDPConn) WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error) {
|
||||
if !c.FullCone {
|
||||
n, err = c.Write(b)
|
||||
return n, 0, err
|
||||
}
|
||||
return c.UDPConn.WriteMsgUDP(b, oob, addr)
|
||||
}
|
||||
|
||||
func (c *directUDPConn) WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) {
|
||||
if !c.FullCone {
|
||||
return c.Write(b)
|
||||
}
|
||||
return c.UDPConn.WriteToUDP(b, addr)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/protocol/direct"
|
||||
"github.com/mzz2017/softwind/protocol/http"
|
||||
"github.com/v2rayA/dae/common"
|
||||
"github.com/v2rayA/dae/component/outbound/dialer"
|
||||
@ -66,7 +67,7 @@ func ParseHTTPURL(link string, option *dialer.GlobalOption) (data *HTTP, err err
|
||||
|
||||
func (s *HTTP) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOption) (*dialer.Dialer, error) {
|
||||
u := s.URL()
|
||||
d, err := http.NewHTTPProxy(&u, dialer.SymmetricDirect) // HTTP Proxy does not support full-cone.
|
||||
d, err := http.NewHTTPProxy(&u, direct.SymmetricDirect) // HTTP Proxy does not support full-cone.
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -3,12 +3,13 @@ package shadowsocks
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/mzz2017/softwind/protocol"
|
||||
"github.com/mzz2017/softwind/protocol/direct"
|
||||
"github.com/mzz2017/softwind/protocol/shadowsocks"
|
||||
"github.com/v2rayA/dae/common"
|
||||
"github.com/v2rayA/dae/component/outbound/dialer"
|
||||
"github.com/v2rayA/dae/component/outbound/transport/simpleobfs"
|
||||
"golang.org/x/net/proxy"
|
||||
"net"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@ -50,10 +51,10 @@ func (s *Shadowsocks) Dialer(option *dialer.GlobalOption, iOption dialer.Instanc
|
||||
return nil, fmt.Errorf("unsupported shadowsocks encryption method: %v", s.Cipher)
|
||||
}
|
||||
var err error
|
||||
var d proxy.Dialer
|
||||
var d netproxy.Dialer
|
||||
switch s.Plugin.Name {
|
||||
case "simple-obfs":
|
||||
d = dialer.SymmetricDirect // Simple-obfs does not supports UDP.
|
||||
d = direct.SymmetricDirect // Simple-obfs does not supports UDP.
|
||||
switch s.Plugin.Opts.Obfs {
|
||||
case "http", "tls":
|
||||
default:
|
||||
@ -78,7 +79,7 @@ func (s *Shadowsocks) Dialer(option *dialer.GlobalOption, iOption dialer.Instanc
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
d = dialer.FullconeDirect // Shadowsocks Proxy supports full-cone.
|
||||
d = direct.FullconeDirect // Shadowsocks Proxy supports full-cone.
|
||||
}
|
||||
d, err = protocol.NewDialer("shadowsocks", d, protocol.Header{
|
||||
ProxyAddress: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)),
|
||||
|
@ -3,9 +3,13 @@ package shadowsocksr
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/protocol"
|
||||
"github.com/mzz2017/softwind/protocol/direct"
|
||||
"github.com/mzz2017/softwind/protocol/shadowsocks_stream"
|
||||
"github.com/mzz2017/softwind/transport/shadowsocksr/obfs"
|
||||
"github.com/mzz2017/softwind/transport/shadowsocksr/proto"
|
||||
"github.com/v2rayA/dae/common"
|
||||
"github.com/v2rayA/dae/component/outbound/dialer"
|
||||
ssr "github.com/v2rayA/shadowsocksR/client"
|
||||
"net"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@ -39,21 +43,34 @@ func NewShadowsocksR(option *dialer.GlobalOption, iOption dialer.InstanceOption,
|
||||
}
|
||||
|
||||
func (s *ShadowsocksR) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOption) (*dialer.Dialer, error) {
|
||||
u := url.URL{
|
||||
Scheme: "ssr",
|
||||
User: url.UserPassword(s.Cipher, s.Password),
|
||||
Host: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)),
|
||||
RawQuery: url.Values{
|
||||
"protocol": []string{s.Proto},
|
||||
"protocol_param": []string{s.ProtoParam},
|
||||
"obfs": []string{s.Obfs},
|
||||
"obfs_param": []string{s.ObfsParam},
|
||||
}.Encode(),
|
||||
}
|
||||
d, err := ssr.NewSSR(u.String(), dialer.SymmetricDirect, nil) // SSR Proxy does not support full-cone.
|
||||
d := direct.SymmetricDirect
|
||||
obfsDialer, err := obfs.NewDialer(d, &obfs.ObfsParam{
|
||||
ObfsHost: s.Server,
|
||||
ObfsPort: uint16(s.Port),
|
||||
Obfs: s.Obfs,
|
||||
ObfsParam: s.ObfsParam,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d = obfsDialer
|
||||
d, err = shadowsocks_stream.NewDialer(d, protocol.Header{
|
||||
ProxyAddress: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)),
|
||||
Cipher: s.Cipher,
|
||||
Password: s.Password,
|
||||
IsClient: true,
|
||||
ShouldFullCone: false,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d = &proto.Dialer{
|
||||
NextDialer: d,
|
||||
Protocol: s.Proto,
|
||||
ProtocolParam: s.ProtoParam,
|
||||
ObfsOverhead: obfsDialer.ObfsOverhead(),
|
||||
}
|
||||
|
||||
return dialer.NewDialer(d, option, iOption, s.Name, s.Protocol, s.ExportToURL()), nil
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package socks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/protocol/direct"
|
||||
"github.com/v2rayA/dae/component/outbound/dialer"
|
||||
//"github.com/mzz2017/softwind/protocol/socks4"
|
||||
"github.com/mzz2017/softwind/protocol/socks5"
|
||||
@ -38,7 +39,7 @@ func (s *Socks) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOptio
|
||||
link := s.ExportToURL()
|
||||
switch s.Protocol {
|
||||
case "", "socks", "socks5":
|
||||
d, err := socks5.NewSocks5Dialer(link, dialer.FullconeDirect) // Socks5 Proxy supports full-cone.
|
||||
d, err := socks5.NewSocks5Dialer(link, direct.FullconeDirect) // Socks5 Proxy supports full-cone.
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -2,7 +2,9 @@ package trojan
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/mzz2017/softwind/protocol"
|
||||
"github.com/mzz2017/softwind/protocol/direct"
|
||||
"github.com/mzz2017/softwind/transport/grpc"
|
||||
"github.com/v2rayA/dae/common"
|
||||
"github.com/v2rayA/dae/component/outbound/dialer"
|
||||
@ -43,7 +45,7 @@ func NewTrojan(option *dialer.GlobalOption, iOption dialer.InstanceOption, link
|
||||
}
|
||||
|
||||
func (s *Trojan) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOption) (*dialer.Dialer, error) {
|
||||
d := dialer.FullconeDirect // Trojan Proxy supports full-cone.
|
||||
d := direct.FullconeDirect // Trojan Proxy supports full-cone.
|
||||
u := url.URL{
|
||||
Scheme: "tls",
|
||||
Host: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)),
|
||||
@ -66,8 +68,8 @@ func (s *Trojan) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOpti
|
||||
Scheme: "ws",
|
||||
Host: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)),
|
||||
RawQuery: url.Values{
|
||||
"host": []string{s.Host},
|
||||
"path": []string{s.Path},
|
||||
"host": []string{s.Host},
|
||||
"path": []string{s.Path},
|
||||
}.Encode(),
|
||||
}
|
||||
if d, err = ws.NewWs(u.String(), d); err != nil {
|
||||
@ -79,7 +81,7 @@ func (s *Trojan) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOpti
|
||||
serviceName = "GunService"
|
||||
}
|
||||
d = &grpc.Dialer{
|
||||
NextDialer: &protocol.DialerConverter{Dialer: d},
|
||||
NextDialer: &netproxy.ContextDialer{Dialer: d},
|
||||
ServiceName: serviceName,
|
||||
ServerName: s.Sni,
|
||||
AllowInsecure: s.AllowInsecure,
|
||||
|
@ -4,13 +4,14 @@ import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/mzz2017/softwind/protocol"
|
||||
"github.com/mzz2017/softwind/protocol/direct"
|
||||
"github.com/mzz2017/softwind/transport/grpc"
|
||||
"github.com/v2rayA/dae/common"
|
||||
"github.com/v2rayA/dae/component/outbound/dialer"
|
||||
"github.com/v2rayA/dae/component/outbound/transport/tls"
|
||||
"github.com/v2rayA/dae/component/outbound/transport/ws"
|
||||
"golang.org/x/net/proxy"
|
||||
"net"
|
||||
"net/url"
|
||||
"regexp"
|
||||
@ -67,12 +68,12 @@ func NewV2Ray(option *dialer.GlobalOption, iOption dialer.InstanceOption, link s
|
||||
}
|
||||
|
||||
func (s *V2Ray) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOption) (data *dialer.Dialer, err error) {
|
||||
var d proxy.Dialer
|
||||
var d netproxy.Dialer
|
||||
switch s.Protocol {
|
||||
case "vmess":
|
||||
d = dialer.FullconeDirect // VMess Proxy supports full-cone.
|
||||
d = direct.FullconeDirect // VMess Proxy supports full-cone.
|
||||
case "vless":
|
||||
d = dialer.SymmetricDirect // VLESS Proxy does not yet support full-cone by softwind.
|
||||
d = direct.SymmetricDirect // VLESS Proxy does not yet support full-cone by softwind.
|
||||
default:
|
||||
return nil, fmt.Errorf("V2Ray.Dialer: unexpected protocol: %v", s.Protocol)
|
||||
}
|
||||
@ -133,7 +134,7 @@ func (s *V2Ray) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOptio
|
||||
serviceName = "GunService"
|
||||
}
|
||||
d = &grpc.Dialer{
|
||||
NextDialer: &protocol.DialerConverter{Dialer: d},
|
||||
NextDialer: &netproxy.ContextDialer{Dialer: d},
|
||||
ServiceName: serviceName,
|
||||
ServerName: sni,
|
||||
AllowInsecure: s.AllowInsecure,
|
||||
@ -147,6 +148,7 @@ func (s *V2Ray) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOptio
|
||||
Cipher: "aes-128-gcm",
|
||||
Password: s.ID,
|
||||
IsClient: true,
|
||||
//ShouldFullCone: true,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -7,17 +7,17 @@ package outbound
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/v2rayA/dae/common/consts"
|
||||
"github.com/v2rayA/dae/component/outbound/dialer"
|
||||
"golang.org/x/net/proxy"
|
||||
"time"
|
||||
)
|
||||
|
||||
var NoAliveDialerError = fmt.Errorf("no alive dialer")
|
||||
|
||||
type DialerGroup struct {
|
||||
proxy.Dialer
|
||||
netproxy.Dialer
|
||||
|
||||
log *logrus.Logger
|
||||
Name string
|
||||
|
@ -6,10 +6,10 @@ import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/mzz2017/softwind/pkg/fastrand"
|
||||
"github.com/mzz2017/softwind/pool"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -17,7 +17,7 @@ import (
|
||||
|
||||
// HTTPObfs is shadowsocks http simple-obfs implementation
|
||||
type HTTPObfs struct {
|
||||
net.Conn
|
||||
netproxy.Conn
|
||||
host string
|
||||
port string
|
||||
path string
|
||||
@ -92,7 +92,7 @@ func (ho *HTTPObfs) Write(b []byte) (int, error) {
|
||||
}
|
||||
|
||||
// NewHTTPObfs return a HTTPObfs
|
||||
func NewHTTPObfs(conn net.Conn, host string, port string, path string) net.Conn {
|
||||
func NewHTTPObfs(conn netproxy.Conn, host string, port string, path string) netproxy.Conn {
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package simpleobfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/net/proxy"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
@ -17,7 +17,7 @@ const (
|
||||
|
||||
// SimpleObfs is a base http-obfs struct
|
||||
type SimpleObfs struct {
|
||||
dialer proxy.Dialer
|
||||
dialer netproxy.Dialer
|
||||
obfstype ObfsType
|
||||
addr string
|
||||
path string
|
||||
@ -25,7 +25,7 @@ type SimpleObfs struct {
|
||||
}
|
||||
|
||||
// NewSimpleobfs returns a simpleobfs proxy.
|
||||
func NewSimpleObfs(s string, d proxy.Dialer) (*SimpleObfs, error) {
|
||||
func NewSimpleObfs(s string, d netproxy.Dialer) (*SimpleObfs, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("simpleobfs: %w", err)
|
||||
@ -56,13 +56,13 @@ func NewSimpleObfs(s string, d proxy.Dialer) (*SimpleObfs, error) {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// Dial connects to the address addr on the network net via the proxy.
|
||||
func (s *SimpleObfs) Dial(network, addr string) (c net.Conn, err error) {
|
||||
if network == "udp" {
|
||||
return nil, fmt.Errorf("simple-obfs does not support UDP")
|
||||
}
|
||||
func (s *SimpleObfs) DialUdp(addr string) (conn netproxy.PacketConn, err error) {
|
||||
return nil, fmt.Errorf("%w: simpleobfs+udp", netproxy.UnsupportedTunnelTypeError)
|
||||
}
|
||||
// DialTcp connects to the address addr on the network net via the proxy.
|
||||
func (s *SimpleObfs) DialTcp(addr string) (c netproxy.Conn, err error) {
|
||||
|
||||
rc, err := s.dialer.Dial("tcp", s.addr)
|
||||
rc, err := s.dialer.DialTcp(s.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[simpleobfs]: dial to %s: %w", s.addr, err)
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ package simpleobfs
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/mzz2017/softwind/pkg/fastrand"
|
||||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@ -18,7 +18,7 @@ const (
|
||||
|
||||
// TLSObfs is shadowsocks tls simple-obfs implementation
|
||||
type TLSObfs struct {
|
||||
net.Conn
|
||||
netproxy.Conn
|
||||
server string
|
||||
remain int
|
||||
firstRequest bool
|
||||
@ -112,7 +112,7 @@ func (to *TLSObfs) write(b []byte) (int, error) {
|
||||
}
|
||||
|
||||
// NewTLSObfs return a SimpleObfs
|
||||
func NewTLSObfs(conn net.Conn, server string) net.Conn {
|
||||
func NewTLSObfs(conn netproxy.Conn, server string) netproxy.Conn {
|
||||
return &TLSObfs{
|
||||
Conn: conn,
|
||||
server: server,
|
||||
|
@ -3,14 +3,13 @@ package tls
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"golang.org/x/net/proxy"
|
||||
"net"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// Tls is a base Tls struct
|
||||
type Tls struct {
|
||||
dialer proxy.Dialer
|
||||
dialer netproxy.Dialer
|
||||
addr string
|
||||
serverName string
|
||||
skipVerify bool
|
||||
@ -18,7 +17,7 @@ type Tls struct {
|
||||
}
|
||||
|
||||
// NewTls returns a Tls infra.
|
||||
func NewTls(s string, d proxy.Dialer) (*Tls, error) {
|
||||
func NewTls(s string, d netproxy.Dialer) (*Tls, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewTls: %w", err)
|
||||
@ -48,13 +47,20 @@ func NewTls(s string, d proxy.Dialer) (*Tls, error) {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (s *Tls) Dial(network, addr string) (conn net.Conn, err error) {
|
||||
rc, err := s.dialer.Dial("tcp", addr)
|
||||
func (s *Tls) DialUdp(addr string) (conn netproxy.PacketConn, err error) {
|
||||
return nil, fmt.Errorf("%w: tls+udp", netproxy.UnsupportedTunnelTypeError)
|
||||
}
|
||||
func (s *Tls) DialTcp(addr string) (conn netproxy.Conn, err error) {
|
||||
rc, err := s.dialer.DialTcp(addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[Tls]: dial to %s: %w", s.addr, err)
|
||||
}
|
||||
|
||||
tlsConn := tls.Client(rc, s.tlsConfig)
|
||||
tlsConn := tls.Client(&netproxy.FakeNetConn{
|
||||
Conn: rc,
|
||||
LAddr: nil,
|
||||
RAddr: nil,
|
||||
}, s.tlsConfig)
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/gorilla/websocket"
|
||||
"golang.org/x/net/proxy"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -13,14 +13,14 @@ import (
|
||||
|
||||
// Ws is a base Ws struct
|
||||
type Ws struct {
|
||||
dialer proxy.Dialer
|
||||
dialer netproxy.Dialer
|
||||
wsAddr string
|
||||
header http.Header
|
||||
wsDialer *websocket.Dialer
|
||||
}
|
||||
|
||||
// NewWs returns a Ws infra.
|
||||
func NewWs(s string, d proxy.Dialer) (*Ws, error) {
|
||||
func NewWs(s string, d netproxy.Dialer) (*Ws, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewWs: %w", err)
|
||||
@ -44,7 +44,17 @@ func NewWs(s string, d proxy.Dialer) (*Ws, error) {
|
||||
}
|
||||
t.wsAddr = wsUrl.String() + u.Path
|
||||
t.wsDialer = &websocket.Dialer{
|
||||
NetDial: d.Dial,
|
||||
NetDial: func(network, addr string) (net.Conn, error) {
|
||||
c, err := d.DialTcp(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &netproxy.FakeNetConn{
|
||||
Conn: c,
|
||||
LAddr: nil,
|
||||
RAddr: nil,
|
||||
}, nil
|
||||
},
|
||||
//Subprotocols: []string{"binary"},
|
||||
}
|
||||
if u.Scheme == "wss" {
|
||||
@ -57,8 +67,12 @@ func NewWs(s string, d proxy.Dialer) (*Ws, error) {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// Dial connects to the address addr on the network net via the infra.
|
||||
func (s *Ws) Dial(network, addr string) (net.Conn, error) {
|
||||
func (s *Ws) DialUdp(addr string) (netproxy.PacketConn, error) {
|
||||
return nil, fmt.Errorf("%w: ws+udp", netproxy.UnsupportedTunnelTypeError)
|
||||
}
|
||||
|
||||
// DialTcp connects to the address addr on the network net via the infra.
|
||||
func (s *Ws) DialTcp(addr string) (netproxy.Conn, error) {
|
||||
rc, _, err := s.wsDialer.Dial(s.wsAddr, s.header)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[Ws]: dial to %s: %w", s.wsAddr, err)
|
||||
|
@ -431,7 +431,7 @@ func (c *ControlPlane) ChooseDialTarget(outbound consts.OutboundIndex, dst netip
|
||||
c.log.WithFields(logrus.Fields{
|
||||
"from": dst.String(),
|
||||
"to": dialTarget,
|
||||
}).Debugln("Reset dial target to domain")
|
||||
}).Debugln("Rewrite dial target to domain")
|
||||
}
|
||||
return dialTarget
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ func (c *ControlPlane) lookupDnsRespCache(domain string, t dnsmessage.Type) (cac
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ControlPlane) LookupDnsRespCache(msg *dnsmessage.Message) (resp []byte) {
|
||||
func (c *ControlPlane) LookupDnsRespCache_(msg *dnsmessage.Message) (resp []byte) {
|
||||
if len(msg.Questions) == 0 {
|
||||
return nil
|
||||
}
|
||||
@ -140,6 +140,7 @@ func (c *ControlPlane) LookupDnsRespCache(msg *dnsmessage.Message) (resp []byte)
|
||||
cache.FillInto(msg)
|
||||
b, err := msg.Pack()
|
||||
if err != nil {
|
||||
c.log.Warnf("failed to pack: %v", err)
|
||||
return nil
|
||||
}
|
||||
if err = c.BatchUpdateDomainRouting(cache); err != nil {
|
||||
|
@ -8,10 +8,10 @@ package control
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/protocol/direct"
|
||||
"github.com/v2rayA/dae/common"
|
||||
"github.com/v2rayA/dae/common/consts"
|
||||
"github.com/v2rayA/dae/common/netutils"
|
||||
"github.com/v2rayA/dae/component/outbound/dialer"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"sync"
|
||||
@ -79,7 +79,7 @@ func ResolveDnsUpstream(ctx context.Context, dnsUpstream *url.URL) (up *DnsUpstr
|
||||
}
|
||||
}()
|
||||
|
||||
ip46, err := netutils.ParseIp46(ctx, dialer.SymmetricDirect, systemDns, hostname, false)
|
||||
ip46, err := netutils.ParseIp46(ctx, direct.SymmetricDirect, systemDns, hostname, false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve dns_upstream: %w", err)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ package control
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/mzz2017/softwind/pkg/zeroalloc/io"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/v2rayA/dae/common"
|
||||
@ -95,7 +96,7 @@ func (c *ControlPlane) handleConn(lConn net.Conn) (err error) {
|
||||
}).Infof("%v <-> %v", RefineSourceToShow(src, dst.Addr(), consts.LanWanFlag_NotApplicable), RefineAddrPortToShow(dst))
|
||||
|
||||
// Dial and relay.
|
||||
rConn, err := d.Dial("tcp", c.ChooseDialTarget(outboundIndex, dst, domain))
|
||||
rConn, err := d.DialTcp(c.ChooseDialTarget(outboundIndex, dst, domain))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to dial %v: %w", dst, err)
|
||||
}
|
||||
@ -117,7 +118,7 @@ type WriteCloser interface {
|
||||
CloseWrite() error
|
||||
}
|
||||
|
||||
func RelayTCP(lConn, rConn net.Conn) (err error) {
|
||||
func RelayTCP(lConn, rConn netproxy.Conn) (err error) {
|
||||
eCh := make(chan error, 1)
|
||||
go func() {
|
||||
_, e := io.Copy(rConn, lConn)
|
||||
|
@ -176,7 +176,7 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
||||
var dummyFrom *netip.AddrPort
|
||||
destToSend := realDst
|
||||
if isDns {
|
||||
if resp := c.LookupDnsRespCache(dnsMessage); resp != nil {
|
||||
if resp := c.LookupDnsRespCache_(dnsMessage); resp != nil {
|
||||
// Send cache to client directly.
|
||||
if err = sendPkt(resp, destToSend, realSrc, src, lConn, lanWanFlag); err != nil {
|
||||
return fmt.Errorf("failed to write cached DNS resp: %w", err)
|
||||
@ -301,8 +301,11 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
||||
// So se should trust home devices even if they make rush-answer (or looks like).
|
||||
return outboundIndex == consts.OutboundDirect && !common.ConvergeIp(from.Addr()).IsPrivate()
|
||||
})
|
||||
|
||||
// Dial and send.
|
||||
// TODO: Rewritten domain should not use full-cone (such as VMess Packet Addr).
|
||||
// Maybe we should set up a mapping for UDP: Dialer + Target Domain => Remote Resolved IP.
|
||||
destToSend = netip.AddrPortFrom(common.ConvergeIp(destToSend.Addr()), destToSend.Port())
|
||||
tgtToSend := c.ChooseDialTarget(outboundIndex, destToSend, domain)
|
||||
switch l4proto {
|
||||
case consts.L4ProtoStr_UDP:
|
||||
// Get udp endpoint.
|
||||
@ -318,14 +321,14 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
||||
DialerFunc: func() (*dialer.Dialer, error) {
|
||||
return dialerForNew, nil
|
||||
},
|
||||
// FIXME: how to write domain into UDP tunnel?
|
||||
Target: destToSend,
|
||||
Target: tgtToSend,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to GetOrCreate (policy: %v): %w", outbound.GetSelectionPolicy(), err)
|
||||
}
|
||||
|
||||
// If the udp endpoint has been not alive, remove it from pool and get a new one.
|
||||
if !isNew && !ue.Dialer.MustGetAlive(networkType) {
|
||||
if !isNew && outbound.GetSelectionPolicy() != consts.DialerSelectionPolicy_Fixed && !ue.Dialer.MustGetAlive(networkType) {
|
||||
c.log.WithFields(logrus.Fields{
|
||||
"src": RefineSourceToShow(realSrc, realDst.Addr(), lanWanFlag),
|
||||
"network": networkType.String(),
|
||||
@ -339,8 +342,7 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
||||
// This is real dialer.
|
||||
realDialer = ue.Dialer
|
||||
|
||||
//log.Printf("WriteToUDPAddrPort->%v", destToSend)
|
||||
_, err = ue.WriteToUDPAddrPort(data, destToSend)
|
||||
_, err = ue.WriteTo(data, tgtToSend)
|
||||
if err != nil {
|
||||
c.log.WithFields(logrus.Fields{
|
||||
"to": destToSend.String(),
|
||||
@ -364,7 +366,7 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
||||
|
||||
// We can block because we are in a coroutine.
|
||||
|
||||
conn, err := dialerForNew.Dial("tcp", c.ChooseDialTarget(outboundIndex, destToSend, domain))
|
||||
conn, err := dialerForNew.DialTcp(tgtToSend)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to dial proxy to tcp: %w", err)
|
||||
}
|
||||
@ -395,7 +397,7 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
||||
buf = bReq
|
||||
}
|
||||
var n int
|
||||
if n, err = conn.Read(buf[:respLen]); err != nil {
|
||||
if n, err = io.ReadFull(conn, buf[:respLen]); err != nil {
|
||||
return fmt.Errorf("failed to read DNS resp payload: %w", err)
|
||||
}
|
||||
if err = udpHandler(buf[:n], destToSend); err != nil {
|
||||
|
@ -8,9 +8,9 @@ package control
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/mzz2017/softwind/pool"
|
||||
"github.com/v2rayA/dae/component/outbound/dialer"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sync"
|
||||
"time"
|
||||
@ -19,7 +19,7 @@ import (
|
||||
type UdpHandler func(data []byte, from netip.AddrPort) error
|
||||
|
||||
type UdpEndpoint struct {
|
||||
conn net.PacketConn
|
||||
conn netproxy.PacketConn
|
||||
// mu protects deadlineTimer
|
||||
mu sync.Mutex
|
||||
deadlineTimer *time.Timer
|
||||
@ -40,7 +40,7 @@ func (ue *UdpEndpoint) start() {
|
||||
ue.mu.Lock()
|
||||
ue.deadlineTimer.Reset(ue.NatTimeout)
|
||||
ue.mu.Unlock()
|
||||
if err = ue.handler(buf[:n], from.(*net.UDPAddr).AddrPort()); err != nil {
|
||||
if err = ue.handler(buf[:n], from); err != nil {
|
||||
if errors.Is(err, SuspectedRushAnswerError) {
|
||||
continue
|
||||
}
|
||||
@ -52,8 +52,8 @@ func (ue *UdpEndpoint) start() {
|
||||
ue.mu.Unlock()
|
||||
}
|
||||
|
||||
func (ue *UdpEndpoint) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (int, error) {
|
||||
return ue.conn.WriteTo(b, net.UDPAddrFromAddrPort(addr))
|
||||
func (ue *UdpEndpoint) WriteTo(b []byte, addr string) (int, error) {
|
||||
return ue.conn.WriteTo(b, addr)
|
||||
}
|
||||
|
||||
func (ue *UdpEndpoint) Close() error {
|
||||
@ -75,7 +75,7 @@ type UdpEndpointOptions struct {
|
||||
NatTimeout time.Duration
|
||||
DialerFunc func() (*dialer.Dialer, error)
|
||||
// Target is useful only if the underlay does not support Full-cone.
|
||||
Target netip.AddrPort
|
||||
Target string
|
||||
}
|
||||
|
||||
var DefaultUdpEndpointPool = NewUdpEndpointPool()
|
||||
@ -100,6 +100,7 @@ func (p *UdpEndpointPool) Remove(lAddr netip.AddrPort, udpEndpoint *UdpEndpoint)
|
||||
}
|
||||
|
||||
func (p *UdpEndpointPool) GetOrCreate(lAddr netip.AddrPort, createOption *UdpEndpointOptions) (udpEndpoint *UdpEndpoint, isNew bool, err error) {
|
||||
// TODO: fine-grained lock.
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
ue, ok := p.pool[lAddr]
|
||||
@ -120,15 +121,15 @@ func (p *UdpEndpointPool) GetOrCreate(lAddr netip.AddrPort, createOption *UdpEnd
|
||||
return nil, true, err
|
||||
}
|
||||
|
||||
udpConn, err := d.Dial("udp", createOption.Target.String())
|
||||
udpConn, err := d.DialUdp(createOption.Target)
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
if _, ok = udpConn.(net.PacketConn); !ok {
|
||||
if _, ok = udpConn.(netproxy.PacketConn); !ok {
|
||||
return nil, true, fmt.Errorf("protocol does not support udp")
|
||||
}
|
||||
ue = &UdpEndpoint{
|
||||
conn: udpConn.(net.PacketConn),
|
||||
conn: udpConn.(netproxy.PacketConn),
|
||||
deadlineTimer: time.AfterFunc(createOption.NatTimeout, func() {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
@ -51,9 +51,10 @@ global {
|
||||
# 1. "ip". Dial proxy using the IP from DNS directly. This allows your ipv4, ipv6 to choose the optimal path
|
||||
# respectively, and makes the IP version requested by the application meet expectations. For example, if you
|
||||
# use curl -4 ip.sb, you will request IPv4 via proxy and get a IPv4 echo. And curl -6 ip.sb will request IPv6.
|
||||
# This may solve some wierd full-cone problem if your are be your node support that.
|
||||
# 2. "domain". Dial proxy using the domain from sniffing. This will relieve DNS pollution problem to a great extent
|
||||
# if have impure DNS environment. This policy does not impact routing. That is to say, domain reset will be
|
||||
# after traffic split.
|
||||
# if have impure DNS environment. Generally, this mode brings faster response time. This policy does not impact
|
||||
# routing. That is to say, domain rewrite will be after traffic split and dae will not resolve IP and re-route.
|
||||
dial_mode: domain
|
||||
}
|
||||
|
||||
|
5
go.mod
5
go.mod
@ -9,14 +9,14 @@ require (
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
||||
github.com/mzz2017/softwind v0.0.0-20230213075606-e58b03d6ac4b
|
||||
github.com/mzz2017/softwind v0.0.0-20230217163103-acb4981669fe
|
||||
github.com/safchain/ethtool v0.0.0-20230116090318-67cc41908669
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/v2rayA/dae-config-dist/go/dae_config v0.0.0-20230201041341-1758ee5161c1
|
||||
github.com/v2rayA/shadowsocksR v1.0.4
|
||||
github.com/vishvananda/netlink v1.1.0
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2
|
||||
golang.org/x/crypto v0.5.0
|
||||
golang.org/x/net v0.5.0
|
||||
golang.org/x/sys v0.4.0
|
||||
google.golang.org/protobuf v1.28.1
|
||||
@ -44,7 +44,6 @@ require (
|
||||
github.com/stretchr/testify v1.8.1 // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
||||
gitlab.com/yawning/chacha20.git v0.0.0-20190903091407-6d1cb28dc72c // indirect
|
||||
golang.org/x/crypto v0.5.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
|
||||
golang.org/x/term v0.4.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
|
18
go.sum
18
go.sum
@ -17,7 +17,6 @@ github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fp
|
||||
github.com/dgryski/go-rc2 v0.0.0-20150621095337-8a9021637152 h1:ED31mPIxDJnrLt9W9dH5xgd/6KjzEACKHBVGQ33czc0=
|
||||
github.com/dgryski/go-rc2 v0.0.0-20150621095337-8a9021637152/go.mod h1:I9fhc/EvSg88cDxmfQ47v35Ssz9rlFunL/KY0A1JAYI=
|
||||
github.com/ebfe/rc2 v0.0.0-20131011165748-24b9757f5521 h1:fBHFH+Y/GPGFGo7LIrErQc3p2MeAhoIQNgaxPWYsSxk=
|
||||
github.com/ebfe/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:ucvhdsUCE3TH0LoLRb6ShHiJl8e39dGlx6A4g/ujlow=
|
||||
github.com/eknkc/basex v1.0.1 h1:TcyAkqh4oJXgV3WYyL4KEfCMk9W8oJCpmx1bo+jVgKY=
|
||||
github.com/eknkc/basex v1.0.1/go.mod h1:k/F/exNEHFdbs3ZHuasoP2E7zeWwZblG84Y7Z59vQRo=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
@ -51,8 +50,6 @@ github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
@ -69,9 +66,8 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/mzz2017/disk-bloom v1.0.1 h1:rEF9MiXd9qMW3ibRpqcerLXULoTgRlM21yqqJl1B90M=
|
||||
github.com/mzz2017/disk-bloom v1.0.1/go.mod h1:JLHETtUu44Z6iBmsqzkOtFlRvXSlKnxjwiBRDapizDI=
|
||||
github.com/mzz2017/softwind v0.0.0-20230213075606-e58b03d6ac4b h1:Hwx9RlLBGWWzr8M3zIoL5bnrhPiT3mHDkawkuCb1E7Q=
|
||||
github.com/mzz2017/softwind v0.0.0-20230213075606-e58b03d6ac4b/go.mod h1:K1nXwtBokwEsfOfdT/5zV6R8QabGkyhcR0iuTrRZcYY=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/mzz2017/softwind v0.0.0-20230217163103-acb4981669fe h1:i2YtHdgl0oYWKixm/kX5skbrhaAQj1ZHR5RZKyqaySY=
|
||||
github.com/mzz2017/softwind v0.0.0-20230217163103-acb4981669fe/go.mod h1:V8GFOtdpTgzCJtCVXRqjmdDsY+PIhCCx4JpD0zq8Z7I=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
@ -91,7 +87,6 @@ github.com/safchain/ethtool v0.0.0-20230116090318-67cc41908669 h1:2uB3lH1zhL5dQf
|
||||
github.com/safchain/ethtool v0.0.0-20230116090318-67cc41908669/go.mod h1:Op2Wq4eQEVKmpd+02CtUlkHYjL2vQJ+wyzyc3/KGqFk=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
@ -101,7 +96,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
@ -113,8 +107,6 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/v2rayA/dae-config-dist/go/dae_config v0.0.0-20230201041341-1758ee5161c1 h1:Ke91ZtZItOO8/SK8nhZ1tXfXcUxj4Meq5pET/L9bHII=
|
||||
github.com/v2rayA/dae-config-dist/go/dae_config v0.0.0-20230201041341-1758ee5161c1/go.mod h1:JiTWeZybOkBfCqv/fy5jbFhXTxuLlyrI76gRNazz2sU=
|
||||
github.com/v2rayA/shadowsocksR v1.0.4 h1:65Ltdy+I/DnlkQTJj+R+X85zhZ63ORE1Roy+agAcF/s=
|
||||
github.com/v2rayA/shadowsocksR v1.0.4/go.mod h1:CyOhDLy8/AKedsi16xRYAMmkxSCH1ukJPaacaTdRfQg=
|
||||
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
@ -128,7 +120,6 @@ gitlab.com/yawning/chacha20.git v0.0.0-20190903091407-6d1cb28dc72c/go.mod h1:3x6
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
|
||||
@ -139,7 +130,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -152,19 +142,16 @@ golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=
|
||||
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -193,7 +180,6 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
|
Loading…
Reference in New Issue
Block a user