Skip to content

Commit

Permalink
New transports and api changes for V2RaySocks
Browse files Browse the repository at this point in the history
  • Loading branch information
theresaarcher committed Aug 6, 2024
1 parent 944e8cd commit f65cdc8
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 31 deletions.
6 changes: 5 additions & 1 deletion api/v2raysocks/model.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package v2raysocks

type UserTraffic struct {
UID int `json:"user_id"`
UID int `json:"uid"`
Upload int64 `json:"u"`
Download int64 `json:"d"`
}
Expand All @@ -19,6 +19,10 @@ type NodeOnline struct {
IP string `json:"ip"`
}

type IllegalItem struct {
UID int `json:"uid"`
}

type REALITYConfig struct {
Dest string `json:"dest,omitempty"`
ProxyProtocolVer uint64 `json:"proxy_protocol_ver,omitempty"`
Expand Down
91 changes: 61 additions & 30 deletions api/v2raysocks/v2raysocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ func (c *APIClient) GetNodeInfo() (nodeInfo *api.NodeInfo, err error) {
res, err := c.client.R().
SetHeader("If-None-Match", c.eTags["config"]).
SetQueryParams(map[string]string{
"act": "config",
"nodetype": nodeType,
"act": "config",
"node_type": nodeType,
}).
ForceContentType("application/json").
Get(c.APIHost)
Expand Down Expand Up @@ -213,8 +213,8 @@ func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) {
res, err := c.client.R().
SetHeader("If-None-Match", c.eTags["user"]).
SetQueryParams(map[string]string{
"act": "user",
"nodetype": nodeType,
"act": "user",
"node_type": nodeType,
}).
ForceContentType("application/json").
Get(c.APIHost)
Expand All @@ -239,22 +239,21 @@ func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) {
user.UID = response.Get("data").GetIndex(i).Get("id").MustInt()
switch c.NodeType {
case "Shadowsocks":
user.Email = response.Get("data").GetIndex(i).Get("shadowsocks_user").Get("secret").MustString()
user.Passwd = response.Get("data").GetIndex(i).Get("shadowsocks_user").Get("secret").MustString()
user.Method = response.Get("data").GetIndex(i).Get("shadowsocks_user").Get("cipher").MustString()
user.SpeedLimit = response.Get("data").GetIndex(i).Get("shadowsocks_user").Get("speed_limit").MustUint64() * 1000000 / 8
user.DeviceLimit = response.Get("data").GetIndex(i).Get("shadowsocks_user").Get("device_limit").MustInt()
user.Email = response.Get("data").GetIndex(i).Get("secret").MustString()
user.Passwd = response.Get("data").GetIndex(i).Get("secret").MustString()
user.Method = response.Get("data").GetIndex(i).Get("cipher").MustString()
user.SpeedLimit = response.Get("data").GetIndex(i).Get("st").MustUint64() * 1000000 / 8
user.DeviceLimit = response.Get("data").GetIndex(i).Get("dt").MustInt()
case "Trojan":
user.UUID = response.Get("data").GetIndex(i).Get("trojan_user").Get("password").MustString()
user.Email = response.Get("data").GetIndex(i).Get("trojan_user").Get("password").MustString()
user.SpeedLimit = response.Get("data").GetIndex(i).Get("trojan_user").Get("speed_limit").MustUint64() * 1000000 / 8
user.DeviceLimit = response.Get("data").GetIndex(i).Get("trojan_user").Get("device_limit").MustInt()
user.UUID = response.Get("data").GetIndex(i).Get("password").MustString()
user.Email = response.Get("data").GetIndex(i).Get("password").MustString()
user.SpeedLimit = response.Get("data").GetIndex(i).Get("st").MustUint64() * 1000000 / 8
user.DeviceLimit = response.Get("data").GetIndex(i).Get("dt").MustInt()
case "V2ray", "Vmess", "Vless":
user.UUID = response.Get("data").GetIndex(i).Get("v2ray_user").Get("uuid").MustString()
user.Email = response.Get("data").GetIndex(i).Get("v2ray_user").Get("email").MustString()
user.AlterID = uint16(response.Get("data").GetIndex(i).Get("v2ray_user").Get("alter_id").MustUint64())
user.SpeedLimit = response.Get("data").GetIndex(i).Get("v2ray_user").Get("speed_limit").MustUint64() * 1000000 / 8
user.DeviceLimit = response.Get("data").GetIndex(i).Get("v2ray_user").Get("device_limit").MustInt()
user.UUID = response.Get("data").GetIndex(i).Get("uuid").MustString()
user.Email = user.UUID + "@x.com"
user.SpeedLimit = response.Get("data").GetIndex(i).Get("st").MustUint64() * 1000000 / 8
user.DeviceLimit = response.Get("data").GetIndex(i).Get("dt").MustInt()
}
if c.SpeedLimit > 0 {
user.SpeedLimit = uint64((c.SpeedLimit * 1000000) / 8)
Expand Down Expand Up @@ -283,8 +282,8 @@ func (c *APIClient) ReportUserTraffic(userTraffic *[]api.UserTraffic) error {
res, err := c.client.R().
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
SetQueryParams(map[string]string{
"act": "submit",
"nodetype": strings.ToLower(c.NodeType),
"act": "submit",
"node_type": strings.ToLower(c.NodeType),
}).
SetBody(data).
ForceContentType("application/json").
Expand Down Expand Up @@ -327,8 +326,8 @@ func (c *APIClient) ReportNodeStatus(nodeStatus *api.NodeStatus) (err error) {
res, err := c.client.R().
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
SetQueryParams(map[string]string{
"act": "nodestatus",
"nodetype": strings.ToLower(c.NodeType),
"act": "nodestatus",
"node_type": strings.ToLower(c.NodeType),
}).
SetBody(systemload).
ForceContentType("application/json").
Expand All @@ -350,8 +349,8 @@ func (c *APIClient) ReportNodeOnlineUsers(onlineUserList *[]api.OnlineUser) erro
res, err := c.client.R().
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
SetQueryParams(map[string]string{
"act": "onlineusers",
"nodetype": strings.ToLower(c.NodeType),
"act": "onlineusers",
"node_type": strings.ToLower(c.NodeType),
}).
SetBody(data).
ForceContentType("application/json").
Expand All @@ -365,6 +364,26 @@ func (c *APIClient) ReportNodeOnlineUsers(onlineUserList *[]api.OnlineUser) erro

// ReportIllegal implements the API interface
func (c *APIClient) ReportIllegal(detectResultList *[]api.DetectResult) error {
data := make([]IllegalItem, len(*detectResultList))
for i, r := range *detectResultList {
data[i] = IllegalItem{
UID: r.UID,
}
}

res, err := c.client.R().
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
SetQueryParams(map[string]string{
"act": "illegal",
"node_type": strings.ToLower(c.NodeType),
}).
SetBody(data).
ForceContentType("application/json").
Post(c.APIHost)
_, err = c.parseResponse(res, "", err)
if err != nil {
return err
}
return nil
}

Expand Down Expand Up @@ -423,7 +442,7 @@ func (c *APIClient) ParseV2rayNodeResponse(nodeInfoResponse *simplejson.Json) (*
var enableTLS bool
var enableVless bool
var enableReality bool
var alterID uint16 = 0
var vlessFlow string

tmpInboundInfo := nodeInfoResponse.Get("inbounds").MustArray()
marshalByte, _ := json.Marshal(tmpInboundInfo[0].(map[string]interface{}))
Expand All @@ -436,6 +455,12 @@ func (c *APIClient) ParseV2rayNodeResponse(nodeInfoResponse *simplejson.Json) (*
case "ws":
path = inboundInfo.Get("streamSettings").Get("wsSettings").Get("path").MustString()
host = inboundInfo.Get("streamSettings").Get("wsSettings").Get("headers").Get("Host").MustString()
case "httpupgrade":
host = inboundInfo.Get("streamSettings").Get("httpupgradeSettings").Get("Host").MustString()
path = inboundInfo.Get("streamSettings").Get("httpupgradeSettings").Get("path").MustString()
case "splithttp":
host = inboundInfo.Get("streamSettings").Get("splithttpSettings").Get("Host").MustString()
path = inboundInfo.Get("streamSettings").Get("splithttpSettings").Get("path").MustString()
case "grpc":
if data, ok := inboundInfo.Get("streamSettings").Get("grpcSettings").CheckGet("serviceName"); ok {
serviceName = data.MustString()
Expand All @@ -448,12 +473,11 @@ func (c *APIClient) ParseV2rayNodeResponse(nodeInfoResponse *simplejson.Json) (*
header = httpHeader
}
}

}

enableTLS = inboundInfo.Get("streamSettings").Get("security").MustString() == "tls"
enableVless = inboundInfo.Get("streamSettings").Get("security").MustString() == "reality"
enableReality = enableVless
enableVless = inboundInfo.Get("protocol").MustString() == "vless"
enableReality = inboundInfo.Get("streamSettings").Get("security").MustString() == "reality"

realityConfig := new(api.REALITYConfig)
if enableVless {
Expand All @@ -470,19 +494,26 @@ func (c *APIClient) ParseV2rayNodeResponse(nodeInfoResponse *simplejson.Json) (*
}
}

// XTLS only supports TLS and REALITY directly for now
if transportProtocol == "tcp" && enableReality {
vlessFlow = "xtls-rprx-vision"
} else {
vlessFlow = c.VlessFlow
}

// Create GeneralNodeInfo
// AlterID will be updated after next sync
nodeInfo := &api.NodeInfo{
NodeType: c.NodeType,
NodeID: c.NodeID,
Port: port,
AlterID: alterID,
AlterID: 0,
TransportProtocol: transportProtocol,
EnableTLS: enableTLS,
Path: path,
Host: host,
EnableVless: enableVless,
VlessFlow: c.VlessFlow,
VlessFlow: vlessFlow,
ServiceName: serviceName,
Header: header,
EnableREALITY: enableReality,
Expand Down

0 comments on commit f65cdc8

Please sign in to comment.