V2bX/api/panel/node.go

237 lines
6.3 KiB
Go
Raw Normal View History

package panel
2022-06-04 00:05:46 -04:00
import (
2023-07-15 07:37:44 -04:00
"encoding/base64"
"fmt"
"reflect"
"strconv"
2023-01-06 12:59:24 -05:00
"strings"
"time"
2023-07-14 00:54:09 -04:00
2023-07-29 07:27:15 -04:00
"github.com/InazumaV/V2bX/common/crypt"
2023-07-14 00:54:09 -04:00
"github.com/goccy/go-json"
2022-06-04 00:05:46 -04:00
)
type CommonNodeRsp struct {
2023-06-09 00:36:49 -04:00
Host string `json:"host"`
ServerPort int `json:"server_port"`
2023-06-09 00:36:49 -04:00
ServerName string `json:"server_name"`
Routes []Route `json:"routes"`
BaseConfig BaseConfig `json:"base_config"`
}
type Route struct {
2023-07-27 13:07:56 -04:00
Id int `json:"id"`
Match interface{} `json:"match"`
Action string `json:"action"`
ActionValue string `json:"action_value"`
}
type BaseConfig struct {
PushInterval any `json:"push_interval"`
PullInterval any `json:"pull_interval"`
2022-09-14 21:24:14 -04:00
}
2022-06-04 00:05:46 -04:00
type V2rayNodeRsp struct {
Tls int `json:"tls"`
Network string `json:"network"`
NetworkSettings json.RawMessage `json:"networkSettings"`
ServerName string `json:"server_name"`
}
type ShadowsocksNodeRsp struct {
Cipher string `json:"cipher"`
ServerKey string `json:"server_key"`
}
type HysteriaNodeRsp struct {
UpMbps int `json:"up_mbps"`
DownMbps int `json:"down_mbps"`
Obfs string `json:"obfs"`
}
type NodeInfo struct {
Id int
Type string
2023-07-20 09:14:18 -04:00
Rules Rules
2023-06-09 00:36:49 -04:00
Host string
Port int
Network string
RawDNS RawDNS
ExtraConfig V2rayExtraConfig
NetworkSettings json.RawMessage
Tls bool
ServerName string
UpMbps int
DownMbps int
ServerKey string
Cipher string
HyObfs string
PushInterval time.Duration
PullInterval time.Duration
}
type RawDNS struct {
DNSMap map[string]map[string]interface{}
DNSJson []byte
}
2023-07-20 09:14:18 -04:00
type Rules struct {
Regexp []string
Protocol []string
}
type V2rayExtraConfig struct {
2023-07-19 11:41:42 -04:00
EnableVless string `json:"EnableVless"`
2023-07-15 07:37:44 -04:00
VlessFlow string `json:"VlessFlow"`
2023-07-19 11:41:42 -04:00
EnableReality string `json:"EnableReality"`
2023-07-15 07:37:44 -04:00
RealityConfig *RealityConfig `json:"RealityConfig"`
}
type RealityConfig struct {
2023-08-07 02:52:50 -04:00
Dest string `yaml:"Dest" json:"Dest"`
Xver string `yaml:"Xver" json:"Xver"`
ServerNames []string `yaml:"ServerNames" json:"ServerNames"`
PrivateKey string `yaml:"PrivateKey" json:"PrivateKey"`
MinClientVer string `yaml:"MinClientVer" json:"MinClientVer"`
MaxClientVer string `yaml:"MaxClientVer" json:"MaxClientVer"`
MaxTimeDiff string `yaml:"MaxTimeDiff" json:"MaxTimeDiff"`
ShortIds []string `yaml:"ShortIds" json:"ShortIds"`
}
func (c *Client) GetNodeInfo() (node *NodeInfo, err error) {
const path = "/api/v1/server/UniProxy/config"
2023-06-24 19:49:51 -04:00
r, err := c.client.
R().
2023-07-21 14:38:07 -04:00
SetHeader("If-None-Match", c.nodeEtag).
2023-06-24 19:49:51 -04:00
Get(path)
if err = c.checkResponse(r, path, err); err != nil {
return
2022-06-04 00:05:46 -04:00
}
2023-06-24 19:49:51 -04:00
if r.StatusCode() == 304 {
2022-09-14 21:24:14 -04:00
return nil, nil
2022-06-04 00:05:46 -04:00
}
// parse common params
2023-06-09 00:36:49 -04:00
node = &NodeInfo{
Id: c.NodeId,
Type: c.NodeType,
RawDNS: RawDNS{
DNSMap: make(map[string]map[string]interface{}),
DNSJson: []byte(""),
},
2023-06-09 00:36:49 -04:00
}
common := CommonNodeRsp{}
err = json.Unmarshal(r.Body(), &common)
if err != nil {
return nil, fmt.Errorf("decode common params error: %s", err)
}
2023-07-27 13:07:56 -04:00
for i := range common.Routes {
var matchs []string
if _, ok := common.Routes[i].Match.(string); ok {
matchs = strings.Split(common.Routes[i].Match.(string), ",")
} else if _, ok = common.Routes[i].Match.([]string); ok {
matchs = common.Routes[i].Match.([]string)
} else {
temp := common.Routes[i].Match.([]interface{})
matchs = make([]string, len(temp))
for i := range temp {
matchs[i] = temp[i].(string)
2023-01-06 12:59:24 -05:00
}
}
switch common.Routes[i].Action {
case "block":
2023-01-06 12:59:24 -05:00
for _, v := range matchs {
2023-07-20 09:14:18 -04:00
if strings.HasPrefix(v, "protocol:") {
// protocol
node.Rules.Protocol = append(node.Rules.Protocol, strings.TrimPrefix(v, "protocol:"))
} else {
// domain
node.Rules.Regexp = append(node.Rules.Regexp, strings.TrimPrefix(v, "regexp:"))
}
2023-01-06 12:59:24 -05:00
}
case "dns":
var domains []string
for _, v := range matchs {
domains = append(domains, v)
}
2023-07-19 00:03:09 -04:00
if matchs[0] != "main" {
node.RawDNS.DNSMap[strconv.Itoa(i)] = map[string]interface{}{
"address": common.Routes[i].ActionValue,
"domains": domains,
2023-07-19 00:03:09 -04:00
}
2023-07-27 13:07:56 -04:00
} else {
dns := []byte(strings.Join(matchs[1:], ""))
node.RawDNS.DNSJson = dns
2023-07-27 13:07:56 -04:00
break
2023-07-19 00:03:09 -04:00
}
2022-06-04 00:05:46 -04:00
}
}
2023-06-09 00:36:49 -04:00
node.ServerName = common.ServerName
node.Host = common.Host
node.Port = common.ServerPort
node.PullInterval = intervalToTime(common.BaseConfig.PullInterval)
node.PushInterval = intervalToTime(common.BaseConfig.PushInterval)
// parse protocol params
switch c.NodeType {
case "v2ray":
rsp := V2rayNodeRsp{}
err = json.Unmarshal(r.Body(), &rsp)
if err != nil {
return nil, fmt.Errorf("decode v2ray params error: %s", err)
}
node.Network = rsp.Network
node.NetworkSettings = rsp.NetworkSettings
node.ServerName = rsp.ServerName
if rsp.Tls == 1 {
node.Tls = true
}
2023-07-14 00:54:09 -04:00
err = json.Unmarshal(rsp.NetworkSettings, &node.ExtraConfig)
if err != nil {
return nil, fmt.Errorf("decode v2ray extra error: %s", err)
}
2023-07-19 11:41:42 -04:00
if node.ExtraConfig.EnableReality == "true" {
2023-07-15 07:37:44 -04:00
if node.ExtraConfig.RealityConfig == nil {
2023-07-19 11:41:42 -04:00
node.ExtraConfig.EnableReality = "false"
2023-07-15 07:37:44 -04:00
} else {
key := crypt.GenX25519Private([]byte(strconv.Itoa(c.NodeId) + c.NodeType + c.Token))
2023-07-15 07:37:44 -04:00
node.ExtraConfig.RealityConfig.PrivateKey = base64.RawURLEncoding.EncodeToString(key)
}
}
case "shadowsocks":
rsp := ShadowsocksNodeRsp{}
err = json.Unmarshal(r.Body(), &rsp)
if err != nil {
return nil, fmt.Errorf("decode v2ray params error: %s", err)
}
node.ServerKey = rsp.ServerKey
node.Cipher = rsp.Cipher
case "trojan":
2023-07-20 04:29:21 -04:00
node.Tls = true
case "hysteria":
rsp := HysteriaNodeRsp{}
err = json.Unmarshal(r.Body(), &rsp)
if err != nil {
return nil, fmt.Errorf("decode v2ray params error: %s", err)
}
node.DownMbps = rsp.DownMbps
node.UpMbps = rsp.UpMbps
node.HyObfs = rsp.Obfs
}
2023-07-21 14:38:07 -04:00
c.nodeEtag = r.Header().Get("ETag")
return
2022-06-04 00:05:46 -04:00
}
func intervalToTime(i interface{}) time.Duration {
switch reflect.TypeOf(i).Kind() {
case reflect.Int:
return time.Duration(i.(int)) * time.Second
case reflect.String:
i, _ := strconv.Atoi(i.(string))
return time.Duration(i) * time.Second
case reflect.Float64:
return time.Duration(i.(float64)) * time.Second
2023-05-19 00:38:16 -04:00
default:
return time.Duration(reflect.ValueOf(i).Int()) * time.Second
}
}