Add admin panel, manager, node_manager, bandwidth limiter, connection limiter, bonding, failover, vless encryption, mkcp transport

This commit is contained in:
Shtorm
2026-02-26 22:44:31 +03:00
parent 0f38dbba4c
commit ded1eb9635
115 changed files with 12582 additions and 301 deletions

View File

@@ -0,0 +1,88 @@
package inbound
import (
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/hysteria"
CM "github.com/sagernet/sing-box/service/manager/constant"
"github.com/sagernet/sing-box/service/node/constant"
)
type HysteriaManager struct {
access sync.Mutex
inbounds map[string]*HysteriaUserManager
}
func NewHysteriaManager() *HysteriaManager {
return &HysteriaManager{
inbounds: make(map[string]*HysteriaUserManager),
}
}
func (m *HysteriaManager) AddUserManager(inbound adapter.Inbound) error {
m.access.Lock()
defer m.access.Unlock()
m.inbounds[inbound.Tag()] = &HysteriaUserManager{
inbound: inbound.(*hysteria.Inbound),
usersMap: make(map[string]option.HysteriaUser),
}
return nil
}
func (m *HysteriaManager) GetUserManager(tag string) (constant.UserManager, bool) {
m.access.Lock()
defer m.access.Unlock()
inbound, ok := m.inbounds[tag]
return inbound, ok
}
func (m *HysteriaManager) GetUserManagerTags() []string {
m.access.Lock()
defer m.access.Unlock()
tags := make([]string, 0, len(m.inbounds))
for tag, _ := range m.inbounds {
tags = append(tags, tag)
}
return tags
}
type HysteriaUserManager struct {
inbound *hysteria.Inbound
usersMap map[string]option.HysteriaUser
mtx sync.Mutex
}
func (i *HysteriaUserManager) postUpdate() {
users := make([]option.HysteriaUser, 0, len(i.usersMap))
for _, user := range i.usersMap {
users = append(users, user)
}
i.inbound.UpdateUsers(users)
}
func (i *HysteriaUserManager) UpdateUser(user CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
i.usersMap[user.Username] = option.HysteriaUser{Name: user.Username, AuthString: user.Password}
i.postUpdate()
}
func (i *HysteriaUserManager) UpdateUsers(users []CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
clear(i.usersMap)
for _, user := range users {
i.usersMap[user.Username] = option.HysteriaUser{Name: user.Username, AuthString: user.Password}
}
i.postUpdate()
}
func (i *HysteriaUserManager) DeleteUser(username string) {
i.mtx.Lock()
defer i.mtx.Unlock()
delete(i.usersMap, username)
i.postUpdate()
}

View File

@@ -0,0 +1,88 @@
package inbound
import (
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/hysteria2"
CM "github.com/sagernet/sing-box/service/manager/constant"
"github.com/sagernet/sing-box/service/node/constant"
)
type Hysteria2Manager struct {
access sync.Mutex
inbounds map[string]*Hysteria2UserManager
}
func NewHysteria2Manager() *Hysteria2Manager {
return &Hysteria2Manager{
inbounds: make(map[string]*Hysteria2UserManager),
}
}
func (m *Hysteria2Manager) AddUserManager(inbound adapter.Inbound) error {
m.access.Lock()
defer m.access.Unlock()
m.inbounds[inbound.Tag()] = &Hysteria2UserManager{
inbound: inbound.(*hysteria2.Inbound),
usersMap: make(map[string]option.Hysteria2User),
}
return nil
}
func (m *Hysteria2Manager) GetUserManager(tag string) (constant.UserManager, bool) {
m.access.Lock()
defer m.access.Unlock()
inbound, ok := m.inbounds[tag]
return inbound, ok
}
func (m *Hysteria2Manager) GetUserManagerTags() []string {
m.access.Lock()
defer m.access.Unlock()
tags := make([]string, 0, len(m.inbounds))
for tag, _ := range m.inbounds {
tags = append(tags, tag)
}
return tags
}
type Hysteria2UserManager struct {
inbound *hysteria2.Inbound
usersMap map[string]option.Hysteria2User
mtx sync.Mutex
}
func (i *Hysteria2UserManager) postUpdate() {
users := make([]option.Hysteria2User, 0, len(i.usersMap))
for _, user := range i.usersMap {
users = append(users, user)
}
i.inbound.UpdateUsers(users)
}
func (i *Hysteria2UserManager) UpdateUser(user CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
i.usersMap[user.Username] = option.Hysteria2User{Name: user.Username, Password: user.Password}
i.postUpdate()
}
func (i *Hysteria2UserManager) UpdateUsers(users []CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
clear(i.usersMap)
for _, user := range users {
i.usersMap[user.Username] = option.Hysteria2User{Name: user.Username, Password: user.Password}
}
i.postUpdate()
}
func (i *Hysteria2UserManager) DeleteUser(username string) {
i.mtx.Lock()
defer i.mtx.Unlock()
delete(i.usersMap, username)
i.postUpdate()
}

