mirror of https://github.com/v2ray/v2ray-core
leverage global object creator in proxies.
parent
db1c9131f0
commit
148e4832eb
|
@ -1,6 +1,7 @@
|
||||||
package proxy_test
|
package proxy_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
|
@ -21,14 +22,17 @@ func TestProxyDial(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
|
|
||||||
space := app.NewSpace()
|
space := app.NewSpace()
|
||||||
|
ctx := app.ContextWithSpace(context.Background(), space)
|
||||||
assert.Error(space.AddApp(new(proxyman.OutboundConfig)))
|
assert.Error(space.AddApp(new(proxyman.OutboundConfig)))
|
||||||
outboundManager := proxyman.OutboundHandlerManagerFromSpace(space)
|
outboundManager := proxyman.OutboundHandlerManagerFromSpace(space)
|
||||||
common.Must(outboundManager.SetHandler("tag", freedom.New(&freedom.Config{}, space, &proxy.OutboundHandlerMeta{
|
freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{
|
||||||
Tag: "tag",
|
Tag: "tag",
|
||||||
StreamSettings: &internet.StreamConfig{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Protocol: internet.TransportProtocol_TCP,
|
Protocol: internet.TransportProtocol_TCP,
|
||||||
},
|
},
|
||||||
})))
|
}), &freedom.Config{})
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
common.Must(outboundManager.SetHandler("tag", freedom))
|
||||||
|
|
||||||
assert.Error(space.AddApp(new(Config))).IsNil()
|
assert.Error(space.AddApp(new(Config))).IsNil()
|
||||||
proxy := OutboundProxyFromSpace(space)
|
proxy := OutboundProxyFromSpace(space)
|
||||||
|
|
16
app/space.go
16
app/space.go
|
@ -1,6 +1,8 @@
|
||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"v2ray.com/core/common/errors"
|
"v2ray.com/core/common/errors"
|
||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
|
@ -104,3 +106,17 @@ func (v *spaceImpl) AddApp(config proto.Message) error {
|
||||||
func (v *spaceImpl) AddAppLegacy(name string, application Application) {
|
func (v *spaceImpl) AddAppLegacy(name string, application Application) {
|
||||||
v.cache[name] = application
|
v.cache[name] = application
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type contextKey int
|
||||||
|
|
||||||
|
const (
|
||||||
|
spaceKey = contextKey(0)
|
||||||
|
)
|
||||||
|
|
||||||
|
func SpaceFromContext(ctx context.Context) Space {
|
||||||
|
return ctx.Value(spaceKey).(Space)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ContextWithSpace(ctx context.Context, space Space) context.Context {
|
||||||
|
return context.WithValue(ctx, spaceKey, space)
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/common/dice"
|
"v2ray.com/core/common/dice"
|
||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
|
@ -15,7 +17,8 @@ type InboundDetourHandlerAlways struct {
|
||||||
ich []proxy.InboundHandler
|
ich []proxy.InboundHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInboundDetourHandlerAlways(space app.Space, config *InboundConnectionConfig) (*InboundDetourHandlerAlways, error) {
|
func NewInboundDetourHandlerAlways(ctx context.Context, config *InboundConnectionConfig) (*InboundDetourHandlerAlways, error) {
|
||||||
|
space := app.SpaceFromContext(ctx)
|
||||||
handler := &InboundDetourHandlerAlways{
|
handler := &InboundDetourHandlerAlways{
|
||||||
space: space,
|
space: space,
|
||||||
config: config,
|
config: config,
|
||||||
|
@ -27,13 +30,14 @@ func NewInboundDetourHandlerAlways(space app.Space, config *InboundConnectionCon
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ich, err := proxy.CreateInboundHandler(config.Settings.Type, space, ichConfig, &proxy.InboundHandlerMeta{
|
ich, err := proxy.CreateInboundHandler(proxy.ContextWithInboundMeta(ctx, &proxy.InboundHandlerMeta{
|
||||||
Address: config.GetListenOnValue(),
|
Address: config.GetListenOnValue(),
|
||||||
Port: i,
|
Port: i,
|
||||||
Tag: config.Tag,
|
Tag: config.Tag,
|
||||||
StreamSettings: config.StreamSettings,
|
StreamSettings: config.StreamSettings,
|
||||||
AllowPassiveConnection: config.AllowPassiveConnection,
|
AllowPassiveConnection: config.AllowPassiveConnection,
|
||||||
})
|
}), ichConfig)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to create inbound connection handler: ", err)
|
log.Error("Failed to create inbound connection handler: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/common/dice"
|
"v2ray.com/core/common/dice"
|
||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
|
@ -20,13 +22,16 @@ type InboundDetourHandlerDynamic struct {
|
||||||
ichs []proxy.InboundHandler
|
ichs []proxy.InboundHandler
|
||||||
ich2Recyle []proxy.InboundHandler
|
ich2Recyle []proxy.InboundHandler
|
||||||
lastRefresh time.Time
|
lastRefresh time.Time
|
||||||
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInboundDetourHandlerDynamic(space app.Space, config *InboundConnectionConfig) (*InboundDetourHandlerDynamic, error) {
|
func NewInboundDetourHandlerDynamic(ctx context.Context, config *InboundConnectionConfig) (*InboundDetourHandlerDynamic, error) {
|
||||||
|
space := app.SpaceFromContext(ctx)
|
||||||
handler := &InboundDetourHandlerDynamic{
|
handler := &InboundDetourHandlerDynamic{
|
||||||
space: space,
|
space: space,
|
||||||
config: config,
|
config: config,
|
||||||
portsInUse: make(map[v2net.Port]bool),
|
portsInUse: make(map[v2net.Port]bool),
|
||||||
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
handler.ichs = make([]proxy.InboundHandler, config.GetAllocationStrategyValue().GetConcurrencyValue())
|
handler.ichs = make([]proxy.InboundHandler, config.GetAllocationStrategyValue().GetConcurrencyValue())
|
||||||
|
|
||||||
|
@ -35,13 +40,13 @@ func NewInboundDetourHandlerDynamic(space app.Space, config *InboundConnectionCo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ich, err := proxy.CreateInboundHandler(config.Settings.Type, space, ichConfig, &proxy.InboundHandlerMeta{
|
ich, err := proxy.CreateInboundHandler(proxy.ContextWithInboundMeta(ctx, &proxy.InboundHandlerMeta{
|
||||||
Address: config.GetListenOnValue(),
|
Address: config.GetListenOnValue(),
|
||||||
Port: 0,
|
Port: 0,
|
||||||
Tag: config.Tag,
|
Tag: config.Tag,
|
||||||
StreamSettings: config.StreamSettings,
|
StreamSettings: config.StreamSettings,
|
||||||
AllowPassiveConnection: config.AllowPassiveConnection,
|
AllowPassiveConnection: config.AllowPassiveConnection,
|
||||||
})
|
}), ichConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Point: Failed to create inbound connection handler: ", err)
|
log.Error("Point: Failed to create inbound connection handler: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -107,8 +112,10 @@ func (v *InboundDetourHandlerDynamic) refresh() error {
|
||||||
err := retry.Timed(5, 100).On(func() error {
|
err := retry.Timed(5, 100).On(func() error {
|
||||||
port := v.pickUnusedPort()
|
port := v.pickUnusedPort()
|
||||||
ichConfig, _ := config.GetTypedSettings()
|
ichConfig, _ := config.GetTypedSettings()
|
||||||
ich, err := proxy.CreateInboundHandler(config.Settings.Type, v.space, ichConfig, &proxy.InboundHandlerMeta{
|
ich, err := proxy.CreateInboundHandler(proxy.ContextWithInboundMeta(v.ctx, &proxy.InboundHandlerMeta{
|
||||||
Address: config.GetListenOnValue(), Port: port, Tag: config.Tag, StreamSettings: config.StreamSettings})
|
Address: config.GetListenOnValue(),
|
||||||
|
Port: port, Tag: config.Tag,
|
||||||
|
StreamSettings: config.StreamSettings}), ichConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
delete(v.portsInUse, port)
|
delete(v.portsInUse, port)
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -2,28 +2,26 @@
|
||||||
package blackhole
|
package blackhole
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/common"
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/proxy"
|
|
||||||
"v2ray.com/core/transport/ray"
|
"v2ray.com/core/transport/ray"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler is an outbound connection that sliently swallow the entire payload.
|
// Handler is an outbound connection that sliently swallow the entire payload.
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
meta *proxy.OutboundHandlerMeta
|
|
||||||
response ResponseConfig
|
response ResponseConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new blackhole handler.
|
// New creates a new blackhole handler.
|
||||||
func New(space app.Space, config *Config, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
func New(ctx context.Context, config *Config) (*Handler, error) {
|
||||||
response, err := config.GetInternalResponse()
|
response, err := config.GetInternalResponse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Handler{
|
return &Handler{
|
||||||
meta: meta,
|
|
||||||
response: response,
|
response: response,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -38,10 +36,8 @@ func (v *Handler) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
|
||||||
ray.OutboundOutput().CloseError()
|
ray.OutboundOutput().CloseError()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Factory is an utility for creating blackhole handlers.
|
func init() {
|
||||||
type Factory struct{}
|
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
|
return New(ctx, config.(*Config))
|
||||||
// Create implements OutboundHandlerFactory.Create().
|
}))
|
||||||
func (v *Factory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
|
||||||
return New(space, config.(*Config), meta)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package blackhole
|
|
||||||
|
|
||||||
import (
|
|
||||||
"v2ray.com/core/common"
|
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
"v2ray.com/core/proxy"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Must listed after config.pb.go
|
|
||||||
common.Must(proxy.RegisterOutboundHandlerCreator(serial.GetMessageType(new(Config)), new(Factory)))
|
|
||||||
}
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type key int
|
||||||
|
|
||||||
|
const (
|
||||||
|
inboundMetaKey = key(0)
|
||||||
|
outboundMetaKey = key(1)
|
||||||
|
)
|
||||||
|
|
||||||
|
func ContextWithInboundMeta(ctx context.Context, meta *InboundHandlerMeta) context.Context {
|
||||||
|
return context.WithValue(ctx, inboundMetaKey, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func InboundMetaFromContext(ctx context.Context) *InboundHandlerMeta {
|
||||||
|
v := ctx.Value(inboundMetaKey)
|
||||||
|
if v == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return v.(*InboundHandlerMeta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ContextWithOutboundMeta(ctx context.Context, meta *OutboundHandlerMeta) context.Context {
|
||||||
|
return context.WithValue(ctx, outboundMetaKey, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func OutboundMetaFromContext(ctx context.Context) *OutboundHandlerMeta {
|
||||||
|
v := ctx.Value(outboundMetaKey)
|
||||||
|
if v == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return v.(*OutboundHandlerMeta)
|
||||||
|
}
|
|
@ -1,11 +0,0 @@
|
||||||
package proxy
|
|
||||||
|
|
||||||
import "v2ray.com/core/app"
|
|
||||||
|
|
||||||
type InboundHandlerFactory interface {
|
|
||||||
Create(space app.Space, config interface{}, meta *InboundHandlerMeta) (InboundHandler, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type OutboundHandlerFactory interface {
|
|
||||||
Create(space app.Space, config interface{}, meta *OutboundHandlerMeta) (OutboundHandler, error)
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dokodemo
|
package dokodemo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
|
@ -10,7 +11,6 @@ import (
|
||||||
"v2ray.com/core/common/errors"
|
"v2ray.com/core/common/errors"
|
||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
"v2ray.com/core/common/signal"
|
"v2ray.com/core/common/signal"
|
||||||
"v2ray.com/core/proxy"
|
"v2ray.com/core/proxy"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
|
@ -31,7 +31,15 @@ type DokodemoDoor struct {
|
||||||
meta *proxy.InboundHandlerMeta
|
meta *proxy.InboundHandlerMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDokodemoDoor(config *Config, space app.Space, meta *proxy.InboundHandlerMeta) *DokodemoDoor {
|
func NewDokodemoDoor(ctx context.Context, config *Config) (*DokodemoDoor, error) {
|
||||||
|
space := app.SpaceFromContext(ctx)
|
||||||
|
if space == nil {
|
||||||
|
return nil, errors.New("Dokodemo: No space in context.")
|
||||||
|
}
|
||||||
|
meta := proxy.InboundMetaFromContext(ctx)
|
||||||
|
if meta == nil {
|
||||||
|
return nil, errors.New("Dokodemo: No outbound meta in context.")
|
||||||
|
}
|
||||||
d := &DokodemoDoor{
|
d := &DokodemoDoor{
|
||||||
config: config,
|
config: config,
|
||||||
address: config.GetPredefinedAddress(),
|
address: config.GetPredefinedAddress(),
|
||||||
|
@ -45,7 +53,7 @@ func NewDokodemoDoor(config *Config, space app.Space, meta *proxy.InboundHandler
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return d
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *DokodemoDoor) Port() v2net.Port {
|
func (v *DokodemoDoor) Port() v2net.Port {
|
||||||
|
@ -205,12 +213,8 @@ func (v *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Factory struct{}
|
|
||||||
|
|
||||||
func (v *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
|
||||||
return NewDokodemoDoor(rawConfig.(*Config), space, meta), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
common.Must(proxy.RegisterInboundHandlerCreator(serial.GetMessageType(new(Config)), new(Factory)))
|
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
|
return NewDokodemoDoor(ctx, config.(*Config))
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/app/dispatcher"
|
"v2ray.com/core/app/dispatcher"
|
||||||
_ "v2ray.com/core/app/dispatcher/impl"
|
_ "v2ray.com/core/app/dispatcher/impl"
|
||||||
|
@ -42,31 +44,36 @@ func TestDokodemoTCP(t *testing.T) {
|
||||||
space.AddApp(new(proxyman.OutboundConfig))
|
space.AddApp(new(proxyman.OutboundConfig))
|
||||||
|
|
||||||
ohm := proxyman.OutboundHandlerManagerFromSpace(space)
|
ohm := proxyman.OutboundHandlerManagerFromSpace(space)
|
||||||
ohm.SetDefaultHandler(
|
ctx := context.Background()
|
||||||
freedom.New(
|
ctx = app.ContextWithSpace(ctx, space)
|
||||||
&freedom.Config{},
|
|
||||||
space,
|
freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{
|
||||||
&proxy.OutboundHandlerMeta{
|
Address: v2net.LocalHostIP,
|
||||||
Address: v2net.LocalHostIP,
|
StreamSettings: &internet.StreamConfig{
|
||||||
StreamSettings: &internet.StreamConfig{
|
Protocol: internet.TransportProtocol_TCP,
|
||||||
Protocol: internet.TransportProtocol_TCP,
|
},
|
||||||
},
|
}), &freedom.Config{})
|
||||||
}))
|
assert.Error(err).IsNil()
|
||||||
|
ohm.SetDefaultHandler(freedom)
|
||||||
|
|
||||||
data2Send := "Data to be sent to remote."
|
data2Send := "Data to be sent to remote."
|
||||||
|
|
||||||
port := v2net.Port(dice.Roll(20000) + 10000)
|
port := v2net.Port(dice.Roll(20000) + 10000)
|
||||||
dokodemo := NewDokodemoDoor(&Config{
|
|
||||||
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
ctx = proxy.ContextWithInboundMeta(ctx, &proxy.InboundHandlerMeta{
|
||||||
Port: uint32(tcpServer.Port),
|
|
||||||
NetworkList: v2net.Network_TCP.AsList(),
|
|
||||||
Timeout: 600,
|
|
||||||
}, space, &proxy.InboundHandlerMeta{
|
|
||||||
Address: v2net.LocalHostIP,
|
Address: v2net.LocalHostIP,
|
||||||
Port: port,
|
Port: port,
|
||||||
StreamSettings: &internet.StreamConfig{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Protocol: internet.TransportProtocol_TCP,
|
Protocol: internet.TransportProtocol_TCP,
|
||||||
}})
|
}})
|
||||||
|
|
||||||
|
dokodemo, err := NewDokodemoDoor(ctx, &Config{
|
||||||
|
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||||
|
Port: uint32(tcpServer.Port),
|
||||||
|
NetworkList: v2net.Network_TCP.AsList(),
|
||||||
|
Timeout: 600,
|
||||||
|
})
|
||||||
|
assert.Error(err).IsNil()
|
||||||
defer dokodemo.Close()
|
defer dokodemo.Close()
|
||||||
|
|
||||||
assert.Error(space.Initialize()).IsNil()
|
assert.Error(space.Initialize()).IsNil()
|
||||||
|
@ -114,30 +121,36 @@ func TestDokodemoUDP(t *testing.T) {
|
||||||
space.AddApp(new(proxyman.OutboundConfig))
|
space.AddApp(new(proxyman.OutboundConfig))
|
||||||
|
|
||||||
ohm := proxyman.OutboundHandlerManagerFromSpace(space)
|
ohm := proxyman.OutboundHandlerManagerFromSpace(space)
|
||||||
ohm.SetDefaultHandler(
|
|
||||||
freedom.New(
|
ctx := context.Background()
|
||||||
&freedom.Config{},
|
ctx = app.ContextWithSpace(ctx, space)
|
||||||
space,
|
freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{
|
||||||
&proxy.OutboundHandlerMeta{
|
Address: v2net.AnyIP,
|
||||||
Address: v2net.AnyIP,
|
StreamSettings: &internet.StreamConfig{
|
||||||
StreamSettings: &internet.StreamConfig{
|
Protocol: internet.TransportProtocol_TCP,
|
||||||
Protocol: internet.TransportProtocol_TCP,
|
},
|
||||||
}}))
|
}), &freedom.Config{})
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
ohm.SetDefaultHandler(freedom)
|
||||||
|
|
||||||
data2Send := "Data to be sent to remote."
|
data2Send := "Data to be sent to remote."
|
||||||
|
|
||||||
port := v2net.Port(dice.Roll(20000) + 10000)
|
port := v2net.Port(dice.Roll(20000) + 10000)
|
||||||
dokodemo := NewDokodemoDoor(&Config{
|
|
||||||
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
ctx = proxy.ContextWithInboundMeta(ctx, &proxy.InboundHandlerMeta{
|
||||||
Port: uint32(udpServer.Port),
|
|
||||||
NetworkList: v2net.Network_UDP.AsList(),
|
|
||||||
Timeout: 600,
|
|
||||||
}, space, &proxy.InboundHandlerMeta{
|
|
||||||
Address: v2net.LocalHostIP,
|
Address: v2net.LocalHostIP,
|
||||||
Port: port,
|
Port: port,
|
||||||
StreamSettings: &internet.StreamConfig{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Protocol: internet.TransportProtocol_TCP,
|
Protocol: internet.TransportProtocol_TCP,
|
||||||
}})
|
}})
|
||||||
|
|
||||||
|
dokodemo, err := NewDokodemoDoor(ctx, &Config{
|
||||||
|
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
|
||||||
|
Port: uint32(udpServer.Port),
|
||||||
|
NetworkList: v2net.Network_UDP.AsList(),
|
||||||
|
Timeout: 600,
|
||||||
|
})
|
||||||
|
assert.Error(err).IsNil()
|
||||||
defer dokodemo.Close()
|
defer dokodemo.Close()
|
||||||
|
|
||||||
assert.Error(space.Initialize()).IsNil()
|
assert.Error(space.Initialize()).IsNil()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package freedom
|
package freedom
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
|
@ -12,7 +13,6 @@ import (
|
||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/common/retry"
|
"v2ray.com/core/common/retry"
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
"v2ray.com/core/common/signal"
|
"v2ray.com/core/common/signal"
|
||||||
"v2ray.com/core/proxy"
|
"v2ray.com/core/proxy"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
|
@ -26,7 +26,15 @@ type Handler struct {
|
||||||
meta *proxy.OutboundHandlerMeta
|
meta *proxy.OutboundHandlerMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(config *Config, space app.Space, meta *proxy.OutboundHandlerMeta) *Handler {
|
func New(ctx context.Context, config *Config) (*Handler, error) {
|
||||||
|
space := app.SpaceFromContext(ctx)
|
||||||
|
if space == nil {
|
||||||
|
return nil, errors.New("Freedom: No space in context.")
|
||||||
|
}
|
||||||
|
meta := proxy.OutboundMetaFromContext(ctx)
|
||||||
|
if meta == nil {
|
||||||
|
return nil, errors.New("Freedom: No outbound meta in context.")
|
||||||
|
}
|
||||||
f := &Handler{
|
f := &Handler{
|
||||||
domainStrategy: config.DomainStrategy,
|
domainStrategy: config.DomainStrategy,
|
||||||
timeout: config.Timeout,
|
timeout: config.Timeout,
|
||||||
|
@ -41,7 +49,7 @@ func New(config *Config, space app.Space, meta *proxy.OutboundHandlerMeta) *Hand
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return f
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
// Private: Visible for testing.
|
||||||
|
@ -128,12 +136,8 @@ func (v *Handler) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Factory struct{}
|
|
||||||
|
|
||||||
func (v *Factory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
|
||||||
return New(config.(*Config), space, meta), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
common.Must(proxy.RegisterOutboundHandlerCreator(serial.GetMessageType(new(Config)), new(Factory)))
|
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
|
return New(ctx, config.(*Config))
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package freedom_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/app/dispatcher"
|
"v2ray.com/core/app/dispatcher"
|
||||||
_ "v2ray.com/core/app/dispatcher/impl"
|
_ "v2ray.com/core/app/dispatcher/impl"
|
||||||
|
@ -37,15 +39,15 @@ func TestSinglePacket(t *testing.T) {
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
|
|
||||||
space := app.NewSpace()
|
space := app.NewSpace()
|
||||||
freedom := New(
|
ctx := app.ContextWithSpace(context.Background(), space)
|
||||||
&Config{},
|
ctx = proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{
|
||||||
space,
|
Address: v2net.AnyIP,
|
||||||
&proxy.OutboundHandlerMeta{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Address: v2net.AnyIP,
|
Protocol: internet.TransportProtocol_TCP,
|
||||||
StreamSettings: &internet.StreamConfig{
|
},
|
||||||
Protocol: internet.TransportProtocol_TCP,
|
})
|
||||||
},
|
freedom, err := New(ctx, &Config{})
|
||||||
})
|
assert.Error(err).IsNil()
|
||||||
assert.Error(space.Initialize()).IsNil()
|
assert.Error(space.Initialize()).IsNil()
|
||||||
|
|
||||||
traffic := ray.NewRay()
|
traffic := ray.NewRay()
|
||||||
|
@ -77,15 +79,15 @@ func TestIPResolution(t *testing.T) {
|
||||||
},
|
},
|
||||||
})).IsNil()
|
})).IsNil()
|
||||||
|
|
||||||
freedom := New(
|
ctx := app.ContextWithSpace(context.Background(), space)
|
||||||
&Config{DomainStrategy: Config_USE_IP},
|
ctx = proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{
|
||||||
space,
|
Address: v2net.AnyIP,
|
||||||
&proxy.OutboundHandlerMeta{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Address: v2net.AnyIP,
|
Protocol: internet.TransportProtocol_TCP,
|
||||||
StreamSettings: &internet.StreamConfig{
|
},
|
||||||
Protocol: internet.TransportProtocol_TCP,
|
})
|
||||||
},
|
freedom, err := New(ctx, &Config{DomainStrategy: Config_USE_IP})
|
||||||
})
|
assert.Error(err).IsNil()
|
||||||
|
|
||||||
assert.Error(space.Initialize()).IsNil()
|
assert.Error(space.Initialize()).IsNil()
|
||||||
|
|
||||||
|
|
|
@ -1,45 +1,34 @@
|
||||||
package proxy
|
package proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"v2ray.com/core/app"
|
"context"
|
||||||
|
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/errors"
|
"v2ray.com/core/common/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
func CreateInboundHandler(ctx context.Context, config interface{}) (InboundHandler, error) {
|
||||||
inboundFactories = make(map[string]InboundHandlerFactory)
|
handler, err := common.CreateObject(ctx, config)
|
||||||
outboundFactories = make(map[string]OutboundHandlerFactory)
|
if err != nil {
|
||||||
)
|
return nil, err
|
||||||
|
}
|
||||||
func RegisterInboundHandlerCreator(name string, creator InboundHandlerFactory) error {
|
switch h := handler.(type) {
|
||||||
if _, found := inboundFactories[name]; found {
|
case InboundHandler:
|
||||||
return common.ErrDuplicatedName
|
return h, nil
|
||||||
|
default:
|
||||||
|
return nil, errors.New("Proxy: Not a InboundHandler.")
|
||||||
}
|
}
|
||||||
inboundFactories[name] = creator
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegisterOutboundHandlerCreator(name string, creator OutboundHandlerFactory) error {
|
func CreateOutboundHandler(ctx context.Context, config interface{}) (OutboundHandler, error) {
|
||||||
if _, found := outboundFactories[name]; found {
|
handler, err := common.CreateObject(ctx, config)
|
||||||
return common.ErrDuplicatedName
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
outboundFactories[name] = creator
|
switch h := handler.(type) {
|
||||||
return nil
|
case OutboundHandler:
|
||||||
}
|
return h, nil
|
||||||
|
default:
|
||||||
func CreateInboundHandler(name string, space app.Space, config interface{}, meta *InboundHandlerMeta) (InboundHandler, error) {
|
return nil, errors.New("Proxy: Not a OutboundHandler.")
|
||||||
creator, found := inboundFactories[name]
|
|
||||||
if !found {
|
|
||||||
return nil, errors.New("Proxy: Unknown inbound name: " + name)
|
|
||||||
}
|
}
|
||||||
return creator.Create(space, config, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateOutboundHandler(name string, space app.Space, config interface{}, meta *OutboundHandlerMeta) (OutboundHandler, error) {
|
|
||||||
creator, found := outboundFactories[name]
|
|
||||||
if !found {
|
|
||||||
return nil, errors.New("Proxy: Unknown outbound name: " + name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return creator.Create(space, config, meta)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/app/dispatcher"
|
"v2ray.com/core/app/dispatcher"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
|
@ -16,7 +18,6 @@ import (
|
||||||
"v2ray.com/core/common/errors"
|
"v2ray.com/core/common/errors"
|
||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
"v2ray.com/core/common/signal"
|
"v2ray.com/core/common/signal"
|
||||||
"v2ray.com/core/proxy"
|
"v2ray.com/core/proxy"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
|
@ -33,7 +34,15 @@ type Server struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer creates a new HTTP inbound handler.
|
// NewServer creates a new HTTP inbound handler.
|
||||||
func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandlerMeta) *Server {
|
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
||||||
|
space := app.SpaceFromContext(ctx)
|
||||||
|
if space == nil {
|
||||||
|
return nil, errors.New("HTTP|Server: No space in context.")
|
||||||
|
}
|
||||||
|
meta := proxy.InboundMetaFromContext(ctx)
|
||||||
|
if meta == nil {
|
||||||
|
return nil, errors.New("HTTP|Server: No inbound meta from context.")
|
||||||
|
}
|
||||||
s := &Server{
|
s := &Server{
|
||||||
config: config,
|
config: config,
|
||||||
meta: meta,
|
meta: meta,
|
||||||
|
@ -45,7 +54,7 @@ func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandler
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return s
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Port implements InboundHandler.Port().
|
// Port implements InboundHandler.Port().
|
||||||
|
@ -285,14 +294,8 @@ func (v *Server) handlePlainHTTP(request *http.Request, session *proxy.SessionIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerFactory is a InboundHandlerFactory.
|
|
||||||
type ServerFactory struct{}
|
|
||||||
|
|
||||||
// Create implements InboundHandlerFactory.Create().
|
|
||||||
func (v *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
|
||||||
return NewServer(rawConfig.(*ServerConfig), space, meta), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
common.Must(proxy.RegisterInboundHandlerCreator(serial.GetMessageType(new(ServerConfig)), new(ServerFactory)))
|
common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
|
return NewServer(ctx, config.(*ServerConfig))
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package shadowsocks
|
package shadowsocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"v2ray.com/core/app"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/bufio"
|
"v2ray.com/core/common/bufio"
|
||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
|
@ -21,7 +24,11 @@ type Client struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient create a new Shadowsocks client.
|
// NewClient create a new Shadowsocks client.
|
||||||
func NewClient(config *ClientConfig, space app.Space, meta *proxy.OutboundHandlerMeta) (*Client, error) {
|
func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
|
||||||
|
meta := proxy.OutboundMetaFromContext(ctx)
|
||||||
|
if meta == nil {
|
||||||
|
return nil, errors.New("Shadowsocks|Client: No outbound meta in context.")
|
||||||
|
}
|
||||||
serverList := protocol.NewServerList()
|
serverList := protocol.NewServerList()
|
||||||
for _, rec := range config.Server {
|
for _, rec := range config.Server {
|
||||||
serverList.AddServer(protocol.NewServerSpecFromPB(*rec))
|
serverList.AddServer(protocol.NewServerSpecFromPB(*rec))
|
||||||
|
@ -164,10 +171,8 @@ func (v *Client) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientFactory is a OutboundHandlerFactory.
|
func init() {
|
||||||
type ClientFactory struct{}
|
common.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
|
return NewClient(ctx, config.(*ClientConfig))
|
||||||
// Create implements OutboundHandlerFactory.Create().
|
}))
|
||||||
func (ClientFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
|
||||||
return NewClient(rawConfig.(*ClientConfig), space, meta)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package shadowsocks
|
|
||||||
|
|
||||||
import (
|
|
||||||
"v2ray.com/core/common"
|
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
"v2ray.com/core/proxy"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Must happen after config is initialized
|
|
||||||
common.Must(proxy.RegisterOutboundHandlerCreator(serial.GetMessageType(new(ClientConfig)), new(ClientFactory)))
|
|
||||||
common.Must(proxy.RegisterInboundHandlerCreator(serial.GetMessageType(new(ServerConfig)), new(ServerFactory)))
|
|
||||||
}
|
|
|
@ -1,8 +1,11 @@
|
||||||
package shadowsocks
|
package shadowsocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/app/dispatcher"
|
"v2ray.com/core/app/dispatcher"
|
||||||
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/bufio"
|
"v2ray.com/core/common/bufio"
|
||||||
"v2ray.com/core/common/errors"
|
"v2ray.com/core/common/errors"
|
||||||
|
@ -27,7 +30,15 @@ type Server struct {
|
||||||
udpServer *udp.Server
|
udpServer *udp.Server
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandlerMeta) (*Server, error) {
|
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
||||||
|
space := app.SpaceFromContext(ctx)
|
||||||
|
if space == nil {
|
||||||
|
return nil, errors.New("Shadowsocks|Server: No space in context.")
|
||||||
|
}
|
||||||
|
meta := proxy.InboundMetaFromContext(ctx)
|
||||||
|
if meta == nil {
|
||||||
|
return nil, errors.New("Shadowsocks|Server: No inbound meta in context.")
|
||||||
|
}
|
||||||
if config.GetUser() == nil {
|
if config.GetUser() == nil {
|
||||||
return nil, protocol.ErrUserMissing
|
return nil, protocol.ErrUserMissing
|
||||||
}
|
}
|
||||||
|
@ -216,8 +227,8 @@ func (v *Server) handleConnection(conn internet.Connection) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerFactory struct{}
|
func init() {
|
||||||
|
common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
func (v *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
return NewServer(ctx, config.(*ServerConfig))
|
||||||
return NewServer(rawConfig.(*ServerConfig), space, meta)
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package socks
|
package socks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"v2ray.com/core/app"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
|
@ -18,7 +21,11 @@ type Client struct {
|
||||||
meta *proxy.OutboundHandlerMeta
|
meta *proxy.OutboundHandlerMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(config *ClientConfig, space app.Space, meta *proxy.OutboundHandlerMeta) (*Client, error) {
|
func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
|
||||||
|
meta := proxy.OutboundMetaFromContext(ctx)
|
||||||
|
if meta == nil {
|
||||||
|
return nil, errors.New("Socks|Client: No outbound meta in context.")
|
||||||
|
}
|
||||||
serverList := protocol.NewServerList()
|
serverList := protocol.NewServerList()
|
||||||
for _, rec := range config.Server {
|
for _, rec := range config.Server {
|
||||||
serverList.AddServer(protocol.NewServerSpecFromPB(*rec))
|
serverList.AddServer(protocol.NewServerSpecFromPB(*rec))
|
||||||
|
@ -112,8 +119,8 @@ func (c *Client) Dispatch(destination net.Destination, ray ray.OutboundRay) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClientFactory struct{}
|
func init() {
|
||||||
|
common.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
func (ClientFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
return NewClient(ctx, config.(*ClientConfig))
|
||||||
return NewClient(rawConfig.(*ClientConfig), space, meta)
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package socks
|
package socks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/app/dispatcher"
|
"v2ray.com/core/app/dispatcher"
|
||||||
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/bufio"
|
"v2ray.com/core/common/bufio"
|
||||||
"v2ray.com/core/common/errors"
|
"v2ray.com/core/common/errors"
|
||||||
|
@ -34,7 +36,15 @@ type Server struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer creates a new Server object.
|
// NewServer creates a new Server object.
|
||||||
func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandlerMeta) *Server {
|
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
||||||
|
space := app.SpaceFromContext(ctx)
|
||||||
|
if space == nil {
|
||||||
|
return nil, errors.New("Socks|Server: No space in context.")
|
||||||
|
}
|
||||||
|
meta := proxy.InboundMetaFromContext(ctx)
|
||||||
|
if meta == nil {
|
||||||
|
return nil, errors.New("Socks|Server: No inbound meta in context.")
|
||||||
|
}
|
||||||
s := &Server{
|
s := &Server{
|
||||||
config: config,
|
config: config,
|
||||||
meta: meta,
|
meta: meta,
|
||||||
|
@ -46,7 +56,7 @@ func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandler
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return s
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Port implements InboundHandler.Port().
|
// Port implements InboundHandler.Port().
|
||||||
|
@ -181,8 +191,8 @@ func (v *Server) transport(reader io.Reader, writer io.Writer, session *proxy.Se
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerFactory struct{}
|
func init() {
|
||||||
|
common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
func (v *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
return NewServer(ctx, config.(*ServerConfig))
|
||||||
return NewServer(rawConfig.(*ServerConfig), space, meta), nil
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,2 @@
|
||||||
|
// Package socks provides implements of Socks protocol 4, 4a and 5.
|
||||||
package socks
|
package socks
|
||||||
|
|
||||||
import (
|
|
||||||
"v2ray.com/core/common"
|
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
"v2ray.com/core/proxy"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
common.Must(proxy.RegisterOutboundHandlerCreator(serial.GetMessageType((*ClientConfig)(nil)), new(ClientFactory)))
|
|
||||||
common.Must(proxy.RegisterInboundHandlerCreator(serial.GetMessageType((*ServerConfig)(nil)), new(ServerFactory)))
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/app/dispatcher"
|
"v2ray.com/core/app/dispatcher"
|
||||||
"v2ray.com/core/app/proxyman"
|
"v2ray.com/core/app/proxyman"
|
||||||
|
@ -82,6 +84,43 @@ type VMessInboundHandler struct {
|
||||||
meta *proxy.InboundHandlerMeta
|
meta *proxy.InboundHandlerMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func New(ctx context.Context, config *Config) (*VMessInboundHandler, error) {
|
||||||
|
space := app.SpaceFromContext(ctx)
|
||||||
|
if space == nil {
|
||||||
|
return nil, errors.New("VMess|Inbound: No space in context.")
|
||||||
|
}
|
||||||
|
meta := proxy.InboundMetaFromContext(ctx)
|
||||||
|
if meta == nil {
|
||||||
|
return nil, errors.New("VMess|Inbound: No inbound meta in context.")
|
||||||
|
}
|
||||||
|
|
||||||
|
allowedClients := vmess.NewTimedUserValidator(protocol.DefaultIDHash)
|
||||||
|
for _, user := range config.User {
|
||||||
|
allowedClients.Add(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
handler := &VMessInboundHandler{
|
||||||
|
clients: allowedClients,
|
||||||
|
detours: config.Detour,
|
||||||
|
usersByEmail: NewUserByEmail(config.User, config.GetDefaultValue()),
|
||||||
|
meta: meta,
|
||||||
|
}
|
||||||
|
|
||||||
|
space.OnInitialize(func() error {
|
||||||
|
handler.packetDispatcher = dispatcher.FromSpace(space)
|
||||||
|
if handler.packetDispatcher == nil {
|
||||||
|
return errors.New("VMess|Inbound: Dispatcher is not found in space.")
|
||||||
|
}
|
||||||
|
handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space)
|
||||||
|
if handler.inboundHandlerManager == nil {
|
||||||
|
return errors.New("VMess|Inbound: InboundHandlerManager is not found is space.")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return handler, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (v *VMessInboundHandler) Port() v2net.Port {
|
func (v *VMessInboundHandler) Port() v2net.Port {
|
||||||
return v.meta.Port
|
return v.meta.Port
|
||||||
}
|
}
|
||||||
|
@ -251,38 +290,8 @@ func (v *VMessInboundHandler) HandleConnection(connection internet.Connection) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Factory struct{}
|
|
||||||
|
|
||||||
func (v *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
|
||||||
config := rawConfig.(*Config)
|
|
||||||
|
|
||||||
allowedClients := vmess.NewTimedUserValidator(protocol.DefaultIDHash)
|
|
||||||
for _, user := range config.User {
|
|
||||||
allowedClients.Add(user)
|
|
||||||
}
|
|
||||||
|
|
||||||
handler := &VMessInboundHandler{
|
|
||||||
clients: allowedClients,
|
|
||||||
detours: config.Detour,
|
|
||||||
usersByEmail: NewUserByEmail(config.User, config.GetDefaultValue()),
|
|
||||||
meta: meta,
|
|
||||||
}
|
|
||||||
|
|
||||||
space.OnInitialize(func() error {
|
|
||||||
handler.packetDispatcher = dispatcher.FromSpace(space)
|
|
||||||
if handler.packetDispatcher == nil {
|
|
||||||
return errors.New("VMess|Inbound: Dispatcher is not found in space.")
|
|
||||||
}
|
|
||||||
handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space)
|
|
||||||
if handler.inboundHandlerManager == nil {
|
|
||||||
return errors.New("VMess|Inbound: InboundHandlerManager is not found is space.")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
return handler, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
common.Must(proxy.RegisterInboundHandlerCreator(serial.GetMessageType(new(Config)), new(Factory)))
|
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
|
return New(ctx, config.(*Config))
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package outbound
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
|
@ -12,7 +14,6 @@ import (
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/common/protocol"
|
"v2ray.com/core/common/protocol"
|
||||||
"v2ray.com/core/common/retry"
|
"v2ray.com/core/common/retry"
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
"v2ray.com/core/common/signal"
|
"v2ray.com/core/common/signal"
|
||||||
"v2ray.com/core/proxy"
|
"v2ray.com/core/proxy"
|
||||||
"v2ray.com/core/proxy/vmess"
|
"v2ray.com/core/proxy/vmess"
|
||||||
|
@ -28,6 +29,29 @@ type VMessOutboundHandler struct {
|
||||||
meta *proxy.OutboundHandlerMeta
|
meta *proxy.OutboundHandlerMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func New(ctx context.Context, config *Config) (*VMessOutboundHandler, error) {
|
||||||
|
space := app.SpaceFromContext(ctx)
|
||||||
|
if space == nil {
|
||||||
|
return nil, errors.New("VMess|Outbound: No space in context.")
|
||||||
|
}
|
||||||
|
meta := proxy.OutboundMetaFromContext(ctx)
|
||||||
|
if meta == nil {
|
||||||
|
return nil, errors.New("VMess|Outbound: No outbound meta in context.")
|
||||||
|
}
|
||||||
|
|
||||||
|
serverList := protocol.NewServerList()
|
||||||
|
for _, rec := range config.Receiver {
|
||||||
|
serverList.AddServer(protocol.NewServerSpecFromPB(*rec))
|
||||||
|
}
|
||||||
|
handler := &VMessOutboundHandler{
|
||||||
|
serverList: serverList,
|
||||||
|
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
|
||||||
|
meta: meta,
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Dispatch implements OutboundHandler.Dispatch().
|
// Dispatch implements OutboundHandler.Dispatch().
|
||||||
func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, outboundRay ray.OutboundRay) {
|
func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, outboundRay ray.OutboundRay) {
|
||||||
var rec *protocol.ServerSpec
|
var rec *protocol.ServerSpec
|
||||||
|
@ -142,25 +166,8 @@ func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, outboundRay ra
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Factory is a proxy factory for VMess outbound.
|
|
||||||
type Factory struct{}
|
|
||||||
|
|
||||||
func (v *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
|
||||||
vOutConfig := rawConfig.(*Config)
|
|
||||||
|
|
||||||
serverList := protocol.NewServerList()
|
|
||||||
for _, rec := range vOutConfig.Receiver {
|
|
||||||
serverList.AddServer(protocol.NewServerSpecFromPB(*rec))
|
|
||||||
}
|
|
||||||
handler := &VMessOutboundHandler{
|
|
||||||
serverList: serverList,
|
|
||||||
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
|
|
||||||
meta: meta,
|
|
||||||
}
|
|
||||||
|
|
||||||
return handler, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
common.Must(proxy.RegisterOutboundHandlerCreator(serial.GetMessageType(new(Config)), new(Factory)))
|
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||||
|
return New(ctx, config.(*Config))
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
21
v2ray.go
21
v2ray.go
|
@ -1,6 +1,8 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/app/dispatcher"
|
"v2ray.com/core/app/dispatcher"
|
||||||
"v2ray.com/core/app/dns"
|
"v2ray.com/core/app/dns"
|
||||||
|
@ -38,6 +40,8 @@ func NewPoint(pConfig *Config) (*Point, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
space := app.NewSpace()
|
space := app.NewSpace()
|
||||||
|
ctx := app.ContextWithSpace(context.Background(), space)
|
||||||
|
|
||||||
vpoint.space = space
|
vpoint.space = space
|
||||||
vpoint.space.AddAppLegacy(serial.GetMessageType((*proxyman.InboundConfig)(nil)), vpoint)
|
vpoint.space.AddAppLegacy(serial.GetMessageType((*proxyman.InboundConfig)(nil)), vpoint)
|
||||||
|
|
||||||
|
@ -94,14 +98,14 @@ func NewPoint(pConfig *Config) (*Point, error) {
|
||||||
var inboundHandler InboundDetourHandler
|
var inboundHandler InboundDetourHandler
|
||||||
switch allocConfig.Type {
|
switch allocConfig.Type {
|
||||||
case AllocationStrategy_Always:
|
case AllocationStrategy_Always:
|
||||||
dh, err := NewInboundDetourHandlerAlways(vpoint.space, inbound)
|
dh, err := NewInboundDetourHandlerAlways(ctx, inbound)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("V2Ray: Failed to create detour handler: ", err)
|
log.Error("V2Ray: Failed to create detour handler: ", err)
|
||||||
return nil, common.ErrBadConfiguration
|
return nil, common.ErrBadConfiguration
|
||||||
}
|
}
|
||||||
inboundHandler = dh
|
inboundHandler = dh
|
||||||
case AllocationStrategy_Random:
|
case AllocationStrategy_Random:
|
||||||
dh, err := NewInboundDetourHandlerDynamic(vpoint.space, inbound)
|
dh, err := NewInboundDetourHandlerDynamic(ctx, inbound)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("V2Ray: Failed to create detour handler: ", err)
|
log.Error("V2Ray: Failed to create detour handler: ", err)
|
||||||
return nil, common.ErrBadConfiguration
|
return nil, common.ErrBadConfiguration
|
||||||
|
@ -124,13 +128,12 @@ func NewPoint(pConfig *Config) (*Point, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
outboundHandler, err := proxy.CreateOutboundHandler(
|
outboundHandler, err := proxy.CreateOutboundHandler(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{
|
||||||
outbound.Settings.Type, vpoint.space, outboundSettings, &proxy.OutboundHandlerMeta{
|
Tag: outbound.Tag,
|
||||||
Tag: outbound.Tag,
|
Address: outbound.GetSendThroughValue(),
|
||||||
Address: outbound.GetSendThroughValue(),
|
StreamSettings: outbound.StreamSettings,
|
||||||
StreamSettings: outbound.StreamSettings,
|
ProxySettings: outbound.ProxySettings,
|
||||||
ProxySettings: outbound.ProxySettings,
|
}), outboundSettings)
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("V2Ray: Failed to create detour outbound connection handler: ", err)
|
log.Error("V2Ray: Failed to create detour outbound connection handler: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in New Issue