mirror of
https://github.com/wyx2685/V2bX.git
synced 2026-02-06 05:30:08 +00:00
Compare commits
2 Commits
v0.0.0-202
...
v0.0.0-202
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f92c5b37d5 | ||
|
|
91e78fbc20 |
@@ -134,8 +134,18 @@ func (c *Client) GetNodeInfo() (node *NodeInfo, err error) {
|
|||||||
if err = c.checkResponse(r, path, err); err != nil {
|
if err = c.checkResponse(r, path, err); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if r.StatusCode() == 304 {
|
|
||||||
return nil, nil
|
if r != nil {
|
||||||
|
defer func() {
|
||||||
|
if r.RawBody() != nil {
|
||||||
|
r.RawBody().Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if r.StatusCode() == 304 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("received nil response")
|
||||||
}
|
}
|
||||||
node = &NodeInfo{
|
node = &NodeInfo{
|
||||||
Id: c.NodeId,
|
Id: c.NodeId,
|
||||||
|
|||||||
@@ -30,13 +30,21 @@ func (c *Client) GetUserList() (UserList []UserInfo, err error) {
|
|||||||
r, err := c.client.R().
|
r, err := c.client.R().
|
||||||
SetHeader("If-None-Match", c.userEtag).
|
SetHeader("If-None-Match", c.userEtag).
|
||||||
Get(path)
|
Get(path)
|
||||||
err = c.checkResponse(r, path, err)
|
if err = c.checkResponse(r, path, err); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.StatusCode() == 304 {
|
if r != nil {
|
||||||
return nil, nil
|
defer func() {
|
||||||
|
if r.RawBody() != nil {
|
||||||
|
r.RawBody().Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if r.StatusCode() == 304 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("received nil response")
|
||||||
}
|
}
|
||||||
var userList *UserListBody
|
var userList *UserListBody
|
||||||
err = json.Unmarshal(r.Body(), &userList)
|
err = json.Unmarshal(r.Body(), &userList)
|
||||||
|
|||||||
18
conf/conf.go
18
conf/conf.go
@@ -2,9 +2,11 @@ package conf
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/InazumaV/V2bX/common/json5"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/InazumaV/V2bX/common/json5"
|
||||||
|
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -29,5 +31,17 @@ func (p *Conf) LoadFromPath(filePath string) error {
|
|||||||
return fmt.Errorf("open config file error: %s", err)
|
return fmt.Errorf("open config file error: %s", err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
return json.NewDecoder(json5.NewTrimNodeReader(f)).Decode(p)
|
|
||||||
|
reader := json5.NewTrimNodeReader(f)
|
||||||
|
data, err := io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("read config file error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unmarshal config error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package conf
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fsnotify/fsnotify"
|
|
||||||
"log"
|
"log"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fsnotify/fsnotify"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Conf) Watch(filePath, xDnsPath string, sDnsPath string, reload func()) error {
|
func (p *Conf) Watch(filePath, xDnsPath string, sDnsPath string, reload func()) error {
|
||||||
@@ -34,7 +34,7 @@ func (p *Conf) Watch(filePath, xDnsPath string, sDnsPath string, reload func())
|
|||||||
case filepath.Base(xDnsPath), filepath.Base(sDnsPath):
|
case filepath.Base(xDnsPath), filepath.Base(sDnsPath):
|
||||||
log.Println("DNS file changed, reloading...")
|
log.Println("DNS file changed, reloading...")
|
||||||
default:
|
default:
|
||||||
log.Println("config dir changed, reloading...")
|
log.Println("config file changed, reloading...")
|
||||||
}
|
}
|
||||||
*p = *New()
|
*p = *New()
|
||||||
err := p.LoadFromPath(filePath)
|
err := p.LoadFromPath(filePath)
|
||||||
@@ -51,18 +51,18 @@ func (p *Conf) Watch(filePath, xDnsPath string, sDnsPath string, reload func())
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
err = watcher.Add(path.Dir(filePath))
|
err = watcher.Add(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("watch file error: %s", err)
|
return fmt.Errorf("watch file error: %s", err)
|
||||||
}
|
}
|
||||||
if xDnsPath != "" {
|
if xDnsPath != "" {
|
||||||
err = watcher.Add(path.Dir(xDnsPath))
|
err = watcher.Add(xDnsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("watch dns file error: %s", err)
|
return fmt.Errorf("watch dns file error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if sDnsPath != "" {
|
if sDnsPath != "" {
|
||||||
err = watcher.Add(path.Dir(sDnsPath))
|
err = watcher.Add(sDnsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("watch dns file error: %s", err)
|
return fmt.Errorf("watch dns file error: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package sing
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
@@ -38,14 +39,13 @@ func init() {
|
|||||||
func New(c *conf.CoreConfig) (vCore.Core, error) {
|
func New(c *conf.CoreConfig) (vCore.Core, error) {
|
||||||
options := option.Options{}
|
options := option.Options{}
|
||||||
if len(c.SingConfig.OriginalPath) != 0 {
|
if len(c.SingConfig.OriginalPath) != 0 {
|
||||||
f, err := os.Open(c.SingConfig.OriginalPath)
|
data, err := os.ReadFile(c.SingConfig.OriginalPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("open original config error: %s", err)
|
return nil, fmt.Errorf("read original config error: %s", err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
err = json.Unmarshal(data, &options)
|
||||||
err = json.NewDecoder(f).Decode(&options)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("decode original config error: %s", err)
|
return nil, fmt.Errorf("unmarshal original config error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
options.Log = &option.LogOptions{
|
options.Log = &option.LogOptions{
|
||||||
@@ -68,11 +68,19 @@ func New(c *conf.CoreConfig) (vCore.Core, error) {
|
|||||||
return nil, fmt.Errorf("failed to open or create sing dns config file: %s", err)
|
return nil, fmt.Errorf("failed to open or create sing dns config file: %s", err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
if err := json.NewDecoder(f).Decode(options.DNS); err != nil {
|
data, err := io.ReadAll(f)
|
||||||
|
if err != nil {
|
||||||
log.Warn(fmt.Sprintf(
|
log.Warn(fmt.Sprintf(
|
||||||
"Failed to unmarshal sing dns config from file '%v': %v. Using default DNS options",
|
"Failed to read sing dns config from file '%v': %v. Using default DNS options",
|
||||||
f.Name(), err))
|
f.Name(), err))
|
||||||
options.DNS = &option.DNSOptions{}
|
options.DNS = &option.DNSOptions{}
|
||||||
|
} else {
|
||||||
|
if err := json.Unmarshal(data, options.DNS); err != nil {
|
||||||
|
log.Warn(fmt.Sprintf(
|
||||||
|
"Failed to unmarshal sing dns config from file '%v': %v. Using default DNS options",
|
||||||
|
f.Name(), err))
|
||||||
|
options.DNS = &option.DNSOptions{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
os.Setenv("SING_DNS_PATH", c.SingConfig.DnsConfigPath)
|
os.Setenv("SING_DNS_PATH", c.SingConfig.DnsConfigPath)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,15 @@ package xray
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/InazumaV/V2bX/api/panel"
|
|
||||||
"github.com/goccy/go-json"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
coreConf "github.com/xtls/xray-core/infra/conf"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/InazumaV/V2bX/api/panel"
|
||||||
|
"github.com/goccy/go-json"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
coreConf "github.com/xtls/xray-core/infra/conf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func updateDNSConfig(node *panel.NodeInfo) (err error) {
|
func updateDNSConfig(node *panel.NodeInfo) (err error) {
|
||||||
@@ -62,7 +63,7 @@ func saveDnsConfig(dns []byte, dnsPath string) (err error) {
|
|||||||
}
|
}
|
||||||
if !bytes.Equal(currentData, dns) {
|
if !bytes.Equal(currentData, dns) {
|
||||||
coreDnsConfig := &coreConf.DNSConfig{}
|
coreDnsConfig := &coreConf.DNSConfig{}
|
||||||
if err = json.NewDecoder(bytes.NewReader(dns)).Decode(coreDnsConfig); err != nil {
|
if err = json.Unmarshal(dns, coreDnsConfig); err != nil {
|
||||||
log.WithField("err", err).Error("Failed to unmarshal DNS config")
|
log.WithField("err", err).Error("Failed to unmarshal DNS config")
|
||||||
}
|
}
|
||||||
_, err := coreDnsConfig.Build()
|
_, err := coreDnsConfig.Build()
|
||||||
|
|||||||
@@ -58,22 +58,24 @@ func parseConnectionConfig(c *conf.XrayConnectionConfig) (policy *coreConf.Polic
|
|||||||
func getCore(c *conf.XrayConfig) *core.Instance {
|
func getCore(c *conf.XrayConfig) *core.Instance {
|
||||||
os.Setenv("XRAY_LOCATION_ASSET", c.AssetPath)
|
os.Setenv("XRAY_LOCATION_ASSET", c.AssetPath)
|
||||||
// Log Config
|
// Log Config
|
||||||
coreLogConfig := &coreConf.LogConfig{}
|
coreLogConfig := &coreConf.LogConfig{
|
||||||
coreLogConfig.LogLevel = c.LogConfig.Level
|
LogLevel: c.LogConfig.Level,
|
||||||
coreLogConfig.AccessLog = c.LogConfig.AccessPath
|
AccessLog: c.LogConfig.AccessPath,
|
||||||
coreLogConfig.ErrorLog = c.LogConfig.ErrorPath
|
ErrorLog: c.LogConfig.ErrorPath,
|
||||||
|
}
|
||||||
// DNS config
|
// DNS config
|
||||||
coreDnsConfig := &coreConf.DNSConfig{}
|
coreDnsConfig := &coreConf.DNSConfig{}
|
||||||
os.Setenv("XRAY_DNS_PATH", "")
|
os.Setenv("XRAY_DNS_PATH", "")
|
||||||
if c.DnsConfigPath != "" {
|
if c.DnsConfigPath != "" {
|
||||||
f, err := os.OpenFile(c.DnsConfigPath, os.O_RDWR|os.O_CREATE, 0755)
|
data, err := os.ReadFile(c.DnsConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to open or create xray dns config file: %v", err)
|
log.Error(fmt.Sprintf("Failed to read xray dns config file: %v", err))
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
if err := json.NewDecoder(f).Decode(coreDnsConfig); err != nil {
|
|
||||||
log.Error(fmt.Sprintf("Failed to unmarshal xray dns config from file '%v': %v. Using default DNS options.", f.Name(), err))
|
|
||||||
coreDnsConfig = &coreConf.DNSConfig{}
|
coreDnsConfig = &coreConf.DNSConfig{}
|
||||||
|
} else {
|
||||||
|
if err := json.Unmarshal(data, coreDnsConfig); err != nil {
|
||||||
|
log.Error(fmt.Sprintf("Failed to unmarshal xray dns config: %v. Using default DNS options.", err))
|
||||||
|
coreDnsConfig = &coreConf.DNSConfig{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
os.Setenv("XRAY_DNS_PATH", c.DnsConfigPath)
|
os.Setenv("XRAY_DNS_PATH", c.DnsConfigPath)
|
||||||
}
|
}
|
||||||
@@ -84,25 +86,27 @@ func getCore(c *conf.XrayConfig) *core.Instance {
|
|||||||
// Routing config
|
// Routing config
|
||||||
coreRouterConfig := &coreConf.RouterConfig{}
|
coreRouterConfig := &coreConf.RouterConfig{}
|
||||||
if c.RouteConfigPath != "" {
|
if c.RouteConfigPath != "" {
|
||||||
if f, err := os.Open(c.RouteConfigPath); err != nil {
|
data, err := os.ReadFile(c.RouteConfigPath)
|
||||||
|
if err != nil {
|
||||||
log.WithField("err", err).Panic("Failed to read Routing config file")
|
log.WithField("err", err).Panic("Failed to read Routing config file")
|
||||||
} else {
|
} else {
|
||||||
if err = json.NewDecoder(f).Decode(coreRouterConfig); err != nil {
|
if err = json.Unmarshal(data, coreRouterConfig); err != nil {
|
||||||
log.WithField("err", err).Panic("Failed to unmarshal Routing config")
|
log.WithField("err", err).Panic("Failed to unmarshal Routing config")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
routeConfig, err := coreRouterConfig.Build()
|
routeConfig, err := coreRouterConfig.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithField("err", err).Panic("Failed to understand Routing config Please check: https://xtls.github.io/config/routing.html")
|
log.WithField("err", err).Panic("Failed to understand Routing config. Please check: https://xtls.github.io/config/routing.html for help")
|
||||||
}
|
}
|
||||||
// Custom Inbound config
|
// Custom Inbound config
|
||||||
var coreCustomInboundConfig []coreConf.InboundDetourConfig
|
var coreCustomInboundConfig []coreConf.InboundDetourConfig
|
||||||
if c.InboundConfigPath != "" {
|
if c.InboundConfigPath != "" {
|
||||||
if f, err := os.Open(c.InboundConfigPath); err != nil {
|
data, err := os.ReadFile(c.InboundConfigPath)
|
||||||
|
if err != nil {
|
||||||
log.WithField("err", err).Panic("Failed to read Custom Inbound config file")
|
log.WithField("err", err).Panic("Failed to read Custom Inbound config file")
|
||||||
} else {
|
} else {
|
||||||
if err = json.NewDecoder(f).Decode(&coreCustomInboundConfig); err != nil {
|
if err = json.Unmarshal(data, &coreCustomInboundConfig); err != nil {
|
||||||
log.WithField("err", err).Panic("Failed to unmarshal Custom Inbound config")
|
log.WithField("err", err).Panic("Failed to unmarshal Custom Inbound config")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,17 +115,18 @@ func getCore(c *conf.XrayConfig) *core.Instance {
|
|||||||
for _, config := range coreCustomInboundConfig {
|
for _, config := range coreCustomInboundConfig {
|
||||||
oc, err := config.Build()
|
oc, err := config.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithField("err", err).Panic("Failed to understand Inbound config, Please check: https://xtls.github.io/config/inbound.html for help")
|
log.WithField("err", err).Panic("Failed to understand Inbound config. Please check: https://xtls.github.io/config/inbound.html for help")
|
||||||
}
|
}
|
||||||
inBoundConfig = append(inBoundConfig, oc)
|
inBoundConfig = append(inBoundConfig, oc)
|
||||||
}
|
}
|
||||||
// Custom Outbound config
|
// Custom Outbound config
|
||||||
var coreCustomOutboundConfig []coreConf.OutboundDetourConfig
|
var coreCustomOutboundConfig []coreConf.OutboundDetourConfig
|
||||||
if c.OutboundConfigPath != "" {
|
if c.OutboundConfigPath != "" {
|
||||||
if f, err := os.Open(c.OutboundConfigPath); err != nil {
|
data, err := os.ReadFile(c.OutboundConfigPath)
|
||||||
|
if err != nil {
|
||||||
log.WithField("err", err).Panic("Failed to read Custom Outbound config file")
|
log.WithField("err", err).Panic("Failed to read Custom Outbound config file")
|
||||||
} else {
|
} else {
|
||||||
if err = json.NewDecoder(f).Decode(&coreCustomOutboundConfig); err != nil {
|
if err = json.Unmarshal(data, &coreCustomOutboundConfig); err != nil {
|
||||||
log.WithField("err", err).Panic("Failed to unmarshal Custom Outbound config")
|
log.WithField("err", err).Panic("Failed to unmarshal Custom Outbound config")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
main.go
7
main.go
@@ -1,16 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "net/http"
|
|
||||||
_ "net/http/pprof"
|
|
||||||
|
|
||||||
"github.com/InazumaV/V2bX/cmd"
|
"github.com/InazumaV/V2bX/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//内存泄漏排查
|
|
||||||
// go func() {
|
|
||||||
// http.ListenAndServe("0.0.0.0:6060", nil)
|
|
||||||
// }()
|
|
||||||
cmd.Run()
|
cmd.Run()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,12 +262,14 @@ func (u *User) DecodePrivate(pemEncodedPriv string) (*ecdsa.PrivateKey, error) {
|
|||||||
privateKey, err := x509.ParseECPrivateKey(x509EncodedPriv)
|
privateKey, err := x509.ParseECPrivateKey(x509EncodedPriv)
|
||||||
return privateKey, err
|
return privateKey, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) Load(path string) error {
|
func (u *User) Load(path string) error {
|
||||||
f, err := os.Open(path)
|
data, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("open file error: %s", err)
|
return fmt.Errorf("open file error: %s", err)
|
||||||
}
|
}
|
||||||
err = json.NewDecoder(f).Decode(u)
|
|
||||||
|
err = json.Unmarshal(data, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unmarshal json error: %s", err)
|
return fmt.Errorf("unmarshal json error: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
35
node/user.go
35
node/user.go
@@ -82,29 +82,24 @@ func (c *Controller) reportUserTrafficTask() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func compareUserList(old, new []panel.UserInfo) (deleted, added []panel.UserInfo) {
|
func compareUserList(old, new []panel.UserInfo) (deleted, added []panel.UserInfo) {
|
||||||
tmp := map[string]struct{}{}
|
oldMap := make(map[string]int)
|
||||||
tmp2 := map[string]struct{}{}
|
for i, user := range old {
|
||||||
for i := range old {
|
key := user.Uuid + strconv.Itoa(user.SpeedLimit)
|
||||||
tmp[old[i].Uuid+strconv.Itoa(old[i].SpeedLimit)] = struct{}{}
|
oldMap[key] = i
|
||||||
}
|
}
|
||||||
l := len(tmp)
|
|
||||||
for i := range new {
|
for _, user := range new {
|
||||||
e := new[i].Uuid + strconv.Itoa(new[i].SpeedLimit)
|
key := user.Uuid + strconv.Itoa(user.SpeedLimit)
|
||||||
tmp[e] = struct{}{}
|
if _, exists := oldMap[key]; !exists {
|
||||||
tmp2[e] = struct{}{}
|
added = append(added, user)
|
||||||
if l != len(tmp) {
|
} else {
|
||||||
added = append(added, new[i])
|
delete(oldMap, key)
|
||||||
l++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmp = nil
|
|
||||||
l = len(tmp2)
|
for _, index := range oldMap {
|
||||||
for i := range old {
|
deleted = append(deleted, old[index])
|
||||||
tmp2[old[i].Uuid+strconv.Itoa(old[i].SpeedLimit)] = struct{}{}
|
|
||||||
if l != len(tmp2) {
|
|
||||||
deleted = append(deleted, old[i])
|
|
||||||
l++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return deleted, added
|
return deleted, added
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user