chore: change C.PacketAdapter from a struct to an interface

This commit is contained in:
wwqgtxx 2022-12-04 14:37:52 +08:00
parent 4f75201a98
commit 6fc62da7ae
32 changed files with 267 additions and 251 deletions

View file

@ -5,9 +5,18 @@ import (
"github.com/Dreamacro/clash/transport/socks5" "github.com/Dreamacro/clash/transport/socks5"
) )
// PacketAdapter is a UDP Packet adapter for socks/redir/tun
type PacketAdapter struct {
C.UDPPacket
metadata *C.Metadata
}
// Metadata returns destination metadata
func (s *PacketAdapter) Metadata() *C.Metadata {
return s.metadata
}
func NewPacketWithInfos(target socks5.Addr, packet C.UDPPacket, source C.Type, inName , preferRulesName string) *C.PacketAdapter { func NewPacketWithInfos(target socks5.Addr, packet C.UDPPacket, source C.Type, inName, preferRulesName string) C.PacketAdapter {
metadata := parseSocksAddr(target) metadata := parseSocksAddr(target)
metadata.NetWork = C.UDP metadata.NetWork = C.UDP
metadata.Type = source metadata.Type = source
@ -24,13 +33,13 @@ func NewPacketWithInfos(target socks5.Addr, packet C.UDPPacket, source C.Type, i
} }
} }
return C.NewPacketAdapter( return &PacketAdapter{
packet, packet,
metadata, metadata,
) }
} }
// NewPacket is PacketAdapter generator // NewPacket is PacketAdapter generator
func NewPacket(target socks5.Addr, packet C.UDPPacket, source C.Type) *C.PacketAdapter { func NewPacket(target socks5.Addr, packet C.UDPPacket, source C.Type) C.PacketAdapter {
return NewPacketWithInfos(target, packet, source, "", "") return NewPacketWithInfos(target, packet, source, "", "")
} }

View file

