mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 05:44:12 +08:00
router accepts services
This commit is contained in:
parent
385475a6f6
commit
356ee6f8fa
@ -4,3 +4,9 @@ type Service interface {
|
||||
Start() error
|
||||
Close() error
|
||||
}
|
||||
|
||||
type BoxService interface {
|
||||
Service
|
||||
Type() string
|
||||
Tag() string
|
||||
}
|
||||
|
47
box.go
47
box.go
@ -15,6 +15,7 @@ import (
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/outbound"
|
||||
"github.com/sagernet/sing-box/route"
|
||||
"github.com/sagernet/sing-box/service"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
@ -27,6 +28,7 @@ type Box struct {
|
||||
router adapter.Router
|
||||
inbounds []adapter.Inbound
|
||||
outbounds []adapter.Outbound
|
||||
services []adapter.BoxService
|
||||
logFactory log.Factory
|
||||
logger log.ContextLogger
|
||||
logFile *os.File
|
||||
@ -108,6 +110,7 @@ func New(ctx context.Context, options option.Options) (*Box, error) {
|
||||
}
|
||||
inbounds := make([]adapter.Inbound, 0, len(options.Inbounds))
|
||||
outbounds := make([]adapter.Outbound, 0, len(options.Outbounds))
|
||||
services := make([]adapter.BoxService, 0, len(options.Services))
|
||||
for i, inboundOptions := range options.Inbounds {
|
||||
var in adapter.Inbound
|
||||
var tag string
|
||||
@ -155,6 +158,34 @@ func New(ctx context.Context, options option.Options) (*Box, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, serviceOptions := range options.Services {
|
||||
var srv adapter.BoxService
|
||||
var tag string
|
||||
if serviceOptions.Tag != "" {
|
||||
tag = serviceOptions.Tag
|
||||
} else {
|
||||
tag = F.ToString(i)
|
||||
}
|
||||
srv, err = service.New(
|
||||
ctx,
|
||||
router,
|
||||
logFactory.NewLogger(F.ToString("service/", serviceOptions.Type, "[", tag, "]")),
|
||||
serviceOptions)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "parse outbound[", i, "]")
|
||||
}
|
||||
services = append(services, srv)
|
||||
}
|
||||
err = router.Initialize(inbounds, outbounds, func() adapter.Outbound {
|
||||
out, oErr := outbound.New(ctx, router, logFactory.NewLogger("outbound/direct"), option.Outbound{Type: "direct", Tag: "default"})
|
||||
common.Must(oErr)
|
||||
outbounds = append(outbounds, out)
|
||||
return out
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var clashServer adapter.ClashServer
|
||||
var v2rayServer adapter.V2RayServer
|
||||
if needClashAPI {
|
||||
@ -175,6 +206,7 @@ func New(ctx context.Context, options option.Options) (*Box, error) {
|
||||
router: router,
|
||||
inbounds: inbounds,
|
||||
outbounds: outbounds,
|
||||
services: services,
|
||||
createdAt: createdAt,
|
||||
logFactory: logFactory,
|
||||
logger: logFactory.Logger(),
|
||||
@ -233,6 +265,18 @@ func (s *Box) start() error {
|
||||
return E.Cause(err, "initialize inbound/", in.Type(), "[", tag, "]")
|
||||
}
|
||||
}
|
||||
for i, srv := range s.services {
|
||||
err = srv.Start()
|
||||
if err != nil {
|
||||
var tag string
|
||||
if srv.Tag() == "" {
|
||||
tag = F.ToString(i)
|
||||
} else {
|
||||
tag = srv.Tag()
|
||||
}
|
||||
return E.Cause(err, "initialize service/", srv.Type(), "[", tag, "]")
|
||||
}
|
||||
}
|
||||
if s.clashServer != nil {
|
||||
err = s.clashServer.Start()
|
||||
if err != nil {
|
||||
@ -262,6 +306,9 @@ func (s *Box) Close() error {
|
||||
for _, out := range s.outbounds {
|
||||
common.Close(out)
|
||||
}
|
||||
for _, srv := range s.services {
|
||||
srv.Close()
|
||||
}
|
||||
return common.Close(
|
||||
s.router,
|
||||
s.logFactory,
|
||||
|
5
constant/service.go
Normal file
5
constant/service.go
Normal file
@ -0,0 +1,5 @@
|
||||
package constant
|
||||
|
||||
const (
|
||||
ServiceSubscription = "subscription"
|
||||
)
|
@ -14,6 +14,7 @@ type _Options struct {
|
||||
Inbounds []Inbound `json:"inbounds,omitempty"`
|
||||
Outbounds []Outbound `json:"outbounds,omitempty"`
|
||||
Route *RouteOptions `json:"route,omitempty"`
|
||||
Services []Service `json:"services,omitempty"`
|
||||
Experimental *ExperimentalOptions `json:"experimental,omitempty"`
|
||||
}
|
||||
|
||||
|
45
option/service.go
Normal file
45
option/service.go
Normal file
@ -0,0 +1,45 @@
|
||||
package option
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing-box/common/json"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
type _Service struct {
|
||||
Type string `json:"type"`
|
||||
Tag string `json:"tag,omitempty"`
|
||||
SubscriptionOptions SubscriptionServiceOptions `json:"-"`
|
||||
}
|
||||
|
||||
type Service _Service
|
||||
|
||||
func (h Service) MarshalJSON() ([]byte, error) {
|
||||
var v any
|
||||
switch h.Type {
|
||||
case C.ServiceSubscription:
|
||||
v = h.SubscriptionOptions
|
||||
default:
|
||||
return nil, E.New("unknown service type: ", h.Type)
|
||||
}
|
||||
return MarshallObjects((_Service)(h), v)
|
||||
}
|
||||
|
||||
func (h *Service) UnmarshalJSON(bytes []byte) error {
|
||||
err := json.Unmarshal(bytes, (*_Service)(h))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var v any
|
||||
switch h.Type {
|
||||
case C.ServiceSubscription:
|
||||
v = &h.SubscriptionOptions
|
||||
default:
|
||||
return E.New("unknown service type: ", h.Type)
|
||||
}
|
||||
err = UnmarshallExcluded(bytes, (*_Service)(h), v)
|
||||
if err != nil {
|
||||
return E.Cause(err, "service options")
|
||||
}
|
||||
return nil
|
||||
}
|
14
option/subscription.go
Normal file
14
option/subscription.go
Normal file
@ -0,0 +1,14 @@
|
||||
package option
|
||||
|
||||
type SubscriptionServiceOptions struct {
|
||||
Interval Duration `json:"interval,omitempty"`
|
||||
Providers []SubscriptionProviderOptions `json:"providers"`
|
||||
|
||||
DialerOptions
|
||||
}
|
||||
|
||||
type SubscriptionProviderOptions struct {
|
||||
Tag string `json:"tag,omitempty"`
|
||||
URL string `json:"url"`
|
||||
Excludes []string `json:"excludes,omitempty"`
|
||||
}
|
23
service/builder.go
Normal file
23
service/builder.go
Normal file
@ -0,0 +1,23 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.Service) (adapter.BoxService, error) {
|
||||
if options.Type == "" {
|
||||
return nil, E.New("missing service type")
|
||||
}
|
||||
switch options.Type {
|
||||
case C.ServiceSubscription:
|
||||
return NewSubscription(router, logger, options)
|
||||
default:
|
||||
return nil, E.New("unknown service type: ", options.Type)
|
||||
}
|
||||
}
|
11
service/subscription.go
Normal file
11
service/subscription.go
Normal file
@ -0,0 +1,11 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
)
|
||||
|
||||
func NewSubscription(router adapter.Router, logger log.ContextLogger, options option.Service) (adapter.BoxService, error) {
|
||||
panic("not implemented")
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user