Skip to content

Commit 16655c7

Browse files
committed
Merge branch 'Dreamacro-master'
2 parents c41bb03 + 00cb715 commit 16655c7

64 files changed

Lines changed: 1253 additions & 626 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ $ go get -u -v github.com/Dreamacro/clash
3737
```
3838

3939
Pre-built binaries are available here: [release](https://github.com/Dreamacro/clash/releases)
40-
Pre-built TUN mode binaries are available here: [TUN release](https://github.com/Dreamacro/clash/releases/tag/TUN). Source is not currently available.
40+
Pre-built Premium binaries are available here: [Premium release](https://github.com/Dreamacro/clash/releases/tag/premium). Source is not currently available.
4141

4242
Check Clash version with:
4343

@@ -120,9 +120,10 @@ experimental:
120120
# - "user2:pass2"
121121

122122
# # experimental hosts, support wildcard (e.g. *.clash.dev Even *.foo.*.example.com)
123-
# # static domain has a higher priority than wildcard domain (foo.example.com > *.example.com)
123+
# # static domain has a higher priority than wildcard domain (foo.example.com > *.example.com > .example.com)
124124
# hosts:
125125
# '*.clash.dev': 127.0.0.1
126+
# '.dev': 127.0.0.1
126127
# 'alpha.clash.dev': '::1'
127128

128129
# dns:
@@ -222,6 +223,24 @@ proxies:
222223
# ws-path: /path
223224
# ws-headers:
224225
# Host: v2ray.com
226+
227+
- name: "vmess-http"
228+
type: vmess
229+
server: server
230+
port: 443
231+
uuid: uuid
232+
alterId: 32
233+
cipher: auto
234+
# udp: true
235+
# network: http
236+
# http-opts:
237+
# # method: "GET"
238+
# # path:
239+
# # - '/'
240+
# # - '/video'
241+
# # headers:
242+
# # Connection:
243+
# # - keep-alive
225244

226245
# socks5
227246
- name: "socks"
@@ -268,7 +287,7 @@ proxies:
268287
# skip-cert-verify: true
269288

270289
proxy-groups:
271-
# relay chains the proxies. proxies shall not contain a proxy-group. No UDP support.
290+
# relay chains the proxies. proxies shall not contain a relay. No UDP support.
272291
# Traffic: clash <-> http <-> vmess <-> ss1 <-> ss2 <-> Internet
273292
- name: "relay"
274293
type: relay

adapters/inbound/socket.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ func (s *SocketAdapter) Metadata() *C.Metadata {
1919
}
2020

2121
// NewSocket is SocketAdapter generator
22-
func NewSocket(target socks5.Addr, conn net.Conn, source C.Type, netType C.NetWork) *SocketAdapter {
22+
func NewSocket(target socks5.Addr, conn net.Conn, source C.Type) *SocketAdapter {
2323
metadata := parseSocksAddr(target)
24-
metadata.NetWork = netType
24+
metadata.NetWork = C.TCP
2525
metadata.Type = source
2626
if ip, port, err := parseAddr(conn.RemoteAddr().String()); err == nil {
2727
metadata.SrcIP = ip

adapters/outbound/base.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ func (b *Base) Addr() string {
5353
return b.addr
5454
}
5555

56+
func (b *Base) Unwrap(metadata *C.Metadata) C.Proxy {
57+
return nil
58+
}
59+
5660
func NewBase(name string, addr string, tp C.AdapterType, udp bool) *Base {
5761
return &Base{name, addr, tp, udp}
5862
}

adapters/outbound/direct.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@ type Direct struct {
1414
}
1515

1616
func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
17-
address := net.JoinHostPort(metadata.Host, metadata.DstPort)
18-
if metadata.DstIP != nil {
19-
address = net.JoinHostPort(metadata.DstIP.String(), metadata.DstPort)
20-
}
17+
address := net.JoinHostPort(metadata.String(), metadata.DstPort)
2118

2219
c, err := dialer.DialContext(ctx, "tcp", address)
2320
if err != nil {

adapters/outbound/parser.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ func ParseProxy(mapping map[string]interface{}) (C.Proxy, error) {
4646
}
4747
proxy = NewHttp(*httpOption)
4848
case "vmess":
49-
vmessOption := &VmessOption{}
49+
vmessOption := &VmessOption{
50+
HTTPOpts: HTTPOptions{
51+
Method: "GET",
52+
Path: []string{"/"},
53+
},
54+
}
5055
err = decoder.Decode(mapping, vmessOption)
5156
if err != nil {
5257
break

adapters/outbound/shadowsocks.go

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package outbound
22

33
import (
44
"context"
5-
"crypto/tls"
65
"encoding/json"
76
"errors"
87
"fmt"
@@ -156,21 +155,17 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
156155
return nil, fmt.Errorf("ss %s obfs mode error: %s", addr, opts.Mode)
157156
}
158157
obfsMode = opts.Mode
158+
v2rayOption = &v2rayObfs.Option{
159+
Host: opts.Host,
160+
Path: opts.Path,
161+
Headers: opts.Headers,
162+
Mux: opts.Mux,
163+
}
159164

160-
var tlsConfig *tls.Config
161165
if opts.TLS {
162-
tlsConfig = &tls.Config{
163-
ServerName: opts.Host,
164-
InsecureSkipVerify: opts.SkipCertVerify,
165-
ClientSessionCache: getClientSessionCache(),
166-
}
167-
}
168-
v2rayOption = &v2rayObfs.Option{
169-
Host: opts.Host,
170-
Path: opts.Path,
171-
Headers: opts.Headers,
172-
TLSConfig: tlsConfig,
173-
Mux: opts.Mux,
166+
v2rayOption.TLS = true
167+
v2rayOption.SkipCertVerify = opts.SkipCertVerify
168+
v2rayOption.SessionCache = getClientSessionCache()
174169
}
175170
}
176171

adapters/outbound/vmess.go

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"net"
8+
"net/http"
89
"strconv"
910
"strings"
1011

@@ -17,6 +18,7 @@ import (
1718
type Vmess struct {
1819
*Base
1920
client *vmess.Client
21+
option *VmessOption
2022
}
2123

2224
type VmessOption struct {
@@ -29,13 +31,71 @@ type VmessOption struct {
2931
TLS bool `proxy:"tls,omitempty"`
3032
UDP bool `proxy:"udp,omitempty"`
3133
Network string `proxy:"network,omitempty"`
34+
HTTPOpts HTTPOptions `proxy:"http-opts,omitempty"`
3235
WSPath string `proxy:"ws-path,omitempty"`
3336
WSHeaders map[string]string `proxy:"ws-headers,omitempty"`
3437
SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"`
3538
}
3639