@ -14,16 +14,11 @@ import (
"strings" "strings"
"time" "time"
"github.com/Dreamacro/clash/common/utils"
"github.com/Dreamacro/clash/listener/sing_tun"
"github.com/Dreamacro/clash/listener/tunnel"
R "github.com/Dreamacro/clash/rules"
RP "github.com/Dreamacro/clash/rules/provider"
L "github.com/Dreamacro/clash/listener"
"github.com/Dreamacro/clash/adapter" "github.com/Dreamacro/clash/adapter"
"github.com/Dreamacro/clash/adapter/outbound" "github.com/Dreamacro/clash/adapter/outbound"
"github.com/Dreamacro/clash/adapter/outboundgroup" "github.com/Dreamacro/clash/adapter/outboundgroup"
"github.com/Dreamacro/clash/adapter/provider" "github.com/Dreamacro/clash/adapter/provider"
"github.com/Dreamacro/clash/common/utils"
"github.com/Dreamacro/clash/component/auth" "github.com/Dreamacro/clash/component/auth"
"github.com/Dreamacro/clash/component/dialer" "github.com/Dreamacro/clash/component/dialer"
"github.com/Dreamacro/clash/component/fakeip" "github.com/Dreamacro/clash/component/fakeip"
@ -34,7 +29,12 @@ import (
providerTypes "github.com/Dreamacro/clash/constant/provider" providerTypes "github.com/Dreamacro/clash/constant/provider"
snifferTypes "github.com/Dreamacro/clash/constant/sniffer" snifferTypes "github.com/Dreamacro/clash/constant/sniffer"
"github.com/Dreamacro/clash/dns" "github.com/Dreamacro/clash/dns"
L "github.com/Dreamacro/clash/listener"
LC "github.com/Dreamacro/clash/listener/config"
"github.com/Dreamacro/clash/listener/tunnel"
"github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/log"
R "github.com/Dreamacro/clash/rules"
RP "github.com/Dreamacro/clash/rules/provider"
T "github.com/Dreamacro/clash/tunnel" T "github.com/Dreamacro/clash/tunnel"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@ -148,21 +148,21 @@ type Tun struct {
AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"` AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"`
RedirectToTun []string `yaml:"-" json:"-"` RedirectToTun []string `yaml:"-" json:"-"`
MTU uint32 `yaml:"mtu" json:"mtu,omitempty"` MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
Inet4Address []sing_tun.ListenPrefix `yaml:"inet4-address" json:"inet4-address,omitempty"` Inet4Address []LC.ListenPrefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
Inet6Address []sing_tun.ListenPrefix `yaml:"inet6-address" json:"inet6-address,omitempty"` Inet6Address []LC.ListenPrefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"` StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"`
Inet4RouteAddress []sing_tun.ListenPrefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"` Inet4RouteAddress []LC.ListenPrefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"`
Inet6RouteAddress []sing_tun.ListenPrefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"` Inet6RouteAddress []LC.ListenPrefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"`
IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"` IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"` IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"` ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"` ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"` IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"`
IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"` IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"`
ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"` ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"`
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"` EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"` UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
} }
// IPTables config // IPTables config
@ -244,19 +244,19 @@ type RawTun struct {
MTU uint32 `yaml:"mtu" json:"mtu,omitempty"` MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
//Inet4Address []ListenPrefix `yaml:"inet4-address" json:"inet4_address,omitempty"` //Inet4Address []ListenPrefix `yaml:"inet4-address" json:"inet4_address,omitempty"`
Inet6Address []sing_tun.ListenPrefix `yaml:"inet6-address" json:"inet6_address,omitempty"` Inet6Address []LC.ListenPrefix `yaml:"inet6-address" json:"inet6_address,omitempty"`
StrictRoute bool `yaml:"strict-route" json:"strict_route,omitempty"` StrictRoute bool `yaml:"strict-route" json:"strict_route,omitempty"`
Inet4RouteAddress []sing_tun.ListenPrefix `yaml:"inet4_route_address" json:"inet4_route_address,omitempty"` Inet4RouteAddress []LC.ListenPrefix `yaml:"inet4_route_address" json:"inet4_route_address,omitempty"`
Inet6RouteAddress []sing_tun.ListenPrefix `yaml:"inet6_route_address" json:"inet6_route_address,omitempty"` Inet6RouteAddress []LC.ListenPrefix `yaml:"inet6_route_address" json:"inet6_route_address,omitempty"`
IncludeUID []uint32 `yaml:"include-uid" json:"include_uid,omitempty"` IncludeUID []uint32 `yaml:"include-uid" json:"include_uid,omitempty"`
IncludeUIDRange []string `yaml:"include-uid-range" json:"include_uid_range,omitempty"` IncludeUIDRange []string `yaml:"include-uid-range" json:"include_uid_range,omitempty"`
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude_uid,omitempty"` ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude_uid,omitempty"`
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude_uid_range,omitempty"` ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude_uid_range,omitempty"`
IncludeAndroidUser []int `yaml:"include-android-user" json:"include_android_user,omitempty"` IncludeAndroidUser []int `yaml:"include-android-user" json:"include_android_user,omitempty"`
IncludePackage []string `yaml:"include-package" json:"include_package,omitempty"` IncludePackage []string `yaml:"include-package" json:"include_package,omitempty"`
ExcludePackage []string `yaml:"exclude-package" json:"exclude_package,omitempty"` ExcludePackage []string `yaml:"exclude-package" json:"exclude_package,omitempty"`
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint_independent_nat,omitempty"` EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint_independent_nat,omitempty"`
UDPTimeout int64 `yaml:"udp-timeout" json:"udp_timeout,omitempty"` UDPTimeout int64 `yaml:"udp-timeout" json:"udp_timeout,omitempty"`
} }
type RawTuicServer struct { type RawTuicServer struct {
@ -272,34 +272,33 @@ type RawTuicServer struct {
MaxUdpRelayPacketSize int `yaml:"max-udp-relay-packet-size" json:"max-udp-relay-packet-size,omitempty"` MaxUdpRelayPacketSize int `yaml:"max-udp-relay-packet-size" json:"max-udp-relay-packet-size,omitempty"`
} }
type RawConfig struct { type RawConfig struct {
Port int `yaml:"port"` Port int `yaml:"port"`
SocksPort int `yaml:"socks-port"` SocksPort int `yaml:"socks-port"`
RedirPort int `yaml:"redir-port"` RedirPort int `yaml:"redir-port"`
TProxyPort int `yaml:"tproxy-port"` TProxyPort int `yaml:"tproxy-port"`
MixedPort int `yaml:"mixed-port"` MixedPort int `yaml:"mixed-port"`
ShadowSocksConfig string `yaml:"ss-config"` ShadowSocksConfig string `yaml:"ss-config"`
VmessConfig string `yaml:"vmess-config"` VmessConfig string `yaml:"vmess-config"`
InboundTfo bool `yaml:"inbound-tfo"` InboundTfo bool `yaml:"inbound-tfo"`
Authentication []string `yaml:"authentication"` Authentication []string `yaml:"authentication"`
AllowLan bool `yaml:"allow-lan"` AllowLan bool `yaml:"allow-lan"`
BindAddress string `yaml:"bind-address"` BindAddress string `yaml:"bind-address"`
Mode T.TunnelMode `yaml:"mode"` Mode T.TunnelMode `yaml:"mode"`
UnifiedDelay bool `yaml:"unified-delay"` UnifiedDelay bool `yaml:"unified-delay"`
LogLevel log.LogLevel `yaml:"log-level"` LogLevel log.LogLevel `yaml:"log-level"`
IPv6 bool `yaml:"ipv6"` IPv6 bool `yaml:"ipv6"`
ExternalController string `yaml:"external-controller"` ExternalController string `yaml:"external-controller"`
ExternalControllerTLS string `yaml:"external-controller-tls"` ExternalControllerTLS string `yaml:"external-controller-tls"`
ExternalUI string `yaml:"external-ui"` ExternalUI string `yaml:"external-ui"`
Secret string `yaml:"secret"` Secret string `yaml:"secret"`
Interface string `yaml:"interface-name"` Interface string `yaml:"interface-name"`
RoutingMark int `yaml:"routing-mark"` RoutingMark int `yaml:"routing-mark"`
Tunnels []tunnel.Tunnel `yaml:"tunnels"` Tunnels []tunnel.Tunnel `yaml:"tunnels"`
GeodataMode bool `yaml:"geodata-mode"` GeodataMode bool `yaml:"geodata-mode"`
GeodataLoader string `yaml:"geodata-loader"` GeodataLoader string `yaml:"geodata-loader"`
TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"` TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
EnableProcess bool `yaml:"enable-process" json:"enable-process"` EnableProcess bool `yaml:"enable-process" json:"enable-process"`
Sniffer RawSniffer `yaml:"sniffer"` Sniffer RawSniffer `yaml:"sniffer"`
ProxyProvider map[string]map[string]any `yaml:"proxy-providers"` ProxyProvider map[string]map[string]any `yaml:"proxy-providers"`
@ -384,7 +383,7 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
DNSHijack: []string{"0.0.0.0:53"}, // default hijack all dns query DNSHijack: []string{"0.0.0.0:53"}, // default hijack all dns query
AutoRoute: true, AutoRoute: true,
AutoDetectInterface: true, AutoDetectInterface: true,
Inet6Address: []sing_tun.ListenPrefix{sing_tun.ListenPrefix(netip.MustParsePrefix("fdfe:dcba:9876::1/126"))}, Inet6Address: []LC.ListenPrefix{LC.ListenPrefix(netip.MustParsePrefix("fdfe:dcba:9876::1/126"))},
}, },
TuicServer: RawTuicServer{ TuicServer: RawTuicServer{
Enable: false, Enable: false,
@ -1232,7 +1231,7 @@ func parseTun(rawTun RawTun, general *General) error {
RedirectToTun: rawTun.RedirectToTun, RedirectToTun: rawTun.RedirectToTun,
MTU: rawTun.MTU, MTU: rawTun.MTU,
Inet4Address: []sing_tun.ListenPrefix{sing_tun.ListenPrefix(tunAddressPrefix)}, Inet4Address: []LC.ListenPrefix{LC.ListenPrefix(tunAddressPrefix)},
Inet6Address: rawTun.Inet6Address, Inet6Address: rawTun.Inet6Address,
StrictRoute: rawTun.StrictRoute, StrictRoute: rawTun.StrictRoute,
Inet4RouteAddress: rawTun.Inet4RouteAddress, Inet4RouteAddress: rawTun.Inet4RouteAddress,

View file

@ -210,3 +210,9 @@ type UDPPacket interface {
type UDPPacketInAddr interface { type UDPPacketInAddr interface {
InAddr() net.Addr InAddr() net.Addr
} }
// PacketAdapter is a UDP Packet adapter for socks/redir/tun
type PacketAdapter interface {
UDPPacket
Metadata() *Metadata
}

View file

@ -16,26 +16,8 @@ type AdvanceListener interface {
type NewListener interface { type NewListener interface {
Name() string Name() string
ReCreate(tcpIn chan<- ConnContext,udpIn chan<-*PacketAdapter) error ReCreate(tcpIn chan<- ConnContext, udpIn chan<- PacketAdapter) error
Close() error Close() error
Address() string Address() string
RawAddress() string RawAddress() string
} }
// PacketAdapter is a UDP Packet adapter for socks/redir/tun
type PacketAdapter struct {
UDPPacket
metadata *Metadata
}
func NewPacketAdapter(udppacket UDPPacket,metadata *Metadata)*PacketAdapter{
return &PacketAdapter{
udppacket,
metadata,
}
}
// Metadata returns destination metadata
func (s *PacketAdapter) Metadata() *Metadata {
return s.metadata
}

View file

@ -8,6 +8,7 @@ import (
"sync" "sync"
"github.com/Dreamacro/clash/adapter" "github.com/Dreamacro/clash/adapter"
"github.com/Dreamacro/clash/adapter/inbound"
"github.com/Dreamacro/clash/adapter/outboundgroup" "github.com/Dreamacro/clash/adapter/outboundgroup"
"github.com/Dreamacro/clash/component/auth" "github.com/Dreamacro/clash/component/auth"
"github.com/Dreamacro/clash/component/dialer" "github.com/Dreamacro/clash/component/dialer"
@ -25,11 +26,9 @@ import (
"github.com/Dreamacro/clash/dns" "github.com/Dreamacro/clash/dns"
"github.com/Dreamacro/clash/listener" "github.com/Dreamacro/clash/listener"
authStore "github.com/Dreamacro/clash/listener/auth" authStore "github.com/Dreamacro/clash/listener/auth"
"github.com/Dreamacro/clash/adapter/inbound" LC "github.com/Dreamacro/clash/listener/config"
"github.com/Dreamacro/clash/listener/inner" "github.com/Dreamacro/clash/listener/inner"
"github.com/Dreamacro/clash/listener/sing_tun"
"github.com/Dreamacro/clash/listener/tproxy" "github.com/Dreamacro/clash/listener/tproxy"
"github.com/Dreamacro/clash/listener/tuic"
T "github.com/Dreamacro/clash/listener/tunnel" T "github.com/Dreamacro/clash/listener/tunnel"
"github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/log"
"github.com/Dreamacro/clash/tunnel" "github.com/Dreamacro/clash/tunnel"
@ -281,7 +280,7 @@ func updateTun(general *config.General) {
if general == nil { if general == nil {
return return
} }
listener.ReCreateTun(sing_tun.Tun(general.Tun), tunnel.TCPIn(), tunnel.UDPIn()) listener.ReCreateTun(LC.Tun(general.Tun), tunnel.TCPIn(), tunnel.UDPIn())
listener.ReCreateRedirToTun(general.Tun.RedirectToTun) listener.ReCreateRedirToTun(general.Tun.RedirectToTun)
} }
@ -367,7 +366,7 @@ func updateGeneral(general *config.General, force bool) {
listener.ReCreateMixed(general.MixedPort, tcpIn, udpIn) listener.ReCreateMixed(general.MixedPort, tcpIn, udpIn)
listener.ReCreateShadowSocks(general.ShadowSocksConfig, tcpIn, udpIn) listener.ReCreateShadowSocks(general.ShadowSocksConfig, tcpIn, udpIn)
listener.ReCreateVmess(general.VmessConfig, tcpIn, udpIn) listener.ReCreateVmess(general.VmessConfig, tcpIn, udpIn)
listener.ReCreateTuic(tuic.TuicServer(general.TuicServer), tcpIn, udpIn) listener.ReCreateTuic(LC.TuicServer(general.TuicServer), tcpIn, udpIn)
} }
func updateUsers(users []auth.AuthUser) { func updateUsers(users []auth.AuthUser) {

View file

@ -13,8 +13,7 @@ import (
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/hub/executor" "github.com/Dreamacro/clash/hub/executor"
P "github.com/Dreamacro/clash/listener" P "github.com/Dreamacro/clash/listener"
"github.com/Dreamacro/clash/listener/sing_tun" LC "github.com/Dreamacro/clash/listener/config"
"github.com/Dreamacro/clash/listener/tuic"
"github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/log"
"github.com/Dreamacro/clash/tunnel" "github.com/Dreamacro/clash/tunnel"
@ -69,19 +68,19 @@ type tunSchema struct {
MTU *uint32 `yaml:"mtu" json:"mtu,omitempty"` MTU *uint32 `yaml:"mtu" json:"mtu,omitempty"`
//Inet4Address *[]config.ListenPrefix `yaml:"inet4-address" json:"inet4-address,omitempty"` //Inet4Address *[]config.ListenPrefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
Inet6Address *[]sing_tun.ListenPrefix `yaml:"inet6-address" json:"inet6-address,omitempty"` Inet6Address *[]LC.ListenPrefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
StrictRoute *bool `yaml:"strict-route" json:"strict-route,omitempty"` StrictRoute *bool `yaml:"strict-route" json:"strict-route,omitempty"`
Inet4RouteAddress *[]sing_tun.ListenPrefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"` Inet4RouteAddress *[]LC.ListenPrefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"`
Inet6RouteAddress *[]sing_tun.ListenPrefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"` Inet6RouteAddress *[]LC.ListenPrefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"`
IncludeUID *[]uint32 `yaml:"include-uid" json:"include-uid,omitempty"` IncludeUID *[]uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
IncludeUIDRange *[]string `yaml:"include-uid-range" json:"include-uid-range,omitempty"` IncludeUIDRange *[]string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
ExcludeUID *[]uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"` ExcludeUID *[]uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
ExcludeUIDRange *[]string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"` ExcludeUIDRange *[]string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
IncludeAndroidUser *[]int `yaml:"include-android-user" json:"include-android-user,omitempty"` IncludeAndroidUser *[]int `yaml:"include-android-user" json:"include-android-user,omitempty"`
IncludePackage *[]string `yaml:"include-package" json:"include-package,omitempty"` IncludePackage *[]string `yaml:"include-package" json:"include-package,omitempty"`
ExcludePackage *[]string `yaml:"exclude-package" json:"exclude-package,omitempty"` ExcludePackage *[]string `yaml:"exclude-package" json:"exclude-package,omitempty"`
EndpointIndependentNat *bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"` EndpointIndependentNat *bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
UDPTimeout *int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"` UDPTimeout *int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
} }
type tuicServerSchema struct { type tuicServerSchema struct {
@ -118,7 +117,7 @@ func pointerOrDefaultString(p *string, def string) string {
return def return def
} }
func pointerOrDefaultTun(p *tunSchema, def sing_tun.Tun) sing_tun.Tun { func pointerOrDefaultTun(p *tunSchema, def LC.Tun) LC.Tun {
if p != nil { if p != nil {
def.Enable = p.Enable def.Enable = p.Enable
if p.Device != nil { if p.Device != nil {
@ -176,7 +175,7 @@ func pointerOrDefaultTun(p *tunSchema, def sing_tun.Tun) sing_tun.Tun {
return def return def
} }
func pointerOrDefaultTuicServer(p *tuicServerSchema, def tuic.TuicServer) tuic.TuicServer { func pointerOrDefaultTuicServer(p *tuicServerSchema, def LC.TuicServer) LC.TuicServer {
if p != nil { if p != nil {
def.Enable = p.Enable def.Enable = p.Enable
if p.Listen != nil { if p.Listen != nil {

View file

@ -9,9 +9,9 @@ import (
"time" "time"
"github.com/Dreamacro/clash/adapter/inbound" "github.com/Dreamacro/clash/adapter/inbound"
CN "github.com/Dreamacro/clash/common/net"
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/log"
CN "github.com/Dreamacro/clash/common/net"
"github.com/Dreamacro/clash/tunnel/statistic" "github.com/Dreamacro/clash/tunnel/statistic"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"

23
listener/config/tuic.go Normal file
View file

@ -0,0 +1,23 @@
package config
import (
"encoding/json"
)
type TuicServer struct {
Enable bool
Listen string
Token []string
Certificate string
PrivateKey string
CongestionController string
MaxIdleTime int
AuthenticationTimeout int
ALPN []string
MaxUdpRelayPacketSize int
}
func (t TuicServer) String() string {
b, _ := json.Marshal(t)
return string(b)
}

View file

@ -1,4 +1,4 @@
package sing_tun package config
import ( import (
"encoding/json" "encoding/json"

View file

@ -9,10 +9,10 @@ import (
) )
type Listener struct { type Listener struct {
listener net.Listener listener net.Listener
addr string addr string
closed bool closed bool
name string name string
preferRulesName string preferRulesName string
} }
@ -33,14 +33,14 @@ func (l *Listener) Close() error {
} }
func New(addr string, in chan<- C.ConnContext) (*Listener, error) { func New(addr string, in chan<- C.ConnContext) (*Listener, error) {
return NewWithAuthenticate(addr,"DEFAULT-HTTP","", in, true) return NewWithAuthenticate(addr, "DEFAULT-HTTP", "", in, true)
} }
func NewWithInfos(addr ,name ,preferRulesName string,in chan<-C.ConnContext)(*Listener,error){ func NewWithInfos(addr, name, preferRulesName string, in chan<- C.ConnContext) (*Listener, error) {
return NewWithAuthenticate(addr,name,preferRulesName,in,true) return NewWithAuthenticate(addr, name, preferRulesName, in, true)
} }
func NewWithAuthenticate(addr,name,preferRulesName string, in chan<- C.ConnContext, authenticate bool) (*Listener, error) { func NewWithAuthenticate(addr, name, preferRulesName string, in chan<- C.ConnContext, authenticate bool) (*Listener, error) {
l, err := inbound.Listen("tcp", addr) l, err := inbound.Listen("tcp", addr)
if err != nil { if err != nil {
@ -53,10 +53,10 @@ func NewWithAuthenticate(addr,name,preferRulesName string, in chan<- C.ConnConte
} }
hl := &Listener{ hl := &Listener{
listener: l, listener: l,
name: name, name: name,
preferRulesName: preferRulesName, preferRulesName: preferRulesName,
addr: addr, addr: addr,
} }
go func() { go func() {
for { for {
@ -67,7 +67,7 @@ func NewWithAuthenticate(addr,name,preferRulesName string, in chan<- C.ConnConte
} }
continue continue
} }
go HandleConn(hl.name,hl.preferRulesName,conn, in, c) go HandleConn(hl.name, hl.preferRulesName, conn, in, c)
} }
}() }()

View file

@ -52,7 +52,7 @@ func (b *Base) RawAddress() string {
} }
// ReCreate implements constant.NewListener // ReCreate implements constant.NewListener
func (*Base) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error { func (*Base) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
return nil return nil
} }

View file

@ -30,7 +30,7 @@ func (h *HTTP) Address() string {
} }
// ReCreate implements constant.NewListener // ReCreate implements constant.NewListener
func (h *HTTP) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error { func (h *HTTP) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
var err error var err error
_ = h.Close() _ = h.Close()
h.l, err = http.NewWithInfos(h.RawAddress(), h.name, h.preferRulesName, tcpIn) h.l, err = http.NewWithInfos(h.RawAddress(), h.name, h.preferRulesName, tcpIn)

View file

@ -39,7 +39,7 @@ func (m *Mixed) Address() string {
} }
// ReCreate implements constant.NewListener // ReCreate implements constant.NewListener
func (m *Mixed) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error { func (m *Mixed) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
var err error var err error
_ = m.Close() _ = m.Close()
m.l, err = mixed.NewWithInfos(m.RawAddress(), m.name, m.preferRulesName, tcpIn) m.l, err = mixed.NewWithInfos(m.RawAddress(), m.name, m.preferRulesName, tcpIn)

View file

@ -31,7 +31,7 @@ func (r *Redir) Address() string {
} }
// ReCreate implements constant.NewListener // ReCreate implements constant.NewListener
func (r *Redir) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error { func (r *Redir) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
var err error var err error
_ = r.Close() _ = r.Close()
r.l, err = redir.NewWithInfos(r.Address(), r.name, r.preferRulesName, tcpIn) r.l, err = redir.NewWithInfos(r.Address(), r.name, r.preferRulesName, tcpIn)

View file

@ -60,7 +60,7 @@ func (s *Socks) Address() string {
} }
// ReCreate implements constant.NewListener // ReCreate implements constant.NewListener
func (s *Socks) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error { func (s *Socks) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
s.mux.Lock() s.mux.Lock()
defer s.mux.Unlock() defer s.mux.Unlock()
var err error var err error

View file

@ -38,7 +38,7 @@ func (t *TProxy) Address() string {
} }
// ReCreate implements constant.NewListener // ReCreate implements constant.NewListener
func (t *TProxy) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error { func (t *TProxy) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
var err error var err error
_ = t.Close() _ = t.Close()
t.lTCP, err = tproxy.NewWithInfos(t.RawAddress(), t.name, t.preferRulesName, tcpIn) t.lTCP, err = tproxy.NewWithInfos(t.RawAddress(), t.name, t.preferRulesName, tcpIn)

View file

@ -12,6 +12,7 @@ import (
"github.com/Dreamacro/clash/component/ebpf" "github.com/Dreamacro/clash/component/ebpf"
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/listener/autoredir" "github.com/Dreamacro/clash/listener/autoredir"
LC "github.com/Dreamacro/clash/listener/config"
"github.com/Dreamacro/clash/listener/http" "github.com/Dreamacro/clash/listener/http"
"github.com/Dreamacro/clash/listener/mixed" "github.com/Dreamacro/clash/listener/mixed"
"github.com/Dreamacro/clash/listener/redir" "github.com/Dreamacro/clash/listener/redir"
@ -64,8 +65,8 @@ var (
autoRedirMux sync.Mutex autoRedirMux sync.Mutex
tcMux sync.Mutex tcMux sync.Mutex
LastTunConf sing_tun.Tun LastTunConf LC.Tun
LastTuicConf tuic.TuicServer LastTuicConf LC.TuicServer
) )
type Ports struct { type Ports struct {
@ -78,18 +79,18 @@ type Ports struct {
VmessConfig string `json:"vmess-config"` VmessConfig string `json:"vmess-config"`
} }
func GetTunConf() sing_tun.Tun { func GetTunConf() LC.Tun {
if tunLister == nil { if tunLister == nil {
return sing_tun.Tun{ return LC.Tun{
Enable: false, Enable: false,
} }
} }
return tunLister.Config() return tunLister.Config()
} }
func GetTuicConf() tuic.TuicServer { func GetTuicConf() LC.TuicServer {
if tuicListener == nil { if tuicListener == nil {
return tuic.TuicServer{Enable: false} return LC.TuicServer{Enable: false}
} }
return tuicListener.Config() return tuicListener.Config()
} }
@ -144,7 +145,7 @@ func ReCreateHTTP(port int, tcpIn chan<- C.ConnContext) {
log.Infoln("HTTP proxy listening at: %s", httpListener.Address()) log.Infoln("HTTP proxy listening at: %s", httpListener.Address())
} }
func ReCreateSocks(port int, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) { func ReCreateSocks(port int, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) {
socksMux.Lock() socksMux.Lock()
defer socksMux.Unlock() defer socksMux.Unlock()
@ -203,7 +204,7 @@ func ReCreateSocks(port int, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketA
log.Infoln("SOCKS proxy listening at: %s", socksListener.Address()) log.Infoln("SOCKS proxy listening at: %s", socksListener.Address())
} }
func ReCreateRedir(port int, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) { func ReCreateRedir(port int, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) {
redirMux.Lock() redirMux.Lock()
defer redirMux.Unlock() defer redirMux.Unlock()
@ -249,7 +250,7 @@ func ReCreateRedir(port int, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketA
log.Infoln("Redirect proxy listening at: %s", redirListener.Address()) log.Infoln("Redirect proxy listening at: %s", redirListener.Address())
} }
func ReCreateShadowSocks(shadowSocksConfig string, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) { func ReCreateShadowSocks(shadowSocksConfig string, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) {
ssMux.Lock() ssMux.Lock()
defer ssMux.Unlock() defer ssMux.Unlock()
@ -289,7 +290,7 @@ func ReCreateShadowSocks(shadowSocksConfig string, tcpIn chan<- C.ConnContext, u
return return
} }
func ReCreateVmess(vmessConfig string, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) { func ReCreateVmess(vmessConfig string, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) {
vmessMux.Lock() vmessMux.Lock()
defer vmessMux.Unlock() defer vmessMux.Unlock()
@ -329,7 +330,7 @@ func ReCreateVmess(vmessConfig string, tcpIn chan<- C.ConnContext, udpIn chan<-
return return
} }
func ReCreateTuic(config tuic.TuicServer, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) { func ReCreateTuic(config LC.TuicServer, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) {
tuicMux.Lock() tuicMux.Lock()
defer func() { defer func() {
LastTuicConf = config LastTuicConf = config
@ -371,7 +372,7 @@ func ReCreateTuic(config tuic.TuicServer, tcpIn chan<- C.ConnContext, udpIn chan
return return
} }
func ReCreateTProxy(port int, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) { func ReCreateTProxy(port int, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) {
tproxyMux.Lock() tproxyMux.Lock()
defer tproxyMux.Unlock() defer tproxyMux.Unlock()
@ -417,7 +418,7 @@ func ReCreateTProxy(port int, tcpIn chan<- C.ConnContext, udpIn chan<- *C.Packet
log.Infoln("TProxy server listening at: %s", tproxyListener.Address()) log.Infoln("TProxy server listening at: %s", tproxyListener.Address())
} }
func ReCreateMixed(port int, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) { func ReCreateMixed(port int, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) {
mixedMux.Lock() mixedMux.Lock()
defer mixedMux.Unlock() defer mixedMux.Unlock()
@ -472,7 +473,7 @@ func ReCreateMixed(port int, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketA
log.Infoln("Mixed(http+socks) proxy listening at: %s", mixedListener.Address()) log.Infoln("Mixed(http+socks) proxy listening at: %s", mixedListener.Address())
} }
func ReCreateTun(tunConf sing_tun.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) { func ReCreateTun(tunConf LC.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) {
tunMux.Lock() tunMux.Lock()
defer func() { defer func() {
LastTunConf = tunConf LastTunConf = tunConf
@ -536,7 +537,7 @@ func ReCreateRedirToTun(ifaceNames []string) {
log.Infoln("Attached tc ebpf program to interfaces %v", tcProgram.RawNICs()) log.Infoln("Attached tc ebpf program to interfaces %v", tcProgram.RawNICs())
} }
func ReCreateAutoRedir(ifaceNames []string, tcpIn chan<- C.ConnContext, _ chan<- *C.PacketAdapter) { func ReCreateAutoRedir(ifaceNames []string, tcpIn chan<- C.ConnContext, _ chan<- C.PacketAdapter) {
autoRedirMux.Lock() autoRedirMux.Lock()
defer autoRedirMux.Unlock() defer autoRedirMux.Unlock()
@ -592,7 +593,7 @@ 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()) log.Infoln("Auto redirect proxy listening at: %s, attached tc ebpf program to interfaces %v", autoRedirListener.Address(), autoRedirProgram.RawNICs())
} }
func PatchTunnel(tunnels []tunnel.Tunnel, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) { func PatchTunnel(tunnels []tunnel.Tunnel, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) {
tunnelMux.Lock() tunnelMux.Lock()
defer tunnelMux.Unlock() defer tunnelMux.Unlock()
@ -745,7 +746,7 @@ func genAddr(host string, port int, allowLan bool) string {
return fmt.Sprintf("127.0.0.1:%d", port) return fmt.Sprintf("127.0.0.1:%d", port)
} }
func hasTunConfigChange(tunConf *sing_tun.Tun) bool { func hasTunConfigChange(tunConf *LC.Tun) bool {
if LastTunConf.Enable != tunConf.Enable || if LastTunConf.Enable != tunConf.Enable ||
LastTunConf.Device != tunConf.Device || LastTunConf.Device != tunConf.Device ||
LastTunConf.Stack != tunConf.Stack || LastTunConf.Stack != tunConf.Stack ||
@ -833,5 +834,5 @@ func Cleanup(wait bool) {
tunLister.Close() tunLister.Close()
tunLister = nil tunLister = nil
} }
LastTunConf = sing_tun.Tun{} LastTunConf = LC.Tun{}
} }

View file

@ -25,23 +25,38 @@ func ParseListener(mapping map[string]any) (C.NewListener, error) {
switch proxyType { switch proxyType {
case "socks": case "socks":
socksOption := &IN.SocksOption{} socksOption := &IN.SocksOption{}
decoder.Decode(mapping, socksOption) err = decoder.Decode(mapping, socksOption)
if err != nil {
return nil, err
}
listener, err = IN.NewSocks(socksOption) listener, err = IN.NewSocks(socksOption)
case "http": case "http":
httpOption := &IN.HTTPOption{} httpOption := &IN.HTTPOption{}
decoder.Decode(mapping, httpOption) err = decoder.Decode(mapping, httpOption)
if err != nil {
return nil, err
}
listener, err = IN.NewHTTP(httpOption) listener, err = IN.NewHTTP(httpOption)
case "tproxy": case "tproxy":
tproxyOption := &IN.TProxyOption{} tproxyOption := &IN.TProxyOption{}
decoder.Decode(mapping, tproxyOption) err = decoder.Decode(mapping, tproxyOption)
if err != nil {
return nil, err
}
listener, err = IN.NewTProxy(tproxyOption) listener, err = IN.NewTProxy(tproxyOption)
case "redir": case "redir":
redirOption := &IN.RedirOption{} redirOption := &IN.RedirOption{}
decoder.Decode(mapping, redirOption) err = decoder.Decode(mapping, redirOption)
if err != nil {
return nil, err
}
listener, err = IN.NewRedir(redirOption) listener, err = IN.NewRedir(redirOption)
case "mixed": case "mixed":
mixedOption := &IN.MixedOption{} mixedOption := &IN.MixedOption{}
decoder.Decode(mapping, mixedOption) err = decoder.Decode(mapping, mixedOption)
if err != nil {
return nil, err
}
listener, err = IN.NewMixed(mixedOption) listener, err = IN.NewMixed(mixedOption)
default: default:
return nil, fmt.Errorf("unsupport proxy type: %s", proxyType) return nil, fmt.Errorf("unsupport proxy type: %s", proxyType)

View file

@ -8,10 +8,10 @@ import (
) )
type Listener struct { type Listener struct {
listener net.Listener listener net.Listener
addr string addr string
closed bool closed bool
name string name string
preferRulesName string preferRulesName string
} }
@ -32,18 +32,18 @@ func (l *Listener) Close() error {
} }
func New(addr string, in chan<- C.ConnContext) (*Listener, error) { func New(addr string, in chan<- C.ConnContext) (*Listener, error) {
return NewWithInfos(addr,"DEFAULT-REDIR","",in) return NewWithInfos(addr, "DEFAULT-REDIR", "", in)
} }
func NewWithInfos(addr,name,preferRulesName string, in chan<- C.ConnContext) (*Listener, error) { func NewWithInfos(addr, name, preferRulesName string, in chan<- C.ConnContext) (*Listener, error) {
l, err := net.Listen("tcp", addr) l, err := net.Listen("tcp", addr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
rl := &Listener{ rl := &Listener{
listener: l, listener: l,
addr: addr, addr: addr,
name: name, name: name,
preferRulesName: preferRulesName, preferRulesName: preferRulesName,
} }
@ -56,18 +56,18 @@ func NewWithInfos(addr,name,preferRulesName string, in chan<- C.ConnContext) (*L
} }
continue continue
} }
go handleRedir(rl.name,rl.preferRulesName,c, in) go handleRedir(rl.name, rl.preferRulesName, c, in)
} }
}() }()
return rl, nil return rl, nil
} }
func handleRedir(name,preferRulesName string,conn net.Conn, in chan<- C.ConnContext) { func handleRedir(name, preferRulesName string, conn net.Conn, in chan<- C.ConnContext) {
target, err := parserPacket(conn) target, err := parserPacket(conn)
if err != nil { if err != nil {
conn.Close() conn.Close()
return return
} }
conn.(*net.TCPConn).SetKeepAlive(true) conn.(*net.TCPConn).SetKeepAlive(true)
in <- inbound.NewSocketWithInfos(target, conn, C.REDIR,name,preferRulesName) in <- inbound.NewSocketWithInfos(target, conn, C.REDIR, name, preferRulesName)
} }

View file

@ -21,7 +21,7 @@ type Listener struct {
var _listener *Listener var _listener *Listener
func New(config string, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) (*Listener, error) { func New(config string, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) (*Listener, error) {
addr, cipher, password, err := ParseSSURL(config) addr, cipher, password, err := ParseSSURL(config)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -17,7 +17,7 @@ type UDPListener struct {
closed bool closed bool
} }
func NewUDP(addr string, pickCipher core.Cipher, in chan<- *C.PacketAdapter) (*UDPListener, error) { func NewUDP(addr string, pickCipher core.Cipher, in chan<- C.PacketAdapter) (*UDPListener, error) {
l, err := net.ListenPacket("udp", addr) l, err := net.ListenPacket("udp", addr)
if err != nil { if err != nil {
return nil, err return nil, err
@ -53,7 +53,7 @@ func (l *UDPListener) Close() error {
return l.packetConn.Close() return l.packetConn.Close()
} }
func handleSocksUDP(pc net.PacketConn, in chan<- *C.PacketAdapter, buf []byte, addr net.Addr) { func handleSocksUDP(pc net.PacketConn, in chan<- C.PacketAdapter, buf []byte, addr net.Addr) {
tgtAddr := socks5.SplitAddr(buf) tgtAddr := socks5.SplitAddr(buf)
if tgtAddr == nil { if tgtAddr == nil {
// Unresolved UDP packet, return buffer to the pool // Unresolved UDP packet, return buffer to the pool

View file

@ -24,7 +24,7 @@ const UDPTimeout = 5 * time.Minute
type ListenerHandler struct { type ListenerHandler struct {
TcpIn chan<- C.ConnContext TcpIn chan<- C.ConnContext
UdpIn chan<- *C.PacketAdapter UdpIn chan<- C.PacketAdapter
Type C.Type Type C.Type
} }

View file

@ -32,7 +32,7 @@ type Listener struct {
var _listener *Listener var _listener *Listener
func New(config string, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) (C.AdvanceListener, error) { func New(config string, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) (C.AdvanceListener, error) {
addr, cipher, password, err := embedSS.ParseSSURL(config) addr, cipher, password, err := embedSS.ParseSSURL(config)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -11,6 +11,7 @@ import (
"github.com/Dreamacro/clash/component/dialer" "github.com/Dreamacro/clash/component/dialer"
"github.com/Dreamacro/clash/component/iface" "github.com/Dreamacro/clash/component/iface"
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
LC "github.com/Dreamacro/clash/listener/config"
"github.com/Dreamacro/clash/listener/sing" "github.com/Dreamacro/clash/listener/sing"
"github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/log"
@ -25,7 +26,7 @@ var InterfaceName = "Meta"
type Listener struct { type Listener struct {
closed bool closed bool
options Tun options LC.Tun
handler *ListenerHandler handler *ListenerHandler
tunName string tunName string
@ -63,7 +64,7 @@ func CalculateInterfaceName(name string) (tunName string) {
return return
} }
func New(options Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) (l *Listener, err error) { func New(options LC.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) (l *Listener, err error) {
tunName := options.Device tunName := options.Device
if tunName == "" { if tunName == "" {
tunName = CalculateInterfaceName(InterfaceName) tunName = CalculateInterfaceName(InterfaceName)
@ -161,12 +162,12 @@ func New(options Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter)
tunOptions := tun.Options{ tunOptions := tun.Options{
Name: tunName, Name: tunName,
MTU: tunMTU, MTU: tunMTU,
Inet4Address: common.Map(options.Inet4Address, ListenPrefix.Build), Inet4Address: common.Map(options.Inet4Address, LC.ListenPrefix.Build),
Inet6Address: common.Map(options.Inet6Address, ListenPrefix.Build), Inet6Address: common.Map(options.Inet6Address, LC.ListenPrefix.Build),
AutoRoute: options.AutoRoute, AutoRoute: options.AutoRoute,
StrictRoute: options.StrictRoute, StrictRoute: options.StrictRoute,
Inet4RouteAddress: common.Map(options.Inet4RouteAddress, ListenPrefix.Build), Inet4RouteAddress: common.Map(options.Inet4RouteAddress, LC.ListenPrefix.Build),
Inet6RouteAddress: common.Map(options.Inet6RouteAddress, ListenPrefix.Build), Inet6RouteAddress: common.Map(options.Inet6RouteAddress, LC.ListenPrefix.Build),
IncludeUID: includeUID, IncludeUID: includeUID,
ExcludeUID: excludeUID, ExcludeUID: excludeUID,
IncludeAndroidUser: options.IncludeAndroidUser, IncludeAndroidUser: options.IncludeAndroidUser,
@ -282,6 +283,6 @@ func (l *Listener) Close() {
) )
} }
func (l *Listener) Config() Tun { func (l *Listener) Config() LC.Tun {
return l.options return l.options
} }

View file

@ -24,7 +24,7 @@ type Listener struct {
var _listener *Listener var _listener *Listener
func New(config string, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) (*Listener, error) { func New(config string, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) (*Listener, error) {
addr, username, password, err := parseVmessURL(config) addr, username, password, err := parseVmessURL(config)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -13,11 +13,11 @@ import (
) )
type Listener struct { type Listener struct {
listener net.Listener listener net.Listener
addr string addr string
closed bool closed bool
preferRulesName string preferRulesName string
name string name string
} }
// RawAddress implements C.Listener // RawAddress implements C.Listener
@ -37,19 +37,19 @@ func (l *Listener) Close() error {
} }
func New(addr string, in chan<- C.ConnContext) (*Listener, error) { func New(addr string, in chan<- C.ConnContext) (*Listener, error) {
return NewWithInfos(addr,"DEFAULT-SOCKS","",in) return NewWithInfos(addr, "DEFAULT-SOCKS", "", in)
} }
func NewWithInfos(addr,name,preferRulesName string, in chan<- C.ConnContext) (*Listener, error) { func NewWithInfos(addr, name, preferRulesName string, in chan<- C.ConnContext) (*Listener, error) {
l, err := inbound.Listen("tcp", addr) l, err := inbound.Listen("tcp", addr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
sl := &Listener{ sl := &Listener{
listener: l, listener: l,
addr: addr, addr: addr,
name: name, name: name,
preferRulesName: preferRulesName, preferRulesName: preferRulesName,
} }
go func() { go func() {
@ -61,14 +61,14 @@ func NewWithInfos(addr,name,preferRulesName string, in chan<- C.ConnContext) (*L
} }
continue continue
} }
go handleSocks(sl.name,sl.preferRulesName,c, in) go handleSocks(sl.name, sl.preferRulesName, c, in)
} }
}() }()
return sl, nil return sl, nil
} }
func handleSocks(name,preferRulesName string,conn net.Conn, in chan<- C.ConnContext) { func handleSocks(name, preferRulesName string, conn net.Conn, in chan<- C.ConnContext) {
conn.(*net.TCPConn).SetKeepAlive(true) conn.(*net.TCPConn).SetKeepAlive(true)
bufConn := N.NewBufferedConn(conn) bufConn := N.NewBufferedConn(conn)
head, err := bufConn.Peek(1) head, err := bufConn.Peek(1)
@ -79,24 +79,24 @@ func handleSocks(name,preferRulesName string,conn net.Conn, in chan<- C.ConnCont
switch head[0] { switch head[0] {
case socks4.Version: case socks4.Version:
HandleSocks4(name,preferRulesName,bufConn, in) HandleSocks4(name, preferRulesName, bufConn, in)
case socks5.Version: case socks5.Version:
HandleSocks5(name,preferRulesName,bufConn, in) HandleSocks5(name, preferRulesName, bufConn, in)
default: default:
conn.Close() conn.Close()
} }
} }
func HandleSocks4(name,preferRulesName string, conn net.Conn, in chan<- C.ConnContext) { func HandleSocks4(name, preferRulesName string, conn net.Conn, in chan<- C.ConnContext) {
addr, _, err := socks4.ServerHandshake(conn, authStore.Authenticator()) addr, _, err := socks4.ServerHandshake(conn, authStore.Authenticator())
if err != nil { if err != nil {
conn.Close() conn.Close()
return return
} }
in <- inbound.NewSocketWithInfos(socks5.ParseAddr(addr), conn, C.SOCKS4,name,preferRulesName) in <- inbound.NewSocketWithInfos(socks5.ParseAddr(addr), conn, C.SOCKS4, name, preferRulesName)
} }
func HandleSocks5(name,preferRulesName string,conn net.Conn, in chan<- C.ConnContext) { func HandleSocks5(name, preferRulesName string, conn net.Conn, in chan<- C.ConnContext) {
target, command, err := socks5.ServerHandshake(conn, authStore.Authenticator()) target, command, err := socks5.ServerHandshake(conn, authStore.Authenticator())
if err != nil { if err != nil {
conn.Close() conn.Close()
@ -107,5 +107,5 @@ func HandleSocks5(name,preferRulesName string,conn net.Conn, in chan<- C.ConnCon
io.Copy(io.Discard, conn) io.Copy(io.Discard, conn)
return return
} }
in <- inbound.NewSocketWithInfos(target, conn, C.SOCKS5,name,preferRulesName) in <- inbound.NewSocketWithInfos(target, conn, C.SOCKS5, name, preferRulesName)
} }

View file

@ -12,10 +12,10 @@ import (
) )
type UDPListener struct { type UDPListener struct {
packetConn net.PacketConn packetConn net.PacketConn
addr string addr string
closed bool closed bool
name string name string
preferRulesName string preferRulesName string
} }
@ -35,11 +35,11 @@ func (l *UDPListener) Close() error {
return l.packetConn.Close() return l.packetConn.Close()
} }
func NewUDP(addr string, in chan<- *C.PacketAdapter) (*UDPListener, error) { func NewUDP(addr string, in chan<- C.PacketAdapter) (*UDPListener, error) {
return NewUDPWithInfos(addr,"DEFAULT-SOCKS","",in) return NewUDPWithInfos(addr, "DEFAULT-SOCKS", "", in)
} }
func NewUDPWithInfos(addr,name ,preferRulesName string, in chan<- *C.PacketAdapter) (*UDPListener, error) { func NewUDPWithInfos(addr, name, preferRulesName string, in chan<- C.PacketAdapter) (*UDPListener, error) {
l, err := net.ListenPacket("udp", addr) l, err := net.ListenPacket("udp", addr)
if err != nil { if err != nil {
return nil, err return nil, err
@ -50,10 +50,10 @@ func NewUDPWithInfos(addr,name ,preferRulesName string, in chan<- *C.PacketAdapt
} }
sl := &UDPListener{ sl := &UDPListener{
packetConn: l, packetConn: l,
addr: addr, addr: addr,
preferRulesName: preferRulesName, preferRulesName: preferRulesName,
name: name, name: name,
} }
go func() { go func() {
for { for {
@ -66,14 +66,14 @@ func NewUDPWithInfos(addr,name ,preferRulesName string, in chan<- *C.PacketAdapt
} }
continue continue
} }
handleSocksUDP(sl.name,sl.preferRulesName,l, in, buf[:n], remoteAddr) handleSocksUDP(sl.name, sl.preferRulesName, l, in, buf[:n], remoteAddr)
} }
}() }()
return sl, nil return sl, nil
} }
func handleSocksUDP(name,preferRulesName string,pc net.PacketConn, in chan<- *C.PacketAdapter, buf []byte, addr net.Addr) { func handleSocksUDP(name, preferRulesName string, pc net.PacketConn, in chan<- C.PacketAdapter, buf []byte, addr net.Addr) {
target, payload, err := socks5.DecodeUDPPacket(buf) target, payload, err := socks5.DecodeUDPPacket(buf)
if err != nil { if err != nil {
// Unresolved UDP packet, return buffer to the pool // Unresolved UDP packet, return buffer to the pool
@ -87,7 +87,7 @@ func handleSocksUDP(name,preferRulesName string,pc net.PacketConn, in chan<- *C.
bufRef: buf, bufRef: buf,
} }
select { select {
case in <- inbound.NewPacketWithInfos(target, packet, C.SOCKS5,name,preferRulesName): case in <- inbound.NewPacketWithInfos(target, packet, C.SOCKS5, name, preferRulesName):
default: default:
} }
} }

View file

@ -9,10 +9,10 @@ import (
) )
type Listener struct { type Listener struct {
listener net.Listener listener net.Listener
addr string addr string
closed bool closed bool
name string name string
preferRulesName string preferRulesName string
} }
@ -32,17 +32,17 @@ func (l *Listener) Close() error {
return l.listener.Close() return l.listener.Close()
} }
func (l *Listener) handleTProxy(name,preferRulesName string ,conn net.Conn, in chan<- C.ConnContext) { func (l *Listener) handleTProxy(name, preferRulesName string, conn net.Conn, in chan<- C.ConnContext) {
target := socks5.ParseAddrToSocksAddr(conn.LocalAddr()) target := socks5.ParseAddrToSocksAddr(conn.LocalAddr())
conn.(*net.TCPConn).SetKeepAlive(true) conn.(*net.TCPConn).SetKeepAlive(true)
in <- inbound.NewSocketWithInfos(target, conn, C.TPROXY,name,preferRulesName) in <- inbound.NewSocketWithInfos(target, conn, C.TPROXY, name, preferRulesName)
} }
func New(addr string, in chan<- C.ConnContext) (*Listener, error) { func New(addr string, in chan<- C.ConnContext) (*Listener, error) {
return NewWithInfos(addr,"DEFAULT-TPROXY","",in) return NewWithInfos(addr, "DEFAULT-TPROXY", "", in)
} }
func NewWithInfos(addr,name,preferRulesName string, in chan<- C.ConnContext) (*Listener, error) { func NewWithInfos(addr, name, preferRulesName string, in chan<- C.ConnContext) (*Listener, error) {
l, err := net.Listen("tcp", addr) l, err := net.Listen("tcp", addr)
if err != nil { if err != nil {
return nil, err return nil, err
@ -60,9 +60,9 @@ func NewWithInfos(addr,name,preferRulesName string, in chan<- C.ConnContext) (*L
} }
rl := &Listener{ rl := &Listener{
listener: l, listener: l,
addr: addr, addr: addr,
name: name, name: name,
preferRulesName: preferRulesName, preferRulesName: preferRulesName,
} }
@ -75,7 +75,7 @@ func NewWithInfos(addr,name,preferRulesName string, in chan<- C.ConnContext) (*L
} }
continue continue
} }
go rl.handleTProxy(rl.name,rl.preferRulesName,c, in) go rl.handleTProxy(rl.name, rl.preferRulesName, c, in)
} }
}() }()

View file

@ -34,11 +34,11 @@ func (l *UDPListener) Close() error {
return l.packetConn.Close() return l.packetConn.Close()
} }
func NewUDP(addr string, in chan<- *C.PacketAdapter) (*UDPListener, error) { func NewUDP(addr string, in chan<- C.PacketAdapter) (*UDPListener, error) {
return NewUDPWithInfos(addr, "DEFAULT-TPROXY", "", in) return NewUDPWithInfos(addr, "DEFAULT-TPROXY", "", in)
} }
func NewUDPWithInfos(addr, name, preferRulesName string, in chan<- *C.PacketAdapter) (*UDPListener, error) { func NewUDPWithInfos(addr, name, preferRulesName string, in chan<- C.PacketAdapter) (*UDPListener, error) {
l, err := net.ListenPacket("udp", addr) l, err := net.ListenPacket("udp", addr)
if err != nil { if err != nil {
return nil, err return nil, err
@ -90,7 +90,7 @@ func NewUDPWithInfos(addr, name, preferRulesName string, in chan<- *C.PacketAdap
return rl, nil return rl, nil
} }
func handlePacketConn(name, preferRulesName string, pc net.PacketConn, in chan<- *C.PacketAdapter, buf []byte, lAddr, rAddr netip.AddrPort) { func handlePacketConn(name, preferRulesName string, pc net.PacketConn, in chan<- C.PacketAdapter, buf []byte, lAddr, rAddr netip.AddrPort) {
target := socks5.AddrFromStdAddrPort(rAddr) target := socks5.AddrFromStdAddrPort(rAddr)
pkt := &packet{ pkt := &packet{
pc: pc, pc: pc,

View file

@ -2,47 +2,29 @@ package tuic
import ( import (
"crypto/tls" "crypto/tls"
"encoding/json"
"net" "net"
"strings" "strings"
"time" "time"
"github.com/metacubex/quic-go" "github.com/metacubex/quic-go"
"github.com/Dreamacro/clash/adapter/inbound"
"github.com/Dreamacro/clash/common/sockopt" "github.com/Dreamacro/clash/common/sockopt"
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/adapter/inbound" LC "github.com/Dreamacro/clash/listener/config"
"github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/log"
"github.com/Dreamacro/clash/transport/socks5" "github.com/Dreamacro/clash/transport/socks5"
"github.com/Dreamacro/clash/transport/tuic" "github.com/Dreamacro/clash/transport/tuic"
) )
type TuicServer struct {
Enable bool
Listen string
Token []string
Certificate string
PrivateKey string
CongestionController string
MaxIdleTime int
AuthenticationTimeout int
ALPN []string
MaxUdpRelayPacketSize int
}
func (t TuicServer) String() string {
b, _ := json.Marshal(t)
return string(b)
}
type Listener struct { type Listener struct {
closed bool closed bool
config TuicServer config LC.TuicServer
udpListeners []net.PacketConn udpListeners []net.PacketConn
servers []*tuic.Server servers []*tuic.Server
} }
func New(config TuicServer, tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) (*Listener, error) { func New(config LC.TuicServer, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) (*Listener, error) {
cert, err := tls.LoadX509KeyPair(config.Certificate, config.PrivateKey) cert, err := tls.LoadX509KeyPair(config.Certificate, config.PrivateKey)
if err != nil { if err != nil {
return nil, err return nil, err
@ -140,6 +122,6 @@ func (l *Listener) Close() {
} }
} }
func (l *Listener) Config() TuicServer { func (l *Listener) Config() LC.TuicServer {
return l.config return l.config
} }

View file

@ -34,7 +34,7 @@ func (l *PacketConn) Close() error {
return l.conn.Close() return l.conn.Close()
} }
func NewUDP(addr, target, proxy string, in chan<- *C.PacketAdapter) (*PacketConn, error) { func NewUDP(addr, target, proxy string, in chan<- C.PacketAdapter) (*PacketConn, error) {
l, err := net.ListenPacket("udp", addr) l, err := net.ListenPacket("udp", addr)
if err != nil { if err != nil {
return nil, err return nil, err
@ -69,7 +69,7 @@ func NewUDP(addr, target, proxy string, in chan<- *C.PacketAdapter) (*PacketConn
return sl, nil return sl, nil
} }
func (l *PacketConn) handleUDP(pc net.PacketConn, in chan<- *C.PacketAdapter, buf []byte, addr net.Addr) { func (l *PacketConn) handleUDP(pc net.PacketConn, in chan<- C.PacketAdapter, buf []byte, addr net.Addr) {
packet := &packet{ packet := &packet{
pc: pc, pc: pc,
rAddr: addr, rAddr: addr,

View file

@ -26,7 +26,7 @@ import (
var ( var (
tcpQueue = make(chan C.ConnContext, 200) tcpQueue = make(chan C.ConnContext, 200)
udpQueue = make(chan *C.PacketAdapter, 200) udpQueue = make(chan C.PacketAdapter, 200)
natTable = nat.New() natTable = nat.New()
rules []C.Rule rules []C.Rule
subRules map[string][]C.Rule subRules map[string][]C.Rule
@ -77,7 +77,7 @@ func TCPIn() chan<- C.ConnContext {
} }
// UDPIn return fan-in udp queue // UDPIn return fan-in udp queue
func UDPIn() chan<- *C.PacketAdapter { func UDPIn() chan<- C.PacketAdapter {
return udpQueue return udpQueue
} }
@ -217,7 +217,7 @@ func resolveMetadata(ctx C.PlainContext, metadata *C.Metadata) (proxy C.Proxy, r
return return
} }
func handleUDPConn(packet *C.PacketAdapter) { func handleUDPConn(packet C.PacketAdapter) {
metadata := packet.Metadata() metadata := packet.Metadata()
if !metadata.Valid() { if !metadata.Valid() {
log.Warnln("[Metadata] not valid: %#v", metadata) log.Warnln("[Metadata] not valid: %#v", metadata)
@ -325,7 +325,7 @@ func handleUDPConn(packet *C.PacketAdapter) {
} }
oAddr := metadata.DstIP oAddr := metadata.DstIP
go handleUDPToLocal(packet.UDPPacket, pc, key, oAddr, fAddr) go handleUDPToLocal(packet, pc, key, oAddr, fAddr)
natTable.Set(key, pc) natTable.Set(key, pc)
handle() handle()