View File

@@ -0,0 +1,88 @@
package inbound
import (
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/trojan"
CM "github.com/sagernet/sing-box/service/manager/constant"
"github.com/sagernet/sing-box/service/node/constant"
)
type TrojanManager struct {
access sync.Mutex
inbounds map[string]*TrojanUserManager
}
func NewTrojanManager() *TrojanManager {
return &TrojanManager{
inbounds: make(map[string]*TrojanUserManager),
}
}
func (m *TrojanManager) AddUserManager(inbound adapter.Inbound) error {
m.access.Lock()
defer m.access.Unlock()
m.inbounds[inbound.Tag()] = &TrojanUserManager{
inbound: inbound.(*trojan.Inbound),
usersMap: make(map[string]option.TrojanUser),
}
return nil
}
func (m *TrojanManager) GetUserManager(tag string) (constant.UserManager, bool) {
m.access.Lock()
defer m.access.Unlock()
inbound, ok := m.inbounds[tag]
return inbound, ok
}
func (m *TrojanManager) GetUserManagerTags() []string {
m.access.Lock()
defer m.access.Unlock()
tags := make([]string, 0, len(m.inbounds))
for tag, _ := range m.inbounds {
tags = append(tags, tag)
}
return tags
}
type TrojanUserManager struct {
inbound *trojan.Inbound
usersMap map[string]option.TrojanUser
mtx sync.Mutex
}
func (i *TrojanUserManager) postUpdate() {
users := make([]option.TrojanUser, 0, len(i.usersMap))
for _, user := range i.usersMap {
users = append(users, user)
}
i.inbound.UpdateUsers(users)
}
func (i *TrojanUserManager) UpdateUser(user CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
i.usersMap[user.Username] = option.TrojanUser{Name: user.Username, Password: user.Password}
i.postUpdate()
}
func (i *TrojanUserManager) UpdateUsers(users []CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
clear(i.usersMap)
for _, user := range users {
i.usersMap[user.Username] = option.TrojanUser{Name: user.Username, Password: user.Password}
}
i.postUpdate()
}
func (i *TrojanUserManager) DeleteUser(username string) {
i.mtx.Lock()
defer i.mtx.Unlock()
delete(i.usersMap, username)
i.postUpdate()
}

View File

@@ -0,0 +1,88 @@
package inbound
import (
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/tuic"
CM "github.com/sagernet/sing-box/service/manager/constant"
"github.com/sagernet/sing-box/service/node/constant"
)
type TUICManager struct {
access sync.Mutex
inbounds map[string]*TUICUserManager
}
func NewTUICManager() *TUICManager {
return &TUICManager{
inbounds: make(map[string]*TUICUserManager),
}
}
func (m *TUICManager) AddUserManager(inbound adapter.Inbound) error {
m.access.Lock()
defer m.access.Unlock()
m.inbounds[inbound.Tag()] = &TUICUserManager{
inbound: inbound.(*tuic.Inbound),
usersMap: make(map[string]option.TUICUser),
}
return nil
}
func (m *TUICManager) GetUserManager(tag string) (constant.UserManager, bool) {
m.access.Lock()
defer m.access.Unlock()
inbound, ok := m.inbounds[tag]
return inbound, ok
}
func (m *TUICManager) GetUserManagerTags() []string {
m.access.Lock()
defer m.access.Unlock()
tags := make([]string, 0, len(m.inbounds))
for tag, _ := range m.inbounds {
tags = append(tags, tag)
}
return tags
}
type TUICUserManager struct {
inbound *tuic.Inbound
usersMap map[string]option.TUICUser
mtx sync.Mutex
}
func (i *TUICUserManager) postUpdate() {
users := make([]option.TUICUser, 0, len(i.usersMap))
for _, user := range i.usersMap {
users = append(users, user)
}
i.inbound.UpdateUsers(users)
}
func (i *TUICUserManager) UpdateUser(user CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
i.usersMap[user.Username] = option.TUICUser{Name: user.Username, UUID: user.UUID, Password: user.Password}
i.postUpdate()
}
func (i *TUICUserManager) UpdateUsers(users []CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
clear(i.usersMap)
for _, user := range users {
i.usersMap[user.Username] = option.TUICUser{Name: user.Username, UUID: user.UUID, Password: user.Password}
}
i.postUpdate()
}
func (i *TUICUserManager) DeleteUser(username string) {
i.mtx.Lock()
defer i.mtx.Unlock()
delete(i.usersMap, username)
i.postUpdate()
}