40+
type HTTPOptions struct {
41+
Method string `proxy:"method,omitempty"`
42+
Path []string `proxy:"path,omitempty"`
43+
Headers map[string][]string `proxy:"headers,omitempty"`
44+
}
45+
3746
func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
38-
return v.client.New(c, parseVmessAddr(metadata))
47+
var err error
48+
switch v.option.Network {
49+
case "ws":
50+
host, port, _ := net.SplitHostPort(v.addr)
51+
wsOpts := &vmess.WebsocketConfig{
52+
Host: host,
53+
Port: port,
54+
Path: v.option.WSPath,
55+
}
56+
57+
if len(v.option.WSHeaders) != 0 {
58+
header := http.Header{}
59+
for key, value := range v.option.WSHeaders {
60+
header.Add(key, value)
61+
}
62+
wsOpts.Headers = header
63+
}
64+
65+
if v.option.TLS {
66+
wsOpts.TLS = true
67+
wsOpts.SessionCache = getClientSessionCache()
68+
wsOpts.SkipCertVerify = v.option.SkipCertVerify
69+
}
70+
c, err = vmess.StreamWebsocketConn(c, wsOpts)
71+
case "http":
72+
host, _, _ := net.SplitHostPort(v.addr)
73+
httpOpts := &vmess.HTTPConfig{
74+
Host: host,
75+
Method: v.option.HTTPOpts.Method,
76+
Path: v.option.HTTPOpts.Path,
77+
Headers: v.option.HTTPOpts.Headers,
78+
}
79+
80+
c = vmess.StreamHTTPConn(c, httpOpts)
81+
default:
82+
// handle TLS
83+
if v.option.TLS {
84+
host, _, _ := net.SplitHostPort(v.addr)
85+
tlsOpts := &vmess.TLSConfig{
86+
Host: host,
87+
SkipCertVerify: v.option.SkipCertVerify,
88+
SessionCache: getClientSessionCache(),
89+
}
90+
c, err = vmess.StreamTLSConn(c, tlsOpts)
91+
}
92+
}
93+
94+
if err != nil {
95+
return nil, err
96+
}
97+
98+
return v.client.StreamConn(c, parseVmessAddr(metadata))
3999
}
40100

41101
func (v *Vmess) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
@@ -66,7 +126,7 @@ func (v *Vmess) DialUDP(metadata *C.Metadata) (C.PacketConn, error) {
66126
return nil, fmt.Errorf("%s connect error", v.addr)
67127
}
68128
tcpKeepAlive(c)
69-
c, err = v.client.New(c, parseVmessAddr(metadata))
129+
c, err = v.StreamConn(c, metadata)
70130
if err != nil {
71131
return nil, fmt.Errorf("new vmess client error: %v", err)
72132
}
@@ -76,17 +136,11 @@ func (v *Vmess) DialUDP(metadata *C.Metadata) (C.PacketConn, error) {
76136
func NewVmess(option VmessOption) (*Vmess, error) {
77137
security := strings.ToLower(option.Cipher)
78138
client, err := vmess.NewClient(vmess.Config{
79-
UUID: option.UUID,
80-
AlterID: uint16(option.AlterID),
81-
Security: security,
82-
TLS: option.TLS,
83-
HostName: option.Server,
84-
Port: strconv.Itoa(option.Port),
85-
NetWork: option.Network,
86-
WebSocketPath: option.WSPath,
87-
WebSocketHeaders: option.WSHeaders,
88-
SkipCertVerify: option.SkipCertVerify,
89-
SessionCache: getClientSessionCache(),
139+
UUID: option.UUID,
140+
AlterID: uint16(option.AlterID),
141+
Security: security,
142+
HostName: option.Server,
143+
Port: strconv.Itoa(option.Port),
90144
})
91145
if err != nil {
92146
return nil, err
@@ -100,6 +154,7 @@ func NewVmess(option VmessOption) (*Vmess, error) {
100154
udp: true,
101155
},
102156
client: client,
157+
option: &option,
103158
}, nil
104159
}
105160

adapters/outboundgroup/fallback.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ func (f *Fallback) MarshalJSON() ([]byte, error) {
5656
})
5757
}
5858

