Skip to content

Commit

Permalink
UPDATE to support shadowsocks
Browse files Browse the repository at this point in the history
  • Loading branch information
iotames committed Apr 20, 2024
1 parent 9a0bee3 commit 76679d4
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 34 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## 升级日志

### v1.5.0

1. 支持shadowsocks(ss://)协议
2. 完善vmess节点解析规则

### v1.4.1

Expand Down
2 changes: 1 addition & 1 deletion docs/coverpage.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!-- ![logo](_media/icon.svg) -->

# V2rayPool <small>v1.3.7</small>
# V2rayPool <small>v1.5.0</small>

> 简单易用的v2ray客户端和代理池服务
Expand Down
109 changes: 86 additions & 23 deletions v2ray_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ import (
"github.com/v2fly/v2ray-core/v5/common/net"

// "github.com/v2fly/v2ray-core/v5/proxy/blackhole"
// "github.com/v2fly/v2ray-core/v5/proxy/freedom"
"github.com/v2fly/v2ray-core/v5/proxy/freedom"
// "github.com/v2fly/v2ray-core/v5/proxy/dokodemo"
// "github.com/v2fly/v2ray-core/v5/proxy/socks"
// "github.com/v2fly/v2ray-core/v5/common/uuid"
"github.com/v2fly/v2ray-core/v5/proxy/http"
"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks"
"github.com/v2fly/v2ray-core/v5/proxy/socks"
"github.com/v2fly/v2ray-core/v5/proxy/vmess"

// "github.com/v2fly/v2ray-core/v5/proxy/shadowsocks"
// "github.com/v2fly/v2ray-core/v5/proxy/shadowsocks2022"
vmessOutbound "github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound"
"google.golang.org/grpc"
Expand Down Expand Up @@ -111,13 +111,20 @@ func (a V2rayApiClient) RemoveInbound(intag string) error {
return err
}

func getTransportStreamConfig(transproto, path string) (conf *internet.StreamConfig, err error) {
func getTransportStreamConfig(nd V2rayNode, hdhost string) (conf *internet.StreamConfig, err error) {
transproto := nd.Net
path := nd.Path
var transptl internet.TransportProtocol
var protoconf proto.Message
switch transproto {
case "ws", "websocket":
transptl = internet.TransportProtocol_WebSocket
protoconf = &websocket.Config{Path: path}
wsconf := websocket.Config{Path: path}
if hdhost != "" {
// wsconf.UseBrowserForwarding = true
wsconf.Header = []*websocket.Header{{Key: "Host", Value: hdhost}}
}
protoconf = &wsconf
case "tcp":
transptl = internet.TransportProtocol_TCP
protoconf = &tcp.Config{}
Expand Down Expand Up @@ -145,23 +152,28 @@ func (a V2rayApiClient) AddOutboundByV2rayNode(nd V2rayNode, outag string) error
return fmt.Errorf("outbound protocol not support %s. only support vmess, ss, shadowsocks", nd.Protocol)
}
}
streamConf, err := getTransportStreamConfig(nd.Net, nd.Path)
var streamConf *internet.StreamConfig
var resp *pros.AddOutboundResponse
var err error

streamConf, err = getTransportStreamConfig(nd, "")
if err != nil {
return err
}

outsendset := proxyman.SenderConfig{
sender := proxyman.SenderConfig{
StreamSettings: streamConf,
}
if nd.Tls == "tls" {
outsendset.StreamSettings.SecurityType = serial.GetMessageType(&tls.Config{})
outsendset.StreamSettings.SecuritySettings = []*anypb.Any{
sender.StreamSettings.SecurityType = serial.GetMessageType(&tls.Config{})
sender.StreamSettings.SecuritySettings = []*anypb.Any{
serial.ToTypedMessage(&tls.Config{
AllowInsecure: true,
}),
}
}
proxyport, err := nd.Port.Int64()
var proxyport int64
proxyport, err = nd.Port.Int64()
if err != nil {
return fmt.Errorf("err AddOutboundByV2rayNode 端口数据解析错误 port val(%v)--err(%v)", nd.Port, err)
}
Expand Down Expand Up @@ -189,21 +201,72 @@ func (a V2rayApiClient) AddOutboundByV2rayNode(nd V2rayNode, outag string) error
},
},
}
resp, err = a.c.AddOutbound(a.ctx, &pros.AddOutboundRequest{Outbound: &v5.OutboundHandlerConfig{
Tag: outag,
SenderSettings: serial.ToTypedMessage(&sender),
ProxySettings: serial.ToTypedMessage(proxySet),
}})

}
// if nd.Protocol == "shadowsocks" || nd.Protocol == "ss" {
// // proxySet = nil TODO
// }

resp, err := a.c.AddOutbound(a.ctx, &pros.AddOutboundRequest{Outbound: &v5.OutboundHandlerConfig{
Tag: outag,
SenderSettings: serial.ToTypedMessage(&outsendset),
ProxySettings: serial.ToTypedMessage(proxySet),
// ProxySettings: serial.ToTypedMessage(&freedom.Config{
// DomainStrategy: freedom.Config_AS_IS,
// UserLevel: 0,
// }),
}})
fmt.Printf("---AddOutbound(%s)--(%s:%v)-portType(%T)--result(%s)--err(%v)--\n", outag, nd.Add, nd.Port, nd.Port, resp, err)
if nd.Protocol == "shadowsocks" || nd.Protocol == "ss" {
ssAccount := serial.ToTypedMessage(&shadowsocks.Account{
Password: nd.Id,
CipherType: func() shadowsocks.CipherType {
method := strings.ReplaceAll(nd.Type, "-", "_") // "aes-256-gcm",
method = strings.ToUpper(method)
val, ok := shadowsocks.CipherType_value[method]
if ok {
return shadowsocks.CipherType(val)
}
return shadowsocks.CipherType_AES_256_GCM
}(),
})
proxySet = &shadowsocks.ClientConfig{
Server: []*protocol.ServerEndpoint{
{
Address: net.NewIPOrDomain(net.DomainAddress(nd.Add)),
Port: uint32(proxyport),
User: []*protocol.User{{
Account: ssAccount,
}},
},
},
}
sender.ProxySettings = &internet.ProxyConfig{
Tag: outag + "-dialer",
}
resp, err = a.c.AddOutbound(a.ctx, &pros.AddOutboundRequest{Outbound: &v5.OutboundHandlerConfig{
Tag: outag,
SenderSettings: serial.ToTypedMessage(&sender),
ProxySettings: serial.ToTypedMessage(proxySet),
}})
fmt.Printf("---AddOutbound--shadowsocks(%s)--(%s:%v)--result(%s)--err(%v)--\n", outag, nd.Add, nd.Port, resp, err)
resp, err = a.c.AddOutbound(a.ctx, &pros.AddOutboundRequest{Outbound: &v5.OutboundHandlerConfig{
Tag: outag + "-dialer",
SenderSettings: serial.ToTypedMessage(func() *proxyman.SenderConfig {
streamConf, _ = getTransportStreamConfig(nd, "cloudflare.com")
sender := proxyman.SenderConfig{
StreamSettings: streamConf,
MultiplexSettings: &proxyman.MultiplexingConfig{
Enabled: true,
Concurrency: 1,
},
}
return &sender
}()),
ProxySettings: serial.ToTypedMessage(&freedom.Config{
DomainStrategy: freedom.Config_AS_IS,
DestinationOverride: &freedom.DestinationOverride{
Server: &protocol.ServerEndpoint{
Address: net.NewIPOrDomain(net.DomainAddress(nd.Add)),
Port: uint32(proxyport),
},
},
}),
}})
}

fmt.Printf("---AddOutbound(%s)--(%s:%v)-result(%s)--err(%v)--\n", outag, nd.Add, nd.Port, resp, err)
return err
}

