1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-09 17:30:44 +00:00

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 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 //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" "context"
"time" "time"
"v2ray.com/core/app" "v2ray.com/core"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/app/router"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
@ -21,31 +19,27 @@ var (
errSniffingTimeout = newError("timeout on sniffing") errSniffingTimeout = newError("timeout on sniffing")
) )
var (
_ app.Application = (*DefaultDispatcher)(nil)
)
// DefaultDispatcher is a default implementation of Dispatcher. // DefaultDispatcher is a default implementation of Dispatcher.
type DefaultDispatcher struct { type DefaultDispatcher struct {
ohm proxyman.OutboundHandlerManager ohm core.OutboundHandlerManager
router *router.Router router core.Router
} }
// NewDefaultDispatcher create a new DefaultDispatcher. // NewDefaultDispatcher create a new DefaultDispatcher.
func NewDefaultDispatcher(ctx context.Context, config *dispatcher.Config) (*DefaultDispatcher, error) { func NewDefaultDispatcher(ctx context.Context, config *Config) (*DefaultDispatcher, error) {
space := app.SpaceFromContext(ctx) v := core.FromContext(ctx)
if space == nil { if v == nil {
return nil, newError("no space in context") 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 return d, nil
} }
@ -57,12 +51,7 @@ func (*DefaultDispatcher) Start() error {
// Close implements app.Application. // Close implements app.Application.
func (*DefaultDispatcher) Close() {} func (*DefaultDispatcher) Close() {}
// Interface implements app.Application. // Dispatch implements core.Dispatcher.
func (*DefaultDispatcher) Interface() interface{} {
return (*dispatcher.Interface)(nil)
}
// Dispatch implements Dispatcher.Interface.
func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destination) (ray.InboundRay, error) { func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destination) (ray.InboundRay, error) {
if !destination.IsValid() { if !destination.IsValid() {
panic("Dispatcher: Invalid destination.") 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) { func (d *DefaultDispatcher) routedDispatch(ctx context.Context, outbound ray.OutboundRay, destination net.Destination) {
dispatcher := d.ohm.GetDefaultHandler() dispatcher := d.ohm.GetDefaultHandler()
if d.router != nil { 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 { if handler := d.ohm.GetHandler(tag); handler != nil {
newError("taking detour [", tag, "] for [", destination, "]").WriteToLog() newError("taking detour [", tag, "] for [", destination, "]").WriteToLog()
dispatcher = handler dispatcher = handler
@ -135,7 +124,7 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, outbound ray.Out
} }
func init() { func init() {
common.Must(common.RegisterConfig((*dispatcher.Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewDefaultDispatcher(ctx, config.(*dispatcher.Config)) return NewDefaultDispatcher(ctx, config.(*Config))
})) }))
} }

View File

@ -1,21 +1,3 @@
package dispatcher package dispatcher
import ( //go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg dispatcher -path App,Dispatcher
"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
}

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 ( import (
"bytes" "bytes"

View File

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

View File

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

View File

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

View File

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

View File

@ -2,10 +2,15 @@ package policy
import ( import (
"time" "time"
"v2ray.com/core"
) )
// Duration converts Second to time.Duration. // Duration converts Second to time.Duration.
func (s *Second) Duration() time.Duration { func (s *Second) Duration() time.Duration {
if s == nil {
return 0
}
return time.Second * time.Duration(s.Value) 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" 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 package policy
import ( //go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg policy -path App,Policy
"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)
}

View File

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

View File

@ -6,7 +6,6 @@ option go_package = "proxyman";
option java_package = "com.v2ray.core.app.proxyman"; option java_package = "com.v2ray.core.app.proxyman";
option java_multiple_files = true; 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/address.proto";
import "v2ray.com/core/common/net/port.proto"; import "v2ray.com/core/common/net/port.proto";
import "v2ray.com/core/transport/internet/config.proto"; import "v2ray.com/core/transport/internet/config.proto";
@ -61,15 +60,6 @@ message ReceiverConfig {
repeated KnownProtocols domain_override = 7; 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 { message OutboundConfig {
} }
@ -82,19 +72,6 @@ message SenderConfig {
MultiplexingConfig multiplex_settings = 4; 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 { message MultiplexingConfig {
// Whether or not Mux is enabled. // Whether or not Mux is enabled.
bool enabled = 1; bool enabled = 1;

View File

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

View File

@ -14,6 +14,7 @@ type AlwaysOnInboundHandler struct {
proxy proxy.Inbound proxy proxy.Inbound
workers []worker workers []worker
mux *mux.Server mux *mux.Server
tag string
} }
func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *proxyman.ReceiverConfig, proxyConfig interface{}) (*AlwaysOnInboundHandler, error) { 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{ h := &AlwaysOnInboundHandler{
proxy: p, proxy: p,
mux: mux.NewServer(ctx), mux: mux.NewServer(ctx),
tag: tag,
} }
nl := p.Network() 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 { if len(h.workers) == 0 {
return nil, 0, 0 return nil, 0, 0
} }
w := h.workers[dice.Roll(len(h.workers))] w := h.workers[dice.Roll(len(h.workers))]
return w.Proxy(), w.Port(), 9999 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() h.cancel()
} }
func (h *DynamicInboundHandler) GetRandomInboundProxy() (proxy.Inbound, net.Port, int) { func (h *DynamicInboundHandler) GetRandomInboundProxy() (interface{}, net.Port, int) {
h.workerMutex.RLock() h.workerMutex.RLock()
defer h.workerMutex.RUnlock() 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) expire := h.receiverConfig.AllocationStrategy.GetRefreshValue() - uint32(time.Since(h.lastRefresh)/time.Minute)
return w.Proxy(), w.Port(), int(expire) return w.Proxy(), w.Port(), int(expire)
} }
func (h *DynamicInboundHandler) Tag() string {
return h.tag
}

View File

@ -5,64 +5,41 @@ package inbound
import ( import (
"context" "context"
"v2ray.com/core"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/common" "v2ray.com/core/common"
) )
// Manager is to manage all inbound handlers. // Manager is to manage all inbound handlers.
type Manager struct { type Manager struct {
handlers []proxyman.InboundHandler handlers []core.InboundHandler
taggedHandlers map[string]proxyman.InboundHandler taggedHandlers map[string]core.InboundHandler
} }
func New(ctx context.Context, config *proxyman.InboundConfig) (*Manager, error) { func New(ctx context.Context, config *proxyman.InboundConfig) (*Manager, error) {
return &Manager{ m := &Manager{
taggedHandlers: make(map[string]proxyman.InboundHandler), taggedHandlers: make(map[string]core.InboundHandler),
}, nil }
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 { func (m *Manager) AddHandler(ctx context.Context, handler core.InboundHandler) 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()
}
m.handlers = append(m.handlers, handler) m.handlers = append(m.handlers, handler)
tag := handler.Tag()
if len(tag) > 0 { if len(tag) > 0 {
m.taggedHandlers[tag] = handler m.taggedHandlers[tag] = handler
} }
return nil 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] handler, found := m.taggedHandlers[tag]
if !found { if !found {
return nil, newError("handler not found: ", tag) return nil, newError("handler not found: ", tag)
@ -85,12 +62,36 @@ func (m *Manager) Close() {
} }
} }
func (m *Manager) Interface() interface{} { func NewHandler(ctx context.Context, config *core.InboundHandlerConfig) (core.InboundHandler, error) {
return (*proxyman.InboundHandlerManager)(nil) 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() { func init() {
common.Must(common.RegisterConfig((*proxyman.InboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { common.Must(common.RegisterConfig((*proxyman.InboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*proxyman.InboundConfig)) 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" "sync/atomic"
"time" "time"
"v2ray.com/core/app/dispatcher" "v2ray.com/core"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
@ -31,7 +31,7 @@ type tcpWorker struct {
stream *internet.StreamConfig stream *internet.StreamConfig
recvOrigDest bool recvOrigDest bool
tag string tag string
dispatcher dispatcher.Interface dispatcher core.Dispatcher
sniffers []proxyman.KnownProtocols sniffers []proxyman.KnownProtocols
ctx context.Context ctx context.Context
@ -185,7 +185,7 @@ type udpWorker struct {
port net.Port port net.Port
recvOrigDest bool recvOrigDest bool
tag string tag string
dispatcher dispatcher.Interface dispatcher core.Dispatcher
ctx context.Context ctx context.Context
cancel context.CancelFunc cancel context.CancelFunc

View File

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

View File

@ -5,7 +5,7 @@ import (
"io" "io"
"time" "time"
"v2ray.com/core/app" "v2ray.com/core"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/app/proxyman/mux" "v2ray.com/core/app/proxyman/mux"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
@ -17,29 +17,22 @@ import (
) )
type Handler struct { type Handler struct {
config *proxyman.OutboundHandlerConfig config *core.OutboundHandlerConfig
senderSettings *proxyman.SenderConfig senderSettings *proxyman.SenderConfig
proxy proxy.Outbound proxy proxy.Outbound
outboundManager proxyman.OutboundHandlerManager outboundManager core.OutboundHandlerManager
mux *mux.ClientManager 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{ 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 { if config.SenderSettings != nil {
senderSettings, err := config.SenderSettings.GetInstance() 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 { if err != nil {
return nil, err return nil, err
} }
@ -71,6 +69,10 @@ func NewHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) (*H
return h, nil return h, nil
} }
func (h *Handler) Tag() string {
return h.config.Tag
}
// Dispatch implements proxy.Outbound.Dispatch. // Dispatch implements proxy.Outbound.Dispatch.
func (h *Handler) Dispatch(ctx context.Context, outboundRay ray.OutboundRay) { func (h *Handler) Dispatch(ctx context.Context, outboundRay ray.OutboundRay) {
if h.mux != nil { 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" "context"
"sync" "sync"
"v2ray.com/core"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/common" "v2ray.com/core/common"
) )
@ -13,20 +14,23 @@ import (
// Manager is to manage all outbound handlers. // Manager is to manage all outbound handlers.
type Manager struct { type Manager struct {
sync.RWMutex sync.RWMutex
defaultHandler *Handler defaultHandler core.OutboundHandler
taggedHandler map[string]*Handler taggedHandler map[string]core.OutboundHandler
} }
// New creates a new Manager. // New creates a new Manager.
func New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager, error) { func New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager, error) {
return &Manager{ m := &Manager{
taggedHandler: make(map[string]*Handler), taggedHandler: make(map[string]core.OutboundHandler),
}, nil }
} v := core.FromContext(ctx)
if v == nil {
// Interface implements Application.Interface. return nil, newError("V is not in context")
func (*Manager) Interface() interface{} { }
return (*proxyman.OutboundHandlerManager)(nil) 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 // Start implements Application.Start
@ -35,7 +39,7 @@ func (*Manager) Start() error { return nil }
// Close implements Application.Close // Close implements Application.Close
func (*Manager) Close() {} func (*Manager) Close() {}
func (m *Manager) GetDefaultHandler() proxyman.OutboundHandler { func (m *Manager) GetDefaultHandler() core.OutboundHandler {
m.RLock() m.RLock()
defer m.RUnlock() defer m.RUnlock()
if m.defaultHandler == nil { if m.defaultHandler == nil {
@ -44,7 +48,7 @@ func (m *Manager) GetDefaultHandler() proxyman.OutboundHandler {
return m.defaultHandler return m.defaultHandler
} }
func (m *Manager) GetHandler(tag string) proxyman.OutboundHandler { func (m *Manager) GetHandler(tag string) core.OutboundHandler {
m.RLock() m.RLock()
defer m.RUnlock() defer m.RUnlock()
if handler, found := m.taggedHandler[tag]; found { if handler, found := m.taggedHandler[tag]; found {
@ -53,20 +57,17 @@ func (m *Manager) GetHandler(tag string) proxyman.OutboundHandler {
return nil 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() m.Lock()
defer m.Unlock() defer m.Unlock()
handler, err := NewHandler(ctx, config)
if err != nil {
return err
}
if m.defaultHandler == nil { if m.defaultHandler == nil {
m.defaultHandler = handler m.defaultHandler = handler
} }
if len(config.Tag) > 0 { tag := handler.Tag()
m.taggedHandler[config.Tag] = handler if len(tag) > 0 {
m.taggedHandler[tag] = handler
} }
return nil return nil
@ -76,4 +77,7 @@ func init() {
common.Must(common.RegisterConfig((*proxyman.OutboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { common.Must(common.RegisterConfig((*proxyman.OutboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*proxyman.OutboundConfig)) 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 ( import (
"context" "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 type key int
const ( const (

View File

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

View File

@ -4,13 +4,14 @@ import (
"context" "context"
"testing" "testing"
"v2ray.com/core/app" "v2ray.com/core"
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
_ "v2ray.com/core/app/dispatcher/impl"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
_ "v2ray.com/core/app/proxyman/outbound" _ "v2ray.com/core/app/proxyman/outbound"
. "v2ray.com/core/app/router" . "v2ray.com/core/app/router"
"v2ray.com/core/common"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
. "v2ray.com/ext/assert" . "v2ray.com/ext/assert"
) )
@ -18,28 +19,30 @@ import (
func TestSimpleRouter(t *testing.T) { func TestSimpleRouter(t *testing.T) {
assert := With(t) assert := With(t)
config := &Config{ config := &core.Config{
Rule: []*RoutingRule{ App: []*serial.TypedMessage{
{ serial.ToTypedMessage(&Config{
Tag: "test", Rule: []*RoutingRule{
NetworkList: &net.NetworkList{ {
Network: []net.Network{net.Network_TCP}, Tag: "test",
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_TCP},
},
},
}, },
}, }),
serial.ToTypedMessage(&dispatcher.Config{}),
serial.ToTypedMessage(&proxyman.OutboundConfig{}),
}, },
} }
space := app.NewSpace() v, err := core.New(config)
ctx := app.ContextWithSpace(context.Background(), space) common.Must(err)
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)
r := FromSpace(space) r := v.Router()
ctx = proxy.ContextWithTarget(ctx, net.TCPDestination(net.DomainAddress("v2ray.com"), 80)) ctx := proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("v2ray.com"), 80))
tag, err := r.TakeDetour(ctx) tag, err := r.PickRoute(ctx)
assert(err, IsNil) assert(err, IsNil)
assert(tag, Equals, "test") 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 { type User struct {
Level uint32 `protobuf:"varint,1,opt,name=level" json:"level,omitempty"` Level uint32 `protobuf:"varint,1,opt,name=level" json:"level,omitempty"`
Email string `protobuf:"bytes,2,opt,name=email" json:"email,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"` 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 proto "github.com/golang/protobuf/proto"
import fmt "fmt" import fmt "fmt"
import math "math" 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_common_serial "v2ray.com/core/common/serial"
import v2ray_core_transport "v2ray.com/core/transport" 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} } 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 { type Config struct {
// Inbound handler configurations. Must have at least one item. // 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 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 configuration. Must be one in the app directory.
App []*v2ray_core_common_serial.TypedMessage `protobuf:"bytes,4,rep,name=app" json:"app,omitempty"` App []*v2ray_core_common_serial.TypedMessage `protobuf:"bytes,4,rep,name=app" json:"app,omitempty"`
// Transport settings. // Transport settings.
@ -60,14 +59,14 @@ func (m *Config) String() string { return proto.CompactTextString(m)
func (*Config) ProtoMessage() {} func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } 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 { if m != nil {
return m.Inbound return m.Inbound
} }
return nil return nil
} }
func (m *Config) GetOutbound() []*v2ray_core_app_proxyman.OutboundHandlerConfig { func (m *Config) GetOutbound() []*OutboundHandlerConfig {
if m != nil { if m != nil {
return m.Outbound return m.Outbound
} }
@ -95,34 +94,131 @@ func (m *Config) GetExtension() []*v2ray_core_common_serial.TypedMessage {
return nil 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() { func init() {
proto.RegisterType((*Config)(nil), "v2ray.core.Config") 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) proto.RegisterEnum("v2ray.core.ConfigFormat", ConfigFormat_name, ConfigFormat_value)
} }
func init() { proto.RegisterFile("v2ray.com/core/config.proto", fileDescriptor0) } func init() { proto.RegisterFile("v2ray.com/core/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 336 bytes of a gzipped FileDescriptorProto // 436 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0xcd, 0x4a, 0xf3, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0x41, 0x6f, 0xd3, 0x30,
0x18, 0x85, 0xbf, 0xb4, 0xf9, 0x6a, 0xfa, 0xb6, 0x48, 0x99, 0x55, 0xa8, 0x2e, 0x8a, 0xd0, 0x52, 0x14, 0xc7, 0x71, 0x13, 0xba, 0xf6, 0x6d, 0x94, 0x60, 0x01, 0xb2, 0x06, 0x87, 0x50, 0x69, 0x53,
0x04, 0x27, 0x12, 0x37, 0xe2, 0xd2, 0x8a, 0x3f, 0x05, 0x6d, 0xa9, 0xe2, 0xc2, 0x8d, 0x4c, 0xd3, 0xc5, 0xc1, 0x45, 0xe5, 0x82, 0x26, 0x71, 0x61, 0x08, 0xc1, 0xa4, 0xd1, 0x29, 0x45, 0x1c, 0xb8,
0x69, 0x09, 0x74, 0xe6, 0x1d, 0x26, 0x53, 0x69, 0x6e, 0xc9, 0x9b, 0xf2, 0x56, 0x24, 0x99, 0xfe, 0x4c, 0x6e, 0xfa, 0x56, 0x45, 0x5a, 0xec, 0xc8, 0x76, 0xa7, 0xe6, 0x2b, 0xf1, 0x3d, 0xb8, 0xf1,
0xa5, 0xe2, 0xc2, 0x55, 0x20, 0x73, 0x9e, 0xe7, 0x4c, 0x4e, 0xe0, 0xe8, 0x23, 0xd4, 0x2c, 0xa5, 0x8d, 0xb8, 0xa0, 0xc4, 0x49, 0x93, 0x41, 0x0f, 0x14, 0x69, 0xa7, 0xc4, 0x79, 0xfe, 0xfd, 0xdf,
0x11, 0x8a, 0x20, 0x42, 0xcd, 0x83, 0x08, 0xe5, 0x34, 0x9e, 0x51, 0xa5, 0xd1, 0x20, 0x81, 0xf5, 0xfb, 0x25, 0x31, 0x3c, 0xbb, 0x99, 0x68, 0x91, 0xf3, 0x58, 0xa5, 0xe3, 0x58, 0x69, 0x1c, 0xc7,
0xa1, 0xe6, 0xcd, 0xee, 0x5e, 0x90, 0x29, 0x15, 0x28, 0x8d, 0xcb, 0x54, 0x30, 0x59, 0xa0, 0x9a, 0x4a, 0x5e, 0x25, 0x4b, 0x9e, 0x69, 0x65, 0x15, 0x85, 0xba, 0xa8, 0xf1, 0xf0, 0xd5, 0x5f, 0x1b,
0xe7, 0x3f, 0x94, 0x42, 0xa0, 0x0c, 0x12, 0xae, 0x63, 0x36, 0x0f, 0x4c, 0xaa, 0xf8, 0xe4, 0x5d, 0xd3, 0x54, 0xc9, 0xb1, 0x41, 0x9d, 0x88, 0xeb, 0xb1, 0xcd, 0x33, 0x5c, 0x5c, 0xa6, 0x68, 0x8c,
0xf0, 0x24, 0x61, 0x33, 0xbe, 0x22, 0xda, 0x7b, 0x84, 0xd1, 0x4c, 0x26, 0x0a, 0xb5, 0x29, 0x88, 0x58, 0xa2, 0xa3, 0x0f, 0x8f, 0xfe, 0x20, 0xac, 0x16, 0xd2, 0x64, 0x4a, 0xdb, 0x5b, 0x4d, 0x86,
0x4f, 0xbe, 0x4a, 0x50, 0xe9, 0xe5, 0x2f, 0xc8, 0x1d, 0x1c, 0xc4, 0x72, 0x8c, 0x0b, 0x39, 0xf1, 0x3f, 0x3a, 0xd0, 0x3d, 0x2d, 0x1f, 0xd0, 0x13, 0xd8, 0x4b, 0xe4, 0x5c, 0xad, 0xe4, 0x82, 0x91,
0x9d, 0x56, 0xb9, 0x5b, 0x0b, 0xcf, 0xe8, 0xf6, 0xae, 0x94, 0x29, 0x45, 0xd7, 0x77, 0xa3, 0x0f, 0xd0, 0x1b, 0xed, 0x4f, 0x42, 0xde, 0x4c, 0xc0, 0x3f, 0xb9, 0xd2, 0x47, 0x21, 0x17, 0xd7, 0xa8,
0x36, 0x77, 0xcf, 0xe4, 0x64, 0xce, 0xb5, 0xe5, 0x47, 0x6b, 0x9a, 0xf4, 0xc1, 0xc3, 0x85, 0xb1, 0x1d, 0x12, 0xd5, 0x00, 0x7d, 0x0b, 0x3d, 0xb5, 0xb2, 0x0e, 0xee, 0x94, 0xf0, 0x8b, 0x36, 0x3c,
0xa6, 0x52, 0x6e, 0xa2, 0xbf, 0x9a, 0x06, 0xab, 0x60, 0x51, 0xb5, 0xe1, 0xc9, 0x25, 0x94, 0x99, 0xad, 0x6a, 0xb7, 0xe9, 0x0d, 0x42, 0xdf, 0x80, 0x27, 0xb2, 0x8c, 0xf9, 0x25, 0x79, 0xdc, 0x26,
0x52, 0xbe, 0x9b, 0x6b, 0x3a, 0xbb, 0x1a, 0x3b, 0x01, 0xb5, 0x13, 0xd0, 0x97, 0x6c, 0x82, 0x47, 0x9d, 0x28, 0x77, 0xa2, 0xfc, 0x4b, 0x21, 0x7a, 0xee, 0x3c, 0xa3, 0x02, 0xa1, 0x27, 0xd0, 0xdf,
0xbb, 0xc0, 0x28, 0x43, 0xc8, 0x15, 0x54, 0x37, 0xdf, 0xec, 0xff, 0x6f, 0x39, 0xdd, 0x5a, 0x78, 0x98, 0xb1, 0xfb, 0x21, 0x19, 0xed, 0x4f, 0x9e, 0xb7, 0xf9, 0x4d, 0x91, 0x57, 0x4d, 0x9b, 0xed,
0xbc, 0xcb, 0x6f, 0x0e, 0xe9, 0xaa, 0x74, 0x1b, 0x27, 0x37, 0x50, 0xe5, 0x4b, 0xc3, 0x65, 0x12, 0xf4, 0x3d, 0xf4, 0x71, 0x6d, 0x51, 0x9a, 0x44, 0x49, 0xd6, 0xdd, 0xa9, 0x77, 0x03, 0x9e, 0xf9,
0xa3, 0xf4, 0x2b, 0x7f, 0xea, 0xde, 0x82, 0x7d, 0xd7, 0x2b, 0x37, 0xdc, 0xd3, 0x0e, 0xd4, 0x6d, 0x3d, 0x2f, 0xf0, 0x87, 0x3f, 0x09, 0x3c, 0xde, 0xf6, 0x8a, 0x68, 0x00, 0x9e, 0x15, 0x4b, 0x46,
0xc1, 0x2d, 0x6a, 0xc1, 0x0c, 0xa9, 0x83, 0x37, 0xcc, 0xa6, 0x1f, 0x2f, 0xa6, 0x8d, 0x7f, 0xc4, 0x42, 0x32, 0xea, 0x47, 0xc5, 0x2d, 0x9d, 0xc1, 0x23, 0x8d, 0x31, 0x26, 0x37, 0xa8, 0x2f, 0x0d,
0x03, 0xb7, 0xff, 0x3c, 0x78, 0x6a, 0x38, 0xd7, 0x6d, 0x38, 0x8c, 0x50, 0xec, 0xb4, 0x0c, 0x9d, 0x5a, 0x9b, 0xc8, 0xa5, 0x61, 0x9d, 0x72, 0xf4, 0x7f, 0x6d, 0x1f, 0xd4, 0x01, 0xb3, 0x8a, 0xa7,
0x37, 0x37, 0x7b, 0x7e, 0x96, 0xe0, 0x35, 0x1c, 0xb1, 0x94, 0xf6, 0x50, 0xf3, 0x71, 0x25, 0xff, 0xe7, 0x30, 0xc8, 0xb4, 0x5a, 0xe7, 0x4d, 0xa2, 0xb7, 0x53, 0xe2, 0x83, 0x92, 0xae, 0xe3, 0x86,
0x6f, 0x17, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x62, 0x93, 0x6d, 0x78, 0x65, 0x02, 0x00, 0x00, 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_package = "com.v2ray.core";
option java_multiple_files = true; 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/common/serial/typed_message.proto";
import "v2ray.com/core/transport/config.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. // Master config of V2Ray. V2Ray takes this config as input and functions accordingly.
message Config { message Config {
// Inbound handler configurations. Must have at least one item. // 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. // 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; reserved 3;
@ -36,3 +35,25 @@ message Config {
// V2Ray will ignore such config during initialization. // V2Ray will ignore such config during initialization.
repeated v2ray.core.common.serial.TypedMessage extension = 6; 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 ( import (
// The following are necessary as they register handlers in their init functions. // 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/dns"
_ "v2ray.com/core/app/log" _ "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/inbound"
_ "v2ray.com/core/app/proxyman/outbound" _ "v2ray.com/core/app/proxyman/outbound"
_ "v2ray.com/core/app/router" _ "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 ( import (
"context" "context"
"time"
"v2ray.com/core/app" "v2ray.com/core"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/policy"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
@ -18,36 +17,29 @@ import (
) )
type DokodemoDoor struct { type DokodemoDoor struct {
config *Config policyManager core.PolicyManager
address net.Address config *Config
port net.Port address net.Address
policy policy.Policy port net.Port
v *core.Instance
} }
func New(ctx context.Context, config *Config) (*DokodemoDoor, error) { 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 { if config.NetworkList == nil || config.NetworkList.Size() == 0 {
return nil, newError("no network specified") return nil, newError("no network specified")
} }
d := &DokodemoDoor{ v := core.FromContext(ctx)
config: config, if v == nil {
address: config.GetPredefinedAddress(), return nil, newError("V is not in context.")
port: net.Port(config.Port),
} }
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space) d := &DokodemoDoor{
if pm == nil { config: config,
return newError("Policy not found in space.") address: config.GetPredefinedAddress(),
} port: net.Port(config.Port),
d.policy = pm.GetPolicy(config.UserLevel) policyManager: v.PolicyManager(),
if config.Timeout > 0 && config.UserLevel == 0 { }
d.policy.Timeout.ConnectionIdle.Value = config.Timeout
}
return nil
})
return d, nil return d, nil
} }
@ -55,7 +47,16 @@ func (d *DokodemoDoor) Network() net.NetworkList {
return *(d.config.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() newError("processing connection from: ", conn.RemoteAddr()).AtDebug().WriteToLog()
dest := net.Destination{ dest := net.Destination{
Network: network, Network: network,
@ -72,7 +73,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
} }
ctx, cancel := context.WithCancel(ctx) 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) inboundRay, err := dispatcher.Dispatch(ctx, dest)
if err != nil { 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) return newError("failed to transport request").Base(err)
} }
timer.SetTimeout(d.policy.Timeout.DownlinkOnly.Duration()) timer.SetTimeout(d.policy().Timeouts.DownlinkOnly)
return nil 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) return newError("failed to transport response").Base(err)
} }
timer.SetTimeout(d.policy.Timeout.UplinkOnly.Duration()) timer.SetTimeout(d.policy().Timeouts.UplinkOnly)
return nil return nil
}) })

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,9 +5,7 @@ import (
"io" "io"
"time" "time"
"v2ray.com/core/app" "v2ray.com/core"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/policy"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
@ -22,32 +20,30 @@ import (
// Server is a SOCKS 5 proxy server // Server is a SOCKS 5 proxy server
type Server struct { type Server struct {
config *ServerConfig config *ServerConfig
policy policy.Policy v *core.Instance
} }
// NewServer creates a new Server object. // NewServer creates a new Server object.
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { 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{ s := &Server{
config: config, 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 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 { func (s *Server) Network() net.NetworkList {
list := net.NetworkList{ list := net.NetworkList{
Network: []net.Network{net.Network_TCP}, Network: []net.Network{net.Network_TCP},
@ -58,7 +54,7 @@ func (s *Server) Network() net.NetworkList {
return list 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 { switch network {
case net.Network_TCP: case net.Network_TCP:
return s.processTCP(ctx, conn, dispatcher) 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 { func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispatcher core.Dispatcher) error {
conn.SetReadDeadline(time.Now().Add(s.policy.Timeout.Handshake.Duration())) conn.SetReadDeadline(time.Now().Add(s.policy().Timeouts.Handshake))
reader := buf.NewBufferedReader(buf.NewReader(conn)) reader := buf.NewBufferedReader(buf.NewReader(conn))
inboundDest, ok := proxy.InboundEntryPointFromContext(ctx) inboundDest, ok := proxy.InboundEntryPointFromContext(ctx)
@ -125,9 +121,9 @@ func (*Server) handleUDP(c net.Conn) error {
return err 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) 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) ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil { 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 { if err := buf.Copy(v2reader, input, buf.UpdateActivity(timer)); err != nil {
return newError("failed to transport all TCP request").Base(err) 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 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 { if err := buf.Copy(output, v2writer, buf.UpdateActivity(timer)); err != nil {
return newError("failed to transport all TCP response").Base(err) 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 return nil
}) })
@ -166,7 +162,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
return nil 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) udpServer := udp.NewDispatcher(dispatcher)
if source, ok := proxy.SourceFromContext(ctx); ok { if source, ok := proxy.SourceFromContext(ctx); ok {

View File

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

View File

@ -6,8 +6,7 @@ import (
"context" "context"
"time" "time"
"v2ray.com/core/app" "v2ray.com/core"
"v2ray.com/core/app/policy"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
@ -23,17 +22,12 @@ import (
// Handler is an outbound connection handler for VMess protocol. // Handler is an outbound connection handler for VMess protocol.
type Handler struct { type Handler struct {
serverList *protocol.ServerList serverList *protocol.ServerList
serverPicker protocol.ServerPicker serverPicker protocol.ServerPicker
policyManager policy.Manager v *core.Instance
} }
func New(ctx context.Context, config *Config) (*Handler, error) { 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() serverList := protocol.NewServerList()
for _, rec := range config.Receiver { for _, rec := range config.Receiver {
serverList.AddServer(protocol.NewServerSpecFromPB(*rec)) serverList.AddServer(protocol.NewServerSpecFromPB(*rec))
@ -41,16 +35,12 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
handler := &Handler{ handler := &Handler{
serverList: serverList, serverList: serverList,
serverPicker: protocol.NewRoundRobinServerPicker(serverList), serverPicker: protocol.NewRoundRobinServerPicker(serverList),
v: core.FromContext(ctx),
} }
space.On(app.SpaceInitializing, func(interface{}) error { if handler.v == nil {
pm := policy.FromSpace(space) return nil, newError("V is not in context.")
if pm == nil { }
return newError("Policy is not found in space.")
}
handler.policyManager = pm
return nil
})
return handler, nil return handler, nil
} }
@ -112,10 +102,10 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
output := outboundRay.OutboundOutput() output := outboundRay.OutboundOutput()
session := encoding.NewClientSession(protocol.DefaultIDHash) 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) 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 { requestDone := signal.ExecuteAsync(func() error {
writer := buf.NewBufferedWriter(buf.NewWriter(conn)) writer := buf.NewBufferedWriter(buf.NewWriter(conn))
@ -148,13 +138,13 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
return err return err
} }
} }
timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration()) timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
return nil return nil
}) })
responseDone := signal.ExecuteAsync(func() error { responseDone := signal.ExecuteAsync(func() error {
defer output.Close() defer output.Close()
defer timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration()) defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
reader := buf.NewBufferedReader(buf.NewReader(conn)) reader := buf.NewBufferedReader(buf.NewReader(conn))
header, err := session.DecodeResponseHeader(reader) 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" "github.com/golang/protobuf/proto"
"v2ray.com/core" "v2ray.com/core"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/retry" "v2ray.com/core/common/retry"
"v2ray.com/core/common/serial"
) )
func pickPort() net.Port { func pickPort() net.Port {
@ -70,6 +73,7 @@ func InitializeServerConfig(config *core.Config) (*exec.Cmd, error) {
return nil, err return nil, err
} }
config = withDefaultApps(config)
configBytes, err := proto.Marshal(config) configBytes, err := proto.Marshal(config)
if err != nil { if err != nil {
return nil, err return nil, err
@ -128,3 +132,10 @@ func CloseAllServers(servers []*exec.Cmd) {
Content: "All server closed.", 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{ ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort), PortRange: net.SinglePortRange(serverPort),
@ -67,7 +67,7 @@ func TestResolveIP(t *testing.T) {
}), }),
}, },
}, },
Outbound: []*proxyman.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&blackhole.Config{}), ProxySettings: serial.ToTypedMessage(&blackhole.Config{}),
}, },

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,7 +46,7 @@ func (TransportProtocol) EnumDescriptor() ([]byte, []int) { return fileDescripto
type TransportConfig struct { type TransportConfig struct {
// Type of network that this settings supports. // Type of network that this settings supports.
Protocol TransportProtocol `protobuf:"varint,1,opt,name=protocol,enum=v2ray.core.transport.internet.TransportProtocol" json:"protocol,omitempty"` 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"` 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"` 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"` 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. // 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"` 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" "sync"
"time" "time"
"v2ray.com/core/app/dispatcher" "v2ray.com/core"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/signal" "v2ray.com/core/common/signal"
@ -23,10 +23,10 @@ type connEntry struct {
type Dispatcher struct { type Dispatcher struct {
sync.RWMutex sync.RWMutex
conns map[net.Destination]*connEntry 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{ return &Dispatcher{
conns: make(map[net.Destination]*connEntry), conns: make(map[net.Destination]*connEntry),
dispatcher: dispatcher, dispatcher: dispatcher,

197
v2ray.go
View File

@ -3,139 +3,160 @@ package core
import ( import (
"context" "context"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/policy"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common" "v2ray.com/core/common"
) )
// Server is an instance of V2Ray. At any time, there must be at most one Server instance running. // 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 { type Server interface {
// Start starts the V2Ray server, and return any error during the process. common.Runnable
// 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()
} }
// New creates a new V2Ray server with given config. // Feature is the interface for V2Ray features. All features must implement this interface.
func New(config *Config) (Server, error) { // All existing features have an implementation in app directory. These features can be replaced by third-party ones.
return newSimpleServer(config) type Feature interface {
common.Runnable
} }
// simpleServer shell of V2Ray. // Instance combines all functionalities in V2Ray.
type simpleServer struct { type Instance struct {
space app.Space dnsClient syncDNSClient
policyManager syncPolicyManager
dispatcher syncDispatcher
router syncRouter
ihm syncInboundHandlerManager
ohm syncOutboundHandlerManager
features []Feature
} }
// newSimpleServer returns a new Point server based on given configuration. // New returns a new V2Ray instance based on given configuration.
// The server is not started at this point. // The instance is not started at this point.
func newSimpleServer(config *Config) (*simpleServer, error) { // To make sure V2Ray instance works properly, the config must contain one Dispatcher, one InboundHandlerManager and one OutboundHandlerManager. Other features are optional.
var server = new(simpleServer) func New(config *Config) (*Instance, error) {
var server = new(Instance)
if err := config.Transport.Apply(); err != nil { if err := config.Transport.Apply(); err != nil {
return nil, err return nil, err
} }
space := app.NewSpace() ctx := context.WithValue(context.Background(), v2rayKey, server)
ctx := app.ContextWithSpace(context.Background(), space)
server.space = space
for _, appSettings := range config.App { for _, appSettings := range config.App {
settings, err := appSettings.GetInstance() settings, err := appSettings.GetInstance()
if err != nil { if err != nil {
return nil, err return nil, err
} }
application, err := app.CreateAppFromConfig(ctx, settings) app, err := common.CreateObject(ctx, settings)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := space.AddApplication(application); err != nil { f, ok := app.(Feature)
return nil, err if !ok {
return nil, newError("not a feature")
} }
} server.features = append(server.features, f)
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))
} }
for _, inbound := range config.Inbound { 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 return nil, err
} }
} }
for _, outbound := range config.Outbound { 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 return nil, err
} }
}
if err := server.space.Initialize(); err != nil {
return nil, err
} }
return server, nil return server, nil
} }
func (s *simpleServer) Close() { // Close shutdown the V2Ray instance.
s.space.Close() func (s *Instance) Close() {
for _, f := range s.features {
f.Close()
}
} }
func (s *simpleServer) Start() error { // Start starts the V2Ray instance, including all registered features. When Start returns error, the state of the instance is unknown.
if err := s.space.Start(); err != nil { func (s *Instance) Start() error {
return err for _, f := range s.features {
if err := f.Start(); err != nil {
return nil
}
} }
newError("V2Ray started").AtWarning().WriteToLog() newError("V2Ray started").AtWarning().WriteToLog()
return nil 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()) port := net.Port(dice.RollUint16())
config := &Config{ config := &Config{
Inbound: []*proxyman.InboundHandlerConfig{ Inbound: []*core.InboundHandlerConfig{
{ {
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(port), PortRange: net.SinglePortRange(port),
@ -37,7 +37,7 @@ func TestV2RayClose(t *testing.T) {
}), }),
}, },
}, },
Outbound: []*proxyman.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&outbound.Config{ ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{ Receiver: []*protocol.ServerEndpoint{