improve client's inbound changes
This commit is contained in:
+41
-17
@@ -1,6 +1,7 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"s-ui/database"
|
||||
"s-ui/database/model"
|
||||
@@ -54,14 +55,22 @@ func (s *ClientService) Save(tx *gorm.DB, act string, data json.RawMessage, host
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = json.Unmarshal(client.Inbounds, &inboundIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = s.updateLinksWithFixedInbounds(tx, []*model.Client{&client}, inboundIds, hostname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if act == "edit" {
|
||||
// Find changed inbounds
|
||||
inboundIds, err = s.findInboundsChanges(tx, client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
err = json.Unmarshal(client.Inbounds, &inboundIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
err = tx.Save(&client).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -140,7 +149,7 @@ func (s *ClientService) updateLinksWithFixedInbounds(tx *gorm.DB, clients []*mod
|
||||
}
|
||||
}
|
||||
|
||||
// Add no local links
|
||||
// Add non local links
|
||||
for _, clientLink := range clientLinks {
|
||||
if clientLink["type"] != "local" {
|
||||
newClientLinks = append(newClientLinks, clientLink)
|
||||
@@ -316,7 +325,8 @@ func (s *ClientService) DepleteClients() ([]uint, error) {
|
||||
users = append(users, client.Name)
|
||||
var userInbounds []uint
|
||||
json.Unmarshal(client.Inbounds, &userInbounds)
|
||||
inboundIds = s.uniqueAppendInboundIds(inboundIds, userInbounds)
|
||||
// Find changed inbounds
|
||||
inboundIds = common.UnionUintArray(inboundIds, userInbounds)
|
||||
changes = append(changes, model.Changes{
|
||||
DateTime: dt,
|
||||
Actor: "DepleteJob",
|
||||
@@ -342,18 +352,32 @@ func (s *ClientService) DepleteClients() ([]uint, error) {
|
||||
return inboundIds, nil
|
||||
}
|
||||
|
||||
// avoid duplicate inboundIds
|
||||
func (s *ClientService) uniqueAppendInboundIds(a []uint, b []uint) []uint {
|
||||
m := make(map[uint]bool)
|
||||
for _, v := range a {
|
||||
m[v] = true
|
||||
func (s *ClientService) findInboundsChanges(tx *gorm.DB, client model.Client) ([]uint, error) {
|
||||
var err error
|
||||
var oldClient model.Client
|
||||
var oldInboundIds, newInboundIds []uint
|
||||
err = tx.Model(model.Client{}).Where("id = ?", client.Id).First(&oldClient).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range b {
|
||||
m[v] = true
|
||||
err = json.Unmarshal(oldClient.Inbounds, &oldInboundIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []uint
|
||||
for k := range m {
|
||||
res = append(res, k)
|
||||
err = json.Unmarshal(client.Inbounds, &newInboundIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res
|
||||
|
||||
// Check client.Config changes
|
||||
if !bytes.Equal(oldClient.Config, client.Config) ||
|
||||
oldClient.Name != client.Name ||
|
||||
oldClient.Enable != client.Enable {
|
||||
return common.UnionUintArray(oldInboundIds, newInboundIds), nil
|
||||
}
|
||||
|
||||
// Check client.Inbounds changes
|
||||
diffInbounds := common.DiffUintArray(oldInboundIds, newInboundIds)
|
||||
|
||||
return diffInbounds, nil
|
||||
}
|
||||
|
||||
+4
-1
@@ -145,7 +145,10 @@ func (s *ConfigService) Save(obj string, act string, data json.RawMessage, initU
|
||||
inboundIds, err := s.ClientService.Save(tx, act, data, hostname)
|
||||
if err == nil && len(inboundIds) > 0 {
|
||||
objs = append(objs, "inbounds")
|
||||
err = s.InboundService.RestartInbounds(tx, inboundIds)
|
||||
err = s.InboundService.UpdateUsers(tx, inboundIds)
|
||||
if err != nil {
|
||||
return nil, common.NewErrorf("failed to update users for inbounds: %v", err)
|
||||
}
|
||||
}
|
||||
case "tls":
|
||||
err = s.TlsService.Save(tx, act, data, hostname)
|
||||
|
||||
@@ -4,12 +4,16 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"s-ui/core/protocol/hysteria"
|
||||
"s-ui/core/protocol/hysteria2"
|
||||
"s-ui/database"
|
||||
"s-ui/database/model"
|
||||
"s-ui/logger"
|
||||
"s-ui/util"
|
||||
"s-ui/util/common"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -327,6 +331,64 @@ func (s *InboundService) initUsers(db *gorm.DB, inboundJson []byte, clientIds st
|
||||
return json.Marshal(inbound)
|
||||
}
|
||||
|
||||
func (s *InboundService) UpdateUsers(tx *gorm.DB, ids []uint) error {
|
||||
var inbounds []model.Inbound
|
||||
err := tx.Model(model.Inbound{}).Preload("Tls").Where("id in ?", ids).Find(&inbounds).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, inbound := range inbounds {
|
||||
inboundConfig, err := inbound.MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
inboundConfig, err = s.addUsers(tx, inboundConfig, inbound.Id, inbound.Type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
inb, ok := corePtr.GetInstance().Inbound().Get(inbound.Tag)
|
||||
if !ok {
|
||||
return common.NewErrorf("inbound %s not found", inbound.Tag)
|
||||
}
|
||||
switch inbound.Type {
|
||||
case "hysteria":
|
||||
var hysteriaOptions option.HysteriaInboundOptions
|
||||
err = json.Unmarshal(inboundConfig, &hysteriaOptions)
|
||||
if err != nil {
|
||||
return common.NewErrorf("failed to unmarshal hysteria options for inbound %s: %v", inbound.Tag, err)
|
||||
}
|
||||
err = inb.(*hysteria.Inbound).UpdateUsers(hysteriaOptions.Users)
|
||||
if err != nil {
|
||||
return common.NewErrorf("failed to update users for hysteria inbound %s: %v", inbound.Tag, err)
|
||||
}
|
||||
logger.Info("Updated users for hysteria inbound:", inbound.Tag)
|
||||
case "hysteria2":
|
||||
var hy2Options option.Hysteria2InboundOptions
|
||||
err = json.Unmarshal(inboundConfig, &hy2Options)
|
||||
if err != nil {
|
||||
return common.NewErrorf("failed to unmarshal hysteria2 options for inbound %s: %v", inbound.Tag, err)
|
||||
}
|
||||
err = inb.(*hysteria2.Inbound).UpdateUsers(hy2Options.Users)
|
||||
if err != nil {
|
||||
return common.NewErrorf("failed to update users for hysteria2 inbound %s: %v", inbound.Tag, err)
|
||||
}
|
||||
logger.Info("Updated users for hysteria2 inbound:", inbound.Tag)
|
||||
default:
|
||||
err = corePtr.RemoveInbound(inbound.Tag)
|
||||
if err != nil && err != os.ErrInvalid {
|
||||
return err
|
||||
}
|
||||
|
||||
err = corePtr.AddInbound(inboundConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *InboundService) RestartInbounds(tx *gorm.DB, ids []uint) error {
|
||||
if !corePtr.IsRunning() {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user