diff --git a/README.md b/README.md index 1af142fa..63724d26 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,7 @@ Proxy: # skip-cert-verify: true # host: bing.com # path: "/" + # mux: true # headers: # custom: value diff --git a/adapters/outbound/shadowsocks.go b/adapters/outbound/shadowsocks.go index a958191f..58c76bc9 100644 --- a/adapters/outbound/shadowsocks.go +++ b/adapters/outbound/shadowsocks.go @@ -23,9 +23,9 @@ type ShadowSocks struct { cipher core.Cipher // obfs - obfsMode string - obfsOption *simpleObfsOption - wsOption *v2rayObfs.WebsocketOption + obfsMode string + obfsOption *simpleObfsOption + v2rayOption *v2rayObfs.Option } type ShadowSocksOption struct { @@ -55,6 +55,7 @@ type v2rayObfsOption struct { TLS bool `obfs:"tls,omitempty"` Headers map[string]string `obfs:"headers,omitempty"` SkipCertVerify bool `obfs:"skip-cert-verify,omitempty"` + Mux bool `obfs:"mux,omitempty"` } func (ss *ShadowSocks) Dial(metadata *C.Metadata) (C.Conn, error) { @@ -71,7 +72,7 @@ func (ss *ShadowSocks) Dial(metadata *C.Metadata) (C.Conn, error) { c = obfs.NewHTTPObfs(c, ss.obfsOption.Host, port) case "websocket": var err error - c, err = v2rayObfs.NewWebsocketObfs(c, ss.wsOption) + c, err = v2rayObfs.NewV2rayObfs(c, ss.v2rayOption) if err != nil { return nil, fmt.Errorf("%s connect error: %s", ss.server, err.Error()) } @@ -116,7 +117,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) { return nil, fmt.Errorf("ss %s initialize error: %s", server, err.Error()) } - var wsOption *v2rayObfs.WebsocketOption + var v2rayOption *v2rayObfs.Option var obfsOption *simpleObfsOption obfsMode := "" @@ -144,7 +145,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) { obfsMode = opts.Mode obfsOption = &opts } else if option.Plugin == "v2ray-plugin" { - opts := v2rayObfsOption{Host: "bing.com"} + opts := v2rayObfsOption{Host: "bing.com", Mux: true} if err := decoder.Decode(option.PluginOpts, &opts); err != nil { return nil, fmt.Errorf("ss %s initialize v2ray-plugin error: %s", server, err.Error()) } @@ -162,11 +163,12 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) { ClientSessionCache: getClientSessionCache(), } } - wsOption = &v2rayObfs.WebsocketOption{ + v2rayOption = &v2rayObfs.Option{ Host: opts.Host, Path: opts.Path, Headers: opts.Headers, TLSConfig: tlsConfig, + Mux: opts.Mux, } } @@ -179,9 +181,9 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) { server: server, cipher: ciph, - obfsMode: obfsMode, - wsOption: wsOption, - obfsOption: obfsOption, + obfsMode: obfsMode, + v2rayOption: v2rayOption, + obfsOption: obfsOption, }, nil } diff --git a/component/v2ray-plugin/websocket.go b/component/v2ray-plugin/websocket.go index 96909aff..df6d05da 100644 --- a/component/v2ray-plugin/websocket.go +++ b/component/v2ray-plugin/websocket.go @@ -8,16 +8,17 @@ import ( "github.com/Dreamacro/clash/component/vmess" ) -// WebsocketOption is options of websocket obfs -type WebsocketOption struct { +// Option is options of websocket obfs +type Option struct { Host string Path string Headers map[string]string TLSConfig *tls.Config + Mux bool } -// NewWebsocketObfs return a HTTPObfs -func NewWebsocketObfs(conn net.Conn, option *WebsocketOption) (net.Conn, error) { +// NewV2rayObfs return a HTTPObfs +func NewV2rayObfs(conn net.Conn, option *Option) (net.Conn, error) { header := http.Header{} for k, v := range option.Headers { header.Add(k, v) @@ -36,10 +37,13 @@ func NewWebsocketObfs(conn net.Conn, option *WebsocketOption) (net.Conn, error) if err != nil { return nil, err } - conn = NewMux(conn, MuxOption{ - ID: [2]byte{0, 0}, - Host: "127.0.0.1", - Port: 0, - }) + + if option.Mux { + conn = NewMux(conn, MuxOption{ + ID: [2]byte{0, 0}, + Host: "127.0.0.1", + Port: 0, + }) + } return conn, nil }