massive refactoring for interoperability

This commit is contained in:
Darien Raymond 2018-01-10 12:22:37 +01:00
parent 5a3c7fdd20
commit 292d7cc353
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
66 changed files with 1515 additions and 1200 deletions

View File

@ -1,3 +1 @@
package app
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg app -path App

View File

@ -1,4 +1,4 @@
package impl
package dispatcher
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg impl -path App,Dispatcher,Default
@ -6,10 +6,8 @@ import (
"context"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/app/router"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/net"
@ -21,31 +19,27 @@ var (
errSniffingTimeout = newError("timeout on sniffing")
)
var (
_ app.Application = (*DefaultDispatcher)(nil)
)
// DefaultDispatcher is a default implementation of Dispatcher.
type DefaultDispatcher struct {
ohm proxyman.OutboundHandlerManager
router *router.Router
ohm core.OutboundHandlerManager
router core.Router
}
// NewDefaultDispatcher create a new DefaultDispatcher.
func NewDefaultDispatcher(ctx context.Context, config *dispatcher.Config) (*DefaultDispatcher, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context")
func NewDefaultDispatcher(ctx context.Context, config *Config) (*DefaultDispatcher, error) {
v := core.FromContext(ctx)
if v == nil {
return nil, newError("V is not in context.")
}
d := &DefaultDispatcher{
ohm: v.OutboundHandlerManager(),
router: v.Router(),
}
if err := v.RegisterFeature((*core.Dispatcher)(nil), d); err != nil {
return nil, newError("unable to register Dispatcher")
}
d := &DefaultDispatcher{}
space.On(app.SpaceInitializing, func(interface{}) error {
d.ohm = proxyman.OutboundHandlerManagerFromSpace(space)
if d.ohm == nil {
return newError("OutboundHandlerManager is not found in the space")
}
d.router = router.FromSpace(space)
return nil
})
return d, nil
}
@ -57,12 +51,7 @@ func (*DefaultDispatcher) Start() error {
// Close implements app.Application.
func (*DefaultDispatcher) Close() {}
// Interface implements app.Application.
func (*DefaultDispatcher) Interface() interface{} {
return (*dispatcher.Interface)(nil)
}
// Dispatch implements Dispatcher.Interface.
// Dispatch implements core.Dispatcher.
func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destination) (ray.InboundRay, error) {
if !destination.IsValid() {
panic("Dispatcher: Invalid destination.")
@ -120,7 +109,7 @@ func snifer(ctx context.Context, sniferList []proxyman.KnownProtocols, outbound
func (d *DefaultDispatcher) routedDispatch(ctx context.Context, outbound ray.OutboundRay, destination net.Destination) {
dispatcher := d.ohm.GetDefaultHandler()
if d.router != nil {
if tag, err := d.router.TakeDetour(ctx); err == nil {
if tag, err := d.router.PickRoute(ctx); err == nil {
if handler := d.ohm.GetHandler(tag); handler != nil {
newError("taking detour [", tag, "] for [", destination, "]").WriteToLog()
dispatcher = handler
@ -135,7 +124,7 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, outbound ray.Out
}
func init() {
common.Must(common.RegisterConfig((*dispatcher.Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewDefaultDispatcher(ctx, config.(*dispatcher.Config))
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewDefaultDispatcher(ctx, config.(*Config))
}))
}

View File

@ -1,21 +1,3 @@
package dispatcher
import (
"context"
"v2ray.com/core/app"
"v2ray.com/core/common/net"
"v2ray.com/core/transport/ray"
)
// Interface dispatch a packet and possibly further network payload to its destination.
type Interface interface {
Dispatch(ctx context.Context, dest net.Destination) (ray.InboundRay, error)
}
func FromSpace(space app.Space) Interface {
if app := space.GetApplication((*Interface)(nil)); app != nil {
return app.(Interface)
}
return nil
}
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg dispatcher -path App,Dispatcher

View File

@ -0,0 +1,5 @@
package dispatcher
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App", "Dispatcher") }

View File

@ -1,7 +0,0 @@
package impl
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("App", "Dispatcher", "Default")
}

View File

@ -1,4 +1,4 @@
package impl
package dispatcher
import (
"bytes"

View File

@ -1,11 +1,10 @@
package impl_test
package dispatcher_test
import (
"testing"
. "v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/proxyman"
. "v2ray.com/core/app/dispatcher/impl"
. "v2ray.com/ext/assert"
)

View File

@ -6,7 +6,7 @@ import (
"time"
"github.com/miekg/dns"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/dice"
"v2ray.com/core/common/net"
@ -48,7 +48,7 @@ type UDPNameServer struct {
nextCleanup time.Time
}
func NewUDPNameServer(address net.Destination, dispatcher dispatcher.Interface) *UDPNameServer {
func NewUDPNameServer(address net.Destination, dispatcher core.Dispatcher) *UDPNameServer {
s := &UDPNameServer{
address: address,
requests: make(map[uint16]*PendingRequest),

View File

@ -1,6 +1,6 @@
package dns
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg server -path App,DNS,Server
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg dns -path App,DNS
import (
"context"
@ -8,8 +8,7 @@ import (
"time"
dnsmsg "github.com/miekg/dns"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/net"
)
@ -41,39 +40,38 @@ type Server struct {
}
func New(ctx context.Context, config *Config) (*Server, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context")
}
server := &Server{
records: make(map[string]*DomainRecord),
servers: make([]NameServer, len(config.NameServers)),
hosts: config.GetInternalHosts(),
}
space.On(app.SpaceInitializing, func(interface{}) error {
disp := dispatcher.FromSpace(space)
if disp == nil {
return newError("dispatcher is not found in the space")
}
for idx, destPB := range config.NameServers {
address := destPB.Address.AsAddress()
if address.Family().IsDomain() && address.Domain() == "localhost" {
server.servers[idx] = &LocalNameServer{}
} else {
dest := destPB.AsDestination()
if dest.Network == net.Network_Unknown {
dest.Network = net.Network_UDP
}
if dest.Network == net.Network_UDP {
server.servers[idx] = NewUDPNameServer(dest, disp)
}
v := core.FromContext(ctx)
if v == nil {
return nil, newError("V is not in context.")
}
if err := v.RegisterFeature((*core.DNSClient)(nil), server); err != nil {
return nil, newError("unable to register DNSClient.").Base(err)
}
for idx, destPB := range config.NameServers {
address := destPB.Address.AsAddress()
if address.Family().IsDomain() && address.Domain() == "localhost" {
server.servers[idx] = &LocalNameServer{}
} else {
dest := destPB.AsDestination()
if dest.Network == net.Network_Unknown {
dest.Network = net.Network_UDP
}
if dest.Network == net.Network_UDP {
server.servers[idx] = NewUDPNameServer(dest, v.Dispatcher())
}
}
if len(config.NameServers) == 0 {
server.servers = append(server.servers, &LocalNameServer{})
}
return nil
})
}
if len(config.NameServers) == 0 {
server.servers = append(server.servers, &LocalNameServer{})
}
return server, nil
}
@ -82,12 +80,10 @@ func (*Server) Interface() interface{} {
}
func (s *Server) Start() error {
net.RegisterIPResolver(s)
return nil
}
func (*Server) Close() {
net.RegisterIPResolver(net.SystemIPResolver())
}
func (s *Server) GetCached(domain string) []net.IP {

View File

@ -1,18 +1,14 @@
package dns_test
import (
"context"
"testing"
"v2ray.com/core/app"
"v2ray.com/core"
"v2ray.com/core/app/dispatcher"
_ "v2ray.com/core/app/dispatcher/impl"
. "v2ray.com/core/app/dns"
"v2ray.com/core/app/policy"
_ "v2ray.com/core/app/policy/manager"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/app/policy"
_ "v2ray.com/core/app/proxyman/outbound"
"v2ray.com/core/common"
"v2ray.com/core/common/net"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy/freedom"
@ -54,50 +50,50 @@ func TestUDPServer(t *testing.T) {
go dnsServer.ListenAndServe()
config := &Config{
NameServers: []*net.Endpoint{
{
Network: net.Network_UDP,
Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Ip{
Ip: []byte{127, 0, 0, 1},
config := &core.Config{
App: []*serial.TypedMessage{
serial.ToTypedMessage(&Config{
NameServers: []*net.Endpoint{
{
Network: net.Network_UDP,
Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Ip{
Ip: []byte{127, 0, 0, 1},
},
},
Port: uint32(port),
},
},
Port: uint32(port),
}),
serial.ToTypedMessage(&dispatcher.Config{}),
serial.ToTypedMessage(&proxyman.OutboundConfig{}),
serial.ToTypedMessage(&policy.Config{}),
},
Outbound: []*core.OutboundHandlerConfig{
&core.OutboundHandlerConfig{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
},
}
ctx := context.Background()
space := app.NewSpace()
v, err := core.New(config)
assert(err, IsNil)
ctx = app.ContextWithSpace(ctx, space)
common.Must(app.AddApplicationToSpace(ctx, config))
common.Must(app.AddApplicationToSpace(ctx, &dispatcher.Config{}))
common.Must(app.AddApplicationToSpace(ctx, &proxyman.OutboundConfig{}))
common.Must(app.AddApplicationToSpace(ctx, &policy.Config{}))
client := v.DNSClient()
om := proxyman.OutboundHandlerManagerFromSpace(space)
om.AddHandler(ctx, &proxyman.OutboundHandlerConfig{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
})
common.Must(space.Initialize())
common.Must(space.Start())
ips, err := net.LookupIP("google.com")
ips, err := client.LookupIP("google.com")
assert(err, IsNil)
assert(len(ips), Equals, 1)
assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})
ips, err = net.LookupIP("facebook.com")
ips, err = client.LookupIP("facebook.com")
assert(err, IsNil)
assert(len(ips), Equals, 1)
assert([]byte(ips[0]), Equals, []byte{9, 9, 9, 9})
dnsServer.Shutdown()
ips, err = net.LookupIP("google.com")
ips, err = client.LookupIP("google.com")
assert(err, IsNil)
assert(len(ips), Equals, 1)
assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})

View File

@ -2,10 +2,15 @@ package policy
import (
"time"
"v2ray.com/core"
)
// Duration converts Second to time.Duration.
func (s *Second) Duration() time.Duration {
if s == nil {
return 0
}
return time.Second * time.Duration(s.Value)
}
@ -26,3 +31,14 @@ func (p *Policy) OverrideWith(another *Policy) {
}
}
}
func (p *Policy) ToCorePolicy() core.Policy {
var cp core.Policy
if p.Timeout != nil {
cp.Timeouts.ConnectionIdle = p.Timeout.ConnectionIdle.Duration()
cp.Timeouts.Handshake = p.Timeout.Handshake.Duration()
cp.Timeouts.DownlinkOnly = p.Timeout.DownlinkOnly.Duration()
cp.Timeouts.UplinkOnly = p.Timeout.UplinkOnly.Duration()
}
return cp
}

View File

@ -1,5 +1,5 @@
package app
package policy
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App") }
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App", "Policy") }

61
app/policy/manager.go Normal file
View File

@ -0,0 +1,61 @@
package policy
import (
"context"
"v2ray.com/core"
"v2ray.com/core/common"
)
// Instance is an instance of Policy manager.
type Instance struct {
levels map[uint32]core.Policy
}
// New creates new Policy manager instance.
func New(ctx context.Context, config *Config) (*Instance, error) {
m := &Instance{
levels: make(map[uint32]core.Policy),
}
if len(config.Level) > 0 {
for lv, p := range config.Level {
dp := core.DefaultPolicy()
dp.OverrideWith(p.ToCorePolicy())
m.levels[lv] = dp
}
}
v := core.FromContext(ctx)
if v == nil {
return nil, newError("V is not in context.")
}
if err := v.RegisterFeature((*core.PolicyManager)(nil), m); err != nil {
return nil, newError("unable to register PolicyManager in core").Base(err).AtError()
}
return m, nil
}
// ForLevel implements core.PolicyManager.
func (m *Instance) ForLevel(level uint32) core.Policy {
if p, ok := m.levels[level]; ok {
return p
}
return core.DefaultPolicy()
}
// Start implements app.Application.Start().
func (m *Instance) Start() error {
return nil
}
// Close implements app.Application.Close().
func (m *Instance) Close() {
}
func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*Config))
}))
}

View File

@ -1,68 +0,0 @@
package manager
import (
"context"
"v2ray.com/core/app/policy"
"v2ray.com/core/common"
)
// Instance is an instance of Policy manager.
type Instance struct {
levels map[uint32]*policy.Policy
}
// New creates new Policy manager instance.
func New(ctx context.Context, config *policy.Config) (*Instance, error) {
levels := config.Level
if levels == nil {
levels = make(map[uint32]*policy.Policy)
}
for _, p := range levels {
g := global()
g.OverrideWith(p)
*p = g
}
return &Instance{
levels: levels,
}, nil
}
func global() policy.Policy {
return policy.Policy{
Timeout: &policy.Policy_Timeout{
Handshake: &policy.Second{Value: 4},
ConnectionIdle: &policy.Second{Value: 300},
UplinkOnly: &policy.Second{Value: 5},
DownlinkOnly: &policy.Second{Value: 30},
},
}
}
// GetPolicy implements policy.Manager.
func (m *Instance) GetPolicy(level uint32) policy.Policy {
if p, ok := m.levels[level]; ok {
return *p
}
return global()
}
// Start implements app.Application.Start().
func (m *Instance) Start() error {
return nil
}
// Close implements app.Application.Close().
func (m *Instance) Close() {
}
// Interface implement app.Application.Interface().
func (m *Instance) Interface() interface{} {
return (*policy.Manager)(nil)
}
func init() {
common.Must(common.RegisterConfig((*policy.Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*policy.Config))
}))
}

View File

@ -1,20 +1,3 @@
package policy
import (
"v2ray.com/core/app"
)
// Manager is an utility to manage policy per user level.
type Manager interface {
// GetPolicy returns the Policy for the given user level.
GetPolicy(level uint32) Policy
}
// FromSpace returns the policy.Manager in a space.
func FromSpace(space app.Space) Manager {
app := space.GetApplication((*Manager)(nil))
if app == nil {
return nil
}
return app.(Manager)
}
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg policy -path App,Policy

View File

@ -1,11 +1,5 @@
package proxyman
import (
"context"
"v2ray.com/core/proxy"
)
func (s *AllocationStrategy) GetConcurrencyValue() uint32 {
if s == nil || s.Concurrency == nil {
return 3
@ -19,14 +13,3 @@ func (s *AllocationStrategy) GetRefreshValue() uint32 {
}
return s.Refresh.Value
}
func (c *OutboundHandlerConfig) GetProxyHandler(ctx context.Context) (proxy.Outbound, error) {
if c == nil {
return nil, newError("OutboundHandlerConfig is nil")
}
config, err := c.ProxySettings.GetInstance()
if err != nil {
return nil, err
}
return proxy.CreateOutboundHandler(ctx, config)
}

View File

@ -3,7 +3,6 @@ package proxyman
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import v2ray_core_common_serial "v2ray.com/core/common/serial"
import v2ray_core_common_net "v2ray.com/core/common/net"
import v2ray_core_common_net1 "v2ray.com/core/common/net"
import v2ray_core_transport_internet "v2ray.com/core/transport/internet"
@ -211,45 +210,13 @@ func (m *ReceiverConfig) GetDomainOverride() []KnownProtocols {
return nil
}
type InboundHandlerConfig struct {
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
ReceiverSettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=receiver_settings,json=receiverSettings" json:"receiver_settings,omitempty"`
ProxySettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"`
}
func (m *InboundHandlerConfig) Reset() { *m = InboundHandlerConfig{} }
func (m *InboundHandlerConfig) String() string { return proto.CompactTextString(m) }
func (*InboundHandlerConfig) ProtoMessage() {}
func (*InboundHandlerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *InboundHandlerConfig) GetTag() string {
if m != nil {
return m.Tag
}
return ""
}
func (m *InboundHandlerConfig) GetReceiverSettings() *v2ray_core_common_serial.TypedMessage {
if m != nil {
return m.ReceiverSettings
}
return nil
}
func (m *InboundHandlerConfig) GetProxySettings() *v2ray_core_common_serial.TypedMessage {
if m != nil {
return m.ProxySettings
}
return nil
}
type OutboundConfig struct {
}
func (m *OutboundConfig) Reset() { *m = OutboundConfig{} }
func (m *OutboundConfig) String() string { return proto.CompactTextString(m) }
func (*OutboundConfig) ProtoMessage() {}
func (*OutboundConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (*OutboundConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
type SenderConfig struct {
// Send traffic through the given IP. Only IP is allowed.
@ -262,7 +229,7 @@ type SenderConfig struct {
func (m *SenderConfig) Reset() { *m = SenderConfig{} }
func (m *SenderConfig) String() string { return proto.CompactTextString(m) }
func (*SenderConfig) ProtoMessage() {}
func (*SenderConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (*SenderConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *SenderConfig) GetVia() *v2ray_core_common_net.IPOrDomain {
if m != nil {
@ -292,54 +259,6 @@ func (m *SenderConfig) GetMultiplexSettings() *MultiplexingConfig {
return nil
}
type OutboundHandlerConfig struct {
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
SenderSettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=sender_settings,json=senderSettings" json:"sender_settings,omitempty"`
ProxySettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"`
Expire int64 `protobuf:"varint,4,opt,name=expire" json:"expire,omitempty"`
Comment string `protobuf:"bytes,5,opt,name=comment" json:"comment,omitempty"`
}
func (m *OutboundHandlerConfig) Reset() { *m = OutboundHandlerConfig{} }
func (m *OutboundHandlerConfig) String() string { return proto.CompactTextString(m) }
func (*OutboundHandlerConfig) ProtoMessage() {}
func (*OutboundHandlerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *OutboundHandlerConfig) GetTag() string {
if m != nil {
return m.Tag
}
return ""
}
func (m *OutboundHandlerConfig) GetSenderSettings() *v2ray_core_common_serial.TypedMessage {
if m != nil {
return m.SenderSettings
}
return nil
}
func (m *OutboundHandlerConfig) GetProxySettings() *v2ray_core_common_serial.TypedMessage {
if m != nil {
return m.ProxySettings
}
return nil
}
func (m *OutboundHandlerConfig) GetExpire() int64 {
if m != nil {
return m.Expire
}
return 0
}
func (m *OutboundHandlerConfig) GetComment() string {
if m != nil {
return m.Comment
}
return ""
}
type MultiplexingConfig struct {
// Whether or not Mux is enabled.
Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"`
@ -350,7 +269,7 @@ type MultiplexingConfig struct {
func (m *MultiplexingConfig) Reset() { *m = MultiplexingConfig{} }
func (m *MultiplexingConfig) String() string { return proto.CompactTextString(m) }
func (*MultiplexingConfig) ProtoMessage() {}
func (*MultiplexingConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (*MultiplexingConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (m *MultiplexingConfig) GetEnabled() bool {
if m != nil {
@ -372,10 +291,8 @@ func init() {
proto.RegisterType((*AllocationStrategy_AllocationStrategyConcurrency)(nil), "v2ray.core.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency")
proto.RegisterType((*AllocationStrategy_AllocationStrategyRefresh)(nil), "v2ray.core.app.proxyman.AllocationStrategy.AllocationStrategyRefresh")
proto.RegisterType((*ReceiverConfig)(nil), "v2ray.core.app.proxyman.ReceiverConfig")
proto.RegisterType((*InboundHandlerConfig)(nil), "v2ray.core.app.proxyman.InboundHandlerConfig")
proto.RegisterType((*OutboundConfig)(nil), "v2ray.core.app.proxyman.OutboundConfig")
proto.RegisterType((*SenderConfig)(nil), "v2ray.core.app.proxyman.SenderConfig")
proto.RegisterType((*OutboundHandlerConfig)(nil), "v2ray.core.app.proxyman.OutboundHandlerConfig")
proto.RegisterType((*MultiplexingConfig)(nil), "v2ray.core.app.proxyman.MultiplexingConfig")
proto.RegisterEnum("v2ray.core.app.proxyman.KnownProtocols", KnownProtocols_name, KnownProtocols_value)
proto.RegisterEnum("v2ray.core.app.proxyman.AllocationStrategy_Type", AllocationStrategy_Type_name, AllocationStrategy_Type_value)
@ -384,57 +301,49 @@ func init() {
func init() { proto.RegisterFile("v2ray.com/core/app/proxyman/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 822 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xd1, 0x8e, 0xdb, 0x44,
0x14, 0xad, 0xe3, 0x34, 0xc9, 0xde, 0xed, 0x7a, 0xdd, 0xa1, 0xd0, 0x10, 0x40, 0x0a, 0x01, 0xd1,
0xa8, 0x20, 0xa7, 0xa4, 0xe2, 0x81, 0x27, 0x58, 0x76, 0x2b, 0x75, 0x81, 0x55, 0xcc, 0x24, 0xe2,
0xa1, 0x42, 0xb2, 0x66, 0xed, 0xa9, 0x19, 0x61, 0xcf, 0x58, 0x33, 0x93, 0x74, 0xfd, 0x4b, 0x7c,
0x05, 0x8f, 0x3c, 0xf0, 0x05, 0xfc, 0x0a, 0x2f, 0xc8, 0x9e, 0x71, 0x76, 0xb7, 0x49, 0x5a, 0x96,
0xaa, 0x6f, 0x33, 0xc9, 0x39, 0xc7, 0x73, 0xcf, 0x3d, 0x77, 0x06, 0xc6, 0xab, 0xa9, 0x24, 0x65,
0x10, 0x8b, 0x7c, 0x12, 0x0b, 0x49, 0x27, 0xa4, 0x28, 0x26, 0x85, 0x14, 0x17, 0x65, 0x4e, 0xf8,
0x24, 0x16, 0xfc, 0x39, 0x4b, 0x83, 0x42, 0x0a, 0x2d, 0xd0, 0xfd, 0x06, 0x29, 0x69, 0x40, 0x8a,
0x22, 0x68, 0x50, 0x83, 0x47, 0x2f, 0x49, 0xc4, 0x22, 0xcf, 0x05, 0x9f, 0x28, 0x2a, 0x19, 0xc9,
0x26, 0xba, 0x2c, 0x68, 0x12, 0xe5, 0x54, 0x29, 0x92, 0x52, 0x23, 0x35, 0x78, 0xb0, 0x9d, 0xc1,
0xa9, 0x9e, 0x90, 0x24, 0x91, 0x54, 0x29, 0x0b, 0xfc, 0x74, 0x37, 0xb0, 0x10, 0x52, 0x5b, 0x54,
0xf0, 0x12, 0x4a, 0x4b, 0xc2, 0x55, 0xf5, 0xff, 0x84, 0x71, 0x4d, 0x65, 0x85, 0xbe, 0x5a, 0xc9,
0xe8, 0x10, 0x0e, 0x4e, 0xf9, 0xb9, 0x58, 0xf2, 0xe4, 0xb8, 0xfe, 0x79, 0xf4, 0x87, 0x0b, 0xe8,
0x28, 0xcb, 0x44, 0x4c, 0x34, 0x13, 0x7c, 0xae, 0x25, 0xd1, 0x34, 0x2d, 0xd1, 0x09, 0xb4, 0xab,
0xd3, 0xf7, 0x9d, 0xa1, 0x33, 0xf6, 0xa6, 0x8f, 0x82, 0x1d, 0x06, 0x04, 0x9b, 0xd4, 0x60, 0x51,
0x16, 0x14, 0xd7, 0x6c, 0xf4, 0x1b, 0xec, 0xc7, 0x82, 0xc7, 0x4b, 0x29, 0x29, 0x8f, 0xcb, 0x7e,
0x6b, 0xe8, 0x8c, 0xf7, 0xa7, 0xa7, 0x37, 0x11, 0xdb, 0xfc, 0xe9, 0xf8, 0x52, 0x10, 0x5f, 0x55,
0x47, 0x11, 0x74, 0x25, 0x7d, 0x2e, 0xa9, 0xfa, 0xb5, 0xef, 0xd6, 0x1f, 0x7a, 0xf2, 0x66, 0x1f,
0xc2, 0x46, 0x0c, 0x37, 0xaa, 0x83, 0xaf, 0xe0, 0xa3, 0x57, 0x1e, 0x07, 0xdd, 0x83, 0xdb, 0x2b,
0x92, 0x2d, 0x8d, 0x6b, 0x07, 0xd8, 0x6c, 0x06, 0x5f, 0xc2, 0xfb, 0x3b, 0xc5, 0xb7, 0x53, 0x46,
0x5f, 0x40, 0xbb, 0x72, 0x11, 0x01, 0x74, 0x8e, 0xb2, 0x17, 0xa4, 0x54, 0xfe, 0xad, 0x6a, 0x8d,
0x09, 0x4f, 0x44, 0xee, 0x3b, 0xe8, 0x0e, 0xf4, 0x9e, 0x5c, 0x54, 0xed, 0x25, 0x99, 0xdf, 0x1a,
0xfd, 0xed, 0x82, 0x87, 0x69, 0x4c, 0xd9, 0x8a, 0x4a, 0xd3, 0x55, 0xf4, 0x0d, 0x40, 0x15, 0x82,
0x48, 0x12, 0x9e, 0x1a, 0xed, 0xfd, 0xe9, 0xf0, 0xaa, 0x1d, 0x26, 0x4d, 0x01, 0xa7, 0x3a, 0x08,
0x85, 0xd4, 0xb8, 0xc2, 0xe1, 0xbd, 0xa2, 0x59, 0xa2, 0xaf, 0xa1, 0x93, 0x31, 0xa5, 0x29, 0xb7,
0x4d, 0xfb, 0x78, 0x07, 0xf9, 0x34, 0x9c, 0xc9, 0x13, 0x91, 0x13, 0xc6, 0xb1, 0x25, 0xa0, 0x5f,
0xe0, 0x1d, 0xb2, 0xae, 0x37, 0x52, 0xb6, 0x60, 0xdb, 0x93, 0xcf, 0x6f, 0xd0, 0x13, 0x8c, 0xc8,
0x66, 0x30, 0x17, 0x70, 0xa8, 0xb4, 0xa4, 0x24, 0x8f, 0x14, 0xd5, 0x9a, 0xf1, 0x54, 0xf5, 0xdb,
0x9b, 0xca, 0xeb, 0x31, 0x08, 0x9a, 0x31, 0x08, 0xe6, 0x35, 0xcb, 0xf8, 0x83, 0x3d, 0xa3, 0x31,
0xb7, 0x12, 0xe8, 0x5b, 0xf8, 0x50, 0x1a, 0x07, 0x23, 0x21, 0x59, 0xca, 0x38, 0xc9, 0xa2, 0x84,
0x2a, 0xcd, 0x78, 0xfd, 0xf5, 0xfe, 0xed, 0xa1, 0x33, 0xee, 0xe1, 0x81, 0xc5, 0xcc, 0x2c, 0xe4,
0xe4, 0x12, 0x81, 0x42, 0x38, 0x4c, 0x6a, 0x1f, 0x22, 0xb1, 0xa2, 0x52, 0xb2, 0x84, 0xf6, 0xbb,
0x43, 0x77, 0xec, 0x4d, 0x1f, 0xec, 0xac, 0xf8, 0x07, 0x2e, 0x5e, 0xf0, 0xb0, 0x1a, 0xcb, 0x58,
0x64, 0x0a, 0x7b, 0x86, 0x3f, 0xb3, 0xf4, 0xef, 0xdb, 0xbd, 0x8e, 0xdf, 0x1d, 0xfd, 0xe5, 0xc0,
0x3d, 0x3b, 0xb1, 0x4f, 0x09, 0x4f, 0xb2, 0x75, 0x8b, 0x7d, 0x70, 0x35, 0x49, 0xeb, 0xde, 0xee,
0xe1, 0x6a, 0x89, 0xe6, 0x70, 0xd7, 0x1e, 0x50, 0x5e, 0x9a, 0x63, 0xda, 0xf7, 0xd9, 0x96, 0xf6,
0x99, 0x4b, 0xaa, 0x1e, 0xd7, 0xe4, 0xcc, 0xdc, 0x51, 0xd8, 0x6f, 0x04, 0xd6, 0xce, 0x9c, 0x81,
0x57, 0x1f, 0xf8, 0x52, 0xd1, 0xbd, 0x91, 0xe2, 0x41, 0xcd, 0x6e, 0xe4, 0x46, 0x3e, 0x78, 0xb3,
0xa5, 0xbe, 0x7a, 0x01, 0xfd, 0xd9, 0x82, 0x3b, 0x73, 0xca, 0x93, 0x75, 0x61, 0x8f, 0xc1, 0x5d,
0x31, 0x62, 0x43, 0xfb, 0x1f, 0x72, 0x57, 0xa1, 0xb7, 0xc5, 0xa2, 0xf5, 0xe6, 0xb1, 0xf8, 0x69,
0x47, 0xf1, 0x0f, 0x5f, 0x23, 0x1a, 0x56, 0x24, 0xab, 0x79, 0xdd, 0x00, 0xf4, 0x0c, 0x50, 0xbe,
0xcc, 0x34, 0x2b, 0x32, 0x7a, 0xf1, 0xca, 0x08, 0x5f, 0x8b, 0xca, 0x59, 0x43, 0x61, 0x3c, 0xb5,
0xba, 0x77, 0xd7, 0x32, 0x6b, 0x73, 0xff, 0x71, 0xe0, 0xdd, 0xc6, 0xdd, 0xd7, 0x85, 0x65, 0x06,
0x87, 0xaa, 0x76, 0xfd, 0xff, 0x46, 0xc5, 0x33, 0xf4, 0xb7, 0x14, 0x14, 0xf4, 0x1e, 0x74, 0xe8,
0x45, 0xc1, 0x24, 0xad, 0xbd, 0x71, 0xb1, 0xdd, 0xa1, 0x3e, 0x74, 0x2b, 0x11, 0xca, 0x75, 0x3d,
0x94, 0x7b, 0xb8, 0xd9, 0x8e, 0x42, 0x40, 0x9b, 0x36, 0x55, 0x78, 0xca, 0xc9, 0x79, 0x46, 0x93,
0xba, 0xfa, 0x1e, 0x6e, 0xb6, 0x68, 0xb8, 0xf9, 0x38, 0x1d, 0x5c, 0x7b, 0x51, 0x1e, 0x7e, 0x02,
0xde, 0xf5, 0x19, 0x45, 0x3d, 0x68, 0x3f, 0x5d, 0x2c, 0x42, 0xff, 0x16, 0xea, 0x82, 0xbb, 0xf8,
0x71, 0xee, 0x3b, 0xdf, 0x1d, 0xc3, 0x07, 0xb1, 0xc8, 0x77, 0x75, 0x2e, 0x74, 0x9e, 0xf5, 0x9a,
0xf5, 0xef, 0xad, 0xfb, 0x3f, 0x4f, 0x31, 0x29, 0x83, 0xe3, 0x0a, 0x75, 0x54, 0x14, 0x26, 0x27,
0x39, 0xe1, 0xe7, 0x9d, 0xfa, 0x75, 0x7e, 0xfc, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x25, 0xdf,
0x6a, 0xb2, 0x93, 0x08, 0x00, 0x00,
// 691 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x94, 0x5d, 0x6f, 0xd3, 0x3a,
0x1c, 0xc6, 0x97, 0xb6, 0x6b, 0x7b, 0xfe, 0x5b, 0xb3, 0x1c, 0x9f, 0x23, 0x2d, 0xa7, 0x07, 0xa4,
0x52, 0x90, 0x56, 0x0d, 0x94, 0x40, 0x27, 0x2e, 0xb8, 0x82, 0xd1, 0x4d, 0x62, 0xbc, 0xa8, 0xc1,
0xad, 0xb8, 0x98, 0x90, 0x22, 0x2f, 0xf1, 0x8a, 0x45, 0x62, 0x47, 0x8e, 0xdb, 0x2d, 0x5f, 0x89,
0x4f, 0xc1, 0x25, 0x9f, 0x81, 0x4f, 0x83, 0xf2, 0xd6, 0x75, 0xeb, 0x3a, 0x98, 0x76, 0xe7, 0xa6,
0xcf, 0xf3, 0xb3, 0xfd, 0x3c, 0xb6, 0xa1, 0x37, 0xeb, 0x4b, 0x92, 0x58, 0x9e, 0x08, 0x6d, 0x4f,
0x48, 0x6a, 0x93, 0x28, 0xb2, 0x23, 0x29, 0xce, 0x93, 0x90, 0x70, 0xdb, 0x13, 0xfc, 0x94, 0x4d,
0xac, 0x48, 0x0a, 0x25, 0xd0, 0x76, 0xa9, 0x94, 0xd4, 0x22, 0x51, 0x64, 0x95, 0xaa, 0xf6, 0xce,
0x15, 0x84, 0x27, 0xc2, 0x50, 0x70, 0x9b, 0x53, 0x65, 0x13, 0xdf, 0x97, 0x34, 0x8e, 0x73, 0x42,
0xfb, 0xd1, 0x6a, 0x61, 0x24, 0xa4, 0x2a, 0x54, 0xd6, 0x15, 0x95, 0x92, 0x84, 0xc7, 0xe9, 0xff,
0x36, 0xe3, 0x8a, 0xca, 0x54, 0xbd, 0xb8, 0xae, 0xee, 0x16, 0xb4, 0x8e, 0xf8, 0x89, 0x98, 0x72,
0x7f, 0x90, 0x7d, 0xee, 0x7e, 0xaf, 0x02, 0xda, 0x0f, 0x02, 0xe1, 0x11, 0xc5, 0x04, 0x1f, 0x29,
0x49, 0x14, 0x9d, 0x24, 0xe8, 0x00, 0x6a, 0x2a, 0x89, 0xa8, 0xa9, 0x75, 0xb4, 0x9e, 0xde, 0x7f,
0x6a, 0xad, 0xd8, 0x8e, 0xb5, 0x6c, 0xb5, 0xc6, 0x49, 0x44, 0x71, 0xe6, 0x46, 0x5f, 0x61, 0xc3,
0x13, 0xdc, 0x9b, 0x4a, 0x49, 0xb9, 0x97, 0x98, 0x95, 0x8e, 0xd6, 0xdb, 0xe8, 0x1f, 0xdd, 0x06,
0xb6, 0xfc, 0x69, 0x70, 0x01, 0xc4, 0x8b, 0x74, 0xe4, 0x42, 0x43, 0xd2, 0x53, 0x49, 0xe3, 0x2f,
0x66, 0x35, 0x9b, 0xe8, 0xf0, 0x6e, 0x13, 0xe1, 0x1c, 0x86, 0x4b, 0x6a, 0xfb, 0x39, 0xdc, 0xbf,
0x71, 0x39, 0xe8, 0x5f, 0x58, 0x9f, 0x91, 0x60, 0x9a, 0xa7, 0xd6, 0xc2, 0xf9, 0x8f, 0xf6, 0x33,
0xf8, 0x6f, 0x25, 0xfc, 0x7a, 0x4b, 0xf7, 0x09, 0xd4, 0xd2, 0x14, 0x11, 0x40, 0x7d, 0x3f, 0x38,
0x23, 0x49, 0x6c, 0xac, 0xa5, 0x63, 0x4c, 0xb8, 0x2f, 0x42, 0x43, 0x43, 0x9b, 0xd0, 0x3c, 0x3c,
0x4f, 0xeb, 0x25, 0x81, 0x51, 0xe9, 0xfe, 0xac, 0x82, 0x8e, 0xa9, 0x47, 0xd9, 0x8c, 0xca, 0xbc,
0x55, 0xf4, 0x12, 0x20, 0x3d, 0x04, 0xae, 0x24, 0x7c, 0x92, 0xb3, 0x37, 0xfa, 0x9d, 0xc5, 0x38,
0xf2, 0xd3, 0x64, 0x71, 0xaa, 0x2c, 0x47, 0x48, 0x85, 0x53, 0x1d, 0xfe, 0x2b, 0x2a, 0x87, 0xe8,
0x05, 0xd4, 0x03, 0x16, 0x2b, 0xca, 0x8b, 0xd2, 0x1e, 0xac, 0x30, 0x1f, 0x39, 0x43, 0x79, 0x20,
0x42, 0xc2, 0x38, 0x2e, 0x0c, 0xe8, 0x33, 0xfc, 0x43, 0xe6, 0xfb, 0x75, 0xe3, 0x62, 0xc3, 0x45,
0x27, 0x8f, 0x6f, 0xd1, 0x09, 0x46, 0x64, 0xf9, 0x60, 0x8e, 0x61, 0x2b, 0x56, 0x92, 0x92, 0xd0,
0x8d, 0xa9, 0x52, 0x8c, 0x4f, 0x62, 0xb3, 0xb6, 0x4c, 0x9e, 0x5f, 0x03, 0xab, 0xbc, 0x06, 0xd6,
0x28, 0x73, 0xe5, 0xf9, 0x60, 0x3d, 0x67, 0x8c, 0x0a, 0x04, 0x7a, 0x05, 0xf7, 0x64, 0x9e, 0xa0,
0x2b, 0x24, 0x9b, 0x30, 0x4e, 0x02, 0xd7, 0xa7, 0xb1, 0x62, 0x3c, 0x9b, 0xdd, 0x5c, 0xef, 0x68,
0xbd, 0x26, 0x6e, 0x17, 0x9a, 0x61, 0x21, 0x39, 0xb8, 0x50, 0x20, 0x07, 0xb6, 0xfc, 0x2c, 0x07,
0x57, 0xcc, 0xa8, 0x94, 0xcc, 0xa7, 0x66, 0xa3, 0x53, 0xed, 0xe9, 0xfd, 0x9d, 0x95, 0x3b, 0x7e,
0xc7, 0xc5, 0x19, 0x77, 0xd2, 0x6b, 0xe9, 0x89, 0x20, 0xc6, 0x7a, 0xee, 0x1f, 0x16, 0xf6, 0xb7,
0xb5, 0x66, 0xdd, 0x68, 0x74, 0x0d, 0xd0, 0x87, 0x53, 0xb5, 0x78, 0x63, 0x7f, 0x54, 0x60, 0x73,
0x44, 0xb9, 0x3f, 0x2f, 0x7b, 0x0f, 0xaa, 0x33, 0x46, 0x8a, 0x96, 0xff, 0xa0, 0xa8, 0x54, 0x7d,
0x5d, 0x8e, 0x95, 0xbb, 0xe7, 0xf8, 0x11, 0xf4, 0x6c, 0x7b, 0x17, 0xd0, 0xbc, 0xf6, 0xdd, 0xdf,
0x40, 0x9d, 0xd4, 0x54, 0x30, 0x5b, 0x19, 0x61, 0x8e, 0x3c, 0x06, 0x14, 0x4e, 0x03, 0xc5, 0xa2,
0x80, 0x9e, 0xdf, 0xd8, 0xf9, 0xa5, 0x6c, 0x3f, 0x94, 0x16, 0xc6, 0x27, 0x05, 0xf7, 0xef, 0x39,
0xa6, 0x64, 0x77, 0x1d, 0x40, 0xcb, 0x42, 0x64, 0x42, 0x83, 0x72, 0x72, 0x12, 0x50, 0x3f, 0xcb,
0xb4, 0x89, 0xcb, 0x9f, 0xa8, 0xb3, 0xfc, 0x9e, 0xb5, 0x2e, 0x3d, 0x42, 0xbb, 0x0f, 0x41, 0xbf,
0x5c, 0x2b, 0x6a, 0x42, 0xed, 0xcd, 0x78, 0xec, 0x18, 0x6b, 0xa8, 0x01, 0xd5, 0xf1, 0xfb, 0x91,
0xa1, 0xbd, 0x1e, 0xc0, 0xff, 0x9e, 0x08, 0x57, 0xad, 0xdd, 0xd1, 0x8e, 0x9b, 0xe5, 0xf8, 0x5b,
0x65, 0xfb, 0x53, 0x1f, 0x93, 0xc4, 0x1a, 0xa4, 0xaa, 0xfd, 0x28, 0xca, 0x93, 0x0a, 0x09, 0x3f,
0xa9, 0x67, 0x0f, 0xfa, 0xde, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x77, 0x7f, 0xdc, 0x8e, 0x94,
0x06, 0x00, 0x00,
}

View File

@ -6,7 +6,6 @@ option go_package = "proxyman";
option java_package = "com.v2ray.core.app.proxyman";
option java_multiple_files = true;
import "v2ray.com/core/common/serial/typed_message.proto";
import "v2ray.com/core/common/net/address.proto";
import "v2ray.com/core/common/net/port.proto";
import "v2ray.com/core/transport/internet/config.proto";
@ -61,15 +60,6 @@ message ReceiverConfig {
repeated KnownProtocols domain_override = 7;
}
message InboundHandlerConfig {
// Tag of the inbound handler.
string tag = 1;
// Settings for how this inbound proxy is handled. Must be ReceiverConfig above.
v2ray.core.common.serial.TypedMessage receiver_settings = 2;
// Settings for inbound proxy. Must be one of the inbound proxies.
v2ray.core.common.serial.TypedMessage proxy_settings = 3;
}
message OutboundConfig {
}
@ -82,19 +72,6 @@ message SenderConfig {
MultiplexingConfig multiplex_settings = 4;
}
message OutboundHandlerConfig {
// Tag of this outbound handler.
string tag = 1;
// Settings for how to dial connection for this outbound handler. Must be SenderConfig above.
v2ray.core.common.serial.TypedMessage sender_settings = 2;
// Settings for this outbound proxy. Must be one of the outbound proxies.
v2ray.core.common.serial.TypedMessage proxy_settings = 3;
// If not zero, this outbound will be expired in seconds. Not used for now.
int64 expire = 4;
// Comment of this outbound handler. Not used for now.
string comment = 5;
}
message MultiplexingConfig {
// Whether or not Mux is enabled.
bool enabled = 1;

View File

@ -2,6 +2,4 @@ package proxyman
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("App", "Proxyman")
}
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App", "Proxyman") }

View File

@ -14,6 +14,7 @@ type AlwaysOnInboundHandler struct {
proxy proxy.Inbound
workers []worker
mux *mux.Server
tag string
}
func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *proxyman.ReceiverConfig, proxyConfig interface{}) (*AlwaysOnInboundHandler, error) {
@ -25,6 +26,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
h := &AlwaysOnInboundHandler{
proxy: p,
mux: mux.NewServer(ctx),
tag: tag,
}
nl := p.Network()
@ -80,10 +82,14 @@ func (h *AlwaysOnInboundHandler) Close() {
}
}
func (h *AlwaysOnInboundHandler) GetRandomInboundProxy() (proxy.Inbound, net.Port, int) {
func (h *AlwaysOnInboundHandler) GetRandomInboundProxy() (interface{}, net.Port, int) {
if len(h.workers) == 0 {
return nil, 0, 0
}
w := h.workers[dice.Roll(len(h.workers))]
return w.Proxy(), w.Port(), 9999
}
func (h *AlwaysOnInboundHandler) Tag() string {
return h.tag
}

View File

@ -163,7 +163,7 @@ func (h *DynamicInboundHandler) Close() {
h.cancel()
}
func (h *DynamicInboundHandler) GetRandomInboundProxy() (proxy.Inbound, net.Port, int) {
func (h *DynamicInboundHandler) GetRandomInboundProxy() (interface{}, net.Port, int) {
h.workerMutex.RLock()
defer h.workerMutex.RUnlock()
@ -174,3 +174,7 @@ func (h *DynamicInboundHandler) GetRandomInboundProxy() (proxy.Inbound, net.Port
expire := h.receiverConfig.AllocationStrategy.GetRefreshValue() - uint32(time.Since(h.lastRefresh)/time.Minute)
return w.Proxy(), w.Port(), int(expire)
}
func (h *DynamicInboundHandler) Tag() string {
return h.tag
}

View File

@ -5,64 +5,41 @@ package inbound
import (
"context"
"v2ray.com/core"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common"
)
// Manager is to manage all inbound handlers.
type Manager struct {
handlers []proxyman.InboundHandler
taggedHandlers map[string]proxyman.InboundHandler
handlers []core.InboundHandler
taggedHandlers map[string]core.InboundHandler
}
func New(ctx context.Context, config *proxyman.InboundConfig) (*Manager, error) {
return &Manager{
taggedHandlers: make(map[string]proxyman.InboundHandler),
}, nil
m := &Manager{
taggedHandlers: make(map[string]core.InboundHandler),
}
v := core.FromContext(ctx)
if v == nil {
return nil, newError("V is not in context")
}
if err := v.RegisterFeature((*core.InboundHandlerManager)(nil), m); err != nil {
return nil, newError("unable to register InboundHandlerManager").Base(err)
}
return m, nil
}
func (m *Manager) AddHandler(ctx context.Context, config *proxyman.InboundHandlerConfig) error {
rawReceiverSettings, err := config.ReceiverSettings.GetInstance()
if err != nil {
return err
}
receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig)
if !ok {
return newError("not a ReceiverConfig").AtError()
}
proxySettings, err := config.ProxySettings.GetInstance()
if err != nil {
return err
}
var handler proxyman.InboundHandler
tag := config.Tag
allocStrategy := receiverSettings.AllocationStrategy
if allocStrategy == nil || allocStrategy.Type == proxyman.AllocationStrategy_Always {
h, err := NewAlwaysOnInboundHandler(ctx, tag, receiverSettings, proxySettings)
if err != nil {
return err
}
handler = h
} else if allocStrategy.Type == proxyman.AllocationStrategy_Random {
h, err := NewDynamicInboundHandler(ctx, tag, receiverSettings, proxySettings)
if err != nil {
return err
}
handler = h
}
if handler == nil {
return newError("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type).AtError()
}
func (m *Manager) AddHandler(ctx context.Context, handler core.InboundHandler) error {
m.handlers = append(m.handlers, handler)
tag := handler.Tag()
if len(tag) > 0 {
m.taggedHandlers[tag] = handler
}
return nil
}
func (m *Manager) GetHandler(ctx context.Context, tag string) (proxyman.InboundHandler, error) {
func (m *Manager) GetHandler(ctx context.Context, tag string) (core.InboundHandler, error) {
handler, found := m.taggedHandlers[tag]
if !found {
return nil, newError("handler not found: ", tag)
@ -85,12 +62,36 @@ func (m *Manager) Close() {
}
}
func (m *Manager) Interface() interface{} {
return (*proxyman.InboundHandlerManager)(nil)
func NewHandler(ctx context.Context, config *core.InboundHandlerConfig) (core.InboundHandler, error) {
rawReceiverSettings, err := config.ReceiverSettings.GetInstance()
if err != nil {
return nil, err
}
receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig)
if !ok {
return nil, newError("not a ReceiverConfig").AtError()
}
proxySettings, err := config.ProxySettings.GetInstance()
if err != nil {
return nil, err
}
tag := config.Tag
allocStrategy := receiverSettings.AllocationStrategy
if allocStrategy == nil || allocStrategy.Type == proxyman.AllocationStrategy_Always {
return NewAlwaysOnInboundHandler(ctx, tag, receiverSettings, proxySettings)
}
if allocStrategy.Type == proxyman.AllocationStrategy_Random {
return NewDynamicInboundHandler(ctx, tag, receiverSettings, proxySettings)
}
return nil, newError("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type).AtError()
}
func init() {
common.Must(common.RegisterConfig((*proxyman.InboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*proxyman.InboundConfig))
}))
common.Must(common.RegisterConfig((*core.InboundHandlerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewHandler(ctx, config.(*core.InboundHandlerConfig))
}))
}

View File

@ -7,7 +7,7 @@ import (
"sync/atomic"
"time"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/net"
@ -31,7 +31,7 @@ type tcpWorker struct {
stream *internet.StreamConfig
recvOrigDest bool
tag string
dispatcher dispatcher.Interface
dispatcher core.Dispatcher
sniffers []proxyman.KnownProtocols
ctx context.Context
@ -185,7 +185,7 @@ type udpWorker struct {
port net.Port
recvOrigDest bool
tag string
dispatcher dispatcher.Interface
dispatcher core.Dispatcher
ctx context.Context
cancel context.CancelFunc

View File

@ -8,8 +8,7 @@ import (
"sync"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
@ -262,21 +261,14 @@ func (m *Client) fetchOutput() {
}
type Server struct {
dispatcher dispatcher.Interface
dispatcher core.Dispatcher
}
// NewServer creates a new mux.Server.
func NewServer(ctx context.Context) *Server {
s := &Server{}
space := app.SpaceFromContext(ctx)
space.On(app.SpaceInitializing, func(interface{}) error {
d := dispatcher.FromSpace(space)
if d == nil {
return newError("no dispatcher in space")
}
s.dispatcher = d
return nil
})
s := &Server{
dispatcher: core.FromContext(ctx).Dispatcher(),
}
return s
}
@ -295,8 +287,15 @@ func (s *Server) Dispatch(ctx context.Context, dest net.Destination) (ray.Inboun
return ray, nil
}
func (s *Server) Start() error {
return nil
}
func (s *Server) Close() {
}
type ServerWorker struct {
dispatcher dispatcher.Interface
dispatcher core.Dispatcher
outboundRay ray.OutboundRay
sessionManager *SessionManager
}

View File

@ -5,7 +5,7 @@ import (
"io"
"time"
"v2ray.com/core/app"
"v2ray.com/core"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/app/proxyman/mux"
"v2ray.com/core/common/buf"
@ -17,29 +17,22 @@ import (
)
type Handler struct {
config *proxyman.OutboundHandlerConfig
config *core.OutboundHandlerConfig
senderSettings *proxyman.SenderConfig
proxy proxy.Outbound
outboundManager proxyman.OutboundHandlerManager
outboundManager core.OutboundHandlerManager
mux *mux.ClientManager
}
func NewHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) (*Handler, error) {
func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (*Handler, error) {
v := core.FromContext(ctx)
if v == nil {
return nil, newError("V is not in context")
}
h := &Handler{
config: config,
config: config,
outboundManager: v.OutboundHandlerManager(),
}
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context")
}
space.On(app.SpaceInitializing, func(interface{}) error {
ohm := proxyman.OutboundHandlerManagerFromSpace(space)
if ohm == nil {
return newError("no OutboundManager in space")
}
h.outboundManager = ohm
return nil
})
if config.SenderSettings != nil {
senderSettings, err := config.SenderSettings.GetInstance()
@ -54,7 +47,12 @@ func NewHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) (*H
}
}
proxyHandler, err := config.GetProxyHandler(ctx)
proxyConfig, err := config.ProxySettings.GetInstance()
if err != nil {
return nil, err
}
proxyHandler, err := proxy.CreateOutboundHandler(ctx, proxyConfig)
if err != nil {
return nil, err
}
@ -71,6 +69,10 @@ func NewHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) (*H
return h, nil
}
func (h *Handler) Tag() string {
return h.config.Tag
}
// Dispatch implements proxy.Outbound.Dispatch.
func (h *Handler) Dispatch(ctx context.Context, outboundRay ray.OutboundRay) {
if h.mux != nil {

View File

@ -0,0 +1,15 @@
package outbound_test
import (
"testing"
"v2ray.com/core"
. "v2ray.com/core/app/proxyman/outbound"
. "v2ray.com/ext/assert"
)
func TestInterfaces(t *testing.T) {
assert := With(t)
assert((*Handler)(nil), Implements, (*core.OutboundHandler)(nil))
}

View File

@ -6,6 +6,7 @@ import (
"context"
"sync"
"v2ray.com/core"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common"
)
@ -13,20 +14,23 @@ import (
// Manager is to manage all outbound handlers.
type Manager struct {
sync.RWMutex
defaultHandler *Handler
taggedHandler map[string]*Handler
defaultHandler core.OutboundHandler
taggedHandler map[string]core.OutboundHandler
}
// New creates a new Manager.
func New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager, error) {
return &Manager{
taggedHandler: make(map[string]*Handler),
}, nil
}
// Interface implements Application.Interface.
func (*Manager) Interface() interface{} {
return (*proxyman.OutboundHandlerManager)(nil)
m := &Manager{
taggedHandler: make(map[string]core.OutboundHandler),
}
v := core.FromContext(ctx)
if v == nil {
return nil, newError("V is not in context")
}
if err := v.RegisterFeature((*core.OutboundHandlerManager)(nil), m); err != nil {
return nil, newError("unable to register OutboundHandlerManager").Base(err)
}
return m, nil
}
// Start implements Application.Start
@ -35,7 +39,7 @@ func (*Manager) Start() error { return nil }
// Close implements Application.Close
func (*Manager) Close() {}
func (m *Manager) GetDefaultHandler() proxyman.OutboundHandler {
func (m *Manager) GetDefaultHandler() core.OutboundHandler {
m.RLock()
defer m.RUnlock()
if m.defaultHandler == nil {
@ -44,7 +48,7 @@ func (m *Manager) GetDefaultHandler() proxyman.OutboundHandler {
return m.defaultHandler
}
func (m *Manager) GetHandler(tag string) proxyman.OutboundHandler {
func (m *Manager) GetHandler(tag string) core.OutboundHandler {
m.RLock()
defer m.RUnlock()
if handler, found := m.taggedHandler[tag]; found {
@ -53,20 +57,17 @@ func (m *Manager) GetHandler(tag string) proxyman.OutboundHandler {
return nil
}
func (m *Manager) AddHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) error {
func (m *Manager) AddHandler(ctx context.Context, handler core.OutboundHandler) error {
m.Lock()
defer m.Unlock()
handler, err := NewHandler(ctx, config)
if err != nil {
return err
}
if m.defaultHandler == nil {
m.defaultHandler = handler
}
if len(config.Tag) > 0 {
m.taggedHandler[config.Tag] = handler
tag := handler.Tag()
if len(tag) > 0 {
m.taggedHandler[tag] = handler
}
return nil
@ -76,4 +77,7 @@ func init() {
common.Must(common.RegisterConfig((*proxyman.OutboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*proxyman.OutboundConfig))
}))
common.Must(common.RegisterConfig((*core.OutboundHandlerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewHandler(ctx, config.(*core.OutboundHandlerConfig))
}))
}

View File

@ -5,52 +5,8 @@ package proxyman
import (
"context"
"v2ray.com/core/app"
"v2ray.com/core/common/net"
"v2ray.com/core/proxy"
"v2ray.com/core/transport/ray"
)
type InboundHandlerManager interface {
GetHandler(ctx context.Context, tag string) (InboundHandler, error)
AddHandler(ctx context.Context, config *InboundHandlerConfig) error
}
type InboundHandler interface {
Start() error
Close()
// For migration
GetRandomInboundProxy() (proxy.Inbound, net.Port, int)
}
type OutboundHandlerManager interface {
GetHandler(tag string) OutboundHandler
GetDefaultHandler() OutboundHandler
AddHandler(ctx context.Context, config *OutboundHandlerConfig) error
}
type OutboundHandler interface {
Dispatch(ctx context.Context, outboundRay ray.OutboundRay)
}
func InboundHandlerManagerFromSpace(space app.Space) InboundHandlerManager {
app := space.GetApplication((*InboundHandlerManager)(nil))
if app == nil {
return nil
}
return app.(InboundHandlerManager)
}
func OutboundHandlerManagerFromSpace(space app.Space) OutboundHandlerManager {
app := space.GetApplication((*OutboundHandlerManager)(nil))
if app == nil {
return nil
}
return app.(OutboundHandlerManager)
}
type key int
const (

View File

@ -5,46 +5,47 @@ package router
import (
"context"
"v2ray.com/core/app"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/net"
"v2ray.com/core/proxy"
)
var (
ErrNoRuleApplicable = newError("No rule applicable")
)
type Router struct {
domainStrategy Config_DomainStrategy
rules []Rule
dns core.DNSClient
}
func NewRouter(ctx context.Context, config *Config) (*Router, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context")
v := core.FromContext(ctx)
if v == nil {
return nil, newError("V is not in context")
}
r := &Router{
domainStrategy: config.DomainStrategy,
rules: make([]Rule, len(config.Rule)),
dns: v.DNSClient(),
}
space.On(app.SpaceInitializing, func(interface{}) error {
for idx, rule := range config.Rule {
r.rules[idx].Tag = rule.Tag
cond, err := rule.BuildCondition()
if err != nil {
return err
}
r.rules[idx].Condition = cond
for idx, rule := range config.Rule {
r.rules[idx].Tag = rule.Tag
cond, err := rule.BuildCondition()
if err != nil {
return nil, err
}
return nil
})
r.rules[idx].Condition = cond
}
if err := v.RegisterFeature((*core.Router)(nil), r); err != nil {
return nil, newError("unable to register Router").Base(err)
}
return r, nil
}
type ipResolver struct {
dns core.DNSClient
ip []net.Address
domain string
resolved bool
@ -57,7 +58,7 @@ func (r *ipResolver) Resolve() []net.Address {
newError("looking for IP for domain: ", r.domain).WriteToLog()
r.resolved = true
ips, err := net.LookupIP(r.domain)
ips, err := r.dns.LookupIP(r.domain)
if err != nil {
newError("failed to get IP address").Base(err).WriteToLog()
}
@ -71,8 +72,10 @@ func (r *ipResolver) Resolve() []net.Address {
return r.ip
}
func (r *Router) TakeDetour(ctx context.Context) (string, error) {
resolver := &ipResolver{}
func (r *Router) PickRoute(ctx context.Context) (string, error) {
resolver := &ipResolver{
dns: r.dns,
}
if r.domainStrategy == Config_IpOnDemand {
if dest, ok := proxy.TargetFromContext(ctx); ok && dest.Address.Family().IsDomain() {
resolver.domain = dest.Address.Domain()
@ -88,7 +91,7 @@ func (r *Router) TakeDetour(ctx context.Context) (string, error) {
dest, ok := proxy.TargetFromContext(ctx)
if !ok {
return "", ErrNoRuleApplicable
return "", core.ErrNoClue
}
if r.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() {
@ -104,11 +107,7 @@ func (r *Router) TakeDetour(ctx context.Context) (string, error) {
}
}
return "", ErrNoRuleApplicable
}
func (*Router) Interface() interface{} {
return (*Router)(nil)
return "", core.ErrNoClue
}
func (*Router) Start() error {
@ -117,14 +116,6 @@ func (*Router) Start() error {
func (*Router) Close() {}
func FromSpace(space app.Space) *Router {
app := space.GetApplication((*Router)(nil))
if app == nil {
return nil
}
return app.(*Router)
}
func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewRouter(ctx, config.(*Config))

View File

@ -4,13 +4,14 @@ import (
"context"
"testing"
"v2ray.com/core/app"
"v2ray.com/core"
"v2ray.com/core/app/dispatcher"
_ "v2ray.com/core/app/dispatcher/impl"
"v2ray.com/core/app/proxyman"
_ "v2ray.com/core/app/proxyman/outbound"
. "v2ray.com/core/app/router"
"v2ray.com/core/common"
"v2ray.com/core/common/net"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy"
. "v2ray.com/ext/assert"
)
@ -18,28 +19,30 @@ import (
func TestSimpleRouter(t *testing.T) {
assert := With(t)
config := &Config{
Rule: []*RoutingRule{
{
Tag: "test",
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_TCP},
config := &core.Config{
App: []*serial.TypedMessage{
serial.ToTypedMessage(&Config{
Rule: []*RoutingRule{
{
Tag: "test",
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_TCP},
},
},
},
},
}),
serial.ToTypedMessage(&dispatcher.Config{}),
serial.ToTypedMessage(&proxyman.OutboundConfig{}),
},
}
space := app.NewSpace()
ctx := app.ContextWithSpace(context.Background(), space)
assert(app.AddApplicationToSpace(ctx, new(dispatcher.Config)), IsNil)
assert(app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig)), IsNil)
assert(app.AddApplicationToSpace(ctx, config), IsNil)
assert(space.Initialize(), IsNil)
v, err := core.New(config)
common.Must(err)
r := FromSpace(space)
r := v.Router()
ctx = proxy.ContextWithTarget(ctx, net.TCPDestination(net.DomainAddress("v2ray.com"), 80))
tag, err := r.TakeDetour(ctx)
ctx := proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("v2ray.com"), 80))
tag, err := r.PickRoute(ctx)
assert(err, IsNil)
assert(tag, Equals, "test")
}

View File

@ -1,132 +0,0 @@
package app
import (
"context"
"reflect"
"v2ray.com/core/common"
"v2ray.com/core/common/event"
)
// Application is a component that runs in Space.
type Application interface {
Interface() interface{}
Start() error
Close()
}
// CreateAppFromConfig creates an Application based on its config. Application must have been registered.
func CreateAppFromConfig(ctx context.Context, config interface{}) (Application, error) {
application, err := common.CreateObject(ctx, config)
if err != nil {
return nil, err
}
switch a := application.(type) {
case Application:
return a, nil
default:
return nil, newError("not an application")
}
}
// A Space contains all apps that may be available in a V2Ray runtime.
type Space interface {
event.Registry
GetApplication(appInterface interface{}) Application
AddApplication(application Application) error
Initialize() error
Start() error
Close()
}
const (
// SpaceInitializing is an event to be fired when Space is being initialized.
SpaceInitializing event.Event = iota
)
type spaceImpl struct {
event.Listener
cache map[reflect.Type]Application
initialized bool
}
// NewSpace creates a new Space.
func NewSpace() Space {
return &spaceImpl{
cache: make(map[reflect.Type]Application),
}
}
func (s *spaceImpl) On(e event.Event, h event.Handler) {
if e == SpaceInitializing && s.initialized {
_ = h(nil) // Ignore error
return
}
s.Listener.On(e, h)
}
func (s *spaceImpl) Initialize() error {
if s.initialized {
return nil
}
s.initialized = true
return s.Fire(SpaceInitializing, nil)
}
func (s *spaceImpl) GetApplication(appInterface interface{}) Application {
if s == nil {
return nil
}
appType := reflect.TypeOf(appInterface)
return s.cache[appType]
}
func (s *spaceImpl) AddApplication(app Application) error {
if s == nil {
return newError("nil space").AtError()
}
appType := reflect.TypeOf(app.Interface())
s.cache[appType] = app
return nil
}
func (s *spaceImpl) Start() error {
for _, app := range s.cache {
if err := app.Start(); err != nil {
return err
}
}
return nil
}
func (s *spaceImpl) Close() {
for _, app := range s.cache {
app.Close()
}
}
type contextKey int
const (
spaceKey = contextKey(0)
)
func AddApplicationToSpace(ctx context.Context, appConfig interface{}) error {
space := SpaceFromContext(ctx)
if space == nil {
return newError("no space in context").AtError()
}
application, err := CreateAppFromConfig(ctx, appConfig)
if err != nil {
return err
}
return space.AddApplication(application)
}
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)
}

10
common/interfaces.go Normal file
View File

@ -0,0 +1,10 @@
package common
// Runnable is the interface for objects that can start to work and stop on demand.
type Runnable interface {
// Start starts the runnable object. Upon the method returning nil, the object begins to function properly.
Start() error
// Close stops the object being working.
Close()
}

View File

@ -14,7 +14,7 @@ var _ = math.Inf
type User struct {
Level uint32 `protobuf:"varint,1,opt,name=level" json:"level,omitempty"`
Email string `protobuf:"bytes,2,opt,name=email" json:"email,omitempty"`
// Protocol specific account information.
// Protocol specific account information. Must be the account proto in one of the proxies.
Account *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=account" json:"account,omitempty"`
}

View File

@ -0,0 +1,12 @@
package router
import (
"context"
"v2ray.com/core/common/net"
"v2ray.com/core/transport/ray"
)
type Dispatcher interface {
Dispatch(ctx context.Context, dest net.Destination) (ray.InboundRay, error)
}

53
common/router/router.go Normal file
View File

@ -0,0 +1,53 @@
package router
import (
"context"
"sync"
)
type Router interface {
Pick(ctx context.Context) (string, bool)
}
type defaultRouter byte
func (defaultRouter) Pick(ctx context.Context) (string, bool) {
return "", false
}
type syncRouter struct {
sync.RWMutex
Router
}
func (r *syncRouter) Pick(ctx context.Context) (string, bool) {
r.RLock()
defer r.RUnlock()
return r.Router.Pick(ctx)
}
func (r *syncRouter) Set(router Router) {
r.Lock()
defer r.Unlock()
r.Router = router
}
var (
routerInstance = &syncRouter{
Router: defaultRouter(0),
}
)
func RegisterRouter(router Router) {
if router == nil {
panic("Router is nil.")
}
routerInstance.Set(router)
}
func Pick(ctx context.Context) (string, bool) {
return routerInstance.Router.Pick(ctx)
}

View File

@ -3,7 +3,6 @@ package core
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import v2ray_core_app_proxyman "v2ray.com/core/app/proxyman"
import v2ray_core_common_serial "v2ray.com/core/common/serial"
import v2ray_core_transport "v2ray.com/core/transport"
@ -40,12 +39,12 @@ func (x ConfigFormat) String() string {
}
func (ConfigFormat) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
// Master config of V2Ray. V2Ray Core takes this config as input and functions accordingly.
// Master config of V2Ray. V2Ray takes this config as input and functions accordingly.
type Config struct {
// Inbound handler configurations. Must have at least one item.
Inbound []*v2ray_core_app_proxyman.InboundHandlerConfig `protobuf:"bytes,1,rep,name=inbound" json:"inbound,omitempty"`
Inbound []*InboundHandlerConfig `protobuf:"bytes,1,rep,name=inbound" json:"inbound,omitempty"`
// Outbound handler configurations. Must have at least one item. The first item is used as default for routing.
Outbound []*v2ray_core_app_proxyman.OutboundHandlerConfig `protobuf:"bytes,2,rep,name=outbound" json:"outbound,omitempty"`
Outbound []*OutboundHandlerConfig `protobuf:"bytes,2,rep,name=outbound" json:"outbound,omitempty"`
// App configuration. Must be one in the app directory.
App []*v2ray_core_common_serial.TypedMessage `protobuf:"bytes,4,rep,name=app" json:"app,omitempty"`
// Transport settings.
@ -60,14 +59,14 @@ func (m *Config) String() string { return proto.CompactTextString(m)
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Config) GetInbound() []*v2ray_core_app_proxyman.InboundHandlerConfig {
func (m *Config) GetInbound() []*InboundHandlerConfig {
if m != nil {
return m.Inbound
}
return nil
}
func (m *Config) GetOutbound() []*v2ray_core_app_proxyman.OutboundHandlerConfig {
func (m *Config) GetOutbound() []*OutboundHandlerConfig {
if m != nil {
return m.Outbound
}
@ -95,34 +94,131 @@ func (m *Config) GetExtension() []*v2ray_core_common_serial.TypedMessage {
return nil
}
type InboundHandlerConfig struct {
// Tag of the inbound handler.
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
// Settings for how this inbound proxy is handled. Must be ReceiverConfig above.
ReceiverSettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=receiver_settings,json=receiverSettings" json:"receiver_settings,omitempty"`
// Settings for inbound proxy. Must be one of the inbound proxies.
ProxySettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"`
}
func (m *InboundHandlerConfig) Reset() { *m = InboundHandlerConfig{} }
func (m *InboundHandlerConfig) String() string { return proto.CompactTextString(m) }
func (*InboundHandlerConfig) ProtoMessage() {}
func (*InboundHandlerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *InboundHandlerConfig) GetTag() string {
if m != nil {
return m.Tag
}
return ""
}
func (m *InboundHandlerConfig) GetReceiverSettings() *v2ray_core_common_serial.TypedMessage {
if m != nil {
return m.ReceiverSettings
}
return nil
}
func (m *InboundHandlerConfig) GetProxySettings() *v2ray_core_common_serial.TypedMessage {
if m != nil {
return m.ProxySettings
}
return nil
}
type OutboundHandlerConfig struct {
// Tag of this outbound handler.
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
// Settings for how to dial connection for this outbound handler. Must be SenderConfig above.
SenderSettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=sender_settings,json=senderSettings" json:"sender_settings,omitempty"`
// Settings for this outbound proxy. Must be one of the outbound proxies.
ProxySettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"`
// If not zero, this outbound will be expired in seconds. Not used for now.
Expire int64 `protobuf:"varint,4,opt,name=expire" json:"expire,omitempty"`
// Comment of this outbound handler. Not used for now.
Comment string `protobuf:"bytes,5,opt,name=comment" json:"comment,omitempty"`
}
func (m *OutboundHandlerConfig) Reset() { *m = OutboundHandlerConfig{} }
func (m *OutboundHandlerConfig) String() string { return proto.CompactTextString(m) }
func (*OutboundHandlerConfig) ProtoMessage() {}
func (*OutboundHandlerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *OutboundHandlerConfig) GetTag() string {
if m != nil {
return m.Tag
}
return ""
}
func (m *OutboundHandlerConfig) GetSenderSettings() *v2ray_core_common_serial.TypedMessage {
if m != nil {
return m.SenderSettings
}
return nil
}
func (m *OutboundHandlerConfig) GetProxySettings() *v2ray_core_common_serial.TypedMessage {
if m != nil {
return m.ProxySettings
}
return nil
}
func (m *OutboundHandlerConfig) GetExpire() int64 {
if m != nil {
return m.Expire
}
return 0
}
func (m *OutboundHandlerConfig) GetComment() string {
if m != nil {
return m.Comment
}
return ""
}
func init() {
proto.RegisterType((*Config)(nil), "v2ray.core.Config")
proto.RegisterType((*InboundHandlerConfig)(nil), "v2ray.core.InboundHandlerConfig")
proto.RegisterType((*OutboundHandlerConfig)(nil), "v2ray.core.OutboundHandlerConfig")
proto.RegisterEnum("v2ray.core.ConfigFormat", ConfigFormat_name, ConfigFormat_value)
}
func init() { proto.RegisterFile("v2ray.com/core/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 336 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0xcd, 0x4a, 0xf3, 0x40,
0x18, 0x85, 0xbf, 0xb4, 0xf9, 0x6a, 0xfa, 0xb6, 0x48, 0x99, 0x55, 0xa8, 0x2e, 0x8a, 0xd0, 0x52,
0x04, 0x27, 0x12, 0x37, 0xe2, 0xd2, 0x8a, 0x3f, 0x05, 0x6d, 0xa9, 0xe2, 0xc2, 0x8d, 0x4c, 0xd3,
0x69, 0x09, 0x74, 0xe6, 0x1d, 0x26, 0x53, 0x69, 0x6e, 0xc9, 0x9b, 0xf2, 0x56, 0x24, 0x99, 0xfe,
0xa5, 0xe2, 0xc2, 0x55, 0x20, 0x73, 0x9e, 0xe7, 0x4c, 0x4e, 0xe0, 0xe8, 0x23, 0xd4, 0x2c, 0xa5,
0x11, 0x8a, 0x20, 0x42, 0xcd, 0x83, 0x08, 0xe5, 0x34, 0x9e, 0x51, 0xa5, 0xd1, 0x20, 0x81, 0xf5,
0xa1, 0xe6, 0xcd, 0xee, 0x5e, 0x90, 0x29, 0x15, 0x28, 0x8d, 0xcb, 0x54, 0x30, 0x59, 0xa0, 0x9a,
0xe7, 0x3f, 0x94, 0x42, 0xa0, 0x0c, 0x12, 0xae, 0x63, 0x36, 0x0f, 0x4c, 0xaa, 0xf8, 0xe4, 0x5d,
0xf0, 0x24, 0x61, 0x33, 0xbe, 0x22, 0xda, 0x7b, 0x84, 0xd1, 0x4c, 0x26, 0x0a, 0xb5, 0x29, 0x88,
0x4f, 0xbe, 0x4a, 0x50, 0xe9, 0xe5, 0x2f, 0xc8, 0x1d, 0x1c, 0xc4, 0x72, 0x8c, 0x0b, 0x39, 0xf1,
0x9d, 0x56, 0xb9, 0x5b, 0x0b, 0xcf, 0xe8, 0xf6, 0xae, 0x94, 0x29, 0x45, 0xd7, 0x77, 0xa3, 0x0f,
0x36, 0x77, 0xcf, 0xe4, 0x64, 0xce, 0xb5, 0xe5, 0x47, 0x6b, 0x9a, 0xf4, 0xc1, 0xc3, 0x85, 0xb1,
0xa6, 0x52, 0x6e, 0xa2, 0xbf, 0x9a, 0x06, 0xab, 0x60, 0x51, 0xb5, 0xe1, 0xc9, 0x25, 0x94, 0x99,
0x52, 0xbe, 0x9b, 0x6b, 0x3a, 0xbb, 0x1a, 0x3b, 0x01, 0xb5, 0x13, 0xd0, 0x97, 0x6c, 0x82, 0x47,
0xbb, 0xc0, 0x28, 0x43, 0xc8, 0x15, 0x54, 0x37, 0xdf, 0xec, 0xff, 0x6f, 0x39, 0xdd, 0x5a, 0x78,
0xbc, 0xcb, 0x6f, 0x0e, 0xe9, 0xaa, 0x74, 0x1b, 0x27, 0x37, 0x50, 0xe5, 0x4b, 0xc3, 0x65, 0x12,
0xa3, 0xf4, 0x2b, 0x7f, 0xea, 0xde, 0x82, 0x7d, 0xd7, 0x2b, 0x37, 0xdc, 0xd3, 0x0e, 0xd4, 0x6d,
0xc1, 0x2d, 0x6a, 0xc1, 0x0c, 0xa9, 0x83, 0x37, 0xcc, 0xa6, 0x1f, 0x2f, 0xa6, 0x8d, 0x7f, 0xc4,
0x03, 0xb7, 0xff, 0x3c, 0x78, 0x6a, 0x38, 0xd7, 0x6d, 0x38, 0x8c, 0x50, 0xec, 0xb4, 0x0c, 0x9d,
0x37, 0x37, 0x7b, 0x7e, 0x96, 0xe0, 0x35, 0x1c, 0xb1, 0x94, 0xf6, 0x50, 0xf3, 0x71, 0x25, 0xff,
0x6f, 0x17, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x62, 0x93, 0x6d, 0x78, 0x65, 0x02, 0x00, 0x00,
// 436 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0x41, 0x6f, 0xd3, 0x30,
0x14, 0xc7, 0x71, 0x13, 0xba, 0xf6, 0x6d, 0x94, 0x60, 0x01, 0xb2, 0x06, 0x87, 0x50, 0x69, 0x53,
0xc5, 0xc1, 0x45, 0xe5, 0x82, 0x26, 0x71, 0x61, 0x08, 0xc1, 0xa4, 0xd1, 0x29, 0x45, 0x1c, 0xb8,
0x4c, 0x6e, 0xfa, 0x56, 0x45, 0x5a, 0xec, 0xc8, 0x76, 0xa7, 0xe6, 0x2b, 0xf1, 0x3d, 0xb8, 0xf1,
0x8d, 0xb8, 0xa0, 0xc4, 0x49, 0x93, 0x41, 0x0f, 0x14, 0x69, 0xa7, 0xc4, 0x79, 0xfe, 0xfd, 0xdf,
0xfb, 0x25, 0x31, 0x3c, 0xbb, 0x99, 0x68, 0x91, 0xf3, 0x58, 0xa5, 0xe3, 0x58, 0x69, 0x1c, 0xc7,
0x4a, 0x5e, 0x25, 0x4b, 0x9e, 0x69, 0x65, 0x15, 0x85, 0xba, 0xa8, 0xf1, 0xf0, 0xd5, 0x5f, 0x1b,
0xd3, 0x54, 0xc9, 0xb1, 0x41, 0x9d, 0x88, 0xeb, 0xb1, 0xcd, 0x33, 0x5c, 0x5c, 0xa6, 0x68, 0x8c,
0x58, 0xa2, 0xa3, 0x0f, 0x8f, 0xfe, 0x20, 0xac, 0x16, 0xd2, 0x64, 0x4a, 0xdb, 0x5b, 0x4d, 0x86,
0x3f, 0x3a, 0xd0, 0x3d, 0x2d, 0x1f, 0xd0, 0x13, 0xd8, 0x4b, 0xe4, 0x5c, 0xad, 0xe4, 0x82, 0x91,
0xd0, 0x1b, 0xed, 0x4f, 0x42, 0xde, 0x4c, 0xc0, 0x3f, 0xb9, 0xd2, 0x47, 0x21, 0x17, 0xd7, 0xa8,
0x1d, 0x12, 0xd5, 0x00, 0x7d, 0x0b, 0x3d, 0xb5, 0xb2, 0x0e, 0xee, 0x94, 0xf0, 0x8b, 0x36, 0x3c,
0xad, 0x6a, 0xb7, 0xe9, 0x0d, 0x42, 0xdf, 0x80, 0x27, 0xb2, 0x8c, 0xf9, 0x25, 0x79, 0xdc, 0x26,
0x9d, 0x28, 0x77, 0xa2, 0xfc, 0x4b, 0x21, 0x7a, 0xee, 0x3c, 0xa3, 0x02, 0xa1, 0x27, 0xd0, 0xdf,
0x98, 0xb1, 0xfb, 0x21, 0x19, 0xed, 0x4f, 0x9e, 0xb7, 0xf9, 0x4d, 0x91, 0x57, 0x4d, 0x9b, 0xed,
0xf4, 0x3d, 0xf4, 0x71, 0x6d, 0x51, 0x9a, 0x44, 0x49, 0xd6, 0xdd, 0xa9, 0x77, 0x03, 0x9e, 0xf9,
0x3d, 0x2f, 0xf0, 0x87, 0x3f, 0x09, 0x3c, 0xde, 0xf6, 0x8a, 0x68, 0x00, 0x9e, 0x15, 0x4b, 0x46,
0x42, 0x32, 0xea, 0x47, 0xc5, 0x2d, 0x9d, 0xc1, 0x23, 0x8d, 0x31, 0x26, 0x37, 0xa8, 0x2f, 0x0d,
0x5a, 0x9b, 0xc8, 0xa5, 0x61, 0x9d, 0x72, 0xf4, 0x7f, 0x6d, 0x1f, 0xd4, 0x01, 0xb3, 0x8a, 0xa7,
0xe7, 0x30, 0xc8, 0xb4, 0x5a, 0xe7, 0x4d, 0xa2, 0xb7, 0x53, 0xe2, 0x83, 0x92, 0xae, 0xe3, 0x86,
0xbf, 0x08, 0x3c, 0xd9, 0xfa, 0xd1, 0xb6, 0xf8, 0x4c, 0xe1, 0xa1, 0x41, 0xb9, 0xf8, 0x7f, 0x9b,
0x81, 0xc3, 0xef, 0xc8, 0x85, 0x3e, 0x85, 0x2e, 0xae, 0xb3, 0x44, 0x23, 0xf3, 0x43, 0x32, 0xf2,
0xa2, 0x6a, 0x45, 0x19, 0xec, 0x15, 0x21, 0x28, 0xdd, 0x8f, 0xd3, 0x8f, 0xea, 0xe5, 0xcb, 0x63,
0x38, 0x70, 0xb6, 0x1f, 0x94, 0x4e, 0x85, 0xa5, 0x07, 0xd0, 0xbb, 0x28, 0x4e, 0xcb, 0x7c, 0x75,
0x15, 0xdc, 0xa3, 0x3d, 0xf0, 0xcf, 0x66, 0xd3, 0xcf, 0x01, 0x79, 0x77, 0x04, 0x83, 0x58, 0xa5,
0xad, 0xa9, 0x2e, 0xc8, 0x37, 0xbf, 0xb8, 0x7e, 0xef, 0xc0, 0xd7, 0x49, 0x24, 0x72, 0x7e, 0xaa,
0x34, 0xce, 0xbb, 0xe5, 0x51, 0x7b, 0xfd, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x59, 0x1b,
0xee, 0x03, 0x00, 0x00,
}

View File

@ -6,7 +6,6 @@ option go_package = "core";
option java_package = "com.v2ray.core";
option java_multiple_files = true;
import "v2ray.com/core/app/proxyman/config.proto";
import "v2ray.com/core/common/serial/typed_message.proto";
import "v2ray.com/core/transport/config.proto";
@ -19,10 +18,10 @@ enum ConfigFormat {
// Master config of V2Ray. V2Ray takes this config as input and functions accordingly.
message Config {
// Inbound handler configurations. Must have at least one item.
repeated v2ray.core.app.proxyman.InboundHandlerConfig inbound = 1;
repeated InboundHandlerConfig inbound = 1;
// Outbound handler configurations. Must have at least one item. The first item is used as default for routing.
repeated v2ray.core.app.proxyman.OutboundHandlerConfig outbound = 2;
repeated OutboundHandlerConfig outbound = 2;
reserved 3;
@ -36,3 +35,25 @@ message Config {
// V2Ray will ignore such config during initialization.
repeated v2ray.core.common.serial.TypedMessage extension = 6;
}
message InboundHandlerConfig {
// Tag of the inbound handler.
string tag = 1;
// Settings for how this inbound proxy is handled. Must be ReceiverConfig above.
v2ray.core.common.serial.TypedMessage receiver_settings = 2;
// Settings for inbound proxy. Must be one of the inbound proxies.
v2ray.core.common.serial.TypedMessage proxy_settings = 3;
}
message OutboundHandlerConfig {
// Tag of this outbound handler.
string tag = 1;
// Settings for how to dial connection for this outbound handler. Must be SenderConfig above.
v2ray.core.common.serial.TypedMessage sender_settings = 2;
// Settings for this outbound proxy. Must be one of the outbound proxies.
v2ray.core.common.serial.TypedMessage proxy_settings = 3;
// If not zero, this outbound will be expired in seconds. Not used for now.
int64 expire = 4;
// Comment of this outbound handler. Not used for now.
string comment = 5;
}

17
context.go Normal file
View File

@ -0,0 +1,17 @@
package core
import (
"context"
)
type key int
const v2rayKey key = 1
// FromContext returns a Instance from the given context, or nil if the context doesn't contain one.
func FromContext(ctx context.Context) *Instance {
if s, ok := ctx.Value(v2rayKey).(*Instance); ok {
return s
}
return nil
}

57
dns.go Normal file
View File

@ -0,0 +1,57 @@
package core
import "net"
import "sync"
// DNSClient is a V2Ray feature for querying DNS information.
type DNSClient interface {
Feature
LookupIP(host string) ([]net.IP, error)
}
type syncDNSClient struct {
sync.RWMutex
DNSClient
}
func (d *syncDNSClient) LookupIP(host string) ([]net.IP, error) {
d.RLock()
defer d.RUnlock()
if d.DNSClient == nil {
return net.LookupIP(host)
}
return d.DNSClient.LookupIP(host)
}
func (d *syncDNSClient) Start() error {
d.RLock()
defer d.RUnlock()
if d.DNSClient == nil {
return nil
}
return d.DNSClient.Start()
}
func (d *syncDNSClient) Close() {
d.RLock()
defer d.RUnlock()
if d.DNSClient != nil {
d.DNSClient.Close()
}
}
func (d *syncDNSClient) Set(client DNSClient) {
if client == nil {
return
}
d.Lock()
defer d.Unlock()
d.DNSClient = client
}

View File

@ -2,10 +2,10 @@ package all
import (
// The following are necessary as they register handlers in their init functions.
_ "v2ray.com/core/app/dispatcher/impl"
_ "v2ray.com/core/app/dispatcher"
_ "v2ray.com/core/app/dns"
_ "v2ray.com/core/app/log"
_ "v2ray.com/core/app/policy/manager"
_ "v2ray.com/core/app/policy"
_ "v2ray.com/core/app/proxyman/inbound"
_ "v2ray.com/core/app/proxyman/outbound"
_ "v2ray.com/core/app/router"

165
network.go Normal file
View File

@ -0,0 +1,165 @@
package core
import (
"context"
"sync"
"v2ray.com/core/common"
"v2ray.com/core/common/net"
"v2ray.com/core/transport/ray"
)
// InboundHandler is the interface for handlers that process inbound connections.
type InboundHandler interface {
common.Runnable
// The tag of this handler.
Tag() string
// Deprecated. Do not use in new code.
GetRandomInboundProxy() (interface{}, net.Port, int)
}
// OutboundHandler is the interface for handlers that process outbound connections.
type OutboundHandler interface {
Tag() string
Dispatch(ctx context.Context, outboundRay ray.OutboundRay)
}
// InboundHandlerManager is a feature that managers InboundHandlers.
type InboundHandlerManager interface {
Feature
// GetHandlers returns an InboundHandler for the given tag.
GetHandler(ctx context.Context, tag string) (InboundHandler, error)
// AddHandler adds the given handler into this InboundHandlerManager.
AddHandler(ctx context.Context, handler InboundHandler) error
}
type syncInboundHandlerManager struct {
sync.RWMutex
InboundHandlerManager
}
func (m *syncInboundHandlerManager) GetHandler(ctx context.Context, tag string) (InboundHandler, error) {
m.RLock()
defer m.RUnlock()
if m.InboundHandlerManager == nil {
return nil, newError("InboundHandlerManager not set.").AtError()
}
return m.InboundHandlerManager.GetHandler(ctx, tag)
}
func (m *syncInboundHandlerManager) AddHandler(ctx context.Context, handler InboundHandler) error {
m.RLock()
defer m.RUnlock()
if m.InboundHandlerManager == nil {
return newError("InboundHandlerManager not set.").AtError()
}
return m.InboundHandlerManager.AddHandler(ctx, handler)
}
func (m *syncInboundHandlerManager) Start() error {
m.RLock()
defer m.RUnlock()
if m.InboundHandlerManager == nil {
return newError("InboundHandlerManager not set.").AtError()
}
return m.InboundHandlerManager.Start()
}
func (m *syncInboundHandlerManager) Close() {
m.RLock()
defer m.RUnlock()
if m.InboundHandlerManager != nil {
m.InboundHandlerManager.Close()
}
}
func (m *syncInboundHandlerManager) Set(manager InboundHandlerManager) {
m.Lock()
defer m.Unlock()
m.InboundHandlerManager = manager
}
// OutboundHandlerManager is a feature that manages OutboundHandlers.
type OutboundHandlerManager interface {
Feature
// GetHandler returns an OutboundHandler will given tag.
GetHandler(tag string) OutboundHandler
// GetDefaultHandler returns the default OutboundHandler. It is usually the first OutboundHandler specified in the configuration.
GetDefaultHandler() OutboundHandler
// AddHandler adds a handler into this OutboundHandlerManager.
AddHandler(ctx context.Context, handler OutboundHandler) error
}
type syncOutboundHandlerManager struct {
sync.RWMutex
OutboundHandlerManager
}
func (m *syncOutboundHandlerManager) GetHandler(tag string) OutboundHandler {
m.RLock()
defer m.RUnlock()
if m.OutboundHandlerManager == nil {
return nil
}
return m.OutboundHandlerManager.GetHandler(tag)
}
func (m *syncOutboundHandlerManager) GetDefaultHandler() OutboundHandler {
m.RLock()
defer m.RUnlock()
if m.OutboundHandlerManager == nil {
return nil
}
return m.OutboundHandlerManager.GetDefaultHandler()
}
func (m *syncOutboundHandlerManager) AddHandler(ctx context.Context, handler OutboundHandler) error {
m.RLock()
defer m.RUnlock()
if m.OutboundHandlerManager == nil {
return newError("OutboundHandlerManager not set.").AtError()
}
return m.OutboundHandlerManager.AddHandler(ctx, handler)
}
func (m *syncOutboundHandlerManager) Start() error {
m.RLock()
defer m.RUnlock()
if m.OutboundHandlerManager == nil {
return newError("OutboundHandlerManager not set.").AtError()
}
return m.OutboundHandlerManager.Start()
}
func (m *syncOutboundHandlerManager) Close() {
m.RLock()
defer m.RUnlock()
if m.OutboundHandlerManager != nil {
m.OutboundHandlerManager.Close()
}
}
func (m *syncOutboundHandlerManager) Set(manager OutboundHandlerManager) {
m.Lock()
defer m.Unlock()
m.OutboundHandlerManager = manager
}

117
policy.go Normal file
View File

@ -0,0 +1,117 @@
package core
import (
"sync"
"time"
)
// TimeoutPolicy contains limits for connection timeout.
type TimeoutPolicy struct {
// Timeout for handshake phase in a connection.
Handshake time.Duration
// Timeout for connection being idle, i.e., there is no egress or ingress traffic in this connection.
ConnectionIdle time.Duration
// Timeout for an uplink only connection, i.e., the downlink of the connection has ben closed.
UplinkOnly time.Duration
// Timeout for an downlink only connection, i.e., the uplink of the connection has ben closed.
DownlinkOnly time.Duration
}
// OverrideWith overrides the current TimeoutPolicy with another one. All timeouts with zero value will be overridden with the new value.
func (p TimeoutPolicy) OverrideWith(another TimeoutPolicy) TimeoutPolicy {
if p.Handshake == 0 {
p.Handshake = another.Handshake
}
if p.ConnectionIdle == 0 {
p.ConnectionIdle = another.ConnectionIdle
}
if p.UplinkOnly == 0 {
p.UplinkOnly = another.UplinkOnly
}
if p.DownlinkOnly == 0 {
p.DownlinkOnly = another.DownlinkOnly
}
return p
}
// Policy is session based settings for controlling V2Ray requests. It contains various settings (or limits) that may differ for different users in the context.
type Policy struct {
Timeouts TimeoutPolicy // Timeout settings
}
// OverrideWith overrides the current Policy with another one. All values with default value will be overridden.
func (p Policy) OverrideWith(another Policy) Policy {
p.Timeouts.OverrideWith(another.Timeouts)
return p
}
// PolicyManager is a feature that provides Policy for the given user by its id or level.
type PolicyManager interface {
Feature
// ForLevel returns the Policy for the given user level.
ForLevel(level uint32) Policy
}
// DefaultPolicy returns the Policy when user is not specified.
func DefaultPolicy() Policy {
return Policy{
Timeouts: TimeoutPolicy{
Handshake: time.Second * 4,
ConnectionIdle: time.Second * 300,
UplinkOnly: time.Second * 5,
DownlinkOnly: time.Second * 30,
},
}
}
type syncPolicyManager struct {
sync.RWMutex
PolicyManager
}
func (m *syncPolicyManager) ForLevel(level uint32) Policy {
m.RLock()
defer m.RUnlock()
if m.PolicyManager == nil {
p := DefaultPolicy()
if level == 1 {
p.Timeouts.ConnectionIdle = time.Second * 600
}
return p
}
return m.PolicyManager.ForLevel(level)
}
func (m *syncPolicyManager) Start() error {
m.RLock()
defer m.RUnlock()
if m.PolicyManager == nil {
return nil
}
return m.PolicyManager.Start()
}
func (m *syncPolicyManager) Close() {
m.RLock()
defer m.RUnlock()
if m.PolicyManager != nil {
m.PolicyManager.Close()
}
}
func (m *syncPolicyManager) Set(manager PolicyManager) {
if manager == nil {
return
}
m.Lock()
defer m.Unlock()
m.PolicyManager = manager
}

View File

@ -4,10 +4,9 @@ package dokodemo
import (
"context"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/policy"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/net"
@ -18,36 +17,29 @@ import (
)
type DokodemoDoor struct {
config *Config
address net.Address
port net.Port
policy policy.Policy
policyManager core.PolicyManager
config *Config
address net.Address
port net.Port
v *core.Instance
}
func New(ctx context.Context, config *Config) (*DokodemoDoor, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context")
}
if config.NetworkList == nil || config.NetworkList.Size() == 0 {
return nil, newError("no network specified")
}
d := &DokodemoDoor{
config: config,
address: config.GetPredefinedAddress(),
port: net.Port(config.Port),
v := core.FromContext(ctx)
if v == nil {
return nil, newError("V is not in context.")
}
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
}
d.policy = pm.GetPolicy(config.UserLevel)
if config.Timeout > 0 && config.UserLevel == 0 {
d.policy.Timeout.ConnectionIdle.Value = config.Timeout
}
return nil
})
d := &DokodemoDoor{
config: config,
address: config.GetPredefinedAddress(),
port: net.Port(config.Port),
policyManager: v.PolicyManager(),
}
return d, nil
}
@ -55,7 +47,16 @@ func (d *DokodemoDoor) Network() net.NetworkList {
return *(d.config.NetworkList)
}
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
func (d *DokodemoDoor) policy() core.Policy {
config := d.config
p := d.policyManager.ForLevel(config.UserLevel)
if config.Timeout > 0 && config.UserLevel == 0 {
p.Timeouts.ConnectionIdle = time.Duration(config.Timeout) * time.Second
}
return p
}
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher core.Dispatcher) error {
newError("processing connection from: ", conn.RemoteAddr()).AtDebug().WriteToLog()
dest := net.Destination{
Network: network,
@ -72,7 +73,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
}
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, d.policy.Timeout.ConnectionIdle.Duration())
timer := signal.CancelAfterInactivity(ctx, cancel, d.policy().Timeouts.ConnectionIdle)
inboundRay, err := dispatcher.Dispatch(ctx, dest)
if err != nil {
@ -88,7 +89,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
return newError("failed to transport request").Base(err)
}
timer.SetTimeout(d.policy.Timeout.DownlinkOnly.Duration())
timer.SetTimeout(d.policy().Timeouts.DownlinkOnly)
return nil
})
@ -115,7 +116,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
return newError("failed to transport response").Base(err)
}
timer.SetTimeout(d.policy.Timeout.UplinkOnly.Duration())
timer.SetTimeout(d.policy().Timeouts.UplinkOnly)
return nil
})

View File

@ -4,9 +4,9 @@ package freedom
import (
"context"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/policy"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/dice"
@ -20,37 +20,35 @@ import (
// Handler handles Freedom connections.
type Handler struct {
domainStrategy Config_DomainStrategy
timeout uint32
destOverride *DestinationOverride
policy policy.Policy
policyManager core.PolicyManager
dns core.DNSClient
config Config
}
// New creates a new Freedom handler.
func New(ctx context.Context, config *Config) (*Handler, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context")
v := core.FromContext(ctx)
if v == nil {
return nil, newError("V is not found in context.")
}
f := &Handler{
domainStrategy: config.DomainStrategy,
timeout: config.Timeout,
destOverride: config.DestinationOverride,
config: *config,
policyManager: v.PolicyManager(),
dns: v.DNSClient(),
}
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
}
f.policy = pm.GetPolicy(config.UserLevel)
if config.Timeout > 0 && config.UserLevel == 0 {
f.policy.Timeout.ConnectionIdle.Value = config.Timeout
}
return nil
})
return f, nil
}
func (h *Handler) policy() core.Policy {
p := h.policyManager.ForLevel(h.config.UserLevel)
if h.config.Timeout > 0 && h.config.UserLevel == 0 {
p.Timeouts.ConnectionIdle = time.Duration(h.config.Timeout) * time.Second
}
return p
}
func (h *Handler) resolveIP(ctx context.Context, domain string) net.Address {
if resolver, ok := proxy.ResolvedIPsFromContext(ctx); ok {
ips := resolver.Resolve()
@ -60,7 +58,7 @@ func (h *Handler) resolveIP(ctx context.Context, domain string) net.Address {
return ips[dice.Roll(len(ips))]
}
ips, err := net.LookupIP(domain)
ips, err := h.dns.LookupIP(domain)
if err != nil {
newError("failed to get IP address for domain ", domain).Base(err).WriteToLog()
}
@ -73,8 +71,8 @@ func (h *Handler) resolveIP(ctx context.Context, domain string) net.Address {
// Process implements proxy.Outbound.
func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dialer proxy.Dialer) error {
destination, _ := proxy.TargetFromContext(ctx)
if h.destOverride != nil {
server := h.destOverride.Server
if h.config.DestinationOverride != nil {
server := h.config.DestinationOverride.Server
destination = net.Destination{
Network: destination.Network,
Address: server.Address.AsAddress(),
@ -86,7 +84,7 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
input := outboundRay.OutboundInput()
output := outboundRay.OutboundOutput()
if h.domainStrategy == Config_USE_IP && destination.Address.Family().IsDomain() {
if h.config.DomainStrategy == Config_USE_IP && destination.Address.Family().IsDomain() {
ip := h.resolveIP(ctx, destination.Address.Domain())
if ip != nil {
destination = net.Destination{
@ -113,7 +111,7 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
defer conn.Close()
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, h.policy.Timeout.ConnectionIdle.Duration())
timer := signal.CancelAfterInactivity(ctx, cancel, h.policy().Timeouts.ConnectionIdle)
requestDone := signal.ExecuteAsync(func() error {
var writer buf.Writer
@ -125,7 +123,7 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
if err := buf.Copy(input, writer, buf.UpdateActivity(timer)); err != nil {
return newError("failed to process request").Base(err)
}
timer.SetTimeout(h.policy.Timeout.DownlinkOnly.Duration())
timer.SetTimeout(h.policy().Timeouts.DownlinkOnly)
return nil
})
@ -136,7 +134,7 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
if err := buf.Copy(v2reader, output, buf.UpdateActivity(timer)); err != nil {
return newError("failed to process response").Base(err)
}
timer.SetTimeout(h.policy.Timeout.UplinkOnly.Duration())
timer.SetTimeout(h.policy().Timeouts.UplinkOnly)
return nil
})

View File

@ -10,9 +10,7 @@ import (
"strings"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/policy"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
@ -26,32 +24,31 @@ import (
// Server is a HTTP proxy server.
type Server struct {
config *ServerConfig
policy policy.Policy
v *core.Instance
}
// NewServer creates a new HTTP inbound handler.
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context.")
}
s := &Server{
config: config,
v: core.FromContext(ctx),
}
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
}
s.policy = pm.GetPolicy(config.UserLevel)
if config.Timeout > 0 && config.UserLevel == 0 {
s.policy.Timeout.ConnectionIdle.Value = config.Timeout
}
return nil
})
if s.v == nil {
return nil, newError("V is not in context.")
}
return s, nil
}
func (s *Server) policy() core.Policy {
config := s.config
p := s.v.PolicyManager().ForLevel(config.UserLevel)
if config.Timeout > 0 && config.UserLevel == 0 {
p.Timeouts.ConnectionIdle = time.Duration(config.Timeout) * time.Second
}
return p
}
func (*Server) Network() net.NetworkList {
return net.NetworkList{
Network: []net.Network{net.Network_TCP},
@ -104,11 +101,11 @@ type readerOnly struct {
io.Reader
}
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher core.Dispatcher) error {
reader := bufio.NewReaderSize(readerOnly{conn}, buf.Size)
Start:
conn.SetReadDeadline(time.Now().Add(s.policy.Timeout.Handshake.Duration()))
conn.SetReadDeadline(time.Now().Add(s.policy().Timeouts.Handshake))
request, err := http.ReadRequest(reader)
if err != nil {
@ -165,14 +162,14 @@ Start:
return err
}
func (s *Server) handleConnect(ctx context.Context, request *http.Request, reader *bufio.Reader, conn internet.Connection, dest net.Destination, dispatcher dispatcher.Interface) error {
func (s *Server) handleConnect(ctx context.Context, request *http.Request, reader *bufio.Reader, conn internet.Connection, dest net.Destination, dispatcher core.Dispatcher) error {
_, err := conn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
if err != nil {
return newError("failed to write back OK response").Base(err)
}
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, s.policy.Timeout.ConnectionIdle.Duration())
timer := signal.CancelAfterInactivity(ctx, cancel, s.policy().Timeouts.ConnectionIdle)
ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil {
return err
@ -191,7 +188,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
requestDone := signal.ExecuteAsync(func() error {
defer ray.InboundInput().Close()
defer timer.SetTimeout(s.policy.Timeout.DownlinkOnly.Duration())
defer timer.SetTimeout(s.policy().Timeouts.DownlinkOnly)
v2reader := buf.NewReader(conn)
return buf.Copy(v2reader, ray.InboundInput(), buf.UpdateActivity(timer))
@ -202,7 +199,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
if err := buf.Copy(ray.InboundOutput(), v2writer, buf.UpdateActivity(timer)); err != nil {
return err
}
timer.SetTimeout(s.policy.Timeout.UplinkOnly.Duration())
timer.SetTimeout(s.policy().Timeouts.UplinkOnly)
return nil
})
@ -217,7 +214,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
var errWaitAnother = newError("keep alive")
func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, writer io.Writer, dest net.Destination, dispatcher dispatcher.Interface) error {
func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, writer io.Writer, dest net.Destination, dispatcher core.Dispatcher) error {
if !s.config.AllowTransparent && len(request.URL.Host) <= 0 {
// RFC 2068 (HTTP/1.1) requires URL to be absolute URL in HTTP proxy.
response := &http.Response{

View File

@ -10,7 +10,7 @@ package proxy
import (
"context"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core"
"v2ray.com/core/common/net"
"v2ray.com/core/transport/internet"
"v2ray.com/core/transport/ray"
@ -22,7 +22,7 @@ type Inbound interface {
Network() net.NetworkList
// Process processes a connection of given network. If necessary, the Inbound can dispatch the connection to an Outbound.
Process(context.Context, net.Network, internet.Connection, dispatcher.Interface) error
Process(context.Context, net.Network, internet.Connection, core.Dispatcher) error
}
// An Outbound process outbound connections.

View File

@ -3,8 +3,7 @@ package shadowsocks
import (
"context"
"v2ray.com/core/app"
"v2ray.com/core/app/policy"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/net"
@ -18,8 +17,8 @@ import (
// Client is a inbound handler for Shadowsocks protocol
type Client struct {
serverPicker protocol.ServerPicker
policyManager policy.Manager
serverPicker protocol.ServerPicker
v *core.Instance
}
// NewClient create a new Shadowsocks client.
@ -33,19 +32,11 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
}
client := &Client{
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
v: core.FromContext(ctx),
}
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("Space not found.")
if client.v == nil {
return nil, newError("V is not in context.")
}
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
}
client.policyManager = pm
return nil
})
return client, nil
}
@ -103,9 +94,9 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
request.Option |= RequestOptionOneTimeAuth
}
sessionPolicy := v.policyManager.GetPolicy(user.Level)
sessionPolicy := v.v.PolicyManager().ForLevel(user.Level)
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
if request.Command == protocol.RequestCommandTCP {
bufferedWriter := buf.NewBufferedWriter(buf.NewWriter(conn))
@ -119,13 +110,13 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
}
requestDone := signal.ExecuteAsync(func() error {
defer timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
return buf.Copy(outboundRay.OutboundInput(), bodyWriter, buf.UpdateActivity(timer))
})
responseDone := signal.ExecuteAsync(func() error {
defer outboundRay.OutboundOutput().Close()
defer timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
responseReader, err := ReadTCPResponse(user, conn)
if err != nil {

View File

@ -4,9 +4,7 @@ import (
"context"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/policy"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/log"
@ -19,18 +17,14 @@ import (
)
type Server struct {
config *ServerConfig
user *protocol.User
account *MemoryAccount
policyManager policy.Manager
config *ServerConfig
user *protocol.User
account *MemoryAccount
v *core.Instance
}
// NewServer create a new Shadowsocks server.
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context")
}
if config.GetUser() == nil {
return nil, newError("user is not specified")
}
@ -45,16 +39,12 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
config: config,
user: config.GetUser(),
account: account,
v: core.FromContext(ctx),
}
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
}
s.policyManager = pm
return nil
})
if s.v == nil {
return nil, newError("V is not in context.")
}
return s, nil
}
@ -69,7 +59,7 @@ func (s *Server) Network() net.NetworkList {
return list
}
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher core.Dispatcher) error {
switch network {
case net.Network_TCP:
return s.handleConnection(ctx, conn, dispatcher)
@ -80,7 +70,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
}
}
func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection, dispatcher core.Dispatcher) error {
udpServer := udp.NewDispatcher(dispatcher)
reader := buf.NewReader(conn)
@ -148,9 +138,9 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
return nil
}
func (s *Server) handleConnection(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
sessionPolicy := s.policyManager.GetPolicy(s.user.Level)
conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeout.Handshake.Duration()))
func (s *Server) handleConnection(ctx context.Context, conn internet.Connection, dispatcher core.Dispatcher) error {
sessionPolicy := s.v.PolicyManager().ForLevel(s.user.Level)
conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake))
bufferedReader := buf.NewBufferedReader(buf.NewReader(conn))
request, bodyReader, err := ReadTCPSession(s.user, bufferedReader)
if err != nil {
@ -178,7 +168,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
ctx = protocol.ContextWithUser(ctx, request.User)
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil {
return err
@ -208,7 +198,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
return newError("failed to transport all TCP response").Base(err)
}
timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
return nil
})
@ -219,7 +209,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
if err := buf.Copy(bodyReader, ray.InboundInput(), buf.UpdateActivity(timer)); err != nil {
return newError("failed to transport all TCP request").Base(err)
}
timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
return nil
})

View File

@ -5,9 +5,7 @@ import (
"io"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/policy"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/log"
@ -22,32 +20,30 @@ import (
// Server is a SOCKS 5 proxy server
type Server struct {
config *ServerConfig
policy policy.Policy
v *core.Instance
}
// NewServer creates a new Server object.
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context").AtWarning()
}
s := &Server{
config: config,
v: core.FromContext(ctx),
}
if s.v == nil {
return nil, newError("V is not in context.")
}
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
}
s.policy = pm.GetPolicy(config.UserLevel)
if config.Timeout > 0 && config.UserLevel == 0 {
s.policy.Timeout.ConnectionIdle.Value = config.Timeout
}
return nil
})
return s, nil
}
func (s *Server) policy() core.Policy {
config := s.config
p := s.v.PolicyManager().ForLevel(config.UserLevel)
if config.Timeout > 0 && config.UserLevel == 0 {
p.Timeouts.ConnectionIdle = time.Duration(config.Timeout) * time.Second
}
return p
}
func (s *Server) Network() net.NetworkList {
list := net.NetworkList{
Network: []net.Network{net.Network_TCP},
@ -58,7 +54,7 @@ func (s *Server) Network() net.NetworkList {
return list
}
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher core.Dispatcher) error {
switch network {
case net.Network_TCP:
return s.processTCP(ctx, conn, dispatcher)
@ -69,8 +65,8 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
}
}
func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
conn.SetReadDeadline(time.Now().Add(s.policy.Timeout.Handshake.Duration()))
func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispatcher core.Dispatcher) error {
conn.SetReadDeadline(time.Now().Add(s.policy().Timeouts.Handshake))
reader := buf.NewBufferedReader(buf.NewReader(conn))
inboundDest, ok := proxy.InboundEntryPointFromContext(ctx)
@ -125,9 +121,9 @@ func (*Server) handleUDP(c net.Conn) error {
return err
}
func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writer, dest net.Destination, dispatcher dispatcher.Interface) error {
func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writer, dest net.Destination, dispatcher core.Dispatcher) error {
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, v.policy.Timeout.ConnectionIdle.Duration())
timer := signal.CancelAfterInactivity(ctx, cancel, v.policy().Timeouts.ConnectionIdle)
ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil {
@ -144,7 +140,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
if err := buf.Copy(v2reader, input, buf.UpdateActivity(timer)); err != nil {
return newError("failed to transport all TCP request").Base(err)
}
timer.SetTimeout(v.policy.Timeout.DownlinkOnly.Duration())
timer.SetTimeout(v.policy().Timeouts.DownlinkOnly)
return nil
})
@ -153,7 +149,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
if err := buf.Copy(output, v2writer, buf.UpdateActivity(timer)); err != nil {
return newError("failed to transport all TCP response").Base(err)
}
timer.SetTimeout(v.policy.Timeout.UplinkOnly.Duration())
timer.SetTimeout(v.policy().Timeouts.UplinkOnly)
return nil
})
@ -166,7 +162,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
return nil
}
func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection, dispatcher core.Dispatcher) error {
udpServer := udp.NewDispatcher(dispatcher)
if source, ok := proxy.SourceFromContext(ctx); ok {

View File

@ -8,10 +8,7 @@ import (
"sync"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/policy"
"v2ray.com/core/app/proxyman"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
@ -74,21 +71,16 @@ func (v *userByEmail) Get(email string) (*protocol.User, bool) {
// Handler is an inbound connection handler that handles messages in VMess protocol.
type Handler struct {
inboundHandlerManager proxyman.InboundHandlerManager
policyManager core.PolicyManager
inboundHandlerManager core.InboundHandlerManager
clients protocol.UserValidator
usersByEmail *userByEmail
detours *DetourConfig
sessionHistory *encoding.SessionHistory
policyManager policy.Manager
}
// New creates a new VMess inbound handler.
func New(ctx context.Context, config *Config) (*Handler, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context")
}
allowedClients := vmess.NewTimedUserValidator(ctx, protocol.DefaultIDHash)
for _, user := range config.User {
if err := allowedClients.Add(user); err != nil {
@ -96,24 +88,19 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
}
}
handler := &Handler{
clients: allowedClients,
detours: config.Detour,
usersByEmail: newUserByEmail(config.User, config.GetDefaultValue()),
sessionHistory: encoding.NewSessionHistory(ctx),
v := core.FromContext(ctx)
if v == nil {
return nil, newError("V is not in context.")
}
space.On(app.SpaceInitializing, func(interface{}) error {
handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space)
if handler.inboundHandlerManager == nil {
return newError("InboundHandlerManager is not found is space.")
}
handler.policyManager = policy.FromSpace(space)
if handler.policyManager == nil {
return newError("Policy is not found in space.")
}
return nil
})
handler := &Handler{
policyManager: v.PolicyManager(),
inboundHandlerManager: v.InboundHandlerManager(),
clients: allowedClients,
detours: config.Detour,
usersByEmail: newUserByEmail(config.User, config.GetDefaultValue()),
sessionHistory: encoding.NewSessionHistory(ctx),
}
return handler, nil
}
@ -179,9 +166,9 @@ func transferResponse(timer signal.ActivityUpdater, session *encoding.ServerSess
}
// Process implements proxy.Inbound.Process().
func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher dispatcher.Interface) error {
sessionPolicy := h.policyManager.GetPolicy(0)
if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeout.Handshake.Duration())); err != nil {
func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher core.Dispatcher) error {
sessionPolicy := h.policyManager.ForLevel(0)
if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {
return newError("unable to set read deadline").Base(err).AtWarning()
}
@ -221,11 +208,11 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
newError("unable to set back read deadline").Base(err).WriteToLog()
}
sessionPolicy = h.policyManager.GetPolicy(request.User.Level)
sessionPolicy = h.policyManager.ForLevel(request.User.Level)
ctx = protocol.ContextWithUser(ctx, request.User)
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
ray, err := dispatcher.Dispatch(ctx, request.Destination())
if err != nil {
return newError("failed to dispatch request to ", request.Destination()).Base(err)
@ -235,14 +222,14 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
output := ray.InboundOutput()
requestDone := signal.ExecuteAsync(func() error {
defer timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
return transferRequest(timer, session, request, reader, input)
})
responseDone := signal.ExecuteAsync(func() error {
writer := buf.NewBufferedWriter(buf.NewWriter(connection))
defer writer.Flush()
defer timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
response := &protocol.ResponseHeader{
Command: h.generateCommand(ctx, request),

View File

@ -6,8 +6,7 @@ import (
"context"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/policy"
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/net"
@ -23,17 +22,12 @@ import (
// Handler is an outbound connection handler for VMess protocol.
type Handler struct {
serverList *protocol.ServerList
serverPicker protocol.ServerPicker
policyManager policy.Manager
serverList *protocol.ServerList
serverPicker protocol.ServerPicker
v *core.Instance
}
func New(ctx context.Context, config *Config) (*Handler, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context.")
}
serverList := protocol.NewServerList()
for _, rec := range config.Receiver {
serverList.AddServer(protocol.NewServerSpecFromPB(*rec))
@ -41,16 +35,12 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
handler := &Handler{
serverList: serverList,
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
v: core.FromContext(ctx),
}
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy is not found in space.")
}
handler.policyManager = pm
return nil
})
if handler.v == nil {
return nil, newError("V is not in context.")
}
return handler, nil
}
@ -112,10 +102,10 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
output := outboundRay.OutboundOutput()
session := encoding.NewClientSession(protocol.DefaultIDHash)
sessionPolicy := v.policyManager.GetPolicy(request.User.Level)
sessionPolicy := v.v.PolicyManager().ForLevel(request.User.Level)
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
requestDone := signal.ExecuteAsync(func() error {
writer := buf.NewBufferedWriter(buf.NewWriter(conn))
@ -148,13 +138,13 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
return err
}
}
timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
return nil
})
responseDone := signal.ExecuteAsync(func() error {
defer output.Close()
defer timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
reader := buf.NewBufferedReader(buf.NewReader(conn))
header, err := session.DecodeResponseHeader(reader)

118
router.go Normal file
View File

@ -0,0 +1,118 @@
package core
import (
"context"
"sync"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net"
"v2ray.com/core/transport/ray"
)
// Dispatcher is a feature that dispatches inbound requests to outbound handlers based on rules.
// Dispatcher is required to be registered in a V2Ray instance to make V2Ray function properly.
type Dispatcher interface {
Feature
// Dispatch returns a Ray for transporting data for the given request.
Dispatch(ctx context.Context, dest net.Destination) (ray.InboundRay, error)
}
type syncDispatcher struct {
sync.RWMutex
Dispatcher
}
func (d *syncDispatcher) Dispatch(ctx context.Context, dest net.Destination) (ray.InboundRay, error) {
d.RLock()
defer d.RUnlock()
if d.Dispatcher == nil {
return nil, newError("Dispatcher not set.").AtError()
}
return d.Dispatcher.Dispatch(ctx, dest)
}
func (d *syncDispatcher) Start() error {
d.RLock()
defer d.RUnlock()
if d.Dispatcher == nil {
return newError("Dispatcher not set.").AtError()
}
return d.Dispatcher.Start()
}
func (d *syncDispatcher) Close() {
d.RLock()
defer d.RUnlock()
if d.Dispatcher != nil {
d.Dispatcher.Close()
}
}
func (d *syncDispatcher) Set(disp Dispatcher) {
d.Lock()
defer d.Unlock()
d.Dispatcher = disp
}
var (
// ErrNoClue is for the situation that existing information is not enough to make a decision. For example, Router may return this error when there is no suitable route.
ErrNoClue = errors.New("not enough information for making a decision")
)
// Router is a feature to choose a outbound tag for the given request.
type Router interface {
Feature
// PickRoute returns a tag of an OutboundHandler based on the given context.
PickRoute(ctx context.Context) (string, error)
}
type syncRouter struct {
sync.RWMutex
Router
}
func (r *syncRouter) PickRoute(ctx context.Context) (string, error) {
r.RLock()
defer r.RUnlock()
if r.Router == nil {
return "", ErrNoClue
}
return r.Router.PickRoute(ctx)
}
func (r *syncRouter) Start() error {
r.RLock()
defer r.RUnlock()
if r.Router == nil {
return nil
}
return r.Router.Start()
}
func (r *syncRouter) Close() {
r.RLock()
defer r.RUnlock()
if r.Router != nil {
r.Router.Close()
}
}
func (r *syncRouter) Set(router Router) {
r.Lock()
defer r.Unlock()
r.Router = router
}

View File

@ -13,10 +13,13 @@ import (
"github.com/golang/protobuf/proto"
"v2ray.com/core"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common"
"v2ray.com/core/common/log"
"v2ray.com/core/common/net"
"v2ray.com/core/common/retry"
"v2ray.com/core/common/serial"
)
func pickPort() net.Port {
@ -70,6 +73,7 @@ func InitializeServerConfig(config *core.Config) (*exec.Cmd, error) {
return nil, err
}
config = withDefaultApps(config)
configBytes, err := proto.Marshal(config)
if err != nil {
return nil, err
@ -128,3 +132,10 @@ func CloseAllServers(servers []*exec.Cmd) {
Content: "All server closed.",
})
}
func withDefaultApps(config *core.Config) *core.Config {
config.App = append(config.App, serial.ToTypedMessage(&dispatcher.Config{}))
config.App = append(config.App, serial.ToTypedMessage(&proxyman.InboundConfig{}))
config.App = append(config.App, serial.ToTypedMessage(&proxyman.OutboundConfig{}))
return config
}

View File

@ -51,7 +51,7 @@ func TestResolveIP(t *testing.T) {
},
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -67,7 +67,7 @@ func TestResolveIP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&blackhole.Config{}),
},

View File

@ -40,7 +40,7 @@ func TestDokodemoTCP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -57,7 +57,7 @@ func TestDokodemoTCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -73,7 +73,7 @@ func TestDokodemoTCP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: &net.PortRange{From: clientPort, To: clientPort + clientPortRange},
@ -88,7 +88,7 @@ func TestDokodemoTCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -147,7 +147,7 @@ func TestDokodemoUDP(t *testing.T) {
userID := protocol.NewID(uuid.New())
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -164,7 +164,7 @@ func TestDokodemoUDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -174,7 +174,7 @@ func TestDokodemoUDP(t *testing.T) {
clientPort := uint32(pickPort())
clientPortRange := uint32(5)
clientConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: &net.PortRange{From: clientPort, To: clientPort + clientPortRange},
@ -189,7 +189,7 @@ func TestDokodemoUDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{

View File

@ -44,7 +44,7 @@ func TestPassiveConnection(t *testing.T) {
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -59,7 +59,7 @@ func TestPassiveConnection(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -115,7 +115,7 @@ func TestProxy(t *testing.T) {
serverUserID := protocol.NewID(uuid.New())
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -132,7 +132,7 @@ func TestProxy(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -142,7 +142,7 @@ func TestProxy(t *testing.T) {
proxyUserID := protocol.NewID(uuid.New())
proxyPort := pickPort()
proxyConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(proxyPort),
@ -159,7 +159,7 @@ func TestProxy(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -168,7 +168,7 @@ func TestProxy(t *testing.T) {
clientPort := pickPort()
clientConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -183,7 +183,7 @@ func TestProxy(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -263,7 +263,7 @@ func TestProxyOverKCP(t *testing.T) {
serverUserID := protocol.NewID(uuid.New())
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -283,7 +283,7 @@ func TestProxyOverKCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -293,7 +293,7 @@ func TestProxyOverKCP(t *testing.T) {
proxyUserID := protocol.NewID(uuid.New())
proxyPort := pickPort()
proxyConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(proxyPort),
@ -310,7 +310,7 @@ func TestProxyOverKCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
@ -324,7 +324,7 @@ func TestProxyOverKCP(t *testing.T) {
clientPort := pickPort()
clientConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -339,7 +339,7 @@ func TestProxyOverKCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -429,7 +429,7 @@ func TestBlackhole(t *testing.T) {
serverPort := pickPort()
serverPort2 := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -457,7 +457,7 @@ func TestBlackhole(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
Tag: "direct",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
@ -519,7 +519,7 @@ func TestForward(t *testing.T) {
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -535,7 +535,7 @@ func TestForward(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{
DestinationOverride: &freedom.DestinationOverride{
@ -585,7 +585,7 @@ func TestUDPConnection(t *testing.T) {
clientPort := pickPort()
clientConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -600,7 +600,7 @@ func TestUDPConnection(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -662,7 +662,7 @@ func TestDomainSniffing(t *testing.T) {
sniffingPort := pickPort()
httpPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
Tag: "snif",
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
@ -689,7 +689,7 @@ func TestDomainSniffing(t *testing.T) {
ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
Tag: "redir",
ProxySettings: serial.ToTypedMessage(&freedom.Config{

View File

@ -37,7 +37,7 @@ func TestHttpConformance(t *testing.T) {
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -46,7 +46,7 @@ func TestHttpConformance(t *testing.T) {
ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -92,7 +92,7 @@ func TestHttpConnectMethod(t *testing.T) {
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -101,7 +101,7 @@ func TestHttpConnectMethod(t *testing.T) {
ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -171,7 +171,7 @@ func TestHttpPost(t *testing.T) {
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -180,7 +180,7 @@ func TestHttpPost(t *testing.T) {
ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -237,7 +237,7 @@ func TestHttpBasicAuth(t *testing.T) {
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -250,7 +250,7 @@ func TestHttpBasicAuth(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},

View File

@ -49,7 +49,7 @@ func TestShadowsocksAES256TCP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -63,7 +63,7 @@ func TestShadowsocksAES256TCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -78,7 +78,7 @@ func TestShadowsocksAES256TCP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -93,7 +93,7 @@ func TestShadowsocksAES256TCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{
Server: []*protocol.ServerEndpoint{
@ -167,7 +167,7 @@ func TestShadowsocksAES128UDP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -182,7 +182,7 @@ func TestShadowsocksAES128UDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -197,7 +197,7 @@ func TestShadowsocksAES128UDP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -212,7 +212,7 @@ func TestShadowsocksAES128UDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{
Server: []*protocol.ServerEndpoint{
@ -286,7 +286,7 @@ func TestShadowsocksChacha20TCP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -300,7 +300,7 @@ func TestShadowsocksChacha20TCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -315,7 +315,7 @@ func TestShadowsocksChacha20TCP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -330,7 +330,7 @@ func TestShadowsocksChacha20TCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{
Server: []*protocol.ServerEndpoint{
@ -403,7 +403,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -417,7 +417,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -432,7 +432,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -447,7 +447,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{
Server: []*protocol.ServerEndpoint{
@ -520,7 +520,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -535,7 +535,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -550,7 +550,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -565,7 +565,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{
Server: []*protocol.ServerEndpoint{
@ -638,7 +638,7 @@ func TestShadowsocksAES256GCMConformance(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -652,7 +652,7 @@ func TestShadowsocksAES256GCMConformance(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -716,7 +716,7 @@ func TestShadowsocksChacha20Poly1305UDPConformance(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -731,7 +731,7 @@ func TestShadowsocksChacha20Poly1305UDPConformance(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -799,7 +799,7 @@ func TestShadowsocksChacha20Conformance(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -813,7 +813,7 @@ func TestShadowsocksChacha20Conformance(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},

View File

@ -30,7 +30,7 @@ func TestSocksBridgeTCP(t *testing.T) {
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -46,7 +46,7 @@ func TestSocksBridgeTCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -55,7 +55,7 @@ func TestSocksBridgeTCP(t *testing.T) {
clientPort := pickPort()
clientConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -70,7 +70,7 @@ func TestSocksBridgeTCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&socks.ClientConfig{
Server: []*protocol.ServerEndpoint{
@ -127,7 +127,7 @@ func TestSocksBridageUDP(t *testing.T) {
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -143,7 +143,7 @@ func TestSocksBridageUDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -152,7 +152,7 @@ func TestSocksBridageUDP(t *testing.T) {
clientPort := pickPort()
clientConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -167,7 +167,7 @@ func TestSocksBridageUDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&socks.ClientConfig{
Server: []*protocol.ServerEndpoint{
@ -225,7 +225,7 @@ func TestSocksConformance(t *testing.T) {
authPort := pickPort()
noAuthPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(authPort),
@ -255,7 +255,7 @@ func TestSocksConformance(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},

View File

@ -38,7 +38,7 @@ func TestSimpleTLSConnection(t *testing.T) {
userID := protocol.NewID(uuid.New())
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -63,7 +63,7 @@ func TestSimpleTLSConnection(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -72,7 +72,7 @@ func TestSimpleTLSConnection(t *testing.T) {
clientPort := pickPort()
clientConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -87,7 +87,7 @@ func TestSimpleTLSConnection(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -152,7 +152,7 @@ func TestTLSOverKCP(t *testing.T) {
userID := protocol.NewID(uuid.New())
serverPort := udp.PickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -178,7 +178,7 @@ func TestTLSOverKCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -187,7 +187,7 @@ func TestTLSOverKCP(t *testing.T) {
clientPort := pickPort()
clientConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -202,7 +202,7 @@ func TestTLSOverKCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -268,7 +268,7 @@ func TestTLSOverWebSocket(t *testing.T) {
userID := protocol.NewID(uuid.New())
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -294,7 +294,7 @@ func TestTLSOverWebSocket(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -303,7 +303,7 @@ func TestTLSOverWebSocket(t *testing.T) {
clientPort := pickPort()
clientConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -318,7 +318,7 @@ func TestTLSOverWebSocket(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{

View File

@ -35,7 +35,7 @@ func TestHttpConnectionHeader(t *testing.T) {
userID := protocol.NewID(uuid.New())
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -62,7 +62,7 @@ func TestHttpConnectionHeader(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -71,7 +71,7 @@ func TestHttpConnectionHeader(t *testing.T) {
clientPort := pickPort()
clientConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -86,7 +86,7 @@ func TestHttpConnectionHeader(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{

View File

@ -44,7 +44,7 @@ func TestVMessDynamicPort(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -84,7 +84,7 @@ func TestVMessDynamicPort(t *testing.T) {
Tag: "detour",
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -99,7 +99,7 @@ func TestVMessDynamicPort(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -114,7 +114,7 @@ func TestVMessDynamicPort(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -179,7 +179,7 @@ func TestVMessGCM(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -197,7 +197,7 @@ func TestVMessGCM(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -212,7 +212,7 @@ func TestVMessGCM(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -227,7 +227,7 @@ func TestVMessGCM(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -302,7 +302,7 @@ func TestVMessGCMUDP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -320,7 +320,7 @@ func TestVMessGCMUDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -335,7 +335,7 @@ func TestVMessGCMUDP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -350,7 +350,7 @@ func TestVMessGCMUDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -435,7 +435,7 @@ func TestVMessChacha20(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -453,7 +453,7 @@ func TestVMessChacha20(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -468,7 +468,7 @@ func TestVMessChacha20(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -483,7 +483,7 @@ func TestVMessChacha20(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -558,7 +558,7 @@ func TestVMessNone(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -576,7 +576,7 @@ func TestVMessNone(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -591,7 +591,7 @@ func TestVMessNone(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -606,7 +606,7 @@ func TestVMessNone(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -683,7 +683,7 @@ func TestVMessKCP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -704,7 +704,7 @@ func TestVMessKCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -719,7 +719,7 @@ func TestVMessKCP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -734,7 +734,7 @@ func TestVMessKCP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -816,7 +816,7 @@ func TestVMessIPv6(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -834,7 +834,7 @@ func TestVMessIPv6(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -849,7 +849,7 @@ func TestVMessIPv6(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -864,7 +864,7 @@ func TestVMessIPv6(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
@ -931,7 +931,7 @@ func TestVMessGCMMux(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -949,7 +949,7 @@ func TestVMessGCMMux(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -964,7 +964,7 @@ func TestVMessGCMMux(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -979,7 +979,7 @@ func TestVMessGCMMux(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
MultiplexSettings: &proxyman.MultiplexingConfig{
@ -1073,7 +1073,7 @@ func TestVMessGCMMuxUDP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
@ -1091,7 +1091,7 @@ func TestVMessGCMMuxUDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
@ -1107,7 +1107,7 @@ func TestVMessGCMMuxUDP(t *testing.T) {
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
@ -1135,7 +1135,7 @@ func TestVMessGCMMuxUDP(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
MultiplexSettings: &proxyman.MultiplexingConfig{

View File

@ -46,7 +46,7 @@ func (TransportProtocol) EnumDescriptor() ([]byte, []int) { return fileDescripto
type TransportConfig struct {
// Type of network that this settings supports.
Protocol TransportProtocol `protobuf:"varint,1,opt,name=protocol,enum=v2ray.core.transport.internet.TransportProtocol" json:"protocol,omitempty"`
// Specific settings.
// Specific settings. Must be of the transports.
Settings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=settings" json:"settings,omitempty"`
}
@ -74,7 +74,8 @@ type StreamConfig struct {
Protocol TransportProtocol `protobuf:"varint,1,opt,name=protocol,enum=v2ray.core.transport.internet.TransportProtocol" json:"protocol,omitempty"`
TransportSettings []*TransportConfig `protobuf:"bytes,2,rep,name=transport_settings,json=transportSettings" json:"transport_settings,omitempty"`
// Type of security. Must be a message name of the settings proto.
SecurityType string `protobuf:"bytes,3,opt,name=security_type,json=securityType" json:"security_type,omitempty"`
SecurityType string `protobuf:"bytes,3,opt,name=security_type,json=securityType" json:"security_type,omitempty"`
// Settings for transport security. For now the only choice is TLS.
SecuritySettings []*v2ray_core_common_serial.TypedMessage `protobuf:"bytes,4,rep,name=security_settings,json=securitySettings" json:"security_settings,omitempty"`
}

View File

@ -5,7 +5,7 @@ import (
"sync"
"time"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/net"
"v2ray.com/core/common/signal"
@ -23,10 +23,10 @@ type connEntry struct {
type Dispatcher struct {
sync.RWMutex
conns map[net.Destination]*connEntry
dispatcher dispatcher.Interface
dispatcher core.Dispatcher
}
func NewDispatcher(dispatcher dispatcher.Interface) *Dispatcher {
func NewDispatcher(dispatcher core.Dispatcher) *Dispatcher {
return &Dispatcher{
conns: make(map[net.Destination]*connEntry),
dispatcher: dispatcher,

197
v2ray.go
View File

@ -3,139 +3,160 @@ package core
import (
"context"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/policy"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common"
)
// Server is an instance of V2Ray. At any time, there must be at most one Server instance running.
// Deprecated. Use Instance directly.
type Server interface {
// Start starts the V2Ray server, and return any error during the process.
// In the case of any errors, the state of the server is unpredicatable.
Start() error
// Close closes the V2Ray server. All inbound and outbound connections will be closed immediately.
Close()
common.Runnable
}
// New creates a new V2Ray server with given config.
func New(config *Config) (Server, error) {
return newSimpleServer(config)
// Feature is the interface for V2Ray features. All features must implement this interface.
// All existing features have an implementation in app directory. These features can be replaced by third-party ones.
type Feature interface {
common.Runnable
}
// simpleServer shell of V2Ray.
type simpleServer struct {
space app.Space
// Instance combines all functionalities in V2Ray.
type Instance struct {
dnsClient syncDNSClient
policyManager syncPolicyManager
dispatcher syncDispatcher
router syncRouter
ihm syncInboundHandlerManager
ohm syncOutboundHandlerManager
features []Feature
}
// newSimpleServer returns a new Point server based on given configuration.
// The server is not started at this point.
func newSimpleServer(config *Config) (*simpleServer, error) {
var server = new(simpleServer)
// New returns a new V2Ray instance based on given configuration.
// The instance is not started at this point.
// To make sure V2Ray instance works properly, the config must contain one Dispatcher, one InboundHandlerManager and one OutboundHandlerManager. Other features are optional.
func New(config *Config) (*Instance, error) {
var server = new(Instance)
if err := config.Transport.Apply(); err != nil {
return nil, err
}
space := app.NewSpace()
ctx := app.ContextWithSpace(context.Background(), space)
server.space = space
ctx := context.WithValue(context.Background(), v2rayKey, server)
for _, appSettings := range config.App {
settings, err := appSettings.GetInstance()
if err != nil {
return nil, err
}
application, err := app.CreateAppFromConfig(ctx, settings)
app, err := common.CreateObject(ctx, settings)
if err != nil {
return nil, err
}
if err := space.AddApplication(application); err != nil {
return nil, err
f, ok := app.(Feature)
if !ok {
return nil, newError("not a feature")
}
}
outboundHandlerManager := proxyman.OutboundHandlerManagerFromSpace(space)
if outboundHandlerManager == nil {
o, err := app.CreateAppFromConfig(ctx, new(proxyman.OutboundConfig))
if err != nil {
return nil, err
}
if err := space.AddApplication(o); err != nil {
return nil, newError("failed to add default outbound handler manager").Base(err)
}
outboundHandlerManager = o.(proxyman.OutboundHandlerManager)
}
inboundHandlerManager := proxyman.InboundHandlerManagerFromSpace(space)
if inboundHandlerManager == nil {
o, err := app.CreateAppFromConfig(ctx, new(proxyman.InboundConfig))
if err != nil {
return nil, err
}
if err := space.AddApplication(o); err != nil {
return nil, newError("failed to add default inbound handler manager").Base(err)
}
inboundHandlerManager = o.(proxyman.InboundHandlerManager)
}
if disp := dispatcher.FromSpace(space); disp == nil {
d, err := app.CreateAppFromConfig(ctx, new(dispatcher.Config))
if err != nil {
return nil, err
}
common.Must(space.AddApplication(d))
}
if p := policy.FromSpace(space); p == nil {
p, err := app.CreateAppFromConfig(ctx, &policy.Config{
Level: map[uint32]*policy.Policy{
1: {
Timeout: &policy.Policy_Timeout{
ConnectionIdle: &policy.Second{
Value: 600,
},
},
},
},
})
if err != nil {
return nil, err
}
common.Must(space.AddApplication(p))
server.features = append(server.features, f)
}
for _, inbound := range config.Inbound {
if err := inboundHandlerManager.AddHandler(ctx, inbound); err != nil {
rawHandler, err := common.CreateObject(ctx, inbound)
if err != nil {
return nil, err
}
handler, ok := rawHandler.(InboundHandler)
if !ok {
return nil, newError("not an InboundHandler")
}
if err := server.InboundHandlerManager().AddHandler(ctx, handler); err != nil {
return nil, err
}
}
for _, outbound := range config.Outbound {
if err := outboundHandlerManager.AddHandler(ctx, outbound); err != nil {
rawHandler, err := common.CreateObject(ctx, outbound)
if err != nil {
return nil, err
}
handler, ok := rawHandler.(OutboundHandler)
if !ok {
return nil, newError("not an OutboundHandler")
}
if err := server.OutboundHandlerManager().AddHandler(ctx, handler); err != nil {
return nil, err
}
}
if err := server.space.Initialize(); err != nil {
return nil, err
}
return server, nil
}
func (s *simpleServer) Close() {
s.space.Close()
// Close shutdown the V2Ray instance.
func (s *Instance) Close() {
for _, f := range s.features {
f.Close()
}
}
func (s *simpleServer) Start() error {
if err := s.space.Start(); err != nil {
return err
// Start starts the V2Ray instance, including all registered features. When Start returns error, the state of the instance is unknown.
func (s *Instance) Start() error {
for _, f := range s.features {
if err := f.Start(); err != nil {
return nil
}
}
newError("V2Ray started").AtWarning().WriteToLog()
return nil
}
// RegisterFeature registers the given feature into V2Ray.
// If feature is one of the following types, the corressponding feature in this Instance
// will be replaced: DNSClient, PolicyManager, Router, Dispatcher, InboundHandlerManager, OutboundHandlerManager.
func (s *Instance) RegisterFeature(feature interface{}, instance Feature) error {
switch feature.(type) {
case DNSClient, *DNSClient:
s.dnsClient.Set(instance.(DNSClient))
case PolicyManager, *PolicyManager:
s.policyManager.Set(instance.(PolicyManager))
case Router, *Router:
s.router.Set(instance.(Router))
case Dispatcher, *Dispatcher:
s.dispatcher.Set(instance.(Dispatcher))
case InboundHandlerManager, *InboundHandlerManager:
s.ihm.Set(instance.(InboundHandlerManager))
case OutboundHandlerManager, *OutboundHandlerManager:
s.ohm.Set(instance.(OutboundHandlerManager))
}
s.features = append(s.features, instance)
return nil
}
// DNSClient returns the DNSClient used by this Instance. The returned DNSClient is always functional.
func (s *Instance) DNSClient() DNSClient {
return &(s.dnsClient)
}
// PolicyManager returns the PolicyManager used by this Instance. The returned PolicyManager is always functional.
func (s *Instance) PolicyManager() PolicyManager {
return &(s.policyManager)
}
// Router returns the Router used by this Instance. The returned Router is always functional.
func (s *Instance) Router() Router {
return &(s.router)
}
// Dispatcher returns the Dispatcher used by this Instance. If Dispatcher was not registered before, the returned value doesn't work, although it is not nil.
func (s *Instance) Dispatcher() Dispatcher {
return &(s.dispatcher)
}
// InboundHandlerManager returns the InboundHandlerManager used by this Instance. If InboundHandlerManager was not registered before, the returned value doesn't work.
func (s *Instance) InboundHandlerManager() InboundHandlerManager {
return &(s.ihm)
}
// OutboundHandlerManager returns the OutboundHandlerManager used by this Instance. If OutboundHandlerManager was not registered before, the returned value doesn't work.
func (s *Instance) OutboundHandlerManager() OutboundHandlerManager {
return &(s.ohm)
}

View File

@ -22,7 +22,7 @@ func TestV2RayClose(t *testing.T) {
port := net.Port(dice.RollUint16())
config := &Config{
Inbound: []*proxyman.InboundHandlerConfig{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(port),
@ -37,7 +37,7 @@ func TestV2RayClose(t *testing.T) {
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{