Expand Down
12 changes: 8 additions & 4 deletions v2ray_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type V2rayInbound struct {

type V2rayOutbound struct {
Protocol string `json:"protocol"`
SendThrough string `json:"sendThrough"` // 用于发送数据的 IP 地址,当主机有多个 IP 地址时有效,默认值为 "0.0.0.0"。
SendThrough *string `json:"sendThrough"` // 用于发送数据的 IP 地址,当主机有多个 IP 地址时有效,默认值为 "0.0.0.0"。
Tag string `json:"tag"`
Settings json.RawMessage `json:"settings"` // 视协议不同而不同。详见每个协议中的 OutboundConfigurationObject
// "streamSettings":{"network":"%s","tlsSettings":{"disableSystemRoot":false},"wsSettings":{"path":""},"xtlsSettings":{"disableSystemRoot":false}}
Expand Down Expand Up @@ -187,7 +187,10 @@ func setV2rayConfigV4Routing(confv4 *V2rayConfigV4, cf conf.Conf, inPort int) {
// setV2rayConfigV4Outbounds 出站配置
// n.Add != "" 时,启用单节点代理模式。
func setV2rayConfigV4Outbounds(confv4 *V2rayConfigV4, n V2rayNode) error {
outdirect := V2rayOutbound{Protocol: "freedom", Tag: TAG_OUTBOUND_DIRECT, SendThrough: "0.0.0.0"}
sendth := "0.0.0.0"
// sendth.Address = net.ParseAddress()
// fmt.Printf("-------setV2rayConfigV4Outbounds---SendThrough---ip(%+v)--domain(%+v)--str(%s)-\n", sendth.Address.IP(), sendth.Address.Domain(), sendth.Address)
outdirect := V2rayOutbound{Protocol: "freedom", Tag: TAG_OUTBOUND_DIRECT, SendThrough: &sendth}
outdirect.Settings = json.RawMessage(`{}`)
outdirect.StreamSetting = json.RawMessage(`{}`)

Expand All @@ -196,7 +199,7 @@ func setV2rayConfigV4Outbounds(confv4 *V2rayConfigV4, n V2rayNode) error {
networkset := n.Net
outbd1 := V2rayOutbound{
Protocol: n.Protocol,
SendThrough: "0.0.0.0",
SendThrough: &sendth,
Tag: TAG_OUTBOUND_ACTIVE,
}

Expand All @@ -219,7 +222,8 @@ func setV2rayConfigV4Outbounds(confv4 *V2rayConfigV4, n V2rayNode) error {
return nil
}
if n.Protocol == "ss" || n.Protocol == "shadowsocks" {
settingstr := fmt.Sprintf(`"servers":[{"address":"%s","method":"%s","password":"%s","port":%s}]`, n.Add, n.Type, n.Id, n.Port)
outbd1.Protocol = "shadowsocks"
settingstr := fmt.Sprintf(`{"servers":[{"address":"%s","method":"%s","password":"%s","port":%s}]}`, n.Add, n.Type, n.Id, n.Port)
outbd1.Settings = json.RawMessage(settingstr)
proxysetTag := fmt.Sprintf("%s-dialer", outbd1.Tag)
outbd1.ProxySettings = json.RawMessage(fmt.Sprintf(`{"tag":"%s"}`, proxysetTag))
Expand Down
14 changes: 11 additions & 3 deletions v2ray_parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
nurl "net/url"
"strings"
)

Expand Down Expand Up @@ -58,17 +59,19 @@ func parseNodeInfo(d string) (nd V2rayNode, err error) {
if nd.Protocol == "ss" {
pwdsplit := strings.Split(ninfo[1], "@")
pwdinfo := pwdsplit[0]
b, err = base64.StdEncoding.DecodeString(pwdinfo)
var b1 string
b1, err = Base64StdDecode(pwdinfo) // base64.StdEncoding.DecodeString(pwdinfo)
if err != nil {
err = fmt.Errorf("parseNodeInfo err(%v) for ss:// base64 DecodeString", err)
return
}
pwdsplit2 := strings.Split(string(b), ":")
pwdsplit2 := strings.Split(b1, ":")
method := pwdsplit2[0]
password := pwdsplit2[1]
addrsplit := strings.Split(pwdsplit[1], `/?`)
addrsplit2 := strings.Split(addrsplit[0], `:`)
args := strings.Split(addrsplit[1], `;`)
argspre, _ := nurl.QueryUnescape(addrsplit[1])
args := strings.Split(argspre, `;`)
for _, arg := range args {
if strings.Contains(arg, "=") {
argsplit := strings.Split(arg, "=")
Expand Down Expand Up @@ -98,6 +101,11 @@ func parseNodeInfo(d string) (nd V2rayNode, err error) {
nd.Port = json.Number(addrsplit2[1])
nd.Type = method
nd.Id = password
portint, _ := nd.Port.Int64()
if nd.Id == "" || nd.Type == "" || portint == 0 || nd.Add == "" || nd.Net == "" {
err = fmt.Errorf("---parse--shadowsocks--err--ss://--raw(%s)---nd(%+v)", ninfo[1], nd)
return
}
return
}
if nd.Protocol == "trojan" {
Expand Down
15 changes: 12 additions & 3 deletions v2raypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,9 +445,13 @@ func (p *ProxyPool) TestAllForce() {
return
}
p.nodes.SortBySpeed()

if p.activeCmd == nil {
p.ActiveNode(p.nodes[0], true)
for _, nd := range p.nodes {
if nd.IsOk() {
p.ActiveNode(nd, true)
break
}
}
}
p.IsLock = false
}
Expand Down Expand Up @@ -501,7 +505,12 @@ func (p *ProxyPool) TestAll() {
}
p.nodes.SortBySpeed()
if p.activeCmd == nil {
p.ActiveNode(p.nodes[0], true)
for _, nd := range p.nodes {
if nd.IsOk() {
p.ActiveNode(nd, true)
break
}
}
}
p.IsLock = false
}
Expand Down

0 comments on commit 76679d4

Please sign in to comment.