diff --git a/app/point/inbound_detour.go b/app/point/inbound_detour.go new file mode 100644 index 00000000..54d35a9b --- /dev/null +++ b/app/point/inbound_detour.go @@ -0,0 +1,56 @@ +package point + +import ( + "github.com/v2ray/v2ray-core/app/point/config" + "github.com/v2ray/v2ray-core/common/log" + "github.com/v2ray/v2ray-core/common/retry" + "github.com/v2ray/v2ray-core/proxy/common/connhandler" +) + +type InboundConnectionHandlerWithPort struct { + port uint16 + handler connhandler.InboundConnectionHandler +} + +type InboundDetourHandler struct { + point *Point + config config.InboundDetourConfig + ich []*InboundConnectionHandlerWithPort +} + +func (this *InboundDetourHandler) Initialize() error { + ichFactory := connhandler.GetInboundConnectionHandlerFactory(this.config.Protocol()) + if ichFactory == nil { + log.Error("Unknown inbound connection handler factory %s", this.config.Protocol()) + return config.BadConfiguration + } + + ports := this.config.PortRange() + this.ich = make([]*InboundConnectionHandlerWithPort, 0, ports.From()-ports.To()+1) + for i := ports.From(); i <= ports.To(); i++ { + ichConfig := this.config.Settings() + ich, err := ichFactory.Create(this.point, ichConfig) + if err != nil { + log.Error("Failed to create inbound connection handler: %v", err) + return err + } + this.ich = append(this.ich, &InboundConnectionHandlerWithPort{ + port: i, + handler: ich, + }) + } + return nil +} + +func (this *InboundDetourHandler) Start() error { + for _, ich := range this.ich { + return retry.Timed(100 /* times */, 100 /* ms */).On(func() error { + err := ich.handler.Listen(ich.port) + if err != nil { + return err + } + return nil + }) + } + return nil +} diff --git a/app/point/point.go b/app/point/point.go index 5a4cabdd..358f069e 100644 --- a/app/point/point.go +++ b/app/point/point.go @@ -14,6 +14,7 @@ type Point struct { port uint16 ich connhandler.InboundConnectionHandler och connhandler.OutboundConnectionHandler + idh []*InboundDetourHandler } // NewPoint returns a new Point server based on given configuration. @@ -48,6 +49,22 @@ func NewPoint(pConfig config.PointConfig) (*Point, error) { } vpoint.och = och + detours := pConfig.InboundDetours() + if len(detours) > 0 { + vpoint.idh = make([]*InboundDetourHandler, len(detours)) + for idx, detourConfig := range detours { + detourHandler := &InboundDetourHandler{ + point: vpoint, + config: detourConfig, + } + err := detourHandler.Initialize() + if err != nil { + return nil, err + } + vpoint.idh[idx] = detourHandler + } + } + return vpoint, nil } @@ -59,14 +76,26 @@ func (vp *Point) Start() error { return config.BadConfiguration } - return retry.Timed(100 /* times */, 100 /* ms */).On(func() error { + err := retry.Timed(100 /* times */, 100 /* ms */).On(func() error { err := vp.ich.Listen(vp.port) - if err == nil { - log.Warning("Point server started on port %d", vp.port) - return nil + if err != nil { + return err } - return err + log.Warning("Point server started on port %d", vp.port) + return nil }) + if err != nil { + return err + } + + for _, detourHandler := range vp.idh { + err := detourHandler.Start() + if err != nil { + return err + } + } + + return nil } func (p *Point) DispatchToOutbound(packet v2net.Packet) ray.InboundRay {