Skip to content

Commit 99840ba

Browse files
committed
Add high-level boundary management interface
I rewrote the router's boundary management part to implement dynamic management from a high-level box interface. This also includes a number of changes I made in the process of rewriting some messy parts, such as the Outbound tree bottom-top starter.
1 parent 0b42f26 commit 99840ba

File tree

13 files changed

+503
-352
lines changed

13 files changed

+503
-352
lines changed

adapter/router.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,28 @@ import (
1818
)
1919

2020
type Router interface {
21-
Service
21+
AddOutbound(outbound Outbound) error
22+
AddInbound(inbound Inbound) error
23+
24+
RemoveOutbound(tag string) error
25+
RemoveInbound(tag string) error
26+
2227
PreStarter
28+
29+
StartOutbounds() error
30+
31+
Service
32+
33+
StartInbounds() error
34+
2335
PostStarter
36+
2437
Cleanup() error
2538

39+
DefaultOutbound(network string) (Outbound, error)
2640
Outbounds() []Outbound
2741
Outbound(tag string) (Outbound, bool)
28-
DefaultOutbound(network string) (Outbound, error)
42+
Inbound(tag string) (Inbound, bool)
2943

3044
FakeIPStore() FakeIPStore
3145

box.go

Lines changed: 101 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ import (
2929
var _ adapter.Service = (*Box)(nil)
3030

3131
type Box struct {
32-
createdAt time.Time
33-
router adapter.Router
34-
inbounds []adapter.Inbound
35-
outbounds []adapter.Outbound
36-
logFactory log.Factory
37-
logger log.ContextLogger
38-
preServices1 map[string]adapter.Service
39-
preServices2 map[string]adapter.Service
40-
postServices map[string]adapter.Service
41-
done chan struct{}
32+
createdAt time.Time
33+
router adapter.Router
34+
logFactory log.Factory
35+
logger log.ContextLogger
36+
preServices1 map[string]adapter.Service
37+
preServices2 map[string]adapter.Service
38+
postServices map[string]adapter.Service
39+
platformInterface platform.Interface
40+
ctx context.Context
41+
done chan struct{}
4242
}
4343

4444
type Options struct {
@@ -97,57 +97,6 @@ func New(options Options) (*Box, error) {
9797
if err != nil {
9898
return nil, E.Cause(err, "parse route options")
9999
}
100-
inbounds := make([]adapter.Inbound, 0, len(options.Inbounds))
101-
outbounds := make([]adapter.Outbound, 0, len(options.Outbounds))
102-
for i, inboundOptions := range options.Inbounds {
103-
var in adapter.Inbound
104-
var tag string
105-
if inboundOptions.Tag != "" {
106-
tag = inboundOptions.Tag
107-
} else {
108-
tag = F.ToString(i)
109-
}
110-
in, err = inbound.New(
111-
ctx,
112-
router,
113-
logFactory.NewLogger(F.ToString("inbound/", inboundOptions.Type, "[", tag, "]")),
114-
tag,
115-
inboundOptions,
116-
options.PlatformInterface,
117-
)
118-
if err != nil {
119-
return nil, E.Cause(err, "parse inbound[", i, "]")
120-
}
121-
inbounds = append(inbounds, in)
122-
}
123-
for i, outboundOptions := range options.Outbounds {
124-
var out adapter.Outbound
125-
var tag string
126-
if outboundOptions.Tag != "" {
127-
tag = outboundOptions.Tag
128-
} else {
129-
tag = F.ToString(i)
130-
}
131-
out, err = outbound.New(
132-
ctx,
133-
router,
134-
logFactory.NewLogger(F.ToString("outbound/", outboundOptions.Type, "[", tag, "]")),
135-
tag,
136-
outboundOptions)
137-
if err != nil {
138-
return nil, E.Cause(err, "parse outbound[", i, "]")
139-
}
140-
outbounds = append(outbounds, out)
141-
}
142-
err = router.Initialize(inbounds, outbounds, func() adapter.Outbound {
143-
out, oErr := outbound.New(ctx, router, logFactory.NewLogger("outbound/direct"), "direct", option.Outbound{Type: "direct", Tag: "default"})
144-
common.Must(oErr)
145-
outbounds = append(outbounds, out)
146-
return out
147-
})
148-
if err != nil {
149-
return nil, err
150-
}
151100
if options.PlatformInterface != nil {
152101
err = options.PlatformInterface.Initialize(ctx, router)
153102
if err != nil {
@@ -183,18 +132,35 @@ func New(options Options) (*Box, error) {
183132
router.SetV2RayServer(v2rayServer)
184133
preServices2["v2ray api"] = v2rayServer
185134
}
186-
return &Box{
187-
router: router,
188-
inbounds: inbounds,
189-
outbounds: outbounds,
190-
createdAt: createdAt,
191-
logFactory: logFactory,
192-
logger: logFactory.Logger(),
193-
preServices1: preServices1,
194-
preServices2: preServices2,
195-
postServices: postServices,
196-
done: make(chan struct{}),
197-
}, nil
135+
box := &Box{
136+
router: router,
137+
createdAt: createdAt,
138+
logFactory: logFactory,
139+
logger: logFactory.Logger(),
140+
preServices1: preServices1,
141+
preServices2: preServices2,
142+
postServices: postServices,
143+
platformInterface: options.PlatformInterface,
144+
ctx: ctx,
145+
done: make(chan struct{}),
146+
}
147+
for i, outOpts := range options.Outbounds {
148+
if outOpts.Tag == "" {
149+
outOpts.Tag = F.ToString(i)
150+
}
151+
if err := box.AddOutbound(outOpts); err != nil {
152+
return nil, E.Cause(err, "create outbound")
153+
}
154+
}
155+
for i, inOpts := range options.Inbounds {
156+
if inOpts.Tag == "" {
157+
inOpts.Tag = F.ToString(i)
158+
}
159+
if err := box.AddInbound(inOpts); err != nil {
160+
return nil, E.Cause(err, "create inbound")
161+
}
162+
}
163+
return box, nil
198164
}
199165

200166
func (s *Box) PreStart() error {
@@ -263,12 +229,10 @@ func (s *Box) preStart() error {
263229
}
264230
}
265231
}
266-
err = s.router.PreStart()
267-
if err != nil {
232+
if err := s.router.PreStart(); err != nil {
268233
return E.Cause(err, "pre-start router")
269234
}
270-
err = s.startOutbounds()
271-
if err != nil {
235+
if err := s.router.StartOutbounds(); err != nil {
272236
return err
273237
}
274238
return s.router.Start()
@@ -291,20 +255,10 @@ func (s *Box) start() error {
291255
return E.Cause(err, "start ", serviceName)
292256
}
293257
}
294-
for i, in := range s.inbounds {
295-
var tag string
296-
if in.Tag() == "" {
297-
tag = F.ToString(i)
298-
} else {
299-
tag = in.Tag()
300-
}
301-
err = in.Start()
302-
if err != nil {
303-
return E.Cause(err, "initialize inbound/", in.Type(), "[", tag, "]")
304-
}
258+
if err := s.router.StartInbounds(); err != nil {
259+
return E.Cause(err, "start inbounds")
305260
}
306-
err = s.postStart()
307-
if err != nil {
261+
if err = s.postStart(); err != nil {
308262
return err
309263
}
310264
return s.router.Cleanup()
@@ -317,26 +271,8 @@ func (s *Box) postStart() error {
317271
return E.Cause(err, "start ", serviceName)
318272
}
319273
}
320-
// TODO: reorganize ALL start order
321-
for _, out := range s.outbounds {
322-
if lateOutbound, isLateOutbound := out.(adapter.PostStarter); isLateOutbound {
323-
err := lateOutbound.PostStart()
324-
if err != nil {
325-
return E.Cause(err, "post-start outbound/", out.Tag())
326-
}
327-
}
328-
}
329-
err := s.router.PostStart()
330-
if err != nil {
331-
return err
332-
}
333-
for _, in := range s.inbounds {
334-
if lateInbound, isLateInbound := in.(adapter.PostStarter); isLateInbound {
335-
err = lateInbound.PostStart()
336-
if err != nil {
337-
return E.Cause(err, "post-start inbound/", in.Tag())
338-
}
339-
}
274+
if err := s.router.PostStart(); err != nil {
275+
return E.Cause(err, "post-start")
340276
}
341277
return nil
342278
}
@@ -357,20 +293,6 @@ func (s *Box) Close() error {
357293
})
358294
monitor.Finish()
359295
}
360-
for i, in := range s.inbounds {
361-
monitor.Start("close inbound/", in.Type(), "[", i, "]")
362-
errors = E.Append(errors, in.Close(), func(err error) error {
363-
return E.Cause(err, "close inbound/", in.Type(), "[", i, "]")
364-
})
365-
monitor.Finish()
366-
}
367-
for i, out := range s.outbounds {
368-
monitor.Start("close outbound/", out.Type(), "[", i, "]")
369-
errors = E.Append(errors, common.Close(out), func(err error) error {
370-
return E.Cause(err, "close outbound/", out.Type(), "[", i, "]")
371-
})
372-
monitor.Finish()
373-
}
374296
monitor.Start("close router")
375297
if err := common.Close(s.router); err != nil {
376298
errors = E.Append(errors, err, func(err error) error {
@@ -403,3 +325,58 @@ func (s *Box) Close() error {
403325
func (s *Box) Router() adapter.Router {
404326
return s.router
405327
}
328+
329+
func (s *Box) AddOutbound(option option.Outbound) error {
330+
if option.Tag == "" {
331+
return E.New("empty tag")
332+
}
333+
out, err := outbound.New(
334+
s.ctx,
335+
s.router,
336+
s.logFactory.NewLogger(F.ToString("outbound/", option.Type, "[", option.Tag, "]")),
337+
option.Tag,
338+
option,
339+
)
340+
if err != nil {
341+
return E.Cause(err, "parse addited outbound")
342+
}
343+
if err := s.router.AddOutbound(out); err != nil {
344+
return E.Cause(err, "outbound/", option.Type, "[", option.Tag, "]")
345+
}
346+
return nil
347+
}
348+
349+
func (s *Box) AddInbound(option option.Inbound) error {
350+
if option.Tag == "" {
351+
return E.New("empty tag")
352+
}
353+
in, err := inbound.New(
354+
s.ctx,
355+
s.router,
356+
s.logFactory.NewLogger(F.ToString("inbound/", option.Type, "[", option.Tag, "]")),
357+
option.Tag,
358+
option,
359+
s.platformInterface,
360+
)
361+
if err != nil {
362+
return E.Cause(err, "parse addited inbound")
363+
}
364+
if err := s.router.AddInbound(in); err != nil {
365+
return E.Cause(err, "inbound/", option.Type, "[", option.Tag, "]")
366+
}
367+
return nil
368+
}
369+
370+
func (s *Box) RemoveOutbound(tag string) error {
371+
if err := s.router.RemoveOutbound(tag); err != nil {
372+
return E.Cause(err, "outbound[", tag, "]")
373+
}
374+
return nil
375+
}
376+
377+
func (s *Box) RemoveInbound(tag string) error {
378+
if err := s.router.RemoveInbound(tag); err != nil {
379+
return E.Cause(err, "inbound[", tag, "]")
380+
}
381+
return nil
382+
}

box_outbound.go

Lines changed: 0 additions & 85 deletions
This file was deleted.

0 commit comments

Comments
 (0)