Fix netns manager

This commit is contained in:
世界
2026-07-11 15:52:20 +08:00
parent f025e6f163
commit b8bd28f357
3 changed files with 75 additions and 70 deletions
+55 -2
View File
@@ -9,20 +9,65 @@ import (
"syscall"
"github.com/sagernet/netlink"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
vnetns "github.com/vishvananda/netns"
)
type Manager struct {
logger logger.ContextLogger
namespaces []option.NetworkNamespace
holderArgs []string
paths map[string]string
holders []*holder
}
type holder struct {
command *exec.Cmd
pipeWriter *os.File
pidFile string
}
func (m *Manager) start() error {
func NewManager(logger logger.ContextLogger, namespaces []option.NetworkNamespace, holderArgs []string) (*Manager, error) {
paths := make(map[string]string)
for _, namespace := range namespaces {
if namespace.Tag == "" {
return nil, E.New("network namespace: missing tag")
}
_, duplicated := paths[namespace.Tag]
if duplicated {
return nil, E.New("network namespace: duplicated tag: ", namespace.Tag)
}
switch namespace.Type {
case C.NetNsTypeDefault:
if namespace.DefaultOptions.Path == "" {
return nil, E.New("network namespace[", namespace.Tag, "]: missing path")
}
paths[namespace.Tag] = namespace.DefaultOptions.Path
case C.NetNsTypeUnshare:
paths[namespace.Tag] = ""
}
}
return &Manager{
logger: logger,
namespaces: namespaces,
holderArgs: holderArgs,
paths: paths,
}, nil
}
func (m *Manager) Name() string {
return "netns"
}
func (m *Manager) Start(stage adapter.StartStage) error {
if stage != adapter.StartStateInitialize {
return nil
}
for _, namespace := range m.namespaces {
switch namespace.Type {
case C.NetNsTypeDefault:
@@ -70,7 +115,7 @@ func (m *Manager) startNamespace(namespace option.NetworkNamespace) error {
return nil
}
func (m *Manager) close() error {
func (m *Manager) Close() error {
for _, created := range m.holders {
created.pipeWriter.Close()
if created.pidFile != "" {
@@ -81,6 +126,14 @@ func (m *Manager) close() error {
return nil
}
func (m *Manager) ResolvePath(nameOrPath string) string {
path, loaded := m.paths[nameOrPath]
if loaded && path != "" {
return path
}
return nameOrPath
}
func netnsPath(pid int) string {
return "/proc/" + strconv.Itoa(pid) + "/ns/net"
}
+20 -5
View File
@@ -3,18 +3,33 @@
package netns
import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
)
type holder struct{}
type Manager struct{}
func (m *Manager) start() error {
if len(m.namespaces) > 0 {
return E.New("network namespaces are only supported on Linux")
func NewManager(logger logger.ContextLogger, namespaces []option.NetworkNamespace, holderArgs []string) (*Manager, error) {
if len(namespaces) > 0 {
return nil, E.New("network namespaces are only supported on Linux")
}
return &Manager{}, nil
}
func (m *Manager) Name() string {
return "netns"
}
func (m *Manager) Start(stage adapter.StartStage) error {
return nil
}
func (m *Manager) close() error {
func (m *Manager) Close() error {
return nil
}
func (m *Manager) ResolvePath(nameOrPath string) string {
return nameOrPath
}
-63
View File
@@ -4,73 +4,10 @@ import (
"os"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
)
var _ adapter.NetworkNamespaceManager = (*Manager)(nil)
type Manager struct {
logger logger.ContextLogger
namespaces []option.NetworkNamespace
holderArgs []string
paths map[string]string
holders []*holder
}
func NewManager(logger logger.ContextLogger, namespaces []option.NetworkNamespace, holderArgs []string) (*Manager, error) {
paths := make(map[string]string)
for _, namespace := range namespaces {
if namespace.Tag == "" {
return nil, E.New("network namespace: missing tag")
}
_, duplicated := paths[namespace.Tag]
if duplicated {
return nil, E.New("network namespace: duplicated tag: ", namespace.Tag)
}
switch namespace.Type {
case C.NetNsTypeDefault:
if namespace.DefaultOptions.Path == "" {
return nil, E.New("network namespace[", namespace.Tag, "]: missing path")
}
paths[namespace.Tag] = namespace.DefaultOptions.Path
case C.NetNsTypeUnshare:
paths[namespace.Tag] = ""
}
}
return &Manager{
logger: logger,
namespaces: namespaces,
holderArgs: holderArgs,
paths: paths,
}, nil
}
func (m *Manager) Name() string {
return "netns"
}
func (m *Manager) Start(stage adapter.StartStage) error {
if stage != adapter.StartStateInitialize {
return nil
}
return m.start()
}
func (m *Manager) Close() error {
return m.close()
}
func (m *Manager) ResolvePath(nameOrPath string) string {
path, loaded := m.paths[nameOrPath]
if loaded && path != "" {
return path
}
return nameOrPath
}
func Hold() {
buffer := make([]byte, 1)
for {