mirror of
https://github.com/v2rayA/v2rayA.git
synced 2024-11-25 16:34:19 +08:00
Provide a new implement way of shadowsocks plugin. (#604)
This commit is contained in:
parent
d35f5d99e0
commit
e1a5f8cfe3
3
.gitignore
vendored
3
.gitignore
vendored
@ -33,3 +33,6 @@ node_modules
|
||||
/PKGBUILD
|
||||
/go.mod
|
||||
/go.sum
|
||||
|
||||
# Virtualenv
|
||||
.env
|
||||
|
@ -289,6 +289,32 @@
|
||||
<option value="v2ray-plugin">v2ray-plugin</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
<b-field
|
||||
v-if="ss.plugin === 'simple-obfs' || ss.plugin === 'v2ray-plugin'"
|
||||
label-position="on-border"
|
||||
class="with-icon-alert"
|
||||
>
|
||||
<template slot="label">
|
||||
Impl
|
||||
<b-tooltip
|
||||
type="is-dark"
|
||||
:label="$t('setting.messages.ssPluginImpl')"
|
||||
multilined
|
||||
position="is-right"
|
||||
>
|
||||
<b-icon
|
||||
size="is-samll"
|
||||
icon=" iconfont icon-help-circle-outline"
|
||||
style="position:relative;top:2px;right:3px;font-weight:normal"
|
||||
/>
|
||||
</b-tooltip>
|
||||
</template>
|
||||
<b-select ref="ss_plugin_impl" v-model="ss.impl" expanded>
|
||||
<option value="">{{ $t("setting.options.default") }}</option>
|
||||
<option value="chained">chained</option>
|
||||
<option value="transport">transport</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
<b-field
|
||||
v-show="ss.plugin === 'simple-obfs'"
|
||||
label="Obfs"
|
||||
@ -753,7 +779,8 @@ export default {
|
||||
server: "",
|
||||
port: "",
|
||||
name: "",
|
||||
protocol: "ss"
|
||||
protocol: "ss",
|
||||
impl: ""
|
||||
},
|
||||
ssr: {
|
||||
method: "aes-128-cfb",
|
||||
@ -936,7 +963,8 @@ export default {
|
||||
name: u.hash,
|
||||
obfs: "http",
|
||||
plugin: "",
|
||||
protocol: "ss"
|
||||
protocol: "ss",
|
||||
impl: ""
|
||||
};
|
||||
if (u.params.plugin) {
|
||||
u.params.plugin = decodeURIComponent(u.params.plugin);
|
||||
@ -972,6 +1000,8 @@ export default {
|
||||
break;
|
||||
case "tls":
|
||||
obj.tls = "tls";
|
||||
case "impl":
|
||||
obj.impl = a[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1159,12 +1189,18 @@ export default {
|
||||
}
|
||||
plugin.push("path=" + srcObj.path);
|
||||
}
|
||||
if (srcObj.impl) {
|
||||
plugin.push("impl=" + srcObj.impl);
|
||||
}
|
||||
} else {
|
||||
plugin.push("obfs=" + srcObj.obfs);
|
||||
plugin.push("obfs-host=" + srcObj.host);
|
||||
if (srcObj.obfs === "http") {
|
||||
plugin.push("obfs-path=" + srcObj.path);
|
||||
}
|
||||
if (srcObj.impl) {
|
||||
plugin.push("impl=" + srcObj.impl);
|
||||
}
|
||||
}
|
||||
tmp += `?plugin=${encodeURIComponent(plugin.join(";"))}`;
|
||||
}
|
||||
|
@ -160,6 +160,10 @@ export default {
|
||||
<p>TCP: {tcpPorts}</p>
|
||||
<p>UDP: {udpPorts}</p>`,
|
||||
grpcShouldWithTls: `gRPC must be with TLS`
|
||||
ssPluginImpl:
|
||||
"★default: 'transport' for simple-obfs, 'chained' for v2ray-plugin." +
|
||||
"★chained: shadowsocks traffic will be redirect to standalone plugin." +
|
||||
"★transport: processed by the transport layer of v2ray/xray core directly."
|
||||
}
|
||||
},
|
||||
customAddressPort: {
|
||||
|
@ -159,6 +159,10 @@ export default {
|
||||
<p>TCP: {tcpPorts}</p>
|
||||
<p>UDP: {udpPorts}</p>`,
|
||||
grpcShouldWithTls: `gRPC必须启用TLS`
|
||||
ssPluginImpl:
|
||||
"★默认:使用 simple-obfs 时为等效传输层,v2ray-plugin 时为链式。" +
|
||||
"★链式:shadowsocks 流量会被转发至独立的插件。" +
|
||||
"★等效传输层:直接由 v2ray/xray 核心的传输层处理。"
|
||||
}
|
||||
},
|
||||
customAddressPort: {
|
||||
|
@ -106,12 +106,7 @@ func ParseSSURL(u string) (data *Shadowsocks, err error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (s *Shadowsocks) Configuration(info PriorInfo) (c Configuration, err error) {
|
||||
switch s.Cipher {
|
||||
case "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "plain", "none":
|
||||
default:
|
||||
return c, fmt.Errorf("unsupported shadowsocks encryption method: %v", s.Cipher)
|
||||
}
|
||||
func (s *Shadowsocks) ConfigurationMC(info PriorInfo) (c Configuration, err error) {
|
||||
v2rayServer := coreObj.Server{
|
||||
Address: s.Server,
|
||||
Port: s.Port,
|
||||
@ -213,6 +208,148 @@ func (s *Shadowsocks) Configuration(info PriorInfo) (c Configuration, err error)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Shadowsocks) ConfigurationMT(info PriorInfo) (c Configuration, err error) {
|
||||
v2rayServer := coreObj.Server{
|
||||
Address: s.Server,
|
||||
Port: s.Port,
|
||||
Method: s.Cipher,
|
||||
Password: s.Password,
|
||||
}
|
||||
udpSupport := true
|
||||
var v2StreamSettings *coreObj.StreamSettings
|
||||
var v2Mux *coreObj.Mux
|
||||
switch s.Plugin.Name {
|
||||
case "simple-obfs":
|
||||
host := s.Plugin.Opts.Host
|
||||
if host == "" {
|
||||
host = "cloudflare.com"
|
||||
}
|
||||
path := s.Plugin.Opts.Path
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
v2StreamSettings = &coreObj.StreamSettings{}
|
||||
tcpSettings := coreObj.TCPSettings{
|
||||
Header: coreObj.TCPHeader{
|
||||
Type: "http",
|
||||
Request: coreObj.HTTPRequest{
|
||||
Version: "1.1",
|
||||
Method: "GET",
|
||||
Path: strings.Split(path, ","),
|
||||
Headers: coreObj.HTTPReqHeader{
|
||||
Host: strings.Split(host, ","),
|
||||
UserAgent: []string{
|
||||
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/527.36 (KHTML, like Gecko) Chrome/55.2883.75 Safari/537.36",
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.46",
|
||||
},
|
||||
AcceptEncoding: []string{"gzip, deflate"},
|
||||
Connection: []string{"keep-alive"},
|
||||
Pragma: "no-cache",
|
||||
},
|
||||
},
|
||||
Response: coreObj.HTTPResponse{
|
||||
Version: "1.1",
|
||||
Status: "200",
|
||||
Reason: "OK",
|
||||
Headers: coreObj.HTTPRespHeader {
|
||||
ContentType: []string{"application/octet-stream", "video/mpeg"},
|
||||
TransferEncoding: []string{"chunked"},
|
||||
Connection: []string{"keep-alive"},
|
||||
Pragma: "no-cache",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
switch s.Plugin.Opts.Obfs {
|
||||
case "http":
|
||||
v2StreamSettings.Network = "tcp"
|
||||
v2StreamSettings.TCPSettings = &tcpSettings
|
||||
case "tls":
|
||||
v2StreamSettings.Security = "tls"
|
||||
v2StreamSettings.TLSSettings = &coreObj.TLSSettings{}
|
||||
// SNI
|
||||
v2StreamSettings.TLSSettings.ServerName = host
|
||||
default:
|
||||
return c, fmt.Errorf("unsupported obfs %v of plugin %v", s.Plugin.Opts.Obfs, s.Plugin.Name)
|
||||
}
|
||||
case "v2ray-plugin":
|
||||
v2StreamSettings = &coreObj.StreamSettings{}
|
||||
host := s.Plugin.Opts.Host
|
||||
if host == "" {
|
||||
host = "cloudflare.com"
|
||||
}
|
||||
path := s.Plugin.Opts.Path
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
if s.Plugin.Opts.Tls == "tls" {
|
||||
v2StreamSettings.Security = "tls"
|
||||
v2StreamSettings.TLSSettings = &coreObj.TLSSettings{}
|
||||
// SNI
|
||||
v2StreamSettings.TLSSettings.ServerName = host
|
||||
}
|
||||
v2Mux = &coreObj.Mux{
|
||||
Enabled: true,
|
||||
Concurrency: 1,
|
||||
}
|
||||
switch s.Plugin.Opts.Obfs {
|
||||
case "quic":
|
||||
return c, fmt.Errorf("quic is not yet supported")
|
||||
default:
|
||||
// "websocket" or ""
|
||||
v2StreamSettings.Network = "ws"
|
||||
v2StreamSettings.WsSettings = &coreObj.WsSettings{
|
||||
Path: path,
|
||||
Headers: coreObj.Headers{
|
||||
Host: host,
|
||||
},
|
||||
}
|
||||
}
|
||||
case "":
|
||||
// no plugin
|
||||
default:
|
||||
return c, fmt.Errorf("unsupported plugin %v", s.Plugin.Name)
|
||||
}
|
||||
return Configuration{
|
||||
CoreOutbound: coreObj.OutboundObject{
|
||||
Tag: info.Tag,
|
||||
Protocol: "shadowsocks",
|
||||
Settings: coreObj.Settings{
|
||||
Servers: []coreObj.Server{v2rayServer},
|
||||
},
|
||||
StreamSettings: v2StreamSettings,
|
||||
Mux: v2Mux,
|
||||
},
|
||||
UDPSupport: udpSupport,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Shadowsocks) Configuration(info PriorInfo) (c Configuration, err error) {
|
||||
switch s.Cipher {
|
||||
case "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "plain", "none":
|
||||
default:
|
||||
return c, fmt.Errorf("unsupported shadowsocks encryption method: %v", s.Cipher)
|
||||
}
|
||||
// check shadowsocks plugin implementation
|
||||
ssPluginImpl := s.Plugin.Opts.Impl
|
||||
if ssPluginImpl == "" {
|
||||
switch s.Plugin.Name {
|
||||
case "simple-obfs":
|
||||
ssPluginImpl = "transport"
|
||||
default:
|
||||
ssPluginImpl = "chained"
|
||||
}
|
||||
}
|
||||
switch ssPluginImpl {
|
||||
case "chained":
|
||||
return s.ConfigurationMC(info)
|
||||
case "transport":
|
||||
return s.ConfigurationMT(info)
|
||||
default:
|
||||
return c, fmt.Errorf("unsupported shadowsocks plugin implementation: %v", ssPluginImpl)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Shadowsocks) ExportToURL() string {
|
||||
// sip002
|
||||
u := &url.URL{
|
||||
@ -273,6 +410,7 @@ type Sip003Opts struct {
|
||||
Obfs string `json:"obfs"`
|
||||
Host string `json:"host"`
|
||||
Path string `json:"uri"`
|
||||
Impl string `json:"impl"`
|
||||
}
|
||||
|
||||
func ParseSip003Opts(opts string) Sip003Opts {
|
||||
@ -296,6 +434,8 @@ func ParseSip003Opts(opts string) Sip003Opts {
|
||||
sip003Opts.Path = a[1]
|
||||
case "obfs-host", "host":
|
||||
sip003Opts.Host = a[1]
|
||||
case "impl":
|
||||
sip003Opts.Impl = a[1]
|
||||
}
|
||||
}
|
||||
return sip003Opts
|
||||
@ -326,6 +466,9 @@ func (s *Sip003) String() string {
|
||||
if s.Opts.Path != "" {
|
||||
list = append(list, "obfs-uri="+s.Opts.Path)
|
||||
}
|
||||
if s.Opts.Impl != "" {
|
||||
list = append(list, "impl="+s.Opts.Impl)
|
||||
}
|
||||
case "v2ray-plugin":
|
||||
if s.Opts.Tls != "" {
|
||||
list = append(list, "tls")
|
||||
@ -339,6 +482,9 @@ func (s *Sip003) String() string {
|
||||
if s.Opts.Path != "" {
|
||||
list = append(list, "path="+s.Opts.Path)
|
||||
}
|
||||
if s.Opts.Impl != "" {
|
||||
list = append(list, "impl="+s.Opts.Impl)
|
||||
}
|
||||
}
|
||||
return strings.Join(list, ";")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user