59+
func (f *Fallback) Unwrap(metadata *C.Metadata) C.Proxy {
60+
proxy := f.findAliveProxy()
61+
return proxy
62+
}
63+
5964
func (f *Fallback) proxies() []C.Proxy {
6065
elm, _, _ := f.single.Do(func() (interface{}, error) {
6166
return getProvidersProxies(f.providers), nil

adapters/outboundgroup/loadbalance.go

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,9 @@ func (lb *LoadBalance) DialContext(ctx context.Context, metadata *C.Metadata) (c
5959
}
6060
}()
6161

62-
key := uint64(murmur3.Sum32([]byte(getKey(metadata))))
63-
proxies := lb.proxies()
64-
buckets := int32(len(proxies))
65-
for i := 0; i < lb.maxRetry; i, key = i+1, key+1 {
66-
idx := jumpHash(key, buckets)
67-
proxy := proxies[idx]
68-
if proxy.Alive() {
69-
c, err = proxy.DialContext(ctx, metadata)
70-
return
71-
}
72-
}
73-
c, err = proxies[0].DialContext(ctx, metadata)
62+
proxy := lb.Unwrap(metadata)
63+
64+
c, err = proxy.DialContext(ctx, metadata)
7465
return
7566
}
7667

@@ -81,22 +72,28 @@ func (lb *LoadBalance) DialUDP(metadata *C.Metadata) (pc C.PacketConn, err error
8172
}
8273
}()
8374

75+
proxy := lb.Unwrap(metadata)
76+
77+
return proxy.DialUDP(metadata)
78+
}
79+
80+
func (lb *LoadBalance) SupportUDP() bool {
81+
return true
82+
}
83+
84+
func (lb *LoadBalance) Unwrap(metadata *C.Metadata) C.Proxy {
8485
key := uint64(murmur3.Sum32([]byte(getKey(metadata))))
8586
proxies := lb.proxies()
8687
buckets := int32(len(proxies))
8788
for i := 0; i < lb.maxRetry; i, key = i+1, key+1 {
8889
idx := jumpHash(key, buckets)
8990
proxy := proxies[idx]
9091
if proxy.Alive() {
91-
return proxy.DialUDP(metadata)
92+
return proxy
9293
}
9394
}
9495

95-
return proxies[0].DialUDP(metadata)
96-
}
97-
98-
func (lb *LoadBalance) SupportUDP() bool {
99-
return true
96+
return proxies[0]
10097
}
10198

10299
func (lb *LoadBalance) proxies() []C.Proxy {

adapters/outboundgroup/relay.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type Relay struct {
2020
}
2121

2222
func (r *Relay) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
23-
proxies := r.proxies()
23+
proxies := r.proxies(metadata)
2424
if len(proxies) == 0 {
2525
return nil, errors.New("Proxy does not exist")
2626
}
@@ -58,7 +58,7 @@ func (r *Relay) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn,
5858

5959
func (r *Relay) MarshalJSON() ([]byte, error) {
6060
var all []string
61-
for _, proxy := range r.proxies() {
61+
for _, proxy := range r.rawProxies() {
6262
all = append(all, proxy.Name())
6363
}
6464
return json.Marshal(map[string]interface{}{
@@ -67,14 +67,28 @@ func (r *Relay) MarshalJSON() ([]byte, error) {
6767
})
6868
}
6969

70-
func (r *Relay) proxies() []C.Proxy {
70+
func (r *Relay) rawProxies() []C.Proxy {
7171
elm, _, _ := r.single.Do(func() (interface{}, error) {
7272
return getProvidersProxies(r.providers), nil
7373
})
7474

7575
return elm.([]C.Proxy)
7676
}
7777

78+
func (r *Relay) proxies(metadata *C.Metadata) []C.Proxy {
79+
proxies := r.rawProxies()
80+
81+
for n, proxy := range proxies {
82+
subproxy := proxy.Unwrap(metadata)
83+
for subproxy != nil {
84+
proxies[n] = subproxy
85+
subproxy = subproxy.Unwrap(metadata)
86+
}
87+
}
88+
89+
return proxies
90+
}
91+
7892
func NewRelay(name string, providers []provider.ProxyProvider) *Relay {
7993
return &Relay{
8094
Base: outbound.NewBase(name, "", C.Relay, false),

0 commit comments

Comments
 (0)