mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 21:54:13 +08:00
router accepts services
This commit is contained in:
parent
385475a6f6
commit
356ee6f8fa
@ -4,3 +4,9 @@ type Service interface {
|
|||||||
Start() error
|
Start() error
|
||||||
Close() 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/option"
|
||||||
"github.com/sagernet/sing-box/outbound"
|
"github.com/sagernet/sing-box/outbound"
|
||||||
"github.com/sagernet/sing-box/route"
|
"github.com/sagernet/sing-box/route"
|
||||||
|
"github.com/sagernet/sing-box/service"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
F "github.com/sagernet/sing/common/format"
|
F "github.com/sagernet/sing/common/format"
|
||||||
@ -27,6 +28,7 @@ type Box struct {
|
|||||||
router adapter.Router
|
router adapter.Router
|
||||||
inbounds []adapter.Inbound
|
inbounds []adapter.Inbound
|
||||||
outbounds []adapter.Outbound
|
outbounds []adapter.Outbound
|
||||||
|
services []adapter.BoxService
|
||||||
logFactory log.Factory
|
logFactory log.Factory
|
||||||
logger log.ContextLogger
|
logger log.ContextLogger
|
||||||
logFile *os.File
|
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))
|
inbounds := make([]adapter.Inbound, 0, len(options.Inbounds))
|
||||||
outbounds := make([]adapter.Outbound, 0, len(options.Outbounds))
|
outbounds := make([]adapter.Outbound, 0, len(options.Outbounds))
|
||||||
|
services := make([]adapter.BoxService, 0, len(options.Services))
|
||||||
for i, inboundOptions := range options.Inbounds {
|
for i, inboundOptions := range options.Inbounds {
|
||||||
var in adapter.Inbound
|
var in adapter.Inbound
|
||||||
var tag string
|
var tag string
|
||||||
@ -155,6 +158,34 @@ func New(ctx context.Context, options option.Options) (*Box, error) {
|
|||||||
return nil, err
|
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 clashServer adapter.ClashServer
|
||||||
var v2rayServer adapter.V2RayServer
|
var v2rayServer adapter.V2RayServer
|
||||||
if needClashAPI {
|
if needClashAPI {
|
||||||
@ -175,6 +206,7 @@ func New(ctx context.Context, options option.Options) (*Box, error) {
|
|||||||
router: router,
|
router: router,
|
||||||
inbounds: inbounds,
|
inbounds: inbounds,
|
||||||
outbounds: outbounds,
|
outbounds: outbounds,
|
||||||
|
services: services,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
logFactory: logFactory,
|
logFactory: logFactory,
|
||||||
logger: logFactory.Logger(),
|
logger: logFactory.Logger(),
|
||||||
@ -233,6 +265,18 @@ func (s *Box) start() error {
|
|||||||
return E.Cause(err, "initialize inbound/", in.Type(), "[", tag, "]")
|
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 {
|
if s.clashServer != nil {
|
||||||
err = s.clashServer.Start()
|
err = s.clashServer.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -262,6 +306,9 @@ func (s *Box) Close() error {
|
|||||||
for _, out := range s.outbounds {
|
for _, out := range s.outbounds {
|
||||||
common.Close(out)
|
common.Close(out)
|
||||||
}
|
}
|
||||||
|
for _, srv := range s.services {
|
||||||
|
srv.Close()
|
||||||
|
}
|
||||||
return common.Close(
|
return common.Close(
|
||||||
s.router,
|
s.router,
|
||||||
s.logFactory,
|
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"`
|
Inbounds []Inbound `json:"inbounds,omitempty"`
|
||||||
Outbounds []Outbound `json:"outbounds,omitempty"`
|
Outbounds []Outbound `json:"outbounds,omitempty"`
|
||||||
Route *RouteOptions `json:"route,omitempty"`
|
Route *RouteOptions `json:"route,omitempty"`
|
||||||
|
Services []Service `json:"services,omitempty"`
|
||||||
Experimental *ExperimentalOptions `json:"experimental,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