mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-06-30 20:52:50 +00:00
107 lines
2.9 KiB
Go
107 lines
2.9 KiB
Go
//go:build with_usbip && (linux || (darwin && cgo) || windows)
|
|
|
|
package usbip
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
|
|
"github.com/sagernet/sing-box/adapter"
|
|
boxService "github.com/sagernet/sing-box/adapter/service"
|
|
"github.com/sagernet/sing-box/common/listener"
|
|
C "github.com/sagernet/sing-box/constant"
|
|
"github.com/sagernet/sing-box/log"
|
|
"github.com/sagernet/sing-box/option"
|
|
"github.com/sagernet/sing-usbip"
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
N "github.com/sagernet/sing/common/network"
|
|
)
|
|
|
|
type ServerService struct {
|
|
boxService.Adapter
|
|
ctx context.Context
|
|
logger log.ContextLogger
|
|
inner *usbip.ServerService
|
|
}
|
|
|
|
type dynamicServerService struct {
|
|
ServerService
|
|
host *usbip.DynamicHost
|
|
}
|
|
|
|
var _ adapter.USBIPDynamicServer = (*dynamicServerService)(nil)
|
|
|
|
func NewServerService(ctx context.Context, logger log.ContextLogger, tag string, options option.USBIPServerServiceOptions) (adapter.Service, error) {
|
|
listenOptions := options.ListenOptions
|
|
if listenOptions.ListenPort == 0 {
|
|
listenOptions.ListenPort = usbip.DefaultPort
|
|
}
|
|
boxListener := listener.New(listener.Options{
|
|
Context: ctx,
|
|
Logger: logger,
|
|
Network: []string{N.NetworkTCP},
|
|
Listen: listenOptions,
|
|
})
|
|
serverOptions := usbip.ServerOptions{
|
|
Logger: logger,
|
|
Listen: func(context.Context) (net.Listener, error) {
|
|
return boxListener.ListenTCP()
|
|
},
|
|
}
|
|
base := ServerService{
|
|
Adapter: boxService.NewAdapter(C.TypeUSBIPServer, tag),
|
|
ctx: ctx,
|
|
logger: logger,
|
|
}
|
|
|
|
providerType := options.Provider
|
|
if providerType == "" {
|
|
providerType = option.USBIPProviderDefault
|
|
}
|
|
switch providerType {
|
|
case option.USBIPProviderDefault:
|
|
defaultOptions, isDefault := options.Options.(*option.USBIPDefaultProviderOptions)
|
|
if isDefault {
|
|
serverOptions.Devices = toDeviceMatches(defaultOptions.Devices)
|
|
}
|
|
inner, err := usbip.NewServerService(ctx, serverOptions)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
base.inner = inner
|
|
return &base, nil
|
|
case option.USBIPProviderDynamic:
|
|
host := usbip.NewDynamicHost(logger)
|
|
inner, err := usbip.NewDynamicServerService(ctx, serverOptions, host)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
base.inner = inner
|
|
return &dynamicServerService{ServerService: base, host: host}, nil
|
|
default:
|
|
return nil, E.New("unknown usbip provider type: ", providerType)
|
|
}
|
|
}
|
|
|
|
func (s *ServerService) Start(stage adapter.StartStage) error {
|
|
if stage != adapter.StartStateStart {
|
|
return nil
|
|
}
|
|
return s.inner.Start()
|
|
}
|
|
|
|
func (s *ServerService) Close() error {
|
|
return s.inner.Close()
|
|
}
|
|
|
|
func (s *dynamicServerService) AddDevice(info usbip.ProvidedDeviceInfo, transport usbip.DeviceTransport) (string, error) {
|
|
return s.host.AddDevice(info, transport)
|
|
}
|
|
|
|
func (s *dynamicServerService) RemoveDevice(busID string) {
|
|
s.host.RemoveDevice(busID)
|
|
}
|
|
|
|
func (s *dynamicServerService) SubscribeDevices(ctx context.Context, listener func([]usbip.ControlDeviceInfo)) {
|
|
s.inner.SubscribeDevices(ctx, listener)
|
|
}
|