Skip to content

Commit

Permalink
Merge branch 'Alpha' into Meta
Browse files Browse the repository at this point in the history
  • Loading branch information
Larvan2 committed Aug 13, 2023
2 parents fa94403 + 3093fc4 commit 65071ea
Show file tree
Hide file tree
Showing 84 changed files with 766 additions and 1,458 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: "1.20"
go-version: "1.21"
check-latest: true

- name: Test
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ RUN echo "I'm building for $TARGETPLATFORM"

RUN apk add --no-cache gzip && \
mkdir /clash-config && \
wget -O /clash-config/Country.mmdb https://raw.githubusercontent.com/Loyalsoldier/geoip/release/Country.mmdb && \
wget -O /clash-config/geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat && \
wget -O /clash-config/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
wget -O /clash-config/geoip.metadb https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.metadb && \
wget -O /clash-config/geosite.dat https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat && \
wget -O /clash-config/geoip.dat https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat

COPY docker/file-name.sh /clash/file-name.sh
WORKDIR /clash
Expand Down
8 changes: 7 additions & 1 deletion adapter/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/http"
"net/netip"
"net/url"
"strconv"
"time"

"github.com/Dreamacro/clash/common/atomic"
Expand Down Expand Up @@ -176,6 +177,7 @@ func (p *Proxy) MarshalJSON() ([]byte, error) {
_ = json.Unmarshal(inner, &mapping)
mapping["history"] = p.DelayHistory()
mapping["extra"] = p.ExtraDelayHistory()
mapping["alive"] = p.Alive()
mapping["name"] = p.Name()
mapping["udp"] = p.SupportUDP()
mapping["xudp"] = p.SupportXUDP()
Expand Down Expand Up @@ -326,11 +328,15 @@ func urlToMetadata(rawURL string) (addr C.Metadata, err error) {
return
}
}
uintPort, err := strconv.ParseUint(port, 10, 16)
if err != nil {
return
}

addr = C.Metadata{
Host: u.Hostname(),
DstIP: netip.Addr{},
DstPort: port,
DstPort: uint16(uintPort),
}
return
}
Expand Down
4 changes: 4 additions & 0 deletions adapter/inbound/listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ func SetTfo(open bool) {
lc.DisableTFO = !open
}

func SetMPTCP(open bool) {
setMultiPathTCP(&lc.ListenConfig, open)
}

func ListenContext(ctx context.Context, network, address string) (net.Listener, error) {
return lc.Listen(ctx, network, address)
}
Expand Down
10 changes: 10 additions & 0 deletions adapter/inbound/mptcp_go120.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//go:build !go1.21

package inbound

import "net"

const multipathTCPAvailable = false

func setMultiPathTCP(listenConfig *net.ListenConfig, open bool) {
}
11 changes: 11 additions & 0 deletions adapter/inbound/mptcp_go121.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build go1.21

package inbound

import "net"

const multipathTCPAvailable = true

