Merge branch 'dev' of https://github.com/Dreamacro/clash into Alpha
This commit is contained in:
commit
c24bb51cc1
15 changed files with 447 additions and 338 deletions
|
@ -23,6 +23,8 @@ import (
|
|||
M "github.com/sagernet/sing/common/metadata"
|
||||
)
|
||||
|
||||
var ErrUDPRemoteAddrMismatch = errors.New("udp packet dropped due to mismatched remote address")
|
||||
|
||||
type Vmess struct {
|
||||
*Base
|
||||
client *vmess.Client
|
||||
|
@ -409,7 +411,14 @@ type vmessPacketConn struct {
|
|||
access sync.Mutex
|
||||
}
|
||||
|
||||
// WriteTo implments C.PacketConn.WriteTo
|
||||
// Since VMess doesn't support full cone NAT by design, we verify if addr matches uc.rAddr, and drop the packet if not.
|
||||
func (uc *vmessPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||
allowedAddr := uc.rAddr.(*net.UDPAddr)
|
||||
destAddr := addr.(*net.UDPAddr)
|
||||
if !(allowedAddr.IP.Equal(destAddr.IP) && allowedAddr.Port == destAddr.Port) {
|
||||
return 0, ErrUDPRemoteAddrMismatch
|
||||
}
|
||||
uc.access.Lock()
|
||||
defer uc.access.Unlock()
|
||||
return uc.Conn.Write(b)
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
"github.com/Dreamacro/clash/log"
|
||||
T "github.com/Dreamacro/clash/tunnel"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
|
@ -68,8 +69,6 @@ type Inbound struct {
|
|||
MixedPort int `json:"mixed-port"`
|
||||
ShadowSocksConfig string `json:"ss-config"`
|
||||
VmessConfig string `json:"vmess-config"`
|
||||
TcpTunConfig string `json:"tcptun-config"`
|
||||
UdpTunConfig string `json:"udptun-config"`
|
||||
Authentication []string `json:"authentication"`
|
||||
AllowLan bool `json:"allow-lan"`
|
||||
BindAddress string `json:"bind-address"`
|
||||
|
@ -247,6 +246,7 @@ type Config struct {
|
|||
Proxies map[string]C.Proxy
|
||||
Providers map[string]providerTypes.ProxyProvider
|
||||
RuleProviders map[string]providerTypes.RuleProvider
|
||||
Tunnels []Tunnel
|
||||
Sniffer *Sniffer
|
||||
}
|
||||
|
||||
|
@ -314,6 +314,64 @@ type RawTuicServer struct {
|
|||
MaxUdpRelayPacketSize int `yaml:"max-udp-relay-packet-size" json:"max-udp-relay-packet-size,omitempty"`
|
||||
}
|
||||
|
||||
type tunnel struct {
|
||||
Network []string `yaml:"network"`
|
||||
Address string `yaml:"address"`
|
||||
Target string `yaml:"target"`
|
||||
Proxy string `yaml:"proxy"`
|
||||
}
|
||||
|
||||
type Tunnel tunnel
|
||||
|
||||
// UnmarshalYAML implements yaml.Unmarshaler
|
||||
func (t *Tunnel) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
var tp string
|
||||
if err := unmarshal(&tp); err != nil {
|
||||
var inner tunnel
|
||||
if err := unmarshal(&inner); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = Tunnel(inner)
|
||||
return nil
|
||||
}
|
||||
|
||||
// parse udp/tcp,address,target,proxy
|
||||
parts := lo.Map(strings.Split(tp, ","), func(s string, _ int) string {
|
||||
return strings.TrimSpace(s)
|
||||
})
|
||||
if len(parts) != 4 {
|
||||
return fmt.Errorf("invalid tunnel config %s", tp)
|
||||
}
|
||||
network := strings.Split(parts[0], "/")
|
||||
|
||||
// validate network
|
||||
for _, n := range network {
|
||||
switch n {
|
||||
case "tcp", "udp":
|
||||
default:
|
||||
return fmt.Errorf("invalid tunnel network %s", n)
|
||||
}
|
||||
}
|
||||
|
||||
// validate address and target
|
||||
address := parts[1]
|
||||
target := parts[2]
|
||||
for _, addr := range []string{address, target} {
|
||||
if _, _, err := net.SplitHostPort(addr); err != nil {
|
||||
return fmt.Errorf("invalid tunnel target or address %s", addr)
|
||||
}
|
||||
}
|
||||
|
||||
*t = Tunnel(tunnel{
|
||||
Network: network,
|
||||
Address: address,
|
||||
Target: target,
|
||||
Proxy: parts[3],
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
type RawConfig struct {
|
||||
Port int `yaml:"port"`
|
||||
SocksPort int `yaml:"socks-port"`
|
||||
|
@ -322,8 +380,6 @@ type RawConfig struct {
|
|||
MixedPort int `yaml:"mixed-port"`
|
||||
ShadowSocksConfig string `yaml:"ss-config"`
|
||||
VmessConfig string `yaml:"vmess-config"`
|
||||
TcpTunConfig string `yaml:"tcptun-config"`
|
||||
UdpTunConfig string `yaml:"udptun-config"`
|
||||
InboundTfo bool `yaml:"inbound-tfo"`
|
||||
Authentication []string `yaml:"authentication"`
|
||||
AllowLan bool `yaml:"allow-lan"`
|
||||
|
@ -337,6 +393,7 @@ type RawConfig struct {
|
|||
Secret string `yaml:"secret"`
|
||||
Interface string `yaml:"interface-name"`
|
||||
RoutingMark int `yaml:"routing-mark"`
|
||||
Tunnels []Tunnel `yaml:"tunnels"`
|
||||
GeodataMode bool `yaml:"geodata-mode"`
|
||||
GeodataLoader string `yaml:"geodata-loader"`
|
||||
TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
|
||||
|
@ -560,6 +617,14 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
|||
|
||||
config.Users = parseAuthentication(rawCfg.Authentication)
|
||||
|
||||
config.Tunnels = rawCfg.Tunnels
|
||||
// verify tunnels
|
||||
for _, t := range config.Tunnels {
|
||||
if _, ok := config.Proxies[t.Proxy]; !ok {
|
||||
return nil, fmt.Errorf("tunnel proxy %s not found", t.Proxy)
|
||||
}
|
||||
}
|
||||
|
||||
config.Sniffer, err = parseSniffer(rawCfg.Sniffer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -567,6 +632,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
|||
|
||||
elapsedTime := time.Since(startTime) / time.Millisecond // duration in ms
|
||||
log.Infoln("Initial configuration complete, total time: %dms", elapsedTime) //Segment finished in xxm
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
|
@ -591,8 +657,6 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
|||
MixedPort: cfg.MixedPort,
|
||||
ShadowSocksConfig: cfg.ShadowSocksConfig,
|
||||
VmessConfig: cfg.VmessConfig,
|
||||
TcpTunConfig: cfg.TcpTunConfig,
|
||||
UdpTunConfig: cfg.UdpTunConfig,
|
||||
AllowLan: cfg.AllowLan,
|
||||
BindAddress: cfg.BindAddress,
|
||||
InboundTfo: cfg.InboundTfo,
|
||||
|
|
|
@ -24,8 +24,7 @@ const (
|
|||
VMESS
|
||||
REDIR
|
||||
TPROXY
|
||||
TCPTUN
|
||||
UDPTUN
|
||||
TUNNEL
|
||||
TUN
|
||||
TUIC
|
||||
INNER
|
||||
|
@ -66,10 +65,8 @@ func (t Type) String() string {
|
|||
return "Redir"
|
||||
case TPROXY:
|
||||
return "TProxy"
|
||||
case TCPTUN:
|
||||
return "TcpTun"
|
||||
case UDPTUN:
|
||||
return "UdpTun"
|
||||
case TUNNEL:
|
||||
return "Tunnel"
|
||||
case TUN:
|
||||
return "Tun"
|
||||
case TUIC:
|
||||
|
@ -100,10 +97,8 @@ func ParseType(t string) (*Type, error) {
|
|||
res = REDIR
|
||||
case "TPROXY":
|
||||
res = TPROXY
|
||||
case "TCPTUN":
|
||||
res = TCPTUN
|
||||
case "UDPTUN":
|
||||
res = UDPTUN
|
||||
case "TUNNEL":
|
||||
res = TUNNEL
|
||||
case "TUN":
|
||||
res = TUN
|
||||
case "TUIC":
|
||||
|
@ -122,20 +117,21 @@ func (t Type) MarshalJSON() ([]byte, error) {
|
|||
|
||||
// Metadata is used to store connection address
|
||||
type Metadata struct {
|
||||
NetWork NetWork `json:"network"`
|
||||
Type Type `json:"type"`
|
||||
SrcIP netip.Addr `json:"sourceIP"`
|
||||
DstIP netip.Addr `json:"destinationIP"`
|
||||
SrcPort string `json:"sourcePort"`
|
||||
DstPort string `json:"destinationPort"`
|
||||
InIP netip.Addr `json:"inboundIP"`
|
||||
InPort string `json:"inboundPort"`
|
||||
Host string `json:"host"`
|
||||
DNSMode DNSMode `json:"dnsMode"`
|
||||
Uid *uint32 `json:"uid"`
|
||||
Process string `json:"process"`
|
||||
ProcessPath string `json:"processPath"`
|
||||
RemoteDst string `json:"remoteDestination"`
|
||||
NetWork NetWork `json:"network"`
|
||||
Type Type `json:"type"`
|
||||
SrcIP netip.Addr `json:"sourceIP"`
|
||||
DstIP netip.Addr `json:"destinationIP"`
|
||||
SrcPort string `json:"sourcePort"`
|
||||
DstPort string `json:"destinationPort"`
|
||||
InIP netip.Addr `json:"inboundIP"`
|
||||
InPort string `json:"inboundPort"`
|
||||
Host string `json:"host"`
|
||||
DNSMode DNSMode `json:"dnsMode"`
|
||||
Uid *uint32 `json:"uid"`
|
||||
Process string `json:"process"`
|
||||
ProcessPath string `json:"processPath"`
|
||||
SpecialProxy string `json:"specialProxy"`
|
||||
RemoteDst string `json:"remoteDestination"`
|
||||
}
|
||||
|
||||
func (m *Metadata) RemoteAddress() string {
|
||||
|
|
12
go.mod
12
go.mod
|
@ -18,7 +18,7 @@ require (
|
|||
github.com/insomniacslk/dhcp v0.0.0-20221001123530-5308ebe5334c
|
||||
github.com/jpillora/backoff v1.0.0
|
||||
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40
|
||||
github.com/mdlayher/netlink v1.1.1
|
||||
github.com/mdlayher/netlink v1.7.0
|
||||
github.com/metacubex/quic-go v0.31.1-0.20221127023445-9f0ce65a734e
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20221109114053-16c22adda03c
|
||||
github.com/miekg/dns v1.1.50
|
||||
|
@ -29,17 +29,18 @@ require (
|
|||
github.com/sagernet/sing-tun v0.0.0-20221104121441-66c48a57776f
|
||||
github.com/sagernet/sing-vmess v0.0.0-20221109021549-b446d5bdddf0
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221108054404-7c2acadba17c
|
||||
github.com/samber/lo v1.35.0
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837
|
||||
go.etcd.io/bbolt v1.3.6
|
||||
go.uber.org/atomic v1.10.0
|
||||
go.uber.org/automaxprocs v1.5.1
|
||||
golang.org/x/crypto v0.2.0
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9
|
||||
golang.org/x/net v0.2.0
|
||||
golang.org/x/net v0.2.1-0.20221117215542-ecf7fda6a59e
|
||||
golang.org/x/sync v0.1.0
|
||||
golang.org/x/sys v0.2.0
|
||||
golang.org/x/sys v0.2.1-0.20221110211117-d684c6f88669
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
lukechampine.com/blake3 v1.1.7
|
||||
|
@ -56,11 +57,14 @@ require (
|
|||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||
github.com/josharian/native v1.0.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
|
||||
github.com/marten-seemann/qpack v0.3.0 // indirect
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect
|
||||
github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect
|
||||
github.com/mdlayher/socket v0.4.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.2.0 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.10.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
|
|
29
go.sum
29
go.sum
|
@ -46,7 +46,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
|||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
|
@ -60,12 +61,13 @@ github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Go
|
|||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20221001123530-5308ebe5334c h1:OCFM4+DXTWfNlyeoddrTwdup/ztkGSyAMR2UGcPckNQ=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20221001123530-5308ebe5334c/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
|
||||
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
|
||||
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c h1:7cpGGTQO6+OuYQWkueqeXuErSjs1NZtpALpv1x7Mq4g=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
|
@ -85,16 +87,20 @@ github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQob
|
|||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||
github.com/mdlayher/netlink v1.1.1 h1:VqG+Voq9V4uZ+04vjIrcSCWDpf91B1xxbP4QBUmUJE8=
|
||||
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
||||
github.com/mdlayher/netlink v1.7.0 h1:ZNGI4V7i1fJ94DPYtWhI/R85i/Q7ZxnuhUJQcJMoodI=
|
||||
github.com/mdlayher/netlink v1.7.0/go.mod h1:nKO5CSjE/DJjVhk/TNp6vCE1ktVxEA8VEh8drhZzxsQ=
|
||||
github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||
github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw=
|
||||
github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc=
|
||||
github.com/metacubex/quic-go v0.31.1-0.20221127023445-9f0ce65a734e h1:RnfC6+sShJ3biU2Q2wuh4FxZ8/3fp1QG+1zAfswVehA=
|
||||
github.com/metacubex/quic-go v0.31.1-0.20221127023445-9f0ce65a734e/go.mod h1:7NPWVTLiX2Ss9q9gBNZaNHsPqZ3Tg/ApyrXxxUYbl78=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20221109114053-16c22adda03c h1:VHtXDny/TNOF7YDT9d9Qkr+x6K1O4cejXLlyPUXDeXQ=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20221109114053-16c22adda03c/go.mod h1:fULJ451x1/XlpIhl+Oo+EPGKla9tFZaqT5dKLrZ+NvM=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
||||
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
||||
|
@ -119,6 +125,8 @@ github.com/sagernet/sing-vmess v0.0.0-20221109021549-b446d5bdddf0 h1:z3kuD3hPNdE
|
|||
github.com/sagernet/sing-vmess v0.0.0-20221109021549-b446d5bdddf0/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221108054404-7c2acadba17c h1:qP3ZOHnjZalvqbjundbXiv/YrNlo3HOgrKc+S1QGs0U=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221108054404-7c2acadba17c/go.mod h1:euOmN6O5kk9dQmgSS8Df4psAl3TCjxOz0NW60EWkSaI=
|
||||
github.com/samber/lo v1.35.0 h1:GlT8CV1GE+v97Y7MLF1wXvX6mjoxZ+hi61tj/ZcQwY0=
|
||||
github.com/samber/lo v1.35.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
|
@ -133,6 +141,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
|
||||
github.com/u-root/uio v0.0.0-20210528114334-82958018845c h1:BFvcl34IGnw8yvJi8hlqLFo9EshRInwWBs2M5fGWzQA=
|
||||
github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||
|
@ -149,8 +158,8 @@ go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66
|
|||
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.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE=
|
||||
golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a h1:diz9pEYuTIuLMJLs3rGDkeaTsNyRs6duYdFyPAxzE/U=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 h1:RjggHMcaTVp0LOVZcW0bo8alwHrOaCrGUDgfWUHhnN4=
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
|
@ -170,8 +179,8 @@ golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.2.1-0.20221117215542-ecf7fda6a59e h1:IVOjWZQH/57UDcpX19vSmMz8w3ohroOMWohn8qWpRkg=
|
||||
golang.org/x/net v0.2.1-0.20221117215542-ecf7fda6a59e/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
|
@ -200,8 +209,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/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-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.1-0.20221110211117-d684c6f88669 h1:pvmSpBoSG0gD2LLPAX15QHPig8xsbU0tu1sSAmResqk=
|
||||
golang.org/x/sys v0.2.1-0.20221110211117-d684c6f88669/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
@ -226,7 +235,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
|||
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-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/constant/provider"
|
||||
"github.com/Dreamacro/clash/dns"
|
||||
P "github.com/Dreamacro/clash/listener"
|
||||
"github.com/Dreamacro/clash/listener"
|
||||
authStore "github.com/Dreamacro/clash/listener/auth"
|
||||
"github.com/Dreamacro/clash/listener/inner"
|
||||
"github.com/Dreamacro/clash/listener/tproxy"
|
||||
|
@ -89,6 +89,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
|
|||
updateIPTables(cfg)
|
||||
updateTun(cfg.General)
|
||||
updateExperimental(cfg)
|
||||
updateTunnels(cfg.Tunnels)
|
||||
|
||||
log.SetLevel(cfg.General.LogLevel)
|
||||
}
|
||||
|
@ -98,7 +99,7 @@ func initInnerTcp() {
|
|||
}
|
||||
|
||||
func GetGeneral() *config.General {
|
||||
ports := P.GetPorts()
|
||||
ports := listener.GetPorts()
|
||||
var authenticator []string
|
||||
if auth := authStore.Authenticator(); auth != nil {
|
||||
authenticator = auth.Users()
|
||||
|
@ -113,18 +114,16 @@ func GetGeneral() *config.General {
|
|||
MixedPort: ports.MixedPort,
|
||||
ShadowSocksConfig: ports.ShadowSocksConfig,
|
||||
VmessConfig: ports.VmessConfig,
|
||||
TcpTunConfig: ports.TcpTunConfig,
|
||||
UdpTunConfig: ports.UdpTunConfig,
|
||||
Authentication: authenticator,
|
||||
AllowLan: P.AllowLan(),
|
||||
BindAddress: P.BindAddress(),
|
||||
AllowLan: listener.AllowLan(),
|
||||
BindAddress: listener.BindAddress(),
|
||||
},
|
||||
Mode: tunnel.Mode(),
|
||||
LogLevel: log.Level(),
|
||||
IPv6: !resolver.DisableIPv6,
|
||||
GeodataLoader: G.LoaderName(),
|
||||
Tun: P.GetTunConf(),
|
||||
TuicServer: P.GetTuicConf(),
|
||||
Tun: listener.GetTunConf(),
|
||||
TuicServer: listener.GetTuicConf(),
|
||||
Interface: dialer.DefaultInterface.Load(),
|
||||
Sniffing: tunnel.IsSniffing(),
|
||||
TCPConcurrent: dialer.GetDial(),
|
||||
|
@ -268,8 +267,8 @@ func updateTun(general *config.General) {
|
|||
if general == nil {
|
||||
return
|
||||
}
|
||||
P.ReCreateTun(general.Tun, tunnel.TCPIn(), tunnel.UDPIn())
|
||||
P.ReCreateRedirToTun(general.Tun.RedirectToTun)
|
||||
listener.ReCreateTun(general.Tun, tunnel.TCPIn(), tunnel.UDPIn())
|
||||
listener.ReCreateRedirToTun(general.Tun.RedirectToTun)
|
||||
}
|
||||
|
||||
func updateSniffer(sniffer *config.Sniffer) {
|
||||
|
@ -295,6 +294,10 @@ func updateSniffer(sniffer *config.Sniffer) {
|
|||
}
|
||||
}
|
||||
|
||||
func updateTunnels(tunnels []config.Tunnel) {
|
||||
listener.PatchTunnel(tunnels, tunnel.TCPIn(), tunnel.UDPIn())
|
||||
}
|
||||
|
||||
func updateGeneral(general *config.General, force bool) {
|
||||
tunnel.SetMode(general.Mode)
|
||||
tunnel.SetAlwaysFindProcess(general.EnableProcess)
|
||||
|
@ -332,27 +335,25 @@ func updateGeneral(general *config.General, force bool) {
|
|||
G.SetLoader(geodataLoader)
|
||||
|
||||
allowLan := general.AllowLan
|
||||
P.SetAllowLan(allowLan)
|
||||
listener.SetAllowLan(allowLan)
|
||||
|
||||
bindAddress := general.BindAddress
|
||||
P.SetBindAddress(bindAddress)
|
||||
listener.SetBindAddress(bindAddress)
|
||||
|
||||
inbound.SetTfo(general.InboundTfo)
|
||||
|
||||
tcpIn := tunnel.TCPIn()
|
||||
udpIn := tunnel.UDPIn()
|
||||
|
||||
P.ReCreateHTTP(general.Port, tcpIn)
|
||||
P.ReCreateSocks(general.SocksPort, tcpIn, udpIn)
|
||||
P.ReCreateRedir(general.RedirPort, tcpIn, udpIn)
|
||||
P.ReCreateAutoRedir(general.EBpf.AutoRedir, tcpIn, udpIn)
|
||||
P.ReCreateTProxy(general.TProxyPort, tcpIn, udpIn)
|
||||
P.ReCreateMixed(general.MixedPort, tcpIn, udpIn)
|
||||
P.ReCreateShadowSocks(general.ShadowSocksConfig, tcpIn, udpIn)
|
||||
P.ReCreateVmess(general.VmessConfig, tcpIn, udpIn)
|
||||
P.ReCreateTcpTun(general.TcpTunConfig, tcpIn, udpIn)
|
||||
P.ReCreateUdpTun(general.UdpTunConfig, tcpIn, udpIn)
|
||||
P.ReCreateTuic(general.TuicServer, tcpIn, udpIn)
|
||||
listener.ReCreateHTTP(general.Port, tcpIn)
|
||||
listener.ReCreateSocks(general.SocksPort, tcpIn, udpIn)
|
||||
listener.ReCreateRedir(general.RedirPort, tcpIn, udpIn)
|
||||
listener.ReCreateAutoRedir(general.EBpf.AutoRedir, tcpIn, udpIn)
|
||||
listener.ReCreateTProxy(general.TProxyPort, tcpIn, udpIn)
|
||||
listener.ReCreateMixed(general.MixedPort, tcpIn, udpIn)
|
||||
listener.ReCreateShadowSocks(general.ShadowSocksConfig, tcpIn, udpIn)
|
||||
listener.ReCreateVmess(general.VmessConfig, tcpIn, udpIn)
|
||||
listener.ReCreateTuic(general.TuicServer, tcpIn, udpIn)
|
||||
}
|
||||
|
||||
func updateUsers(users []auth.AuthUser) {
|
||||
|
@ -459,7 +460,7 @@ func updateIPTables(cfg *config.Config) {
|
|||
}
|
||||
|
||||
func Shutdown() {
|
||||
P.Cleanup(false)
|
||||
listener.Cleanup(false)
|
||||
tproxy.CleanupTProxyIPTables()
|
||||
resolver.StoreFakePoolState()
|
||||
|
||||
|
|
|
@ -249,8 +249,6 @@ func patchConfigs(w http.ResponseWriter, r *http.Request) {
|
|||
P.ReCreateTun(pointerOrDefaultTun(general.Tun, P.LastTunConf), tcpIn, udpIn)
|
||||
P.ReCreateShadowSocks(pointerOrDefaultString(general.ShadowSocksConfig, ports.ShadowSocksConfig), tcpIn, udpIn)
|
||||
P.ReCreateVmess(pointerOrDefaultString(general.VmessConfig, ports.VmessConfig), tcpIn, udpIn)
|
||||
P.ReCreateTcpTun(pointerOrDefaultString(general.TcptunConfig, ports.TcpTunConfig), tcpIn, udpIn)
|
||||
P.ReCreateUdpTun(pointerOrDefaultString(general.UdptunConfig, ports.UdpTunConfig), tcpIn, udpIn)
|
||||
P.ReCreateTuic(pointerOrDefaultTuicServer(general.TuicServer, P.LastTuicConf), tcpIn, udpIn)
|
||||
|
||||
if general.Mode != nil {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package proxy
|
||||
package listener
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -6,6 +6,7 @@ import (
|
|||
"net"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/Dreamacro/clash/adapter/inbound"
|
||||
|
@ -24,6 +25,8 @@ import (
|
|||
"github.com/Dreamacro/clash/listener/tuic"
|
||||
"github.com/Dreamacro/clash/listener/tunnel"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -39,11 +42,11 @@ var (
|
|||
tproxyUDPListener *tproxy.UDPListener
|
||||
mixedListener *mixed.Listener
|
||||
mixedUDPLister *socks.UDPListener
|
||||
tunnelTCPListeners = map[string]*tunnel.Listener{}
|
||||
tunnelUDPListeners = map[string]*tunnel.PacketConn{}
|
||||
tunLister *sing_tun.Listener
|
||||
shadowSocksListener C.AdvanceListener
|
||||
vmessListener *sing_vmess.Listener
|
||||
tcpTunListener *tunnel.Listener
|
||||
udpTunListener *tunnel.UdpListener
|
||||
tuicListener *tuic.Listener
|
||||
autoRedirListener *autoredir.Listener
|
||||
autoRedirProgram *ebpf.TcEBpfProgram
|
||||
|
@ -55,11 +58,10 @@ var (
|
|||
redirMux sync.Mutex
|
||||
tproxyMux sync.Mutex
|
||||
mixedMux sync.Mutex
|
||||
tunnelMux sync.Mutex
|
||||
tunMux sync.Mutex
|
||||
ssMux sync.Mutex
|
||||
vmessMux sync.Mutex
|
||||
tcpTunMux sync.Mutex
|
||||
udpTunMux sync.Mutex
|
||||
tuicMux sync.Mutex
|
||||
autoRedirMux sync.Mutex
|
||||
tcMux sync.Mutex
|
||||
|
@ -76,8 +78,6 @@ type Ports struct {
|
|||
MixedPort int `json:"mixed-port"`
|
||||
ShadowSocksConfig string `json:"ss-config"`
|
||||
VmessConfig string `json:"vmess-config"`
|
||||
TcpTunConfig string `json:"tcptun-config"`
|
||||
UdpTunConfig string `json:"udptun-config"`
|
||||
}
|
||||
|
||||
func GetTunConf() config.Tun {
|
||||
|
@ -331,76 +331,6 @@ func ReCreateVmess(vmessConfig string, tcpIn chan<- C.ConnContext, udpIn chan<-
|
|||
return
|
||||
}
|
||||
|
||||
func ReCreateTcpTun(config string, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) {
|
||||
tcpTunMux.Lock()
|
||||
defer tcpTunMux.Unlock()
|
||||
shouldIgnore := false
|
||||
|
||||
var err error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
log.Errorln("Start TcpTun server error: %s", err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
if tcpTunListener != nil {
|
||||
if tcpTunListener.Config() != config {
|
||||
tcpTunListener.Close()
|
||||
tcpTunListener = nil
|
||||
} else {
|
||||
shouldIgnore = true
|
||||
}
|
||||
}
|
||||
|
||||
if shouldIgnore {
|
||||
return
|
||||
}
|
||||
|
||||
tcpListener, err := tunnel.New(config, tcpIn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
tcpTunListener = tcpListener
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func ReCreateUdpTun(config string, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) {
|
||||
udpTunMux.Lock()
|
||||
defer udpTunMux.Unlock()
|
||||
shouldIgnore := false
|
||||
|
||||
var err error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
log.Errorln("Start UdpTun server error: %s", err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
if udpTunListener != nil {
|
||||
if udpTunListener.Config() != config {
|
||||
udpTunListener.Close()
|
||||
udpTunListener = nil
|
||||
} else {
|
||||
shouldIgnore = true
|
||||
}
|
||||
}
|
||||
|
||||
if shouldIgnore {
|
||||
return
|
||||
}
|
||||
|
||||
udpListener, err := tunnel.NewUdp(config, udpIn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
udpTunListener = udpListener
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func ReCreateTuic(config config.TuicServer, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) {
|
||||
tuicMux.Lock()
|
||||
defer func() {
|
||||
|
@ -664,6 +594,95 @@ func ReCreateAutoRedir(ifaceNames []string, tcpIn chan<- C.ConnContext, _ chan<-
|
|||
log.Infoln("Auto redirect proxy listening at: %s, attached tc ebpf program to interfaces %v", autoRedirListener.Address(), autoRedirProgram.RawNICs())
|
||||
}
|
||||
|
||||
func PatchTunnel(tunnels []config.Tunnel, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) {
|
||||
tunnelMux.Lock()
|
||||
defer tunnelMux.Unlock()
|
||||
|
||||
type addrProxy struct {
|
||||
network string
|
||||
addr string
|
||||
target string
|
||||
proxy string
|
||||
}
|
||||
|
||||
tcpOld := lo.Map(
|
||||
lo.Keys(tunnelTCPListeners),
|
||||
func(key string, _ int) addrProxy {
|
||||
parts := strings.Split(key, "/")
|
||||
return addrProxy{
|
||||
network: "tcp",
|
||||
addr: parts[0],
|
||||
target: parts[1],
|
||||
proxy: parts[2],
|
||||
}
|
||||
},
|
||||
)
|
||||
udpOld := lo.Map(
|
||||
lo.Keys(tunnelUDPListeners),
|
||||
func(key string, _ int) addrProxy {
|
||||
parts := strings.Split(key, "/")
|
||||
return addrProxy{
|
||||
network: "udp",
|
||||
addr: parts[0],
|
||||
target: parts[1],
|
||||
proxy: parts[2],
|
||||
}
|
||||
},
|
||||
)
|
||||
oldElm := lo.Union(tcpOld, udpOld)
|
||||
|
||||
newElm := lo.FlatMap(
|
||||
tunnels,
|
||||
func(tunnel config.Tunnel, _ int) []addrProxy {
|
||||
return lo.Map(
|
||||
tunnel.Network,
|
||||
func(network string, _ int) addrProxy {
|
||||
return addrProxy{
|
||||
network: network,
|
||||
addr: tunnel.Address,
|
||||
target: tunnel.Target,
|
||||
proxy: tunnel.Proxy,
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
needClose, needCreate := lo.Difference(oldElm, newElm)
|
||||
|
||||
for _, elm := range needClose {
|
||||
key := fmt.Sprintf("%s/%s/%s", elm.addr, elm.target, elm.proxy)
|
||||
if elm.network == "tcp" {
|
||||
tunnelTCPListeners[key].Close()
|
||||
delete(tunnelTCPListeners, key)
|
||||
} else {
|
||||
tunnelUDPListeners[key].Close()
|
||||
delete(tunnelUDPListeners, key)
|
||||
}
|
||||
}
|
||||
|
||||
for _, elm := range needCreate {
|
||||
key := fmt.Sprintf("%s/%s/%s", elm.addr, elm.target, elm.proxy)
|
||||
if elm.network == "tcp" {
|
||||
l, err := tunnel.New(elm.addr, elm.target, elm.proxy, tcpIn)
|
||||
if err != nil {
|
||||
log.Errorln("Start tunnel %s error: %s", elm.target, err.Error())
|
||||
continue
|
||||
}
|
||||
tunnelTCPListeners[key] = l
|
||||
log.Infoln("Tunnel(tcp/%s) proxy %s listening at: %s", elm.target, elm.proxy, tunnelTCPListeners[key].Address())
|
||||
} else {
|
||||
l, err := tunnel.NewUDP(elm.addr, elm.target, elm.proxy, udpIn)
|
||||
if err != nil {
|
||||
log.Errorln("Start tunnel %s error: %s", elm.target, err.Error())
|
||||
continue
|
||||
}
|
||||
tunnelUDPListeners[key] = l
|
||||
log.Infoln("Tunnel(udp/%s) proxy %s listening at: %s", elm.target, elm.proxy, tunnelUDPListeners[key].Address())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetPorts return the ports of proxy servers
|
||||
func GetPorts() *Ports {
|
||||
ports := &Ports{}
|
||||
|
@ -706,14 +725,6 @@ func GetPorts() *Ports {
|
|||
ports.VmessConfig = vmessListener.Config()
|
||||
}
|
||||
|
||||
if tcpTunListener != nil {
|
||||
ports.TcpTunConfig = tcpTunListener.Config()
|
||||
}
|
||||
|
||||
if udpTunListener != nil {
|
||||
ports.UdpTunConfig = udpTunListener.Config()
|
||||
}
|
||||
|
||||
return ports
|
||||
}
|
||||
|
||||
|
|
35
listener/tunnel/packet.go
Normal file
35
listener/tunnel/packet.go
Normal file
|
@ -0,0 +1,35 @@
|
|||
package tunnel
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/Dreamacro/clash/common/pool"
|
||||
)
|
||||
|
||||
type packet struct {
|
||||
pc net.PacketConn
|
||||
rAddr net.Addr
|
||||
payload []byte
|
||||
}
|
||||
|
||||
func (c *packet) Data() []byte {
|
||||
return c.payload
|
||||
}
|
||||
|
||||
// WriteBack write UDP packet with source(ip, port) = `addr`
|
||||
func (c *packet) WriteBack(b []byte, addr net.Addr) (n int, err error) {
|
||||
return c.pc.WriteTo(b, c.rAddr)
|
||||
}
|
||||
|
||||
// LocalAddr returns the source IP/Port of UDP Packet
|
||||
func (c *packet) LocalAddr() net.Addr {
|
||||
return c.rAddr
|
||||
}
|
||||
|
||||
func (c *packet) Drop() {
|
||||
pool.Put(c.payload)
|
||||
}
|
||||
|
||||
func (c *packet) InAddr() net.Addr {
|
||||
return c.pc.LocalAddr()
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package tunnel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/Dreamacro/clash/adapter/inbound"
|
||||
|
@ -10,59 +11,68 @@ import (
|
|||
)
|
||||
|
||||
type Listener struct {
|
||||
closed bool
|
||||
config string
|
||||
listeners []net.Listener
|
||||
listener net.Listener
|
||||
addr string
|
||||
target socks5.Addr
|
||||
proxy string
|
||||
closed bool
|
||||
}
|
||||
|
||||
func New(config string, in chan<- C.ConnContext) (*Listener, error) {
|
||||
tl := &Listener{false, config, nil}
|
||||
pl := PairList{}
|
||||
err := pl.Set(config)
|
||||
// RawAddress implements C.Listener
|
||||
func (l *Listener) RawAddress() string {
|
||||
return l.addr
|
||||
}
|
||||
|
||||
// Address implements C.Listener
|
||||
func (l *Listener) Address() string {
|
||||
return l.listener.Addr().String()
|
||||
}
|
||||
|
||||
// Close implements C.Listener
|
||||
func (l *Listener) Close() error {
|
||||
l.closed = true
|
||||
return l.listener.Close()
|
||||
}
|
||||
|
||||
func (l *Listener) handleTCP(conn net.Conn, in chan<- C.ConnContext) {
|
||||
conn.(*net.TCPConn).SetKeepAlive(true)
|
||||
ctx := inbound.NewSocket(l.target, conn, C.TUNNEL)
|
||||
ctx.Metadata().SpecialProxy = l.proxy
|
||||
in <- ctx
|
||||
}
|
||||
|
||||
func New(addr, target, proxy string, in chan<- C.ConnContext) (*Listener, error) {
|
||||
l, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, p := range pl {
|
||||
addr := p[0]
|
||||
target := p[1]
|
||||
go func() {
|
||||
tgt := socks5.ParseAddr(target)
|
||||
if tgt == nil {
|
||||
log.Errorln("invalid target address %q", target)
|
||||
return
|
||||
}
|
||||
l, err := inbound.Listen("tcp", addr)
|
||||
targetAddr := socks5.ParseAddr(target)
|
||||
if targetAddr == nil {
|
||||
return nil, fmt.Errorf("invalid target address %s", target)
|
||||
}
|
||||
|
||||
log.Infoln("TCP tunnel %s <-> %s", l.Addr().String(), target)
|
||||
|
||||
rl := &Listener{
|
||||
listener: l,
|
||||
target: targetAddr,
|
||||
proxy: proxy,
|
||||
addr: addr,
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
c, err := l.Accept()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
tl.listeners = append(tl.listeners, l)
|
||||
log.Infoln("TCP tunnel %s <-> %s", l.Addr().String(), target)
|
||||
for {
|
||||
c, err := l.Accept()
|
||||
if err != nil {
|
||||
if tl.closed {
|
||||
break
|
||||
}
|
||||
continue
|
||||
if rl.closed {
|
||||
break
|
||||
}
|
||||
_ = c.(*net.TCPConn).SetKeepAlive(true)
|
||||
|
||||
in <- inbound.NewSocket(tgt, c, C.TCPTUN)
|
||||
continue
|
||||
}
|
||||
}()
|
||||
}
|
||||
go rl.handleTCP(c, in)
|
||||
}
|
||||
}()
|
||||
|
||||
return tl, nil
|
||||
}
|
||||
|
||||
func (l *Listener) Close() {
|
||||
l.closed = true
|
||||
for _, lis := range l.listeners {
|
||||
_ = lis.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Listener) Config() string {
|
||||
return l.config
|
||||
return rl, nil
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package tunnel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/Dreamacro/clash/adapter/inbound"
|
||||
|
@ -10,70 +11,78 @@ import (
|
|||
"github.com/Dreamacro/clash/transport/socks5"
|
||||
)
|
||||
|
||||
type UdpListener struct {
|
||||
closed bool
|
||||
config string
|
||||
listeners []net.PacketConn
|
||||
type PacketConn struct {
|
||||
conn net.PacketConn
|
||||
addr string
|
||||
target socks5.Addr
|
||||
proxy string
|
||||
closed bool
|
||||
}
|
||||
|
||||
func NewUdp(config string, in chan<- *inbound.PacketAdapter) (*UdpListener, error) {
|
||||
ul := &UdpListener{false, config, nil}
|
||||
pl := PairList{}
|
||||
err := pl.Set(config)
|
||||
// RawAddress implements C.Listener
|
||||
func (l *PacketConn) RawAddress() string {
|
||||
return l.addr
|
||||
}
|
||||
|
||||
// Address implements C.Listener
|
||||
func (l *PacketConn) Address() string {
|
||||
return l.conn.LocalAddr().String()
|
||||
}
|
||||
|
||||
// Close implements C.Listener
|
||||
func (l *PacketConn) Close() error {
|
||||
l.closed = true
|
||||
return l.conn.Close()
|
||||
}
|
||||
|
||||
func NewUDP(addr, target, proxy string, in chan<- *inbound.PacketAdapter) (*PacketConn, error) {
|
||||
l, err := net.ListenPacket("udp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, p := range pl {
|
||||
addr := p[0]
|
||||
target := p[1]
|
||||
go func() {
|
||||
tgt := socks5.ParseAddr(target)
|
||||
if tgt == nil {
|
||||
log.Errorln("invalid target address %q", target)
|
||||
return
|
||||
}
|
||||
l, err := net.ListenPacket("udp", addr)
|
||||
targetAddr := socks5.ParseAddr(target)
|
||||
if targetAddr == nil {
|
||||
return nil, fmt.Errorf("invalid target address %s", target)
|
||||
}
|
||||
|
||||
log.Infoln("Udp tunnel %s <-> %s", l.LocalAddr().String(), target)
|
||||
|
||||
sl := &PacketConn{
|
||||
conn: l,
|
||||
target: targetAddr,
|
||||
proxy: proxy,
|
||||
addr: addr,
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
buf := pool.Get(pool.UDPBufferSize)
|
||||
n, remoteAddr, err := l.ReadFrom(buf)
|
||||
if err != nil {
|
||||
return
|
||||
pool.Put(buf)
|
||||
if sl.closed {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
ul.listeners = append(ul.listeners, l)
|
||||
log.Infoln("Udp tunnel %s <-> %s", l.LocalAddr().String(), target)
|
||||
for {
|
||||
buf := pool.Get(pool.RelayBufferSize)
|
||||
n, remoteAddr, err := l.ReadFrom(buf)
|
||||
if err != nil {
|
||||
pool.Put(buf)
|
||||
if ul.closed {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
packet := &packet{
|
||||
pc: l,
|
||||
rAddr: remoteAddr,
|
||||
payload: buf[:n],
|
||||
bufRef: buf,
|
||||
}
|
||||
select {
|
||||
case in <- inbound.NewPacket(tgt, packet, C.UDPTUN):
|
||||
default:
|
||||
}
|
||||
sl.handleUDP(l, in, buf[:n], remoteAddr)
|
||||
}
|
||||
}()
|
||||
|
||||
}
|
||||
}()
|
||||
return sl, nil
|
||||
}
|
||||
|
||||
func (l *PacketConn) handleUDP(pc net.PacketConn, in chan<- *inbound.PacketAdapter, buf []byte, addr net.Addr) {
|
||||
packet := &packet{
|
||||
pc: pc,
|
||||
rAddr: addr,
|
||||
payload: buf,
|
||||
}
|
||||
|
||||
return ul, nil
|
||||
}
|
||||
|
||||
func (l *UdpListener) Close() {
|
||||
l.closed = true
|
||||
for _, lis := range l.listeners {
|
||||
_ = lis.Close()
|
||||
ctx := inbound.NewPacket(l.target, packet, C.TUNNEL)
|
||||
ctx.Metadata().SpecialProxy = l.proxy
|
||||
select {
|
||||
case in <- ctx:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func (l *UdpListener) Config() string {
|
||||
return l.config
|
||||
}
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
package tunnel
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/Dreamacro/clash/common/pool"
|
||||
)
|
||||
|
||||
type PairList [][2]string // key1=val1,key2=val2,...
|
||||
|
||||
func (l PairList) String() string {
|
||||
s := make([]string, len(l))
|
||||
for i, pair := range l {
|
||||
s[i] = pair[0] + "=" + pair[1]
|
||||
}
|
||||
return strings.Join(s, ",")
|
||||
}
|
||||
func (l *PairList) Set(s string) error {
|
||||
for _, item := range strings.Split(s, ",") {
|
||||
pair := strings.Split(item, "=")
|
||||
if len(pair) != 2 {
|
||||
return nil
|
||||
}
|
||||
*l = append(*l, [2]string{pair[0], pair[1]})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type packet struct {
|
||||
pc net.PacketConn
|
||||
rAddr net.Addr
|
||||
payload []byte
|
||||
bufRef []byte
|
||||
}
|
||||
|
||||
func (c *packet) Data() []byte {
|
||||
return c.payload
|
||||
}
|
||||
|
||||
// WriteBack wirtes UDP packet with source(ip, port) = `addr`
|
||||
func (c *packet) WriteBack(b []byte, addr net.Addr) (n int, err error) {
|
||||
if addr == nil {
|
||||
err = errors.New("address is invalid")
|
||||
return
|
||||
}
|
||||
packet := b
|
||||
return c.pc.WriteTo(packet, c.rAddr)
|
||||
}
|
||||
|
||||
// LocalAddr returns the source IP/Port of UDP Packet
|
||||
func (c *packet) LocalAddr() net.Addr {
|
||||
return c.rAddr
|
||||
}
|
||||
|
||||
func (c *packet) Drop() {
|
||||
pool.Put(c.bufRef)
|
||||
}
|
||||
|
||||
func (c *packet) InAddr() net.Addr {
|
||||
return c.pc.LocalAddr()
|
||||
}
|
16
test/go.mod
16
test/go.mod
|
@ -4,11 +4,11 @@ go 1.19
|
|||
|
||||
require (
|
||||
github.com/Dreamacro/clash v0.0.0
|
||||
github.com/docker/docker v20.10.17+incompatible
|
||||
github.com/docker/docker v20.10.21+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/miekg/dns v1.1.50
|
||||
github.com/stretchr/testify v1.8.1
|
||||
golang.org/x/net v0.2.0
|
||||
golang.org/x/net v0.2.1-0.20221117215542-ecf7fda6a59e
|
||||
)
|
||||
|
||||
replace github.com/Dreamacro/clash => ../
|
||||
|
@ -29,18 +29,21 @@ require (
|
|||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/gopacket v1.1.19 // indirect
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/insomniacslk/dhcp v0.0.0-20221001123530-5308ebe5334c // indirect
|
||||
github.com/josharian/native v1.0.0 // indirect
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
|
||||
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 // indirect
|
||||
github.com/marten-seemann/qpack v0.3.0 // indirect
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect
|
||||
github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect
|
||||
github.com/mdlayher/netlink v1.1.1 // indirect
|
||||
github.com/metacubex/quic-go v0.31.1-0.20221125020617-0f0618ad3eaa // indirect
|
||||
github.com/mdlayher/netlink v1.7.0 // indirect
|
||||
github.com/mdlayher/socket v0.4.0 // indirect
|
||||
github.com/metacubex/quic-go v0.31.1-0.20221127023445-9f0ce65a734e // indirect
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20221109114053-16c22adda03c // indirect
|
||||
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
|
@ -59,17 +62,18 @@ require (
|
|||
github.com/sagernet/sing-tun v0.0.0-20221104121441-66c48a57776f // indirect
|
||||
github.com/sagernet/sing-vmess v0.0.0-20221109021549-b446d5bdddf0 // indirect
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221108054404-7c2acadba17c // indirect
|
||||
github.com/samber/lo v1.35.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
||||
github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
golang.org/x/crypto v0.2.0 // indirect
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a // indirect
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
golang.org/x/sys v0.2.1-0.20221110211117-d684c6f88669 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
|
|
37
test/go.sum
37
test/go.sum
|
@ -19,8 +19,8 @@ github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo
|
|||
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
||||
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE=
|
||||
github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.21+incompatible h1:UTLdBmHk3bEY+w8qeO5KttOhy6OmXWsl/FEet9Uswog=
|
||||
github.com/docker/docker v20.10.21+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
|
@ -47,7 +47,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
|||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
|
@ -59,12 +60,13 @@ github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Go
|
|||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20221001123530-5308ebe5334c h1:OCFM4+DXTWfNlyeoddrTwdup/ztkGSyAMR2UGcPckNQ=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20221001123530-5308ebe5334c/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
|
||||
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
|
||||
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c h1:7cpGGTQO6+OuYQWkueqeXuErSjs1NZtpALpv1x7Mq4g=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
|
@ -86,12 +88,15 @@ github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQob
|
|||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||
github.com/mdlayher/netlink v1.1.1 h1:VqG+Voq9V4uZ+04vjIrcSCWDpf91B1xxbP4QBUmUJE8=
|
||||
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
||||
github.com/mdlayher/netlink v1.7.0 h1:ZNGI4V7i1fJ94DPYtWhI/R85i/Q7ZxnuhUJQcJMoodI=
|
||||
github.com/mdlayher/netlink v1.7.0/go.mod h1:nKO5CSjE/DJjVhk/TNp6vCE1ktVxEA8VEh8drhZzxsQ=
|
||||
github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||
github.com/metacubex/quic-go v0.31.1-0.20221125020617-0f0618ad3eaa h1:Zc0nF/kgKDRn/Ab9jL1KNjOOe8JaM/sjsak1gNVVG6g=
|
||||
github.com/metacubex/quic-go v0.31.1-0.20221125020617-0f0618ad3eaa/go.mod h1:7NPWVTLiX2Ss9q9gBNZaNHsPqZ3Tg/ApyrXxxUYbl78=
|
||||
github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw=
|
||||
github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc=
|
||||
github.com/metacubex/quic-go v0.31.1-0.20221127023445-9f0ce65a734e h1:RnfC6+sShJ3biU2Q2wuh4FxZ8/3fp1QG+1zAfswVehA=
|
||||
github.com/metacubex/quic-go v0.31.1-0.20221127023445-9f0ce65a734e/go.mod h1:7NPWVTLiX2Ss9q9gBNZaNHsPqZ3Tg/ApyrXxxUYbl78=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20221109114053-16c22adda03c h1:VHtXDny/TNOF7YDT9d9Qkr+x6K1O4cejXLlyPUXDeXQ=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20221109114053-16c22adda03c/go.mod h1:fULJ451x1/XlpIhl+Oo+EPGKla9tFZaqT5dKLrZ+NvM=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
|
@ -100,6 +105,7 @@ github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c h1:RC8WMpjonrBfyAh6VN/PO
|
|||
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c/go.mod h1:9OcmHNQQUTbk4XCffrLgN1NEKc2mh5u++biHVrvHsSU=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
||||
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
||||
|
@ -133,6 +139,8 @@ github.com/sagernet/sing-vmess v0.0.0-20221109021549-b446d5bdddf0 h1:z3kuD3hPNdE
|
|||
github.com/sagernet/sing-vmess v0.0.0-20221109021549-b446d5bdddf0/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221108054404-7c2acadba17c h1:qP3ZOHnjZalvqbjundbXiv/YrNlo3HOgrKc+S1QGs0U=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221108054404-7c2acadba17c/go.mod h1:euOmN6O5kk9dQmgSS8Df4psAl3TCjxOz0NW60EWkSaI=
|
||||
github.com/samber/lo v1.35.0 h1:GlT8CV1GE+v97Y7MLF1wXvX6mjoxZ+hi61tj/ZcQwY0=
|
||||
github.com/samber/lo v1.35.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8=
|
||||
github.com/sirupsen/logrus v1.7.0/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=
|
||||
|
@ -149,6 +157,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
|
||||
github.com/u-root/uio v0.0.0-20210528114334-82958018845c h1:BFvcl34IGnw8yvJi8hlqLFo9EshRInwWBs2M5fGWzQA=
|
||||
github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||
|
@ -165,8 +174,8 @@ go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0
|
|||
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.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE=
|
||||
golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a h1:diz9pEYuTIuLMJLs3rGDkeaTsNyRs6duYdFyPAxzE/U=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 h1:RjggHMcaTVp0LOVZcW0bo8alwHrOaCrGUDgfWUHhnN4=
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
|
@ -190,8 +199,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.2.1-0.20221117215542-ecf7fda6a59e h1:IVOjWZQH/57UDcpX19vSmMz8w3ohroOMWohn8qWpRkg=
|
||||
golang.org/x/net v0.2.1-0.20221117215542-ecf7fda6a59e/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -225,8 +234,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/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-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.1-0.20221110211117-d684c6f88669 h1:pvmSpBoSG0gD2LLPAX15QHPig8xsbU0tu1sSAmResqk=
|
||||
golang.org/x/sys v0.2.1-0.20221110211117-d684c6f88669/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
@ -254,7 +263,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
|||
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-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
|
|
@ -194,7 +194,16 @@ func preHandleMetadata(metadata *C.Metadata) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func resolveMetadata(_ C.PlainContext, metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err error) {
|
||||
func resolveMetadata(ctx C.PlainContext, metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err error) {
|
||||
if metadata.SpecialProxy != "" {
|
||||
var exist bool
|
||||
proxy, exist = proxies[metadata.SpecialProxy]
|
||||
if !exist {
|
||||
err = fmt.Errorf("proxy %s not found", metadata.SpecialProxy)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
switch mode {
|
||||
case Direct:
|
||||
proxy = proxies["DIRECT"]
|
||||
|
@ -298,6 +307,8 @@ func handleUDPConn(packet *inbound.PacketAdapter) {
|
|||
pc := statistic.NewUDPTracker(rawPc, statistic.DefaultManager, metadata, rule)
|
||||
|
||||
switch true {
|
||||
case metadata.SpecialProxy != "":
|
||||
log.Infoln("[UDP] %s --> %s using %s", metadata.SourceAddress(), metadata.RemoteAddress(), metadata.SpecialProxy)
|
||||
case rule != nil:
|
||||
if rule.Payload() != "" {
|
||||
log.Infoln("[UDP] %s --> %s match %s using %s", metadata.SourceDetail(), metadata.RemoteAddress(), fmt.Sprintf("%s(%s)", rule.RuleType().String(), rule.Payload()), rawPc.Chains().String())
|
||||
|
@ -384,6 +395,8 @@ func handleTCPConn(connCtx C.ConnContext) {
|
|||
}(remoteConn)
|
||||
|
||||
switch true {
|
||||
case metadata.SpecialProxy != "":
|
||||
log.Infoln("[TCP] %s --> %s using %s", metadata.SourceAddress(), metadata.RemoteAddress(), metadata.SpecialProxy)
|
||||
case rule != nil:
|
||||
if rule.Payload() != "" {
|
||||
log.Infoln("[TCP] %s --> %s match %s using %s", metadata.SourceDetail(), metadata.RemoteAddress(), fmt.Sprintf("%s(%s)", rule.RuleType().String(), rule.Payload()), remoteConn.Chains().String())
|
||||
|
|
Loading…
Reference in a new issue