View File

@@ -0,0 +1,88 @@
package inbound
import (
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/vless"
CM "github.com/sagernet/sing-box/service/manager/constant"
"github.com/sagernet/sing-box/service/node/constant"
)
type VLESSManager struct {
access sync.Mutex
inbounds map[string]*VLESSUserManager
}
func NewVLESSManager() *VLESSManager {
return &VLESSManager{
inbounds: make(map[string]*VLESSUserManager),
}
}
func (m *VLESSManager) AddUserManager(inbound adapter.Inbound) error {
m.access.Lock()
defer m.access.Unlock()
m.inbounds[inbound.Tag()] = &VLESSUserManager{
inbound: inbound.(*vless.Inbound),
usersMap: make(map[string]option.VLESSUser),
}
return nil
}
func (m *VLESSManager) GetUserManager(tag string) (constant.UserManager, bool) {
m.access.Lock()
defer m.access.Unlock()
inbound, ok := m.inbounds[tag]
return inbound, ok
}
func (m *VLESSManager) GetUserManagerTags() []string {
m.access.Lock()
defer m.access.Unlock()
tags := make([]string, 0, len(m.inbounds))
for tag, _ := range m.inbounds {
tags = append(tags, tag)
}
return tags
}
type VLESSUserManager struct {
inbound *vless.Inbound
usersMap map[string]option.VLESSUser
mtx sync.Mutex
}
func (i *VLESSUserManager) postUpdate() {
users := make([]option.VLESSUser, 0, len(i.usersMap))
for _, user := range i.usersMap {
users = append(users, user)
}
i.inbound.UpdateUsers(users)
}
func (i *VLESSUserManager) UpdateUser(user CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
i.usersMap[user.Username] = option.VLESSUser{Name: user.Username, UUID: user.UUID, Flow: user.Flow}
i.postUpdate()
}
func (i *VLESSUserManager) UpdateUsers(users []CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
clear(i.usersMap)
for _, user := range users {
i.usersMap[user.Username] = option.VLESSUser{Name: user.Username, UUID: user.UUID, Flow: user.Flow}
}
i.postUpdate()
}
func (i *VLESSUserManager) DeleteUser(username string) {
i.mtx.Lock()
defer i.mtx.Unlock()
delete(i.usersMap, username)
i.postUpdate()
}

View File

@@ -0,0 +1,88 @@
package inbound
import (
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/vmess"
CM "github.com/sagernet/sing-box/service/manager/constant"
"github.com/sagernet/sing-box/service/node/constant"
)
type VMessManager struct {
inbounds map[string]*VMessUserManager
mtx sync.Mutex
}
func NewVMessManager() *VMessManager {
return &VMessManager{
inbounds: make(map[string]*VMessUserManager),
}
}
func (m *VMessManager) AddUserManager(inbound adapter.Inbound) error {
m.mtx.Lock()
defer m.mtx.Unlock()
m.inbounds[inbound.Tag()] = &VMessUserManager{
inbound: inbound.(*vmess.Inbound),
usersMap: make(map[string]option.VMessUser),
}
return nil
}
func (m *VMessManager) GetUserManager(tag string) (constant.UserManager, bool) {
m.mtx.Lock()
defer m.mtx.Unlock()
inbound, ok := m.inbounds[tag]
return inbound, ok
}
func (m *VMessManager) GetUserManagerTags() []string {
m.mtx.Lock()
defer m.mtx.Unlock()
tags := make([]string, 0, len(m.inbounds))
for tag, _ := range m.inbounds {
tags = append(tags, tag)
}
return tags
}
type VMessUserManager struct {
inbound *vmess.Inbound
usersMap map[string]option.VMessUser
mtx sync.Mutex
}
func (i *VMessUserManager) postUpdate() {
users := make([]option.VMessUser, 0, len(i.usersMap))
for _, user := range i.usersMap {
users = append(users, user)
}
i.inbound.UpdateUsers(users)
}
func (i *VMessUserManager) UpdateUser(user CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
i.usersMap[user.Username] = option.VMessUser{Name: user.Username, UUID: user.UUID, AlterId: user.AlterID}
i.postUpdate()
}
func (i *VMessUserManager) UpdateUsers(users []CM.User) {
i.mtx.Lock()
defer i.mtx.Unlock()
clear(i.usersMap)
for _, user := range users {
i.usersMap[user.Username] = option.VMessUser{Name: user.Username, UUID: user.UUID, AlterId: user.AlterID}
}
i.postUpdate()
}
func (i *VMessUserManager) DeleteUser(username string) {
i.mtx.Lock()
defer i.mtx.Unlock()
delete(i.usersMap, username)
i.postUpdate()
}