func setMultiPathTCP(listenConfig *net.ListenConfig, open bool) {
listenConfig.SetMultipathTCP(open)
}
5 changes: 4 additions & 1 deletion adapter/inbound/socket.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package inbound
import (
"net"
"net/netip"
"strconv"

C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/context"
Expand Down Expand Up @@ -37,7 +38,9 @@ func NewInner(conn net.Conn, address string) *context.ConnContext {
metadata.DNSMode = C.DNSNormal
metadata.Process = C.ClashName
if h, port, err := net.SplitHostPort(address); err == nil {
metadata.DstPort = port
if port, err := strconv.ParseUint(port, 10, 16); err == nil {
metadata.DstPort = uint16(port)
}
if ip, err := netip.ParseAddr(h); err == nil {
metadata.DstIP = ip
} else {
Expand Down
26 changes: 18 additions & 8 deletions adapter/inbound/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ func parseSocksAddr(target socks5.Addr) *C.Metadata {
case socks5.AtypDomainName:
// trim for FQDN
metadata.Host = strings.TrimRight(string(target[2:2+target[1]]), ".")
metadata.DstPort = strconv.Itoa((int(target[2+target[1]]) << 8) | int(target[2+target[1]+1]))
metadata.DstPort = uint16((int(target[2+target[1]]) << 8) | int(target[2+target[1]+1]))
case socks5.AtypIPv4:
metadata.DstIP = nnip.IpToAddr(net.IP(target[1 : 1+net.IPv4len]))
metadata.DstPort = strconv.Itoa((int(target[1+net.IPv4len]) << 8) | int(target[1+net.IPv4len+1]))
metadata.DstPort = uint16((int(target[1+net.IPv4len]) << 8) | int(target[1+net.IPv4len+1]))
case socks5.AtypIPv6:
ip6, _ := netip.AddrFromSlice(target[1 : 1+net.IPv6len])
metadata.DstIP = ip6.Unmap()
metadata.DstPort = strconv.Itoa((int(target[1+net.IPv6len]) << 8) | int(target[1+net.IPv6len+1]))
metadata.DstPort = uint16((int(target[1+net.IPv6len]) << 8) | int(target[1+net.IPv6len+1]))
}

return metadata
Expand All @@ -43,11 +43,16 @@ func parseHTTPAddr(request *http.Request) *C.Metadata {
// trim FQDN (#737)
host = strings.TrimRight(host, ".")

var uint16Port uint16
if port, err := strconv.ParseUint(port, 10, 16); err == nil {
uint16Port = uint16(port)
}

metadata := &C.Metadata{
NetWork: C.TCP,
Host: host,
DstIP: netip.Addr{},
DstPort: port,
DstPort: uint16Port,
}

ip, err := netip.ParseAddr(host)
Expand All @@ -58,10 +63,10 @@ func parseHTTPAddr(request *http.Request) *C.Metadata {
return metadata
}

func parseAddr(addr net.Addr) (netip.Addr, string, error) {
func parseAddr(addr net.Addr) (netip.Addr, uint16, error) {
// Filter when net.Addr interface is nil
if addr == nil {
return netip.Addr{}, "", errors.New("nil addr")
return netip.Addr{}, 0, errors.New("nil addr")
}
if rawAddr, ok := addr.(interface{ RawAddr() net.Addr }); ok {
ip, port, err := parseAddr(rawAddr.RawAddr())
Expand All @@ -72,9 +77,14 @@ func parseAddr(addr net.Addr) (netip.Addr, string, error) {
addrStr := addr.String()
host, port, err := net.SplitHostPort(addrStr)
if err != nil {
return netip.Addr{}, "", err
return netip.Addr{}, 0, err
}

var uint16Port uint16
if port, err := strconv.ParseUint(port, 10, 16); err == nil {
uint16Port = uint16(port)
}

ip, err := netip.ParseAddr(host)
return ip, port, err
return ip, uint16Port, err
}
8 changes: 8 additions & 0 deletions adapter/outbound/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Base struct {
udp bool
xudp bool
tfo bool
mpTcp bool
rmark int
id string
prefer C.DNSPrefer
Expand Down Expand Up @@ -143,11 +144,16 @@ func (b *Base) DialOptions(opts ...dialer.Option) []dialer.Option {
opts = append(opts, dialer.WithTFO(true))
}

if b.mpTcp {
opts = append(opts, dialer.WithMPTCP(true))
}

return opts
}

type BasicOption struct {
TFO bool `proxy:"tfo,omitempty" group:"tfo,omitempty"`
MPTCP bool `proxy:"mptcp,omitempty" group:"mptcp,omitempty"`
Interface string `proxy:"interface-name,omitempty" group:"interface-name,omitempty"`
RoutingMark int `proxy:"routing-mark,omitempty" group:"routing-mark,omitempty"`
IPVersion string `proxy:"ip-version,omitempty" group:"ip-version,omitempty"`
Expand All @@ -161,6 +167,7 @@ type BaseOption struct {
UDP bool
XUDP bool
TFO bool
MPTCP bool
Interface string
RoutingMark int
Prefer C.DNSPrefer
Expand All @@ -174,6 +181,7 @@ func NewBase(opt BaseOption) *Base {
udp: opt.UDP,
xudp: opt.XUDP,
tfo: opt.TFO,
mpTcp: opt.MPTCP,
iface: opt.Interface,
rmark: opt.RoutingMark,
prefer: opt.Prefer,
Expand Down
1 change: 1 addition & 0 deletions adapter/outbound/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func NewHttp(option HttpOption) (*Http, error) {
addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
tp: C.Http,
tfo: option.TFO,
mpTcp: option.MPTCP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
Expand Down
1 change: 1 addition & 0 deletions adapter/outbound/shadowsocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
tp: C.Shadowsocks,
udp: option.UDP,
tfo: option.TFO,
mpTcp: option.MPTCP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
Expand Down
1 change: 1 addition & 0 deletions adapter/outbound/shadowsocksr.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ func NewShadowSocksR(option ShadowSocksROption) (*ShadowSocksR, error) {
tp: C.ShadowsocksR,
udp: option.UDP,
tfo: option.TFO,
mpTcp: option.MPTCP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
Expand Down
7 changes: 3 additions & 4 deletions adapter/outbound/snell.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ func (s *Snell) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
err := snell.WriteUDPHeader(c, s.version)
return c, err
}
port, _ := strconv.ParseUint(metadata.DstPort, 10, 16)
err := snell.WriteHeader(c, metadata.String(), uint(port), s.version)
err := snell.WriteHeader(c, metadata.String(), uint(metadata.DstPort), s.version)
return c, err
}

Expand All @@ -72,8 +71,7 @@ func (s *Snell) DialContext(ctx context.Context, metadata *C.Metadata, opts ...d
return nil, err
}

port, _ := strconv.ParseUint(metadata.DstPort, 10, 16)
if err = snell.WriteHeader(c, metadata.String(), uint(port), s.version); err != nil {
if err = snell.WriteHeader(c, metadata.String(), uint(metadata.DstPort), s.version); err != nil {
c.Close()
return nil, err
}
Expand Down Expand Up @@ -183,6 +181,7 @@ func NewSnell(option SnellOption) (*Snell, error) {
tp: C.Snell,
udp: option.UDP,
tfo: option.TFO,
mpTcp: option.MPTCP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
Expand Down
1 change: 1 addition & 0 deletions adapter/outbound/socks5.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ func NewSocks5(option Socks5Option) (*Socks5, error) {
tp: C.Socks5,
udp: option.UDP,
tfo: option.TFO,
mpTcp: option.MPTCP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
Expand Down
29 changes: 1 addition & 28 deletions adapter/outbound/trojan.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/transport/gun"
"github.com/Dreamacro/clash/transport/trojan"
"github.com/Dreamacro/clash/transport/vless"
)

type Trojan struct {
Expand Down Expand Up @@ -45,8 +44,6 @@ type TrojanOption struct {
RealityOpts RealityOptions `proxy:"reality-opts,omitempty"`
GrpcOpts GrpcOptions `proxy:"grpc-opts,omitempty"`
WSOpts WSOptions `proxy:"ws-opts,omitempty"`
Flow string `proxy:"flow,omitempty"`
FlowShow bool `proxy:"flow-show,omitempty"`
ClientFingerprint string `proxy:"client-fingerprint,omitempty"`
}

Expand Down Expand Up @@ -95,11 +92,6 @@ func (t *Trojan) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.
return nil, fmt.Errorf("%s connect error: %w", t.addr, err)
}

c, err = t.instance.PresetXTLSConn(c)
if err != nil {
return nil, err
}

if metadata.NetWork == C.UDP {
err = t.instance.WriteHeader(c, trojan.CommandUDP, serializesSocksAddr(metadata))
return c, err
Expand All @@ -117,12 +109,6 @@ func (t *Trojan) DialContext(ctx context.Context, metadata *C.Metadata, opts ...
return nil, err
}

c, err = t.instance.PresetXTLSConn(c)
if err != nil {
c.Close()
return nil, err
}

if err = t.instance.WriteHeader(c, trojan.CommandTCP, serializesSocksAddr(metadata)); err != nil {
c.Close()
return nil, err
Expand Down Expand Up @@ -237,24 +223,10 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
ALPN: option.ALPN,
ServerName: option.Server,
SkipCertVerify: option.SkipCertVerify,
FlowShow: option.FlowShow,
Fingerprint: option.Fingerprint,
ClientFingerprint: option.ClientFingerprint,
}

switch option.Network {
case "", "tcp":
if len(option.Flow) >= 16 {
option.Flow = option.Flow[:16]
switch option.Flow {
case vless.XRO, vless.XRD, vless.XRS:
tOption.Flow = option.Flow
default:
return nil, fmt.Errorf("unsupported xtls flow type: %s", option.Flow)
}
}
}

if option.SNI != "" {
tOption.ServerName = option.SNI
}
Expand All @@ -266,6 +238,7 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
tp: C.Trojan,
udp: option.UDP,
tfo: option.TFO,
mpTcp: option.MPTCP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
Expand Down
2 changes: 1 addition & 1 deletion adapter/outbound/tuic.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func NewTuic(option TuicOption) (*Tuic, error) {
tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
}

if len(option.ALPN) > 0 {
if option.ALPN != nil { // structure's Decode will ensure value not nil when input has value even it was set an empty array
tlsConfig.NextProtos = option.ALPN
} else {
tlsConfig.NextProtos = []string{"h3"}
Expand Down
Loading

0 comments on commit 65071ea

Please sign in to comment.