mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-30 05:56:54 -05:00
massive refactoring for interoperability
This commit is contained in:
parent
5a3c7fdd20
commit
292d7cc353
@ -1,3 +1 @@
|
||||
package app
|
||||
|
||||
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg app -path App
|
||||
|
@ -1,4 +1,4 @@
|
||||
package impl
|
||||
package dispatcher
|
||||
|
||||
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg impl -path App,Dispatcher,Default
|
||||
|
||||
@ -6,10 +6,8 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
"v2ray.com/core/app/router"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/net"
|
||||
@ -21,31 +19,27 @@ var (
|
||||
errSniffingTimeout = newError("timeout on sniffing")
|
||||
)
|
||||
|
||||
var (
|
||||
_ app.Application = (*DefaultDispatcher)(nil)
|
||||
)
|
||||
|
||||
// DefaultDispatcher is a default implementation of Dispatcher.
|
||||
type DefaultDispatcher struct {
|
||||
ohm proxyman.OutboundHandlerManager
|
||||
router *router.Router
|
||||
ohm core.OutboundHandlerManager
|
||||
router core.Router
|
||||
}
|
||||
|
||||
// NewDefaultDispatcher create a new DefaultDispatcher.
|
||||
func NewDefaultDispatcher(ctx context.Context, config *dispatcher.Config) (*DefaultDispatcher, error) {
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context")
|
||||
func NewDefaultDispatcher(ctx context.Context, config *Config) (*DefaultDispatcher, error) {
|
||||
v := core.FromContext(ctx)
|
||||
if v == nil {
|
||||
return nil, newError("V is not in context.")
|
||||
}
|
||||
|
||||
d := &DefaultDispatcher{
|
||||
ohm: v.OutboundHandlerManager(),
|
||||
router: v.Router(),
|
||||
}
|
||||
|
||||
if err := v.RegisterFeature((*core.Dispatcher)(nil), d); err != nil {
|
||||
return nil, newError("unable to register Dispatcher")
|
||||
}
|
||||
d := &DefaultDispatcher{}
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
d.ohm = proxyman.OutboundHandlerManagerFromSpace(space)
|
||||
if d.ohm == nil {
|
||||
return newError("OutboundHandlerManager is not found in the space")
|
||||
}
|
||||
d.router = router.FromSpace(space)
|
||||
return nil
|
||||
})
|
||||
return d, nil
|
||||
}
|
||||
|
||||
@ -57,12 +51,7 @@ func (*DefaultDispatcher) Start() error {
|
||||
// Close implements app.Application.
|
||||
func (*DefaultDispatcher) Close() {}
|
||||
|
||||
// Interface implements app.Application.
|
||||
func (*DefaultDispatcher) Interface() interface{} {
|
||||
return (*dispatcher.Interface)(nil)
|
||||
}
|
||||
|
||||
// Dispatch implements Dispatcher.Interface.
|
||||
// Dispatch implements core.Dispatcher.
|
||||
func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destination) (ray.InboundRay, error) {
|
||||
if !destination.IsValid() {
|
||||
panic("Dispatcher: Invalid destination.")
|
||||
@ -120,7 +109,7 @@ func snifer(ctx context.Context, sniferList []proxyman.KnownProtocols, outbound
|
||||
func (d *DefaultDispatcher) routedDispatch(ctx context.Context, outbound ray.OutboundRay, destination net.Destination) {
|
||||
dispatcher := d.ohm.GetDefaultHandler()
|
||||
if d.router != nil {
|
||||
if tag, err := d.router.TakeDetour(ctx); err == nil {
|
||||
if tag, err := d.router.PickRoute(ctx); err == nil {
|
||||
if handler := d.ohm.GetHandler(tag); handler != nil {
|
||||
newError("taking detour [", tag, "] for [", destination, "]").WriteToLog()
|
||||
dispatcher = handler
|
||||
@ -135,7 +124,7 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, outbound ray.Out
|
||||
}
|
||||
|
||||
func init() {
|
||||
common.Must(common.RegisterConfig((*dispatcher.Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||
return NewDefaultDispatcher(ctx, config.(*dispatcher.Config))
|
||||
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||
return NewDefaultDispatcher(ctx, config.(*Config))
|
||||
}))
|
||||
}
|
@ -1,21 +1,3 @@
|
||||
package dispatcher
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/common/net"
|
||||
"v2ray.com/core/transport/ray"
|
||||
)
|
||||
|
||||
// Interface dispatch a packet and possibly further network payload to its destination.
|
||||
type Interface interface {
|
||||
Dispatch(ctx context.Context, dest net.Destination) (ray.InboundRay, error)
|
||||
}
|
||||
|
||||
func FromSpace(space app.Space) Interface {
|
||||
if app := space.GetApplication((*Interface)(nil)); app != nil {
|
||||
return app.(Interface)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg dispatcher -path App,Dispatcher
|
||||
|
5
app/dispatcher/errors.generated.go
Normal file
5
app/dispatcher/errors.generated.go
Normal 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") }
|
@ -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")
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package impl
|
||||
package dispatcher
|
||||
|
||||
import (
|
||||
"bytes"
|
@ -1,11 +1,10 @@
|
||||
package impl_test
|
||||
package dispatcher_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
|
||||
. "v2ray.com/core/app/dispatcher/impl"
|
||||
. "v2ray.com/ext/assert"
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/dice"
|
||||
"v2ray.com/core/common/net"
|
||||
@ -48,7 +48,7 @@ type UDPNameServer struct {
|
||||
nextCleanup time.Time
|
||||
}
|
||||
|
||||
func NewUDPNameServer(address net.Destination, dispatcher dispatcher.Interface) *UDPNameServer {
|
||||
func NewUDPNameServer(address net.Destination, dispatcher core.Dispatcher) *UDPNameServer {
|
||||
s := &UDPNameServer{
|
||||
address: address,
|
||||
requests: make(map[uint16]*PendingRequest),
|
||||
|
@ -1,6 +1,6 @@
|
||||
package dns
|
||||
|
||||
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg server -path App,DNS,Server
|
||||
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg dns -path App,DNS
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -8,8 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
dnsmsg "github.com/miekg/dns"
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/net"
|
||||
)
|
||||
@ -41,39 +40,38 @@ type Server struct {
|
||||
}
|
||||
|
||||
func New(ctx context.Context, config *Config) (*Server, error) {
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context")
|
||||
}
|
||||
server := &Server{
|
||||
records: make(map[string]*DomainRecord),
|
||||
servers: make([]NameServer, len(config.NameServers)),
|
||||
hosts: config.GetInternalHosts(),
|
||||
}
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
disp := dispatcher.FromSpace(space)
|
||||
if disp == nil {
|
||||
return newError("dispatcher is not found in the space")
|
||||
}
|
||||
for idx, destPB := range config.NameServers {
|
||||
address := destPB.Address.AsAddress()
|
||||
if address.Family().IsDomain() && address.Domain() == "localhost" {
|
||||
server.servers[idx] = &LocalNameServer{}
|
||||
} else {
|
||||
dest := destPB.AsDestination()
|
||||
if dest.Network == net.Network_Unknown {
|
||||
dest.Network = net.Network_UDP
|
||||
}
|
||||
if dest.Network == net.Network_UDP {
|
||||
server.servers[idx] = NewUDPNameServer(dest, disp)
|
||||
}
|
||||
v := core.FromContext(ctx)
|
||||
if v == nil {
|
||||
return nil, newError("V is not in context.")
|
||||
}
|
||||
|
||||
if err := v.RegisterFeature((*core.DNSClient)(nil), server); err != nil {
|
||||
return nil, newError("unable to register DNSClient.").Base(err)
|
||||
}
|
||||
|
||||
for idx, destPB := range config.NameServers {
|
||||
address := destPB.Address.AsAddress()
|
||||
if address.Family().IsDomain() && address.Domain() == "localhost" {
|
||||
server.servers[idx] = &LocalNameServer{}
|
||||
} else {
|
||||
dest := destPB.AsDestination()
|
||||
if dest.Network == net.Network_Unknown {
|
||||
dest.Network = net.Network_UDP
|
||||
}
|
||||
if dest.Network == net.Network_UDP {
|
||||
server.servers[idx] = NewUDPNameServer(dest, v.Dispatcher())
|
||||
}
|
||||
}
|
||||
if len(config.NameServers) == 0 {
|
||||
server.servers = append(server.servers, &LocalNameServer{})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
if len(config.NameServers) == 0 {
|
||||
server.servers = append(server.servers, &LocalNameServer{})
|
||||
}
|
||||
|
||||
return server, nil
|
||||
}
|
||||
|
||||
@ -82,12 +80,10 @@ func (*Server) Interface() interface{} {
|
||||
}
|
||||
|
||||
func (s *Server) Start() error {
|
||||
net.RegisterIPResolver(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*Server) Close() {
|
||||
net.RegisterIPResolver(net.SystemIPResolver())
|
||||
}
|
||||
|
||||
func (s *Server) GetCached(domain string) []net.IP {
|
||||
|
@ -1,18 +1,14 @@
|
||||
package dns_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
_ "v2ray.com/core/app/dispatcher/impl"
|
||||
. "v2ray.com/core/app/dns"
|
||||
"v2ray.com/core/app/policy"
|
||||
_ "v2ray.com/core/app/policy/manager"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
"v2ray.com/core/app/policy"
|
||||
_ "v2ray.com/core/app/proxyman/outbound"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/serial"
|
||||
"v2ray.com/core/proxy/freedom"
|
||||
@ -54,50 +50,50 @@ func TestUDPServer(t *testing.T) {
|
||||
|
||||
go dnsServer.ListenAndServe()
|
||||
|
||||
config := &Config{
|
||||
NameServers: []*net.Endpoint{
|
||||
{
|
||||
Network: net.Network_UDP,
|
||||
Address: &net.IPOrDomain{
|
||||
Address: &net.IPOrDomain_Ip{
|
||||
Ip: []byte{127, 0, 0, 1},
|
||||
config := &core.Config{
|
||||
App: []*serial.TypedMessage{
|
||||
serial.ToTypedMessage(&Config{
|
||||
NameServers: []*net.Endpoint{
|
||||
{
|
||||
Network: net.Network_UDP,
|
||||
Address: &net.IPOrDomain{
|
||||
Address: &net.IPOrDomain_Ip{
|
||||
Ip: []byte{127, 0, 0, 1},
|
||||
},
|
||||
},
|
||||
Port: uint32(port),
|
||||
},
|
||||
},
|
||||
Port: uint32(port),
|
||||
}),
|
||||
serial.ToTypedMessage(&dispatcher.Config{}),
|
||||
serial.ToTypedMessage(&proxyman.OutboundConfig{}),
|
||||
serial.ToTypedMessage(&policy.Config{}),
|
||||
},
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
&core.OutboundHandlerConfig{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
space := app.NewSpace()
|
||||
v, err := core.New(config)
|
||||
assert(err, IsNil)
|
||||
|
||||
ctx = app.ContextWithSpace(ctx, space)
|
||||
common.Must(app.AddApplicationToSpace(ctx, config))
|
||||
common.Must(app.AddApplicationToSpace(ctx, &dispatcher.Config{}))
|
||||
common.Must(app.AddApplicationToSpace(ctx, &proxyman.OutboundConfig{}))
|
||||
common.Must(app.AddApplicationToSpace(ctx, &policy.Config{}))
|
||||
client := v.DNSClient()
|
||||
|
||||
om := proxyman.OutboundHandlerManagerFromSpace(space)
|
||||
om.AddHandler(ctx, &proxyman.OutboundHandlerConfig{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
})
|
||||
|
||||
common.Must(space.Initialize())
|
||||
common.Must(space.Start())
|
||||
|
||||
ips, err := net.LookupIP("google.com")
|
||||
ips, err := client.LookupIP("google.com")
|
||||
assert(err, IsNil)
|
||||
assert(len(ips), Equals, 1)
|
||||
assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})
|
||||
|
||||
ips, err = net.LookupIP("facebook.com")
|
||||
ips, err = client.LookupIP("facebook.com")
|
||||
assert(err, IsNil)
|
||||
assert(len(ips), Equals, 1)
|
||||
assert([]byte(ips[0]), Equals, []byte{9, 9, 9, 9})
|
||||
|
||||
dnsServer.Shutdown()
|
||||
|
||||
ips, err = net.LookupIP("google.com")
|
||||
ips, err = client.LookupIP("google.com")
|
||||
assert(err, IsNil)
|
||||
assert(len(ips), Equals, 1)
|
||||
assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})
|
||||
|
@ -2,10 +2,15 @@ package policy
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"v2ray.com/core"
|
||||
)
|
||||
|
||||
// Duration converts Second to time.Duration.
|
||||
func (s *Second) Duration() time.Duration {
|
||||
if s == nil {
|
||||
return 0
|
||||
}
|
||||
return time.Second * time.Duration(s.Value)
|
||||
}
|
||||
|
||||
@ -26,3 +31,14 @@ func (p *Policy) OverrideWith(another *Policy) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Policy) ToCorePolicy() core.Policy {
|
||||
var cp core.Policy
|
||||
if p.Timeout != nil {
|
||||
cp.Timeouts.ConnectionIdle = p.Timeout.ConnectionIdle.Duration()
|
||||
cp.Timeouts.Handshake = p.Timeout.Handshake.Duration()
|
||||
cp.Timeouts.DownlinkOnly = p.Timeout.DownlinkOnly.Duration()
|
||||
cp.Timeouts.UplinkOnly = p.Timeout.UplinkOnly.Duration()
|
||||
}
|
||||
return cp
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
package app
|
||||
package policy
|
||||
|
||||
import "v2ray.com/core/common/errors"
|
||||
|
||||
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App") }
|
||||
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App", "Policy") }
|
61
app/policy/manager.go
Normal file
61
app/policy/manager.go
Normal 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))
|
||||
}))
|
||||
}
|
@ -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))
|
||||
}))
|
||||
}
|
@ -1,20 +1,3 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"v2ray.com/core/app"
|
||||
)
|
||||
|
||||
// Manager is an utility to manage policy per user level.
|
||||
type Manager interface {
|
||||
// GetPolicy returns the Policy for the given user level.
|
||||
GetPolicy(level uint32) Policy
|
||||
}
|
||||
|
||||
// FromSpace returns the policy.Manager in a space.
|
||||
func FromSpace(space app.Space) Manager {
|
||||
app := space.GetApplication((*Manager)(nil))
|
||||
if app == nil {
|
||||
return nil
|
||||
}
|
||||
return app.(Manager)
|
||||
}
|
||||
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg policy -path App,Policy
|
||||
|
@ -1,11 +1,5 @@
|
||||
package proxyman
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"v2ray.com/core/proxy"
|
||||
)
|
||||
|
||||
func (s *AllocationStrategy) GetConcurrencyValue() uint32 {
|
||||
if s == nil || s.Concurrency == nil {
|
||||
return 3
|
||||
@ -19,14 +13,3 @@ func (s *AllocationStrategy) GetRefreshValue() uint32 {
|
||||
}
|
||||
return s.Refresh.Value
|
||||
}
|
||||
|
||||
func (c *OutboundHandlerConfig) GetProxyHandler(ctx context.Context) (proxy.Outbound, error) {
|
||||
if c == nil {
|
||||
return nil, newError("OutboundHandlerConfig is nil")
|
||||
}
|
||||
config, err := c.ProxySettings.GetInstance()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proxy.CreateOutboundHandler(ctx, config)
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package proxyman
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import v2ray_core_common_serial "v2ray.com/core/common/serial"
|
||||
import v2ray_core_common_net "v2ray.com/core/common/net"
|
||||
import v2ray_core_common_net1 "v2ray.com/core/common/net"
|
||||
import v2ray_core_transport_internet "v2ray.com/core/transport/internet"
|
||||
@ -211,45 +210,13 @@ func (m *ReceiverConfig) GetDomainOverride() []KnownProtocols {
|
||||
return nil
|
||||
}
|
||||
|
||||
type InboundHandlerConfig struct {
|
||||
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
|
||||
ReceiverSettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=receiver_settings,json=receiverSettings" json:"receiver_settings,omitempty"`
|
||||
ProxySettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"`
|
||||
}
|
||||
|
||||
func (m *InboundHandlerConfig) Reset() { *m = InboundHandlerConfig{} }
|
||||
func (m *InboundHandlerConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*InboundHandlerConfig) ProtoMessage() {}
|
||||
func (*InboundHandlerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
||||
|
||||
func (m *InboundHandlerConfig) GetTag() string {
|
||||
if m != nil {
|
||||
return m.Tag
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *InboundHandlerConfig) GetReceiverSettings() *v2ray_core_common_serial.TypedMessage {
|
||||
if m != nil {
|
||||
return m.ReceiverSettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *InboundHandlerConfig) GetProxySettings() *v2ray_core_common_serial.TypedMessage {
|
||||
if m != nil {
|
||||
return m.ProxySettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type OutboundConfig struct {
|
||||
}
|
||||
|
||||
func (m *OutboundConfig) Reset() { *m = OutboundConfig{} }
|
||||
func (m *OutboundConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*OutboundConfig) ProtoMessage() {}
|
||||
func (*OutboundConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
|
||||
func (*OutboundConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
||||
|
||||
type SenderConfig struct {
|
||||
// Send traffic through the given IP. Only IP is allowed.
|
||||
@ -262,7 +229,7 @@ type SenderConfig struct {
|
||||
func (m *SenderConfig) Reset() { *m = SenderConfig{} }
|
||||
func (m *SenderConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*SenderConfig) ProtoMessage() {}
|
||||
func (*SenderConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
|
||||
func (*SenderConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
|
||||
|
||||
func (m *SenderConfig) GetVia() *v2ray_core_common_net.IPOrDomain {
|
||||
if m != nil {
|
||||
@ -292,54 +259,6 @@ func (m *SenderConfig) GetMultiplexSettings() *MultiplexingConfig {
|
||||
return nil
|
||||
}
|
||||
|
||||
type OutboundHandlerConfig struct {
|
||||
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
|
||||
SenderSettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=sender_settings,json=senderSettings" json:"sender_settings,omitempty"`
|
||||
ProxySettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"`
|
||||
Expire int64 `protobuf:"varint,4,opt,name=expire" json:"expire,omitempty"`
|
||||
Comment string `protobuf:"bytes,5,opt,name=comment" json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
func (m *OutboundHandlerConfig) Reset() { *m = OutboundHandlerConfig{} }
|
||||
func (m *OutboundHandlerConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*OutboundHandlerConfig) ProtoMessage() {}
|
||||
func (*OutboundHandlerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
|
||||
|
||||
func (m *OutboundHandlerConfig) GetTag() string {
|
||||
if m != nil {
|
||||
return m.Tag
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *OutboundHandlerConfig) GetSenderSettings() *v2ray_core_common_serial.TypedMessage {
|
||||
if m != nil {
|
||||
return m.SenderSettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *OutboundHandlerConfig) GetProxySettings() *v2ray_core_common_serial.TypedMessage {
|
||||
if m != nil {
|
||||
return m.ProxySettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *OutboundHandlerConfig) GetExpire() int64 {
|
||||
if m != nil {
|
||||
return m.Expire
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *OutboundHandlerConfig) GetComment() string {
|
||||
if m != nil {
|
||||
return m.Comment
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type MultiplexingConfig struct {
|
||||
// Whether or not Mux is enabled.
|
||||
Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"`
|
||||
@ -350,7 +269,7 @@ type MultiplexingConfig struct {
|
||||
func (m *MultiplexingConfig) Reset() { *m = MultiplexingConfig{} }
|
||||
func (m *MultiplexingConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*MultiplexingConfig) ProtoMessage() {}
|
||||
func (*MultiplexingConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
|
||||
func (*MultiplexingConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
|
||||
|
||||
func (m *MultiplexingConfig) GetEnabled() bool {
|
||||
if m != nil {
|
||||
@ -372,10 +291,8 @@ func init() {
|
||||
proto.RegisterType((*AllocationStrategy_AllocationStrategyConcurrency)(nil), "v2ray.core.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency")
|
||||
proto.RegisterType((*AllocationStrategy_AllocationStrategyRefresh)(nil), "v2ray.core.app.proxyman.AllocationStrategy.AllocationStrategyRefresh")
|
||||
proto.RegisterType((*ReceiverConfig)(nil), "v2ray.core.app.proxyman.ReceiverConfig")
|
||||
proto.RegisterType((*InboundHandlerConfig)(nil), "v2ray.core.app.proxyman.InboundHandlerConfig")
|
||||
proto.RegisterType((*OutboundConfig)(nil), "v2ray.core.app.proxyman.OutboundConfig")
|
||||
proto.RegisterType((*SenderConfig)(nil), "v2ray.core.app.proxyman.SenderConfig")
|
||||
proto.RegisterType((*OutboundHandlerConfig)(nil), "v2ray.core.app.proxyman.OutboundHandlerConfig")
|
||||
proto.RegisterType((*MultiplexingConfig)(nil), "v2ray.core.app.proxyman.MultiplexingConfig")
|
||||
proto.RegisterEnum("v2ray.core.app.proxyman.KnownProtocols", KnownProtocols_name, KnownProtocols_value)
|
||||
proto.RegisterEnum("v2ray.core.app.proxyman.AllocationStrategy_Type", AllocationStrategy_Type_name, AllocationStrategy_Type_value)
|
||||
@ -384,57 +301,49 @@ func init() {
|
||||
func init() { proto.RegisterFile("v2ray.com/core/app/proxyman/config.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 822 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xd1, 0x8e, 0xdb, 0x44,
|
||||
0x14, 0xad, 0xe3, 0x34, 0xc9, 0xde, 0xed, 0x7a, 0xdd, 0xa1, 0xd0, 0x10, 0x40, 0x0a, 0x01, 0xd1,
|
||||
0xa8, 0x20, 0xa7, 0xa4, 0xe2, 0x81, 0x27, 0x58, 0x76, 0x2b, 0x75, 0x81, 0x55, 0xcc, 0x24, 0xe2,
|
||||
0xa1, 0x42, 0xb2, 0x66, 0xed, 0xa9, 0x19, 0x61, 0xcf, 0x58, 0x33, 0x93, 0x74, 0xfd, 0x4b, 0x7c,
|
||||
0x05, 0x8f, 0x3c, 0xf0, 0x05, 0xfc, 0x0a, 0x2f, 0xc8, 0x9e, 0x71, 0x76, 0xb7, 0x49, 0x5a, 0x96,
|
||||
0xaa, 0x6f, 0x33, 0xc9, 0x39, 0xc7, 0x73, 0xcf, 0x3d, 0x77, 0x06, 0xc6, 0xab, 0xa9, 0x24, 0x65,
|
||||
0x10, 0x8b, 0x7c, 0x12, 0x0b, 0x49, 0x27, 0xa4, 0x28, 0x26, 0x85, 0x14, 0x17, 0x65, 0x4e, 0xf8,
|
||||
0x24, 0x16, 0xfc, 0x39, 0x4b, 0x83, 0x42, 0x0a, 0x2d, 0xd0, 0xfd, 0x06, 0x29, 0x69, 0x40, 0x8a,
|
||||
0x22, 0x68, 0x50, 0x83, 0x47, 0x2f, 0x49, 0xc4, 0x22, 0xcf, 0x05, 0x9f, 0x28, 0x2a, 0x19, 0xc9,
|
||||
0x26, 0xba, 0x2c, 0x68, 0x12, 0xe5, 0x54, 0x29, 0x92, 0x52, 0x23, 0x35, 0x78, 0xb0, 0x9d, 0xc1,
|
||||
0xa9, 0x9e, 0x90, 0x24, 0x91, 0x54, 0x29, 0x0b, 0xfc, 0x74, 0x37, 0xb0, 0x10, 0x52, 0x5b, 0x54,
|
||||
0xf0, 0x12, 0x4a, 0x4b, 0xc2, 0x55, 0xf5, 0xff, 0x84, 0x71, 0x4d, 0x65, 0x85, 0xbe, 0x5a, 0xc9,
|
||||
0xe8, 0x10, 0x0e, 0x4e, 0xf9, 0xb9, 0x58, 0xf2, 0xe4, 0xb8, 0xfe, 0x79, 0xf4, 0x87, 0x0b, 0xe8,
|
||||
0x28, 0xcb, 0x44, 0x4c, 0x34, 0x13, 0x7c, 0xae, 0x25, 0xd1, 0x34, 0x2d, 0xd1, 0x09, 0xb4, 0xab,
|
||||
0xd3, 0xf7, 0x9d, 0xa1, 0x33, 0xf6, 0xa6, 0x8f, 0x82, 0x1d, 0x06, 0x04, 0x9b, 0xd4, 0x60, 0x51,
|
||||
0x16, 0x14, 0xd7, 0x6c, 0xf4, 0x1b, 0xec, 0xc7, 0x82, 0xc7, 0x4b, 0x29, 0x29, 0x8f, 0xcb, 0x7e,
|
||||
0x6b, 0xe8, 0x8c, 0xf7, 0xa7, 0xa7, 0x37, 0x11, 0xdb, 0xfc, 0xe9, 0xf8, 0x52, 0x10, 0x5f, 0x55,
|
||||
0x47, 0x11, 0x74, 0x25, 0x7d, 0x2e, 0xa9, 0xfa, 0xb5, 0xef, 0xd6, 0x1f, 0x7a, 0xf2, 0x66, 0x1f,
|
||||
0xc2, 0x46, 0x0c, 0x37, 0xaa, 0x83, 0xaf, 0xe0, 0xa3, 0x57, 0x1e, 0x07, 0xdd, 0x83, 0xdb, 0x2b,
|
||||
0x92, 0x2d, 0x8d, 0x6b, 0x07, 0xd8, 0x6c, 0x06, 0x5f, 0xc2, 0xfb, 0x3b, 0xc5, 0xb7, 0x53, 0x46,
|
||||
0x5f, 0x40, 0xbb, 0x72, 0x11, 0x01, 0x74, 0x8e, 0xb2, 0x17, 0xa4, 0x54, 0xfe, 0xad, 0x6a, 0x8d,
|
||||
0x09, 0x4f, 0x44, 0xee, 0x3b, 0xe8, 0x0e, 0xf4, 0x9e, 0x5c, 0x54, 0xed, 0x25, 0x99, 0xdf, 0x1a,
|
||||
0xfd, 0xed, 0x82, 0x87, 0x69, 0x4c, 0xd9, 0x8a, 0x4a, 0xd3, 0x55, 0xf4, 0x0d, 0x40, 0x15, 0x82,
|
||||
0x48, 0x12, 0x9e, 0x1a, 0xed, 0xfd, 0xe9, 0xf0, 0xaa, 0x1d, 0x26, 0x4d, 0x01, 0xa7, 0x3a, 0x08,
|
||||
0x85, 0xd4, 0xb8, 0xc2, 0xe1, 0xbd, 0xa2, 0x59, 0xa2, 0xaf, 0xa1, 0x93, 0x31, 0xa5, 0x29, 0xb7,
|
||||
0x4d, 0xfb, 0x78, 0x07, 0xf9, 0x34, 0x9c, 0xc9, 0x13, 0x91, 0x13, 0xc6, 0xb1, 0x25, 0xa0, 0x5f,
|
||||
0xe0, 0x1d, 0xb2, 0xae, 0x37, 0x52, 0xb6, 0x60, 0xdb, 0x93, 0xcf, 0x6f, 0xd0, 0x13, 0x8c, 0xc8,
|
||||
0x66, 0x30, 0x17, 0x70, 0xa8, 0xb4, 0xa4, 0x24, 0x8f, 0x14, 0xd5, 0x9a, 0xf1, 0x54, 0xf5, 0xdb,
|
||||
0x9b, 0xca, 0xeb, 0x31, 0x08, 0x9a, 0x31, 0x08, 0xe6, 0x35, 0xcb, 0xf8, 0x83, 0x3d, 0xa3, 0x31,
|
||||
0xb7, 0x12, 0xe8, 0x5b, 0xf8, 0x50, 0x1a, 0x07, 0x23, 0x21, 0x59, 0xca, 0x38, 0xc9, 0xa2, 0x84,
|
||||
0x2a, 0xcd, 0x78, 0xfd, 0xf5, 0xfe, 0xed, 0xa1, 0x33, 0xee, 0xe1, 0x81, 0xc5, 0xcc, 0x2c, 0xe4,
|
||||
0xe4, 0x12, 0x81, 0x42, 0x38, 0x4c, 0x6a, 0x1f, 0x22, 0xb1, 0xa2, 0x52, 0xb2, 0x84, 0xf6, 0xbb,
|
||||
0x43, 0x77, 0xec, 0x4d, 0x1f, 0xec, 0xac, 0xf8, 0x07, 0x2e, 0x5e, 0xf0, 0xb0, 0x1a, 0xcb, 0x58,
|
||||
0x64, 0x0a, 0x7b, 0x86, 0x3f, 0xb3, 0xf4, 0xef, 0xdb, 0xbd, 0x8e, 0xdf, 0x1d, 0xfd, 0xe5, 0xc0,
|
||||
0x3d, 0x3b, 0xb1, 0x4f, 0x09, 0x4f, 0xb2, 0x75, 0x8b, 0x7d, 0x70, 0x35, 0x49, 0xeb, 0xde, 0xee,
|
||||
0xe1, 0x6a, 0x89, 0xe6, 0x70, 0xd7, 0x1e, 0x50, 0x5e, 0x9a, 0x63, 0xda, 0xf7, 0xd9, 0x96, 0xf6,
|
||||
0x99, 0x4b, 0xaa, 0x1e, 0xd7, 0xe4, 0xcc, 0xdc, 0x51, 0xd8, 0x6f, 0x04, 0xd6, 0xce, 0x9c, 0x81,
|
||||
0x57, 0x1f, 0xf8, 0x52, 0xd1, 0xbd, 0x91, 0xe2, 0x41, 0xcd, 0x6e, 0xe4, 0x46, 0x3e, 0x78, 0xb3,
|
||||
0xa5, 0xbe, 0x7a, 0x01, 0xfd, 0xd9, 0x82, 0x3b, 0x73, 0xca, 0x93, 0x75, 0x61, 0x8f, 0xc1, 0x5d,
|
||||
0x31, 0x62, 0x43, 0xfb, 0x1f, 0x72, 0x57, 0xa1, 0xb7, 0xc5, 0xa2, 0xf5, 0xe6, 0xb1, 0xf8, 0x69,
|
||||
0x47, 0xf1, 0x0f, 0x5f, 0x23, 0x1a, 0x56, 0x24, 0xab, 0x79, 0xdd, 0x00, 0xf4, 0x0c, 0x50, 0xbe,
|
||||
0xcc, 0x34, 0x2b, 0x32, 0x7a, 0xf1, 0xca, 0x08, 0x5f, 0x8b, 0xca, 0x59, 0x43, 0x61, 0x3c, 0xb5,
|
||||
0xba, 0x77, 0xd7, 0x32, 0x6b, 0x73, 0xff, 0x71, 0xe0, 0xdd, 0xc6, 0xdd, 0xd7, 0x85, 0x65, 0x06,
|
||||
0x87, 0xaa, 0x76, 0xfd, 0xff, 0x46, 0xc5, 0x33, 0xf4, 0xb7, 0x14, 0x14, 0xf4, 0x1e, 0x74, 0xe8,
|
||||
0x45, 0xc1, 0x24, 0xad, 0xbd, 0x71, 0xb1, 0xdd, 0xa1, 0x3e, 0x74, 0x2b, 0x11, 0xca, 0x75, 0x3d,
|
||||
0x94, 0x7b, 0xb8, 0xd9, 0x8e, 0x42, 0x40, 0x9b, 0x36, 0x55, 0x78, 0xca, 0xc9, 0x79, 0x46, 0x93,
|
||||
0xba, 0xfa, 0x1e, 0x6e, 0xb6, 0x68, 0xb8, 0xf9, 0x38, 0x1d, 0x5c, 0x7b, 0x51, 0x1e, 0x7e, 0x02,
|
||||
0xde, 0xf5, 0x19, 0x45, 0x3d, 0x68, 0x3f, 0x5d, 0x2c, 0x42, 0xff, 0x16, 0xea, 0x82, 0xbb, 0xf8,
|
||||
0x71, 0xee, 0x3b, 0xdf, 0x1d, 0xc3, 0x07, 0xb1, 0xc8, 0x77, 0x75, 0x2e, 0x74, 0x9e, 0xf5, 0x9a,
|
||||
0xf5, 0xef, 0xad, 0xfb, 0x3f, 0x4f, 0x31, 0x29, 0x83, 0xe3, 0x0a, 0x75, 0x54, 0x14, 0x26, 0x27,
|
||||
0x39, 0xe1, 0xe7, 0x9d, 0xfa, 0x75, 0x7e, 0xfc, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x25, 0xdf,
|
||||
0x6a, 0xb2, 0x93, 0x08, 0x00, 0x00,
|
||||
// 691 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x94, 0x5d, 0x6f, 0xd3, 0x3a,
|
||||
0x1c, 0xc6, 0x97, 0xb6, 0x6b, 0x7b, 0xfe, 0x5b, 0xb3, 0x1c, 0x9f, 0x23, 0x2d, 0xa7, 0x07, 0xa4,
|
||||
0x52, 0x90, 0x56, 0x0d, 0x94, 0x40, 0x27, 0x2e, 0xb8, 0x82, 0xd1, 0x4d, 0x62, 0xbc, 0xa8, 0xc1,
|
||||
0xad, 0xb8, 0x98, 0x90, 0x22, 0x2f, 0xf1, 0x8a, 0x45, 0x62, 0x47, 0x8e, 0xdb, 0x2d, 0x5f, 0x89,
|
||||
0x4f, 0xc1, 0x25, 0x9f, 0x81, 0x4f, 0x83, 0xf2, 0xd6, 0x75, 0xeb, 0x3a, 0x98, 0x76, 0xe7, 0xa6,
|
||||
0xcf, 0xf3, 0xb3, 0xfd, 0x3c, 0xb6, 0xa1, 0x37, 0xeb, 0x4b, 0x92, 0x58, 0x9e, 0x08, 0x6d, 0x4f,
|
||||
0x48, 0x6a, 0x93, 0x28, 0xb2, 0x23, 0x29, 0xce, 0x93, 0x90, 0x70, 0xdb, 0x13, 0xfc, 0x94, 0x4d,
|
||||
0xac, 0x48, 0x0a, 0x25, 0xd0, 0x76, 0xa9, 0x94, 0xd4, 0x22, 0x51, 0x64, 0x95, 0xaa, 0xf6, 0xce,
|
||||
0x15, 0x84, 0x27, 0xc2, 0x50, 0x70, 0x9b, 0x53, 0x65, 0x13, 0xdf, 0x97, 0x34, 0x8e, 0x73, 0x42,
|
||||
0xfb, 0xd1, 0x6a, 0x61, 0x24, 0xa4, 0x2a, 0x54, 0xd6, 0x15, 0x95, 0x92, 0x84, 0xc7, 0xe9, 0xff,
|
||||
0x36, 0xe3, 0x8a, 0xca, 0x54, 0xbd, 0xb8, 0xae, 0xee, 0x16, 0xb4, 0x8e, 0xf8, 0x89, 0x98, 0x72,
|
||||
0x7f, 0x90, 0x7d, 0xee, 0x7e, 0xaf, 0x02, 0xda, 0x0f, 0x02, 0xe1, 0x11, 0xc5, 0x04, 0x1f, 0x29,
|
||||
0x49, 0x14, 0x9d, 0x24, 0xe8, 0x00, 0x6a, 0x2a, 0x89, 0xa8, 0xa9, 0x75, 0xb4, 0x9e, 0xde, 0x7f,
|
||||
0x6a, 0xad, 0xd8, 0x8e, 0xb5, 0x6c, 0xb5, 0xc6, 0x49, 0x44, 0x71, 0xe6, 0x46, 0x5f, 0x61, 0xc3,
|
||||
0x13, 0xdc, 0x9b, 0x4a, 0x49, 0xb9, 0x97, 0x98, 0x95, 0x8e, 0xd6, 0xdb, 0xe8, 0x1f, 0xdd, 0x06,
|
||||
0xb6, 0xfc, 0x69, 0x70, 0x01, 0xc4, 0x8b, 0x74, 0xe4, 0x42, 0x43, 0xd2, 0x53, 0x49, 0xe3, 0x2f,
|
||||
0x66, 0x35, 0x9b, 0xe8, 0xf0, 0x6e, 0x13, 0xe1, 0x1c, 0x86, 0x4b, 0x6a, 0xfb, 0x39, 0xdc, 0xbf,
|
||||
0x71, 0x39, 0xe8, 0x5f, 0x58, 0x9f, 0x91, 0x60, 0x9a, 0xa7, 0xd6, 0xc2, 0xf9, 0x8f, 0xf6, 0x33,
|
||||
0xf8, 0x6f, 0x25, 0xfc, 0x7a, 0x4b, 0xf7, 0x09, 0xd4, 0xd2, 0x14, 0x11, 0x40, 0x7d, 0x3f, 0x38,
|
||||
0x23, 0x49, 0x6c, 0xac, 0xa5, 0x63, 0x4c, 0xb8, 0x2f, 0x42, 0x43, 0x43, 0x9b, 0xd0, 0x3c, 0x3c,
|
||||
0x4f, 0xeb, 0x25, 0x81, 0x51, 0xe9, 0xfe, 0xac, 0x82, 0x8e, 0xa9, 0x47, 0xd9, 0x8c, 0xca, 0xbc,
|
||||
0x55, 0xf4, 0x12, 0x20, 0x3d, 0x04, 0xae, 0x24, 0x7c, 0x92, 0xb3, 0x37, 0xfa, 0x9d, 0xc5, 0x38,
|
||||
0xf2, 0xd3, 0x64, 0x71, 0xaa, 0x2c, 0x47, 0x48, 0x85, 0x53, 0x1d, 0xfe, 0x2b, 0x2a, 0x87, 0xe8,
|
||||
0x05, 0xd4, 0x03, 0x16, 0x2b, 0xca, 0x8b, 0xd2, 0x1e, 0xac, 0x30, 0x1f, 0x39, 0x43, 0x79, 0x20,
|
||||
0x42, 0xc2, 0x38, 0x2e, 0x0c, 0xe8, 0x33, 0xfc, 0x43, 0xe6, 0xfb, 0x75, 0xe3, 0x62, 0xc3, 0x45,
|
||||
0x27, 0x8f, 0x6f, 0xd1, 0x09, 0x46, 0x64, 0xf9, 0x60, 0x8e, 0x61, 0x2b, 0x56, 0x92, 0x92, 0xd0,
|
||||
0x8d, 0xa9, 0x52, 0x8c, 0x4f, 0x62, 0xb3, 0xb6, 0x4c, 0x9e, 0x5f, 0x03, 0xab, 0xbc, 0x06, 0xd6,
|
||||
0x28, 0x73, 0xe5, 0xf9, 0x60, 0x3d, 0x67, 0x8c, 0x0a, 0x04, 0x7a, 0x05, 0xf7, 0x64, 0x9e, 0xa0,
|
||||
0x2b, 0x24, 0x9b, 0x30, 0x4e, 0x02, 0xd7, 0xa7, 0xb1, 0x62, 0x3c, 0x9b, 0xdd, 0x5c, 0xef, 0x68,
|
||||
0xbd, 0x26, 0x6e, 0x17, 0x9a, 0x61, 0x21, 0x39, 0xb8, 0x50, 0x20, 0x07, 0xb6, 0xfc, 0x2c, 0x07,
|
||||
0x57, 0xcc, 0xa8, 0x94, 0xcc, 0xa7, 0x66, 0xa3, 0x53, 0xed, 0xe9, 0xfd, 0x9d, 0x95, 0x3b, 0x7e,
|
||||
0xc7, 0xc5, 0x19, 0x77, 0xd2, 0x6b, 0xe9, 0x89, 0x20, 0xc6, 0x7a, 0xee, 0x1f, 0x16, 0xf6, 0xb7,
|
||||
0xb5, 0x66, 0xdd, 0x68, 0x74, 0x0d, 0xd0, 0x87, 0x53, 0xb5, 0x78, 0x63, 0x7f, 0x54, 0x60, 0x73,
|
||||
0x44, 0xb9, 0x3f, 0x2f, 0x7b, 0x0f, 0xaa, 0x33, 0x46, 0x8a, 0x96, 0xff, 0xa0, 0xa8, 0x54, 0x7d,
|
||||
0x5d, 0x8e, 0x95, 0xbb, 0xe7, 0xf8, 0x11, 0xf4, 0x6c, 0x7b, 0x17, 0xd0, 0xbc, 0xf6, 0xdd, 0xdf,
|
||||
0x40, 0x9d, 0xd4, 0x54, 0x30, 0x5b, 0x19, 0x61, 0x8e, 0x3c, 0x06, 0x14, 0x4e, 0x03, 0xc5, 0xa2,
|
||||
0x80, 0x9e, 0xdf, 0xd8, 0xf9, 0xa5, 0x6c, 0x3f, 0x94, 0x16, 0xc6, 0x27, 0x05, 0xf7, 0xef, 0x39,
|
||||
0xa6, 0x64, 0x77, 0x1d, 0x40, 0xcb, 0x42, 0x64, 0x42, 0x83, 0x72, 0x72, 0x12, 0x50, 0x3f, 0xcb,
|
||||
0xb4, 0x89, 0xcb, 0x9f, 0xa8, 0xb3, 0xfc, 0x9e, 0xb5, 0x2e, 0x3d, 0x42, 0xbb, 0x0f, 0x41, 0xbf,
|
||||
0x5c, 0x2b, 0x6a, 0x42, 0xed, 0xcd, 0x78, 0xec, 0x18, 0x6b, 0xa8, 0x01, 0xd5, 0xf1, 0xfb, 0x91,
|
||||
0xa1, 0xbd, 0x1e, 0xc0, 0xff, 0x9e, 0x08, 0x57, 0xad, 0xdd, 0xd1, 0x8e, 0x9b, 0xe5, 0xf8, 0x5b,
|
||||
0x65, 0xfb, 0x53, 0x1f, 0x93, 0xc4, 0x1a, 0xa4, 0xaa, 0xfd, 0x28, 0xca, 0x93, 0x0a, 0x09, 0x3f,
|
||||
0xa9, 0x67, 0x0f, 0xfa, 0xde, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x77, 0x7f, 0xdc, 0x8e, 0x94,
|
||||
0x06, 0x00, 0x00,
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ option go_package = "proxyman";
|
||||
option java_package = "com.v2ray.core.app.proxyman";
|
||||
option java_multiple_files = true;
|
||||
|
||||
import "v2ray.com/core/common/serial/typed_message.proto";
|
||||
import "v2ray.com/core/common/net/address.proto";
|
||||
import "v2ray.com/core/common/net/port.proto";
|
||||
import "v2ray.com/core/transport/internet/config.proto";
|
||||
@ -61,15 +60,6 @@ message ReceiverConfig {
|
||||
repeated KnownProtocols domain_override = 7;
|
||||
}
|
||||
|
||||
message InboundHandlerConfig {
|
||||
// Tag of the inbound handler.
|
||||
string tag = 1;
|
||||
// Settings for how this inbound proxy is handled. Must be ReceiverConfig above.
|
||||
v2ray.core.common.serial.TypedMessage receiver_settings = 2;
|
||||
// Settings for inbound proxy. Must be one of the inbound proxies.
|
||||
v2ray.core.common.serial.TypedMessage proxy_settings = 3;
|
||||
}
|
||||
|
||||
message OutboundConfig {
|
||||
|
||||
}
|
||||
@ -82,19 +72,6 @@ message SenderConfig {
|
||||
MultiplexingConfig multiplex_settings = 4;
|
||||
}
|
||||
|
||||
message OutboundHandlerConfig {
|
||||
// Tag of this outbound handler.
|
||||
string tag = 1;
|
||||
// Settings for how to dial connection for this outbound handler. Must be SenderConfig above.
|
||||
v2ray.core.common.serial.TypedMessage sender_settings = 2;
|
||||
// Settings for this outbound proxy. Must be one of the outbound proxies.
|
||||
v2ray.core.common.serial.TypedMessage proxy_settings = 3;
|
||||
// If not zero, this outbound will be expired in seconds. Not used for now.
|
||||
int64 expire = 4;
|
||||
// Comment of this outbound handler. Not used for now.
|
||||
string comment = 5;
|
||||
}
|
||||
|
||||
message MultiplexingConfig {
|
||||
// Whether or not Mux is enabled.
|
||||
bool enabled = 1;
|
||||
|
@ -2,6 +2,4 @@ package proxyman
|
||||
|
||||
import "v2ray.com/core/common/errors"
|
||||
|
||||
func newError(values ...interface{}) *errors.Error {
|
||||
return errors.New(values...).Path("App", "Proxyman")
|
||||
}
|
||||
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App", "Proxyman") }
|
||||
|
@ -14,6 +14,7 @@ type AlwaysOnInboundHandler struct {
|
||||
proxy proxy.Inbound
|
||||
workers []worker
|
||||
mux *mux.Server
|
||||
tag string
|
||||
}
|
||||
|
||||
func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *proxyman.ReceiverConfig, proxyConfig interface{}) (*AlwaysOnInboundHandler, error) {
|
||||
@ -25,6 +26,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
|
||||
h := &AlwaysOnInboundHandler{
|
||||
proxy: p,
|
||||
mux: mux.NewServer(ctx),
|
||||
tag: tag,
|
||||
}
|
||||
|
||||
nl := p.Network()
|
||||
@ -80,10 +82,14 @@ func (h *AlwaysOnInboundHandler) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *AlwaysOnInboundHandler) GetRandomInboundProxy() (proxy.Inbound, net.Port, int) {
|
||||
func (h *AlwaysOnInboundHandler) GetRandomInboundProxy() (interface{}, net.Port, int) {
|
||||
if len(h.workers) == 0 {
|
||||
return nil, 0, 0
|
||||
}
|
||||
w := h.workers[dice.Roll(len(h.workers))]
|
||||
return w.Proxy(), w.Port(), 9999
|
||||
}
|
||||
|
||||
func (h *AlwaysOnInboundHandler) Tag() string {
|
||||
return h.tag
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ func (h *DynamicInboundHandler) Close() {
|
||||
h.cancel()
|
||||
}
|
||||
|
||||
func (h *DynamicInboundHandler) GetRandomInboundProxy() (proxy.Inbound, net.Port, int) {
|
||||
func (h *DynamicInboundHandler) GetRandomInboundProxy() (interface{}, net.Port, int) {
|
||||
h.workerMutex.RLock()
|
||||
defer h.workerMutex.RUnlock()
|
||||
|
||||
@ -174,3 +174,7 @@ func (h *DynamicInboundHandler) GetRandomInboundProxy() (proxy.Inbound, net.Port
|
||||
expire := h.receiverConfig.AllocationStrategy.GetRefreshValue() - uint32(time.Since(h.lastRefresh)/time.Minute)
|
||||
return w.Proxy(), w.Port(), int(expire)
|
||||
}
|
||||
|
||||
func (h *DynamicInboundHandler) Tag() string {
|
||||
return h.tag
|
||||
}
|
||||
|
@ -5,64 +5,41 @@ package inbound
|
||||
import (
|
||||
"context"
|
||||
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
"v2ray.com/core/common"
|
||||
)
|
||||
|
||||
// Manager is to manage all inbound handlers.
|
||||
type Manager struct {
|
||||
handlers []proxyman.InboundHandler
|
||||
taggedHandlers map[string]proxyman.InboundHandler
|
||||
handlers []core.InboundHandler
|
||||
taggedHandlers map[string]core.InboundHandler
|
||||
}
|
||||
|
||||
func New(ctx context.Context, config *proxyman.InboundConfig) (*Manager, error) {
|
||||
return &Manager{
|
||||
taggedHandlers: make(map[string]proxyman.InboundHandler),
|
||||
}, nil
|
||||
m := &Manager{
|
||||
taggedHandlers: make(map[string]core.InboundHandler),
|
||||
}
|
||||
v := core.FromContext(ctx)
|
||||
if v == nil {
|
||||
return nil, newError("V is not in context")
|
||||
}
|
||||
if err := v.RegisterFeature((*core.InboundHandlerManager)(nil), m); err != nil {
|
||||
return nil, newError("unable to register InboundHandlerManager").Base(err)
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *Manager) AddHandler(ctx context.Context, config *proxyman.InboundHandlerConfig) error {
|
||||
rawReceiverSettings, err := config.ReceiverSettings.GetInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig)
|
||||
if !ok {
|
||||
return newError("not a ReceiverConfig").AtError()
|
||||
}
|
||||
proxySettings, err := config.ProxySettings.GetInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var handler proxyman.InboundHandler
|
||||
tag := config.Tag
|
||||
allocStrategy := receiverSettings.AllocationStrategy
|
||||
if allocStrategy == nil || allocStrategy.Type == proxyman.AllocationStrategy_Always {
|
||||
h, err := NewAlwaysOnInboundHandler(ctx, tag, receiverSettings, proxySettings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
handler = h
|
||||
} else if allocStrategy.Type == proxyman.AllocationStrategy_Random {
|
||||
h, err := NewDynamicInboundHandler(ctx, tag, receiverSettings, proxySettings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
handler = h
|
||||
}
|
||||
|
||||
if handler == nil {
|
||||
return newError("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type).AtError()
|
||||
}
|
||||
|
||||
func (m *Manager) AddHandler(ctx context.Context, handler core.InboundHandler) error {
|
||||
m.handlers = append(m.handlers, handler)
|
||||
tag := handler.Tag()
|
||||
if len(tag) > 0 {
|
||||
m.taggedHandlers[tag] = handler
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) GetHandler(ctx context.Context, tag string) (proxyman.InboundHandler, error) {
|
||||
func (m *Manager) GetHandler(ctx context.Context, tag string) (core.InboundHandler, error) {
|
||||
handler, found := m.taggedHandlers[tag]
|
||||
if !found {
|
||||
return nil, newError("handler not found: ", tag)
|
||||
@ -85,12 +62,36 @@ func (m *Manager) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) Interface() interface{} {
|
||||
return (*proxyman.InboundHandlerManager)(nil)
|
||||
func NewHandler(ctx context.Context, config *core.InboundHandlerConfig) (core.InboundHandler, error) {
|
||||
rawReceiverSettings, err := config.ReceiverSettings.GetInstance()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig)
|
||||
if !ok {
|
||||
return nil, newError("not a ReceiverConfig").AtError()
|
||||
}
|
||||
proxySettings, err := config.ProxySettings.GetInstance()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tag := config.Tag
|
||||
allocStrategy := receiverSettings.AllocationStrategy
|
||||
if allocStrategy == nil || allocStrategy.Type == proxyman.AllocationStrategy_Always {
|
||||
return NewAlwaysOnInboundHandler(ctx, tag, receiverSettings, proxySettings)
|
||||
}
|
||||
|
||||
if allocStrategy.Type == proxyman.AllocationStrategy_Random {
|
||||
return NewDynamicInboundHandler(ctx, tag, receiverSettings, proxySettings)
|
||||
}
|
||||
return nil, newError("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type).AtError()
|
||||
}
|
||||
|
||||
func init() {
|
||||
common.Must(common.RegisterConfig((*proxyman.InboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||
return New(ctx, config.(*proxyman.InboundConfig))
|
||||
}))
|
||||
common.Must(common.RegisterConfig((*core.InboundHandlerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||
return NewHandler(ctx, config.(*core.InboundHandlerConfig))
|
||||
}))
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/net"
|
||||
@ -31,7 +31,7 @@ type tcpWorker struct {
|
||||
stream *internet.StreamConfig
|
||||
recvOrigDest bool
|
||||
tag string
|
||||
dispatcher dispatcher.Interface
|
||||
dispatcher core.Dispatcher
|
||||
sniffers []proxyman.KnownProtocols
|
||||
|
||||
ctx context.Context
|
||||
@ -185,7 +185,7 @@ type udpWorker struct {
|
||||
port net.Port
|
||||
recvOrigDest bool
|
||||
tag string
|
||||
dispatcher dispatcher.Interface
|
||||
dispatcher core.Dispatcher
|
||||
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
|
@ -8,8 +8,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/errors"
|
||||
@ -262,21 +261,14 @@ func (m *Client) fetchOutput() {
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
dispatcher dispatcher.Interface
|
||||
dispatcher core.Dispatcher
|
||||
}
|
||||
|
||||
// NewServer creates a new mux.Server.
|
||||
func NewServer(ctx context.Context) *Server {
|
||||
s := &Server{}
|
||||
space := app.SpaceFromContext(ctx)
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
d := dispatcher.FromSpace(space)
|
||||
if d == nil {
|
||||
return newError("no dispatcher in space")
|
||||
}
|
||||
s.dispatcher = d
|
||||
return nil
|
||||
})
|
||||
s := &Server{
|
||||
dispatcher: core.FromContext(ctx).Dispatcher(),
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
@ -295,8 +287,15 @@ func (s *Server) Dispatch(ctx context.Context, dest net.Destination) (ray.Inboun
|
||||
return ray, nil
|
||||
}
|
||||
|
||||
func (s *Server) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) Close() {
|
||||
}
|
||||
|
||||
type ServerWorker struct {
|
||||
dispatcher dispatcher.Interface
|
||||
dispatcher core.Dispatcher
|
||||
outboundRay ray.OutboundRay
|
||||
sessionManager *SessionManager
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
"v2ray.com/core/app/proxyman/mux"
|
||||
"v2ray.com/core/common/buf"
|
||||
@ -17,29 +17,22 @@ import (
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
config *proxyman.OutboundHandlerConfig
|
||||
config *core.OutboundHandlerConfig
|
||||
senderSettings *proxyman.SenderConfig
|
||||
proxy proxy.Outbound
|
||||
outboundManager proxyman.OutboundHandlerManager
|
||||
outboundManager core.OutboundHandlerManager
|
||||
mux *mux.ClientManager
|
||||
}
|
||||
|
||||
func NewHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) (*Handler, error) {
|
||||
func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (*Handler, error) {
|
||||
v := core.FromContext(ctx)
|
||||
if v == nil {
|
||||
return nil, newError("V is not in context")
|
||||
}
|
||||
h := &Handler{
|
||||
config: config,
|
||||
config: config,
|
||||
outboundManager: v.OutboundHandlerManager(),
|
||||
}
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context")
|
||||
}
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
ohm := proxyman.OutboundHandlerManagerFromSpace(space)
|
||||
if ohm == nil {
|
||||
return newError("no OutboundManager in space")
|
||||
}
|
||||
h.outboundManager = ohm
|
||||
return nil
|
||||
})
|
||||
|
||||
if config.SenderSettings != nil {
|
||||
senderSettings, err := config.SenderSettings.GetInstance()
|
||||
@ -54,7 +47,12 @@ func NewHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) (*H
|
||||
}
|
||||
}
|
||||
|
||||
proxyHandler, err := config.GetProxyHandler(ctx)
|
||||
proxyConfig, err := config.ProxySettings.GetInstance()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
proxyHandler, err := proxy.CreateOutboundHandler(ctx, proxyConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -71,6 +69,10 @@ func NewHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) (*H
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h *Handler) Tag() string {
|
||||
return h.config.Tag
|
||||
}
|
||||
|
||||
// Dispatch implements proxy.Outbound.Dispatch.
|
||||
func (h *Handler) Dispatch(ctx context.Context, outboundRay ray.OutboundRay) {
|
||||
if h.mux != nil {
|
||||
|
15
app/proxyman/outbound/handler_test.go
Normal file
15
app/proxyman/outbound/handler_test.go
Normal 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))
|
||||
}
|
@ -6,6 +6,7 @@ import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
"v2ray.com/core/common"
|
||||
)
|
||||
@ -13,20 +14,23 @@ import (
|
||||
// Manager is to manage all outbound handlers.
|
||||
type Manager struct {
|
||||
sync.RWMutex
|
||||
defaultHandler *Handler
|
||||
taggedHandler map[string]*Handler
|
||||
defaultHandler core.OutboundHandler
|
||||
taggedHandler map[string]core.OutboundHandler
|
||||
}
|
||||
|
||||
// New creates a new Manager.
|
||||
func New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager, error) {
|
||||
return &Manager{
|
||||
taggedHandler: make(map[string]*Handler),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Interface implements Application.Interface.
|
||||
func (*Manager) Interface() interface{} {
|
||||
return (*proxyman.OutboundHandlerManager)(nil)
|
||||
m := &Manager{
|
||||
taggedHandler: make(map[string]core.OutboundHandler),
|
||||
}
|
||||
v := core.FromContext(ctx)
|
||||
if v == nil {
|
||||
return nil, newError("V is not in context")
|
||||
}
|
||||
if err := v.RegisterFeature((*core.OutboundHandlerManager)(nil), m); err != nil {
|
||||
return nil, newError("unable to register OutboundHandlerManager").Base(err)
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Start implements Application.Start
|
||||
@ -35,7 +39,7 @@ func (*Manager) Start() error { return nil }
|
||||
// Close implements Application.Close
|
||||
func (*Manager) Close() {}
|
||||
|
||||
func (m *Manager) GetDefaultHandler() proxyman.OutboundHandler {
|
||||
func (m *Manager) GetDefaultHandler() core.OutboundHandler {
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
if m.defaultHandler == nil {
|
||||
@ -44,7 +48,7 @@ func (m *Manager) GetDefaultHandler() proxyman.OutboundHandler {
|
||||
return m.defaultHandler
|
||||
}
|
||||
|
||||
func (m *Manager) GetHandler(tag string) proxyman.OutboundHandler {
|
||||
func (m *Manager) GetHandler(tag string) core.OutboundHandler {
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
if handler, found := m.taggedHandler[tag]; found {
|
||||
@ -53,20 +57,17 @@ func (m *Manager) GetHandler(tag string) proxyman.OutboundHandler {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) AddHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) error {
|
||||
func (m *Manager) AddHandler(ctx context.Context, handler core.OutboundHandler) error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
handler, err := NewHandler(ctx, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if m.defaultHandler == nil {
|
||||
m.defaultHandler = handler
|
||||
}
|
||||
|
||||
if len(config.Tag) > 0 {
|
||||
m.taggedHandler[config.Tag] = handler
|
||||
tag := handler.Tag()
|
||||
if len(tag) > 0 {
|
||||
m.taggedHandler[tag] = handler
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -76,4 +77,7 @@ func init() {
|
||||
common.Must(common.RegisterConfig((*proxyman.OutboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||
return New(ctx, config.(*proxyman.OutboundConfig))
|
||||
}))
|
||||
common.Must(common.RegisterConfig((*core.OutboundHandlerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||
return NewHandler(ctx, config.(*core.OutboundHandlerConfig))
|
||||
}))
|
||||
}
|
||||
|
@ -5,52 +5,8 @@ package proxyman
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/common/net"
|
||||
"v2ray.com/core/proxy"
|
||||
"v2ray.com/core/transport/ray"
|
||||
)
|
||||
|
||||
type InboundHandlerManager interface {
|
||||
GetHandler(ctx context.Context, tag string) (InboundHandler, error)
|
||||
AddHandler(ctx context.Context, config *InboundHandlerConfig) error
|
||||
}
|
||||
|
||||
type InboundHandler interface {
|
||||
Start() error
|
||||
Close()
|
||||
|
||||
// For migration
|
||||
GetRandomInboundProxy() (proxy.Inbound, net.Port, int)
|
||||
}
|
||||
|
||||
type OutboundHandlerManager interface {
|
||||
GetHandler(tag string) OutboundHandler
|
||||
GetDefaultHandler() OutboundHandler
|
||||
AddHandler(ctx context.Context, config *OutboundHandlerConfig) error
|
||||
}
|
||||
|
||||
type OutboundHandler interface {
|
||||
Dispatch(ctx context.Context, outboundRay ray.OutboundRay)
|
||||
}
|
||||
|
||||
func InboundHandlerManagerFromSpace(space app.Space) InboundHandlerManager {
|
||||
app := space.GetApplication((*InboundHandlerManager)(nil))
|
||||
if app == nil {
|
||||
return nil
|
||||
}
|
||||
return app.(InboundHandlerManager)
|
||||
}
|
||||
|
||||
func OutboundHandlerManagerFromSpace(space app.Space) OutboundHandlerManager {
|
||||
app := space.GetApplication((*OutboundHandlerManager)(nil))
|
||||
if app == nil {
|
||||
return nil
|
||||
}
|
||||
return app.(OutboundHandlerManager)
|
||||
}
|
||||
|
||||
type key int
|
||||
|
||||
const (
|
||||
|
@ -5,46 +5,47 @@ package router
|
||||
import (
|
||||
"context"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/net"
|
||||
"v2ray.com/core/proxy"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoRuleApplicable = newError("No rule applicable")
|
||||
)
|
||||
|
||||
type Router struct {
|
||||
domainStrategy Config_DomainStrategy
|
||||
rules []Rule
|
||||
dns core.DNSClient
|
||||
}
|
||||
|
||||
func NewRouter(ctx context.Context, config *Config) (*Router, error) {
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context")
|
||||
v := core.FromContext(ctx)
|
||||
if v == nil {
|
||||
return nil, newError("V is not in context")
|
||||
}
|
||||
|
||||
r := &Router{
|
||||
domainStrategy: config.DomainStrategy,
|
||||
rules: make([]Rule, len(config.Rule)),
|
||||
dns: v.DNSClient(),
|
||||
}
|
||||
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
for idx, rule := range config.Rule {
|
||||
r.rules[idx].Tag = rule.Tag
|
||||
cond, err := rule.BuildCondition()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.rules[idx].Condition = cond
|
||||
for idx, rule := range config.Rule {
|
||||
r.rules[idx].Tag = rule.Tag
|
||||
cond, err := rule.BuildCondition()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
r.rules[idx].Condition = cond
|
||||
}
|
||||
|
||||
if err := v.RegisterFeature((*core.Router)(nil), r); err != nil {
|
||||
return nil, newError("unable to register Router").Base(err)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
type ipResolver struct {
|
||||
dns core.DNSClient
|
||||
ip []net.Address
|
||||
domain string
|
||||
resolved bool
|
||||
@ -57,7 +58,7 @@ func (r *ipResolver) Resolve() []net.Address {
|
||||
|
||||
newError("looking for IP for domain: ", r.domain).WriteToLog()
|
||||
r.resolved = true
|
||||
ips, err := net.LookupIP(r.domain)
|
||||
ips, err := r.dns.LookupIP(r.domain)
|
||||
if err != nil {
|
||||
newError("failed to get IP address").Base(err).WriteToLog()
|
||||
}
|
||||
@ -71,8 +72,10 @@ func (r *ipResolver) Resolve() []net.Address {
|
||||
return r.ip
|
||||
}
|
||||
|
||||
func (r *Router) TakeDetour(ctx context.Context) (string, error) {
|
||||
resolver := &ipResolver{}
|
||||
func (r *Router) PickRoute(ctx context.Context) (string, error) {
|
||||
resolver := &ipResolver{
|
||||
dns: r.dns,
|
||||
}
|
||||
if r.domainStrategy == Config_IpOnDemand {
|
||||
if dest, ok := proxy.TargetFromContext(ctx); ok && dest.Address.Family().IsDomain() {
|
||||
resolver.domain = dest.Address.Domain()
|
||||
@ -88,7 +91,7 @@ func (r *Router) TakeDetour(ctx context.Context) (string, error) {
|
||||
|
||||
dest, ok := proxy.TargetFromContext(ctx)
|
||||
if !ok {
|
||||
return "", ErrNoRuleApplicable
|
||||
return "", core.ErrNoClue
|
||||
}
|
||||
|
||||
if r.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() {
|
||||
@ -104,11 +107,7 @@ func (r *Router) TakeDetour(ctx context.Context) (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return "", ErrNoRuleApplicable
|
||||
}
|
||||
|
||||
func (*Router) Interface() interface{} {
|
||||
return (*Router)(nil)
|
||||
return "", core.ErrNoClue
|
||||
}
|
||||
|
||||
func (*Router) Start() error {
|
||||
@ -117,14 +116,6 @@ func (*Router) Start() error {
|
||||
|
||||
func (*Router) Close() {}
|
||||
|
||||
func FromSpace(space app.Space) *Router {
|
||||
app := space.GetApplication((*Router)(nil))
|
||||
if app == nil {
|
||||
return nil
|
||||
}
|
||||
return app.(*Router)
|
||||
}
|
||||
|
||||
func init() {
|
||||
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||
return NewRouter(ctx, config.(*Config))
|
||||
|
@ -4,13 +4,14 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
_ "v2ray.com/core/app/dispatcher/impl"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
_ "v2ray.com/core/app/proxyman/outbound"
|
||||
. "v2ray.com/core/app/router"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/serial"
|
||||
"v2ray.com/core/proxy"
|
||||
. "v2ray.com/ext/assert"
|
||||
)
|
||||
@ -18,28 +19,30 @@ import (
|
||||
func TestSimpleRouter(t *testing.T) {
|
||||
assert := With(t)
|
||||
|
||||
config := &Config{
|
||||
Rule: []*RoutingRule{
|
||||
{
|
||||
Tag: "test",
|
||||
NetworkList: &net.NetworkList{
|
||||
Network: []net.Network{net.Network_TCP},
|
||||
config := &core.Config{
|
||||
App: []*serial.TypedMessage{
|
||||
serial.ToTypedMessage(&Config{
|
||||
Rule: []*RoutingRule{
|
||||
{
|
||||
Tag: "test",
|
||||
NetworkList: &net.NetworkList{
|
||||
Network: []net.Network{net.Network_TCP},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
serial.ToTypedMessage(&dispatcher.Config{}),
|
||||
serial.ToTypedMessage(&proxyman.OutboundConfig{}),
|
||||
},
|
||||
}
|
||||
|
||||
space := app.NewSpace()
|
||||
ctx := app.ContextWithSpace(context.Background(), space)
|
||||
assert(app.AddApplicationToSpace(ctx, new(dispatcher.Config)), IsNil)
|
||||
assert(app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig)), IsNil)
|
||||
assert(app.AddApplicationToSpace(ctx, config), IsNil)
|
||||
assert(space.Initialize(), IsNil)
|
||||
v, err := core.New(config)
|
||||
common.Must(err)
|
||||
|
||||
r := FromSpace(space)
|
||||
r := v.Router()
|
||||
|
||||
ctx = proxy.ContextWithTarget(ctx, net.TCPDestination(net.DomainAddress("v2ray.com"), 80))
|
||||
tag, err := r.TakeDetour(ctx)
|
||||
ctx := proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("v2ray.com"), 80))
|
||||
tag, err := r.PickRoute(ctx)
|
||||
assert(err, IsNil)
|
||||
assert(tag, Equals, "test")
|
||||
}
|
||||
|
132
app/space.go
132
app/space.go
@ -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
10
common/interfaces.go
Normal 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()
|
||||
}
|
@ -14,7 +14,7 @@ var _ = math.Inf
|
||||
type User struct {
|
||||
Level uint32 `protobuf:"varint,1,opt,name=level" json:"level,omitempty"`
|
||||
Email string `protobuf:"bytes,2,opt,name=email" json:"email,omitempty"`
|
||||
// Protocol specific account information.
|
||||
// Protocol specific account information. Must be the account proto in one of the proxies.
|
||||
Account *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=account" json:"account,omitempty"`
|
||||
}
|
||||
|
||||
|
12
common/router/dispatcher.go
Normal file
12
common/router/dispatcher.go
Normal 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
53
common/router/router.go
Normal 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)
|
||||
}
|
152
config.pb.go
152
config.pb.go
@ -3,7 +3,6 @@ package core
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import v2ray_core_app_proxyman "v2ray.com/core/app/proxyman"
|
||||
import v2ray_core_common_serial "v2ray.com/core/common/serial"
|
||||
import v2ray_core_transport "v2ray.com/core/transport"
|
||||
|
||||
@ -40,12 +39,12 @@ func (x ConfigFormat) String() string {
|
||||
}
|
||||
func (ConfigFormat) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
|
||||
// Master config of V2Ray. V2Ray Core takes this config as input and functions accordingly.
|
||||
// Master config of V2Ray. V2Ray takes this config as input and functions accordingly.
|
||||
type Config struct {
|
||||
// Inbound handler configurations. Must have at least one item.
|
||||
Inbound []*v2ray_core_app_proxyman.InboundHandlerConfig `protobuf:"bytes,1,rep,name=inbound" json:"inbound,omitempty"`
|
||||
Inbound []*InboundHandlerConfig `protobuf:"bytes,1,rep,name=inbound" json:"inbound,omitempty"`
|
||||
// Outbound handler configurations. Must have at least one item. The first item is used as default for routing.
|
||||
Outbound []*v2ray_core_app_proxyman.OutboundHandlerConfig `protobuf:"bytes,2,rep,name=outbound" json:"outbound,omitempty"`
|
||||
Outbound []*OutboundHandlerConfig `protobuf:"bytes,2,rep,name=outbound" json:"outbound,omitempty"`
|
||||
// App configuration. Must be one in the app directory.
|
||||
App []*v2ray_core_common_serial.TypedMessage `protobuf:"bytes,4,rep,name=app" json:"app,omitempty"`
|
||||
// Transport settings.
|
||||
@ -60,14 +59,14 @@ func (m *Config) String() string { return proto.CompactTextString(m)
|
||||
func (*Config) ProtoMessage() {}
|
||||
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
|
||||
func (m *Config) GetInbound() []*v2ray_core_app_proxyman.InboundHandlerConfig {
|
||||
func (m *Config) GetInbound() []*InboundHandlerConfig {
|
||||
if m != nil {
|
||||
return m.Inbound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Config) GetOutbound() []*v2ray_core_app_proxyman.OutboundHandlerConfig {
|
||||
func (m *Config) GetOutbound() []*OutboundHandlerConfig {
|
||||
if m != nil {
|
||||
return m.Outbound
|
||||
}
|
||||
@ -95,34 +94,131 @@ func (m *Config) GetExtension() []*v2ray_core_common_serial.TypedMessage {
|
||||
return nil
|
||||
}
|
||||
|
||||
type InboundHandlerConfig struct {
|
||||
// Tag of the inbound handler.
|
||||
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
|
||||
// Settings for how this inbound proxy is handled. Must be ReceiverConfig above.
|
||||
ReceiverSettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=receiver_settings,json=receiverSettings" json:"receiver_settings,omitempty"`
|
||||
// Settings for inbound proxy. Must be one of the inbound proxies.
|
||||
ProxySettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"`
|
||||
}
|
||||
|
||||
func (m *InboundHandlerConfig) Reset() { *m = InboundHandlerConfig{} }
|
||||
func (m *InboundHandlerConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*InboundHandlerConfig) ProtoMessage() {}
|
||||
func (*InboundHandlerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||
|
||||
func (m *InboundHandlerConfig) GetTag() string {
|
||||
if m != nil {
|
||||
return m.Tag
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *InboundHandlerConfig) GetReceiverSettings() *v2ray_core_common_serial.TypedMessage {
|
||||
if m != nil {
|
||||
return m.ReceiverSettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *InboundHandlerConfig) GetProxySettings() *v2ray_core_common_serial.TypedMessage {
|
||||
if m != nil {
|
||||
return m.ProxySettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type OutboundHandlerConfig struct {
|
||||
// Tag of this outbound handler.
|
||||
Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"`
|
||||
// Settings for how to dial connection for this outbound handler. Must be SenderConfig above.
|
||||
SenderSettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=sender_settings,json=senderSettings" json:"sender_settings,omitempty"`
|
||||
// Settings for this outbound proxy. Must be one of the outbound proxies.
|
||||
ProxySettings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"`
|
||||
// If not zero, this outbound will be expired in seconds. Not used for now.
|
||||
Expire int64 `protobuf:"varint,4,opt,name=expire" json:"expire,omitempty"`
|
||||
// Comment of this outbound handler. Not used for now.
|
||||
Comment string `protobuf:"bytes,5,opt,name=comment" json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
func (m *OutboundHandlerConfig) Reset() { *m = OutboundHandlerConfig{} }
|
||||
func (m *OutboundHandlerConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*OutboundHandlerConfig) ProtoMessage() {}
|
||||
func (*OutboundHandlerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
|
||||
|
||||
func (m *OutboundHandlerConfig) GetTag() string {
|
||||
if m != nil {
|
||||
return m.Tag
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *OutboundHandlerConfig) GetSenderSettings() *v2ray_core_common_serial.TypedMessage {
|
||||
if m != nil {
|
||||
return m.SenderSettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *OutboundHandlerConfig) GetProxySettings() *v2ray_core_common_serial.TypedMessage {
|
||||
if m != nil {
|
||||
return m.ProxySettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *OutboundHandlerConfig) GetExpire() int64 {
|
||||
if m != nil {
|
||||
return m.Expire
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *OutboundHandlerConfig) GetComment() string {
|
||||
if m != nil {
|
||||
return m.Comment
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Config)(nil), "v2ray.core.Config")
|
||||
proto.RegisterType((*InboundHandlerConfig)(nil), "v2ray.core.InboundHandlerConfig")
|
||||
proto.RegisterType((*OutboundHandlerConfig)(nil), "v2ray.core.OutboundHandlerConfig")
|
||||
proto.RegisterEnum("v2ray.core.ConfigFormat", ConfigFormat_name, ConfigFormat_value)
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("v2ray.com/core/config.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 336 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0xcd, 0x4a, 0xf3, 0x40,
|
||||
0x18, 0x85, 0xbf, 0xb4, 0xf9, 0x6a, 0xfa, 0xb6, 0x48, 0x99, 0x55, 0xa8, 0x2e, 0x8a, 0xd0, 0x52,
|
||||
0x04, 0x27, 0x12, 0x37, 0xe2, 0xd2, 0x8a, 0x3f, 0x05, 0x6d, 0xa9, 0xe2, 0xc2, 0x8d, 0x4c, 0xd3,
|
||||
0x69, 0x09, 0x74, 0xe6, 0x1d, 0x26, 0x53, 0x69, 0x6e, 0xc9, 0x9b, 0xf2, 0x56, 0x24, 0x99, 0xfe,
|
||||
0xa5, 0xe2, 0xc2, 0x55, 0x20, 0x73, 0x9e, 0xe7, 0x4c, 0x4e, 0xe0, 0xe8, 0x23, 0xd4, 0x2c, 0xa5,
|
||||
0x11, 0x8a, 0x20, 0x42, 0xcd, 0x83, 0x08, 0xe5, 0x34, 0x9e, 0x51, 0xa5, 0xd1, 0x20, 0x81, 0xf5,
|
||||
0xa1, 0xe6, 0xcd, 0xee, 0x5e, 0x90, 0x29, 0x15, 0x28, 0x8d, 0xcb, 0x54, 0x30, 0x59, 0xa0, 0x9a,
|
||||
0xe7, 0x3f, 0x94, 0x42, 0xa0, 0x0c, 0x12, 0xae, 0x63, 0x36, 0x0f, 0x4c, 0xaa, 0xf8, 0xe4, 0x5d,
|
||||
0xf0, 0x24, 0x61, 0x33, 0xbe, 0x22, 0xda, 0x7b, 0x84, 0xd1, 0x4c, 0x26, 0x0a, 0xb5, 0x29, 0x88,
|
||||
0x4f, 0xbe, 0x4a, 0x50, 0xe9, 0xe5, 0x2f, 0xc8, 0x1d, 0x1c, 0xc4, 0x72, 0x8c, 0x0b, 0x39, 0xf1,
|
||||
0x9d, 0x56, 0xb9, 0x5b, 0x0b, 0xcf, 0xe8, 0xf6, 0xae, 0x94, 0x29, 0x45, 0xd7, 0x77, 0xa3, 0x0f,
|
||||
0x36, 0x77, 0xcf, 0xe4, 0x64, 0xce, 0xb5, 0xe5, 0x47, 0x6b, 0x9a, 0xf4, 0xc1, 0xc3, 0x85, 0xb1,
|
||||
0xa6, 0x52, 0x6e, 0xa2, 0xbf, 0x9a, 0x06, 0xab, 0x60, 0x51, 0xb5, 0xe1, 0xc9, 0x25, 0x94, 0x99,
|
||||
0x52, 0xbe, 0x9b, 0x6b, 0x3a, 0xbb, 0x1a, 0x3b, 0x01, 0xb5, 0x13, 0xd0, 0x97, 0x6c, 0x82, 0x47,
|
||||
0xbb, 0xc0, 0x28, 0x43, 0xc8, 0x15, 0x54, 0x37, 0xdf, 0xec, 0xff, 0x6f, 0x39, 0xdd, 0x5a, 0x78,
|
||||
0xbc, 0xcb, 0x6f, 0x0e, 0xe9, 0xaa, 0x74, 0x1b, 0x27, 0x37, 0x50, 0xe5, 0x4b, 0xc3, 0x65, 0x12,
|
||||
0xa3, 0xf4, 0x2b, 0x7f, 0xea, 0xde, 0x82, 0x7d, 0xd7, 0x2b, 0x37, 0xdc, 0xd3, 0x0e, 0xd4, 0x6d,
|
||||
0xc1, 0x2d, 0x6a, 0xc1, 0x0c, 0xa9, 0x83, 0x37, 0xcc, 0xa6, 0x1f, 0x2f, 0xa6, 0x8d, 0x7f, 0xc4,
|
||||
0x03, 0xb7, 0xff, 0x3c, 0x78, 0x6a, 0x38, 0xd7, 0x6d, 0x38, 0x8c, 0x50, 0xec, 0xb4, 0x0c, 0x9d,
|
||||
0x37, 0x37, 0x7b, 0x7e, 0x96, 0xe0, 0x35, 0x1c, 0xb1, 0x94, 0xf6, 0x50, 0xf3, 0x71, 0x25, 0xff,
|
||||
0x6f, 0x17, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x62, 0x93, 0x6d, 0x78, 0x65, 0x02, 0x00, 0x00,
|
||||
// 436 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0x41, 0x6f, 0xd3, 0x30,
|
||||
0x14, 0xc7, 0x71, 0x13, 0xba, 0xf6, 0x6d, 0x94, 0x60, 0x01, 0xb2, 0x06, 0x87, 0x50, 0x69, 0x53,
|
||||
0xc5, 0xc1, 0x45, 0xe5, 0x82, 0x26, 0x71, 0x61, 0x08, 0xc1, 0xa4, 0xd1, 0x29, 0x45, 0x1c, 0xb8,
|
||||
0x4c, 0x6e, 0xfa, 0x56, 0x45, 0x5a, 0xec, 0xc8, 0x76, 0xa7, 0xe6, 0x2b, 0xf1, 0x3d, 0xb8, 0xf1,
|
||||
0x8d, 0xb8, 0xa0, 0xc4, 0x49, 0x93, 0x41, 0x0f, 0x14, 0x69, 0xa7, 0xc4, 0x79, 0xfe, 0xfd, 0xdf,
|
||||
0xfb, 0x25, 0x31, 0x3c, 0xbb, 0x99, 0x68, 0x91, 0xf3, 0x58, 0xa5, 0xe3, 0x58, 0x69, 0x1c, 0xc7,
|
||||
0x4a, 0x5e, 0x25, 0x4b, 0x9e, 0x69, 0x65, 0x15, 0x85, 0xba, 0xa8, 0xf1, 0xf0, 0xd5, 0x5f, 0x1b,
|
||||
0xd3, 0x54, 0xc9, 0xb1, 0x41, 0x9d, 0x88, 0xeb, 0xb1, 0xcd, 0x33, 0x5c, 0x5c, 0xa6, 0x68, 0x8c,
|
||||
0x58, 0xa2, 0xa3, 0x0f, 0x8f, 0xfe, 0x20, 0xac, 0x16, 0xd2, 0x64, 0x4a, 0xdb, 0x5b, 0x4d, 0x86,
|
||||
0x3f, 0x3a, 0xd0, 0x3d, 0x2d, 0x1f, 0xd0, 0x13, 0xd8, 0x4b, 0xe4, 0x5c, 0xad, 0xe4, 0x82, 0x91,
|
||||
0xd0, 0x1b, 0xed, 0x4f, 0x42, 0xde, 0x4c, 0xc0, 0x3f, 0xb9, 0xd2, 0x47, 0x21, 0x17, 0xd7, 0xa8,
|
||||
0x1d, 0x12, 0xd5, 0x00, 0x7d, 0x0b, 0x3d, 0xb5, 0xb2, 0x0e, 0xee, 0x94, 0xf0, 0x8b, 0x36, 0x3c,
|
||||
0xad, 0x6a, 0xb7, 0xe9, 0x0d, 0x42, 0xdf, 0x80, 0x27, 0xb2, 0x8c, 0xf9, 0x25, 0x79, 0xdc, 0x26,
|
||||
0x9d, 0x28, 0x77, 0xa2, 0xfc, 0x4b, 0x21, 0x7a, 0xee, 0x3c, 0xa3, 0x02, 0xa1, 0x27, 0xd0, 0xdf,
|
||||
0x98, 0xb1, 0xfb, 0x21, 0x19, 0xed, 0x4f, 0x9e, 0xb7, 0xf9, 0x4d, 0x91, 0x57, 0x4d, 0x9b, 0xed,
|
||||
0xf4, 0x3d, 0xf4, 0x71, 0x6d, 0x51, 0x9a, 0x44, 0x49, 0xd6, 0xdd, 0xa9, 0x77, 0x03, 0x9e, 0xf9,
|
||||
0x3d, 0x2f, 0xf0, 0x87, 0x3f, 0x09, 0x3c, 0xde, 0xf6, 0x8a, 0x68, 0x00, 0x9e, 0x15, 0x4b, 0x46,
|
||||
0x42, 0x32, 0xea, 0x47, 0xc5, 0x2d, 0x9d, 0xc1, 0x23, 0x8d, 0x31, 0x26, 0x37, 0xa8, 0x2f, 0x0d,
|
||||
0x5a, 0x9b, 0xc8, 0xa5, 0x61, 0x9d, 0x72, 0xf4, 0x7f, 0x6d, 0x1f, 0xd4, 0x01, 0xb3, 0x8a, 0xa7,
|
||||
0xe7, 0x30, 0xc8, 0xb4, 0x5a, 0xe7, 0x4d, 0xa2, 0xb7, 0x53, 0xe2, 0x83, 0x92, 0xae, 0xe3, 0x86,
|
||||
0xbf, 0x08, 0x3c, 0xd9, 0xfa, 0xd1, 0xb6, 0xf8, 0x4c, 0xe1, 0xa1, 0x41, 0xb9, 0xf8, 0x7f, 0x9b,
|
||||
0x81, 0xc3, 0xef, 0xc8, 0x85, 0x3e, 0x85, 0x2e, 0xae, 0xb3, 0x44, 0x23, 0xf3, 0x43, 0x32, 0xf2,
|
||||
0xa2, 0x6a, 0x45, 0x19, 0xec, 0x15, 0x21, 0x28, 0xdd, 0x8f, 0xd3, 0x8f, 0xea, 0xe5, 0xcb, 0x63,
|
||||
0x38, 0x70, 0xb6, 0x1f, 0x94, 0x4e, 0x85, 0xa5, 0x07, 0xd0, 0xbb, 0x28, 0x4e, 0xcb, 0x7c, 0x75,
|
||||
0x15, 0xdc, 0xa3, 0x3d, 0xf0, 0xcf, 0x66, 0xd3, 0xcf, 0x01, 0x79, 0x77, 0x04, 0x83, 0x58, 0xa5,
|
||||
0xad, 0xa9, 0x2e, 0xc8, 0x37, 0xbf, 0xb8, 0x7e, 0xef, 0xc0, 0xd7, 0x49, 0x24, 0x72, 0x7e, 0xaa,
|
||||
0x34, 0xce, 0xbb, 0xe5, 0x51, 0x7b, 0xfd, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x59, 0x1b,
|
||||
0xee, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
27
config.proto
27
config.proto
@ -6,7 +6,6 @@ option go_package = "core";
|
||||
option java_package = "com.v2ray.core";
|
||||
option java_multiple_files = true;
|
||||
|
||||
import "v2ray.com/core/app/proxyman/config.proto";
|
||||
import "v2ray.com/core/common/serial/typed_message.proto";
|
||||
import "v2ray.com/core/transport/config.proto";
|
||||
|
||||
@ -19,10 +18,10 @@ enum ConfigFormat {
|
||||
// Master config of V2Ray. V2Ray takes this config as input and functions accordingly.
|
||||
message Config {
|
||||
// Inbound handler configurations. Must have at least one item.
|
||||
repeated v2ray.core.app.proxyman.InboundHandlerConfig inbound = 1;
|
||||
repeated InboundHandlerConfig inbound = 1;
|
||||
|
||||
// Outbound handler configurations. Must have at least one item. The first item is used as default for routing.
|
||||
repeated v2ray.core.app.proxyman.OutboundHandlerConfig outbound = 2;
|
||||
repeated OutboundHandlerConfig outbound = 2;
|
||||
|
||||
reserved 3;
|
||||
|
||||
@ -36,3 +35,25 @@ message Config {
|
||||
// V2Ray will ignore such config during initialization.
|
||||
repeated v2ray.core.common.serial.TypedMessage extension = 6;
|
||||
}
|
||||
|
||||
message InboundHandlerConfig {
|
||||
// Tag of the inbound handler.
|
||||
string tag = 1;
|
||||
// Settings for how this inbound proxy is handled. Must be ReceiverConfig above.
|
||||
v2ray.core.common.serial.TypedMessage receiver_settings = 2;
|
||||
// Settings for inbound proxy. Must be one of the inbound proxies.
|
||||
v2ray.core.common.serial.TypedMessage proxy_settings = 3;
|
||||
}
|
||||
|
||||
message OutboundHandlerConfig {
|
||||
// Tag of this outbound handler.
|
||||
string tag = 1;
|
||||
// Settings for how to dial connection for this outbound handler. Must be SenderConfig above.
|
||||
v2ray.core.common.serial.TypedMessage sender_settings = 2;
|
||||
// Settings for this outbound proxy. Must be one of the outbound proxies.
|
||||
v2ray.core.common.serial.TypedMessage proxy_settings = 3;
|
||||
// If not zero, this outbound will be expired in seconds. Not used for now.
|
||||
int64 expire = 4;
|
||||
// Comment of this outbound handler. Not used for now.
|
||||
string comment = 5;
|
||||
}
|
||||
|
17
context.go
Normal file
17
context.go
Normal 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
57
dns.go
Normal 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
|
||||
}
|
@ -2,10 +2,10 @@ package all
|
||||
|
||||
import (
|
||||
// The following are necessary as they register handlers in their init functions.
|
||||
_ "v2ray.com/core/app/dispatcher/impl"
|
||||
_ "v2ray.com/core/app/dispatcher"
|
||||
_ "v2ray.com/core/app/dns"
|
||||
_ "v2ray.com/core/app/log"
|
||||
_ "v2ray.com/core/app/policy/manager"
|
||||
_ "v2ray.com/core/app/policy"
|
||||
_ "v2ray.com/core/app/proxyman/inbound"
|
||||
_ "v2ray.com/core/app/proxyman/outbound"
|
||||
_ "v2ray.com/core/app/router"
|
||||
|
165
network.go
Normal file
165
network.go
Normal 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
117
policy.go
Normal 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
|
||||
}
|
@ -4,10 +4,9 @@ package dokodemo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core/app/policy"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/net"
|
||||
@ -18,36 +17,29 @@ import (
|
||||
)
|
||||
|
||||
type DokodemoDoor struct {
|
||||
config *Config
|
||||
address net.Address
|
||||
port net.Port
|
||||
policy policy.Policy
|
||||
policyManager core.PolicyManager
|
||||
config *Config
|
||||
address net.Address
|
||||
port net.Port
|
||||
v *core.Instance
|
||||
}
|
||||
|
||||
func New(ctx context.Context, config *Config) (*DokodemoDoor, error) {
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context")
|
||||
}
|
||||
if config.NetworkList == nil || config.NetworkList.Size() == 0 {
|
||||
return nil, newError("no network specified")
|
||||
}
|
||||
d := &DokodemoDoor{
|
||||
config: config,
|
||||
address: config.GetPredefinedAddress(),
|
||||
port: net.Port(config.Port),
|
||||
v := core.FromContext(ctx)
|
||||
if v == nil {
|
||||
return nil, newError("V is not in context.")
|
||||
}
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
pm := policy.FromSpace(space)
|
||||
if pm == nil {
|
||||
return newError("Policy not found in space.")
|
||||
}
|
||||
d.policy = pm.GetPolicy(config.UserLevel)
|
||||
if config.Timeout > 0 && config.UserLevel == 0 {
|
||||
d.policy.Timeout.ConnectionIdle.Value = config.Timeout
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
d := &DokodemoDoor{
|
||||
config: config,
|
||||
address: config.GetPredefinedAddress(),
|
||||
port: net.Port(config.Port),
|
||||
policyManager: v.PolicyManager(),
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
@ -55,7 +47,16 @@ func (d *DokodemoDoor) Network() net.NetworkList {
|
||||
return *(d.config.NetworkList)
|
||||
}
|
||||
|
||||
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
|
||||
func (d *DokodemoDoor) policy() core.Policy {
|
||||
config := d.config
|
||||
p := d.policyManager.ForLevel(config.UserLevel)
|
||||
if config.Timeout > 0 && config.UserLevel == 0 {
|
||||
p.Timeouts.ConnectionIdle = time.Duration(config.Timeout) * time.Second
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher core.Dispatcher) error {
|
||||
newError("processing connection from: ", conn.RemoteAddr()).AtDebug().WriteToLog()
|
||||
dest := net.Destination{
|
||||
Network: network,
|
||||
@ -72,7 +73,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, d.policy.Timeout.ConnectionIdle.Duration())
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, d.policy().Timeouts.ConnectionIdle)
|
||||
|
||||
inboundRay, err := dispatcher.Dispatch(ctx, dest)
|
||||
if err != nil {
|
||||
@ -88,7 +89,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
|
||||
return newError("failed to transport request").Base(err)
|
||||
}
|
||||
|
||||
timer.SetTimeout(d.policy.Timeout.DownlinkOnly.Duration())
|
||||
timer.SetTimeout(d.policy().Timeouts.DownlinkOnly)
|
||||
|
||||
return nil
|
||||
})
|
||||
@ -115,7 +116,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
|
||||
return newError("failed to transport response").Base(err)
|
||||
}
|
||||
|
||||
timer.SetTimeout(d.policy.Timeout.UplinkOnly.Duration())
|
||||
timer.SetTimeout(d.policy().Timeouts.UplinkOnly)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
@ -4,9 +4,9 @@ package freedom
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/policy"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/dice"
|
||||
@ -20,37 +20,35 @@ import (
|
||||
|
||||
// Handler handles Freedom connections.
|
||||
type Handler struct {
|
||||
domainStrategy Config_DomainStrategy
|
||||
timeout uint32
|
||||
destOverride *DestinationOverride
|
||||
policy policy.Policy
|
||||
policyManager core.PolicyManager
|
||||
dns core.DNSClient
|
||||
config Config
|
||||
}
|
||||
|
||||
// New creates a new Freedom handler.
|
||||
func New(ctx context.Context, config *Config) (*Handler, error) {
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context")
|
||||
v := core.FromContext(ctx)
|
||||
if v == nil {
|
||||
return nil, newError("V is not found in context.")
|
||||
}
|
||||
|
||||
f := &Handler{
|
||||
domainStrategy: config.DomainStrategy,
|
||||
timeout: config.Timeout,
|
||||
destOverride: config.DestinationOverride,
|
||||
config: *config,
|
||||
policyManager: v.PolicyManager(),
|
||||
dns: v.DNSClient(),
|
||||
}
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
pm := policy.FromSpace(space)
|
||||
if pm == nil {
|
||||
return newError("Policy not found in space.")
|
||||
}
|
||||
f.policy = pm.GetPolicy(config.UserLevel)
|
||||
if config.Timeout > 0 && config.UserLevel == 0 {
|
||||
f.policy.Timeout.ConnectionIdle.Value = config.Timeout
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (h *Handler) policy() core.Policy {
|
||||
p := h.policyManager.ForLevel(h.config.UserLevel)
|
||||
if h.config.Timeout > 0 && h.config.UserLevel == 0 {
|
||||
p.Timeouts.ConnectionIdle = time.Duration(h.config.Timeout) * time.Second
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (h *Handler) resolveIP(ctx context.Context, domain string) net.Address {
|
||||
if resolver, ok := proxy.ResolvedIPsFromContext(ctx); ok {
|
||||
ips := resolver.Resolve()
|
||||
@ -60,7 +58,7 @@ func (h *Handler) resolveIP(ctx context.Context, domain string) net.Address {
|
||||
return ips[dice.Roll(len(ips))]
|
||||
}
|
||||
|
||||
ips, err := net.LookupIP(domain)
|
||||
ips, err := h.dns.LookupIP(domain)
|
||||
if err != nil {
|
||||
newError("failed to get IP address for domain ", domain).Base(err).WriteToLog()
|
||||
}
|
||||
@ -73,8 +71,8 @@ func (h *Handler) resolveIP(ctx context.Context, domain string) net.Address {
|
||||
// Process implements proxy.Outbound.
|
||||
func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dialer proxy.Dialer) error {
|
||||
destination, _ := proxy.TargetFromContext(ctx)
|
||||
if h.destOverride != nil {
|
||||
server := h.destOverride.Server
|
||||
if h.config.DestinationOverride != nil {
|
||||
server := h.config.DestinationOverride.Server
|
||||
destination = net.Destination{
|
||||
Network: destination.Network,
|
||||
Address: server.Address.AsAddress(),
|
||||
@ -86,7 +84,7 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
|
||||
input := outboundRay.OutboundInput()
|
||||
output := outboundRay.OutboundOutput()
|
||||
|
||||
if h.domainStrategy == Config_USE_IP && destination.Address.Family().IsDomain() {
|
||||
if h.config.DomainStrategy == Config_USE_IP && destination.Address.Family().IsDomain() {
|
||||
ip := h.resolveIP(ctx, destination.Address.Domain())
|
||||
if ip != nil {
|
||||
destination = net.Destination{
|
||||
@ -113,7 +111,7 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
|
||||
defer conn.Close()
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, h.policy.Timeout.ConnectionIdle.Duration())
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, h.policy().Timeouts.ConnectionIdle)
|
||||
|
||||
requestDone := signal.ExecuteAsync(func() error {
|
||||
var writer buf.Writer
|
||||
@ -125,7 +123,7 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
|
||||
if err := buf.Copy(input, writer, buf.UpdateActivity(timer)); err != nil {
|
||||
return newError("failed to process request").Base(err)
|
||||
}
|
||||
timer.SetTimeout(h.policy.Timeout.DownlinkOnly.Duration())
|
||||
timer.SetTimeout(h.policy().Timeouts.DownlinkOnly)
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -136,7 +134,7 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
|
||||
if err := buf.Copy(v2reader, output, buf.UpdateActivity(timer)); err != nil {
|
||||
return newError("failed to process response").Base(err)
|
||||
}
|
||||
timer.SetTimeout(h.policy.Timeout.UplinkOnly.Duration())
|
||||
timer.SetTimeout(h.policy().Timeouts.UplinkOnly)
|
||||
return nil
|
||||
})
|
||||
|
||||
|
@ -10,9 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core/app/policy"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/errors"
|
||||
@ -26,32 +24,31 @@ import (
|
||||
// Server is a HTTP proxy server.
|
||||
type Server struct {
|
||||
config *ServerConfig
|
||||
policy policy.Policy
|
||||
v *core.Instance
|
||||
}
|
||||
|
||||
// NewServer creates a new HTTP inbound handler.
|
||||
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context.")
|
||||
}
|
||||
s := &Server{
|
||||
config: config,
|
||||
v: core.FromContext(ctx),
|
||||
}
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
pm := policy.FromSpace(space)
|
||||
if pm == nil {
|
||||
return newError("Policy not found in space.")
|
||||
}
|
||||
s.policy = pm.GetPolicy(config.UserLevel)
|
||||
if config.Timeout > 0 && config.UserLevel == 0 {
|
||||
s.policy.Timeout.ConnectionIdle.Value = config.Timeout
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if s.v == nil {
|
||||
return nil, newError("V is not in context.")
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Server) policy() core.Policy {
|
||||
config := s.config
|
||||
p := s.v.PolicyManager().ForLevel(config.UserLevel)
|
||||
if config.Timeout > 0 && config.UserLevel == 0 {
|
||||
p.Timeouts.ConnectionIdle = time.Duration(config.Timeout) * time.Second
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (*Server) Network() net.NetworkList {
|
||||
return net.NetworkList{
|
||||
Network: []net.Network{net.Network_TCP},
|
||||
@ -104,11 +101,11 @@ type readerOnly struct {
|
||||
io.Reader
|
||||
}
|
||||
|
||||
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
|
||||
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher core.Dispatcher) error {
|
||||
reader := bufio.NewReaderSize(readerOnly{conn}, buf.Size)
|
||||
|
||||
Start:
|
||||
conn.SetReadDeadline(time.Now().Add(s.policy.Timeout.Handshake.Duration()))
|
||||
conn.SetReadDeadline(time.Now().Add(s.policy().Timeouts.Handshake))
|
||||
|
||||
request, err := http.ReadRequest(reader)
|
||||
if err != nil {
|
||||
@ -165,14 +162,14 @@ Start:
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Server) handleConnect(ctx context.Context, request *http.Request, reader *bufio.Reader, conn internet.Connection, dest net.Destination, dispatcher dispatcher.Interface) error {
|
||||
func (s *Server) handleConnect(ctx context.Context, request *http.Request, reader *bufio.Reader, conn internet.Connection, dest net.Destination, dispatcher core.Dispatcher) error {
|
||||
_, err := conn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
|
||||
if err != nil {
|
||||
return newError("failed to write back OK response").Base(err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, s.policy.Timeout.ConnectionIdle.Duration())
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, s.policy().Timeouts.ConnectionIdle)
|
||||
ray, err := dispatcher.Dispatch(ctx, dest)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -191,7 +188,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
|
||||
|
||||
requestDone := signal.ExecuteAsync(func() error {
|
||||
defer ray.InboundInput().Close()
|
||||
defer timer.SetTimeout(s.policy.Timeout.DownlinkOnly.Duration())
|
||||
defer timer.SetTimeout(s.policy().Timeouts.DownlinkOnly)
|
||||
|
||||
v2reader := buf.NewReader(conn)
|
||||
return buf.Copy(v2reader, ray.InboundInput(), buf.UpdateActivity(timer))
|
||||
@ -202,7 +199,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
|
||||
if err := buf.Copy(ray.InboundOutput(), v2writer, buf.UpdateActivity(timer)); err != nil {
|
||||
return err
|
||||
}
|
||||
timer.SetTimeout(s.policy.Timeout.UplinkOnly.Duration())
|
||||
timer.SetTimeout(s.policy().Timeouts.UplinkOnly)
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -217,7 +214,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
|
||||
|
||||
var errWaitAnother = newError("keep alive")
|
||||
|
||||
func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, writer io.Writer, dest net.Destination, dispatcher dispatcher.Interface) error {
|
||||
func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, writer io.Writer, dest net.Destination, dispatcher core.Dispatcher) error {
|
||||
if !s.config.AllowTransparent && len(request.URL.Host) <= 0 {
|
||||
// RFC 2068 (HTTP/1.1) requires URL to be absolute URL in HTTP proxy.
|
||||
response := &http.Response{
|
||||
|
@ -10,7 +10,7 @@ package proxy
|
||||
import (
|
||||
"context"
|
||||
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common/net"
|
||||
"v2ray.com/core/transport/internet"
|
||||
"v2ray.com/core/transport/ray"
|
||||
@ -22,7 +22,7 @@ type Inbound interface {
|
||||
Network() net.NetworkList
|
||||
|
||||
// Process processes a connection of given network. If necessary, the Inbound can dispatch the connection to an Outbound.
|
||||
Process(context.Context, net.Network, internet.Connection, dispatcher.Interface) error
|
||||
Process(context.Context, net.Network, internet.Connection, core.Dispatcher) error
|
||||
}
|
||||
|
||||
// An Outbound process outbound connections.
|
||||
|
@ -3,8 +3,7 @@ package shadowsocks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/policy"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/net"
|
||||
@ -18,8 +17,8 @@ import (
|
||||
|
||||
// Client is a inbound handler for Shadowsocks protocol
|
||||
type Client struct {
|
||||
serverPicker protocol.ServerPicker
|
||||
policyManager policy.Manager
|
||||
serverPicker protocol.ServerPicker
|
||||
v *core.Instance
|
||||
}
|
||||
|
||||
// NewClient create a new Shadowsocks client.
|
||||
@ -33,19 +32,11 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
|
||||
}
|
||||
client := &Client{
|
||||
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
|
||||
v: core.FromContext(ctx),
|
||||
}
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("Space not found.")
|
||||
if client.v == nil {
|
||||
return nil, newError("V is not in context.")
|
||||
}
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
pm := policy.FromSpace(space)
|
||||
if pm == nil {
|
||||
return newError("Policy not found in space.")
|
||||
}
|
||||
client.policyManager = pm
|
||||
return nil
|
||||
})
|
||||
|
||||
return client, nil
|
||||
}
|
||||
@ -103,9 +94,9 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
|
||||
request.Option |= RequestOptionOneTimeAuth
|
||||
}
|
||||
|
||||
sessionPolicy := v.policyManager.GetPolicy(user.Level)
|
||||
sessionPolicy := v.v.PolicyManager().ForLevel(user.Level)
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
|
||||
|
||||
if request.Command == protocol.RequestCommandTCP {
|
||||
bufferedWriter := buf.NewBufferedWriter(buf.NewWriter(conn))
|
||||
@ -119,13 +110,13 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
|
||||
}
|
||||
|
||||
requestDone := signal.ExecuteAsync(func() error {
|
||||
defer timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
|
||||
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
|
||||
return buf.Copy(outboundRay.OutboundInput(), bodyWriter, buf.UpdateActivity(timer))
|
||||
})
|
||||
|
||||
responseDone := signal.ExecuteAsync(func() error {
|
||||
defer outboundRay.OutboundOutput().Close()
|
||||
defer timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
|
||||
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
|
||||
|
||||
responseReader, err := ReadTCPResponse(user, conn)
|
||||
if err != nil {
|
||||
|
@ -4,9 +4,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core/app/policy"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/log"
|
||||
@ -19,18 +17,14 @@ import (
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
config *ServerConfig
|
||||
user *protocol.User
|
||||
account *MemoryAccount
|
||||
policyManager policy.Manager
|
||||
config *ServerConfig
|
||||
user *protocol.User
|
||||
account *MemoryAccount
|
||||
v *core.Instance
|
||||
}
|
||||
|
||||
// NewServer create a new Shadowsocks server.
|
||||
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context")
|
||||
}
|
||||
if config.GetUser() == nil {
|
||||
return nil, newError("user is not specified")
|
||||
}
|
||||
@ -45,16 +39,12 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
||||
config: config,
|
||||
user: config.GetUser(),
|
||||
account: account,
|
||||
v: core.FromContext(ctx),
|
||||
}
|
||||
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
pm := policy.FromSpace(space)
|
||||
if pm == nil {
|
||||
return newError("Policy not found in space.")
|
||||
}
|
||||
s.policyManager = pm
|
||||
return nil
|
||||
})
|
||||
if s.v == nil {
|
||||
return nil, newError("V is not in context.")
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
@ -69,7 +59,7 @@ func (s *Server) Network() net.NetworkList {
|
||||
return list
|
||||
}
|
||||
|
||||
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
|
||||
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher core.Dispatcher) error {
|
||||
switch network {
|
||||
case net.Network_TCP:
|
||||
return s.handleConnection(ctx, conn, dispatcher)
|
||||
@ -80,7 +70,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
|
||||
func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection, dispatcher core.Dispatcher) error {
|
||||
udpServer := udp.NewDispatcher(dispatcher)
|
||||
|
||||
reader := buf.NewReader(conn)
|
||||
@ -148,9 +138,9 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) handleConnection(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
|
||||
sessionPolicy := s.policyManager.GetPolicy(s.user.Level)
|
||||
conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeout.Handshake.Duration()))
|
||||
func (s *Server) handleConnection(ctx context.Context, conn internet.Connection, dispatcher core.Dispatcher) error {
|
||||
sessionPolicy := s.v.PolicyManager().ForLevel(s.user.Level)
|
||||
conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake))
|
||||
bufferedReader := buf.NewBufferedReader(buf.NewReader(conn))
|
||||
request, bodyReader, err := ReadTCPSession(s.user, bufferedReader)
|
||||
if err != nil {
|
||||
@ -178,7 +168,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
|
||||
ctx = protocol.ContextWithUser(ctx, request.User)
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
|
||||
ray, err := dispatcher.Dispatch(ctx, dest)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -208,7 +198,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
|
||||
return newError("failed to transport all TCP response").Base(err)
|
||||
}
|
||||
|
||||
timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
|
||||
timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
|
||||
|
||||
return nil
|
||||
})
|
||||
@ -219,7 +209,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
|
||||
if err := buf.Copy(bodyReader, ray.InboundInput(), buf.UpdateActivity(timer)); err != nil {
|
||||
return newError("failed to transport all TCP request").Base(err)
|
||||
}
|
||||
timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
|
||||
timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
|
||||
return nil
|
||||
})
|
||||
|
||||
|
@ -5,9 +5,7 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core/app/policy"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/log"
|
||||
@ -22,32 +20,30 @@ import (
|
||||
// Server is a SOCKS 5 proxy server
|
||||
type Server struct {
|
||||
config *ServerConfig
|
||||
policy policy.Policy
|
||||
v *core.Instance
|
||||
}
|
||||
|
||||
// NewServer creates a new Server object.
|
||||
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context").AtWarning()
|
||||
}
|
||||
s := &Server{
|
||||
config: config,
|
||||
v: core.FromContext(ctx),
|
||||
}
|
||||
if s.v == nil {
|
||||
return nil, newError("V is not in context.")
|
||||
}
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
pm := policy.FromSpace(space)
|
||||
if pm == nil {
|
||||
return newError("Policy not found in space.")
|
||||
}
|
||||
s.policy = pm.GetPolicy(config.UserLevel)
|
||||
if config.Timeout > 0 && config.UserLevel == 0 {
|
||||
s.policy.Timeout.ConnectionIdle.Value = config.Timeout
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Server) policy() core.Policy {
|
||||
config := s.config
|
||||
p := s.v.PolicyManager().ForLevel(config.UserLevel)
|
||||
if config.Timeout > 0 && config.UserLevel == 0 {
|
||||
p.Timeouts.ConnectionIdle = time.Duration(config.Timeout) * time.Second
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (s *Server) Network() net.NetworkList {
|
||||
list := net.NetworkList{
|
||||
Network: []net.Network{net.Network_TCP},
|
||||
@ -58,7 +54,7 @@ func (s *Server) Network() net.NetworkList {
|
||||
return list
|
||||
}
|
||||
|
||||
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
|
||||
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher core.Dispatcher) error {
|
||||
switch network {
|
||||
case net.Network_TCP:
|
||||
return s.processTCP(ctx, conn, dispatcher)
|
||||
@ -69,8 +65,8 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
|
||||
conn.SetReadDeadline(time.Now().Add(s.policy.Timeout.Handshake.Duration()))
|
||||
func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispatcher core.Dispatcher) error {
|
||||
conn.SetReadDeadline(time.Now().Add(s.policy().Timeouts.Handshake))
|
||||
reader := buf.NewBufferedReader(buf.NewReader(conn))
|
||||
|
||||
inboundDest, ok := proxy.InboundEntryPointFromContext(ctx)
|
||||
@ -125,9 +121,9 @@ func (*Server) handleUDP(c net.Conn) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writer, dest net.Destination, dispatcher dispatcher.Interface) error {
|
||||
func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writer, dest net.Destination, dispatcher core.Dispatcher) error {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, v.policy.Timeout.ConnectionIdle.Duration())
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, v.policy().Timeouts.ConnectionIdle)
|
||||
|
||||
ray, err := dispatcher.Dispatch(ctx, dest)
|
||||
if err != nil {
|
||||
@ -144,7 +140,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
|
||||
if err := buf.Copy(v2reader, input, buf.UpdateActivity(timer)); err != nil {
|
||||
return newError("failed to transport all TCP request").Base(err)
|
||||
}
|
||||
timer.SetTimeout(v.policy.Timeout.DownlinkOnly.Duration())
|
||||
timer.SetTimeout(v.policy().Timeouts.DownlinkOnly)
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -153,7 +149,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
|
||||
if err := buf.Copy(output, v2writer, buf.UpdateActivity(timer)); err != nil {
|
||||
return newError("failed to transport all TCP response").Base(err)
|
||||
}
|
||||
timer.SetTimeout(v.policy.Timeout.UplinkOnly.Duration())
|
||||
timer.SetTimeout(v.policy().Timeouts.UplinkOnly)
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -166,7 +162,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
|
||||
func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection, dispatcher core.Dispatcher) error {
|
||||
udpServer := udp.NewDispatcher(dispatcher)
|
||||
|
||||
if source, ok := proxy.SourceFromContext(ctx); ok {
|
||||
|
@ -8,10 +8,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core/app/policy"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/errors"
|
||||
@ -74,21 +71,16 @@ func (v *userByEmail) Get(email string) (*protocol.User, bool) {
|
||||
|
||||
// Handler is an inbound connection handler that handles messages in VMess protocol.
|
||||
type Handler struct {
|
||||
inboundHandlerManager proxyman.InboundHandlerManager
|
||||
policyManager core.PolicyManager
|
||||
inboundHandlerManager core.InboundHandlerManager
|
||||
clients protocol.UserValidator
|
||||
usersByEmail *userByEmail
|
||||
detours *DetourConfig
|
||||
sessionHistory *encoding.SessionHistory
|
||||
policyManager policy.Manager
|
||||
}
|
||||
|
||||
// New creates a new VMess inbound handler.
|
||||
func New(ctx context.Context, config *Config) (*Handler, error) {
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context")
|
||||
}
|
||||
|
||||
allowedClients := vmess.NewTimedUserValidator(ctx, protocol.DefaultIDHash)
|
||||
for _, user := range config.User {
|
||||
if err := allowedClients.Add(user); err != nil {
|
||||
@ -96,24 +88,19 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
|
||||
}
|
||||
}
|
||||
|
||||
handler := &Handler{
|
||||
clients: allowedClients,
|
||||
detours: config.Detour,
|
||||
usersByEmail: newUserByEmail(config.User, config.GetDefaultValue()),
|
||||
sessionHistory: encoding.NewSessionHistory(ctx),
|
||||
v := core.FromContext(ctx)
|
||||
if v == nil {
|
||||
return nil, newError("V is not in context.")
|
||||
}
|
||||
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space)
|
||||
if handler.inboundHandlerManager == nil {
|
||||
return newError("InboundHandlerManager is not found is space.")
|
||||
}
|
||||
handler.policyManager = policy.FromSpace(space)
|
||||
if handler.policyManager == nil {
|
||||
return newError("Policy is not found in space.")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
handler := &Handler{
|
||||
policyManager: v.PolicyManager(),
|
||||
inboundHandlerManager: v.InboundHandlerManager(),
|
||||
clients: allowedClients,
|
||||
detours: config.Detour,
|
||||
usersByEmail: newUserByEmail(config.User, config.GetDefaultValue()),
|
||||
sessionHistory: encoding.NewSessionHistory(ctx),
|
||||
}
|
||||
|
||||
return handler, nil
|
||||
}
|
||||
@ -179,9 +166,9 @@ func transferResponse(timer signal.ActivityUpdater, session *encoding.ServerSess
|
||||
}
|
||||
|
||||
// Process implements proxy.Inbound.Process().
|
||||
func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher dispatcher.Interface) error {
|
||||
sessionPolicy := h.policyManager.GetPolicy(0)
|
||||
if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeout.Handshake.Duration())); err != nil {
|
||||
func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher core.Dispatcher) error {
|
||||
sessionPolicy := h.policyManager.ForLevel(0)
|
||||
if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {
|
||||
return newError("unable to set read deadline").Base(err).AtWarning()
|
||||
}
|
||||
|
||||
@ -221,11 +208,11 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
|
||||
newError("unable to set back read deadline").Base(err).WriteToLog()
|
||||
}
|
||||
|
||||
sessionPolicy = h.policyManager.GetPolicy(request.User.Level)
|
||||
sessionPolicy = h.policyManager.ForLevel(request.User.Level)
|
||||
ctx = protocol.ContextWithUser(ctx, request.User)
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
|
||||
ray, err := dispatcher.Dispatch(ctx, request.Destination())
|
||||
if err != nil {
|
||||
return newError("failed to dispatch request to ", request.Destination()).Base(err)
|
||||
@ -235,14 +222,14 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
|
||||
output := ray.InboundOutput()
|
||||
|
||||
requestDone := signal.ExecuteAsync(func() error {
|
||||
defer timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
|
||||
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
|
||||
return transferRequest(timer, session, request, reader, input)
|
||||
})
|
||||
|
||||
responseDone := signal.ExecuteAsync(func() error {
|
||||
writer := buf.NewBufferedWriter(buf.NewWriter(connection))
|
||||
defer writer.Flush()
|
||||
defer timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
|
||||
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
|
||||
|
||||
response := &protocol.ResponseHeader{
|
||||
Command: h.generateCommand(ctx, request),
|
||||
|
@ -6,8 +6,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/policy"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/net"
|
||||
@ -23,17 +22,12 @@ import (
|
||||
|
||||
// Handler is an outbound connection handler for VMess protocol.
|
||||
type Handler struct {
|
||||
serverList *protocol.ServerList
|
||||
serverPicker protocol.ServerPicker
|
||||
policyManager policy.Manager
|
||||
serverList *protocol.ServerList
|
||||
serverPicker protocol.ServerPicker
|
||||
v *core.Instance
|
||||
}
|
||||
|
||||
func New(ctx context.Context, config *Config) (*Handler, error) {
|
||||
space := app.SpaceFromContext(ctx)
|
||||
if space == nil {
|
||||
return nil, newError("no space in context.")
|
||||
}
|
||||
|
||||
serverList := protocol.NewServerList()
|
||||
for _, rec := range config.Receiver {
|
||||
serverList.AddServer(protocol.NewServerSpecFromPB(*rec))
|
||||
@ -41,16 +35,12 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
|
||||
handler := &Handler{
|
||||
serverList: serverList,
|
||||
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
|
||||
v: core.FromContext(ctx),
|
||||
}
|
||||
|
||||
space.On(app.SpaceInitializing, func(interface{}) error {
|
||||
pm := policy.FromSpace(space)
|
||||
if pm == nil {
|
||||
return newError("Policy is not found in space.")
|
||||
}
|
||||
handler.policyManager = pm
|
||||
return nil
|
||||
})
|
||||
if handler.v == nil {
|
||||
return nil, newError("V is not in context.")
|
||||
}
|
||||
|
||||
return handler, nil
|
||||
}
|
||||
@ -112,10 +102,10 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
|
||||
output := outboundRay.OutboundOutput()
|
||||
|
||||
session := encoding.NewClientSession(protocol.DefaultIDHash)
|
||||
sessionPolicy := v.policyManager.GetPolicy(request.User.Level)
|
||||
sessionPolicy := v.v.PolicyManager().ForLevel(request.User.Level)
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
|
||||
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
|
||||
|
||||
requestDone := signal.ExecuteAsync(func() error {
|
||||
writer := buf.NewBufferedWriter(buf.NewWriter(conn))
|
||||
@ -148,13 +138,13 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
|
||||
return err
|
||||
}
|
||||
}
|
||||
timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
|
||||
timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
|
||||
return nil
|
||||
})
|
||||
|
||||
responseDone := signal.ExecuteAsync(func() error {
|
||||
defer output.Close()
|
||||
defer timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
|
||||
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
|
||||
|
||||
reader := buf.NewBufferedReader(buf.NewReader(conn))
|
||||
header, err := session.DecodeResponseHeader(reader)
|
||||
|
118
router.go
Normal file
118
router.go
Normal 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
|
||||
}
|
@ -13,10 +13,13 @@ import (
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/log"
|
||||
"v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/retry"
|
||||
"v2ray.com/core/common/serial"
|
||||
)
|
||||
|
||||
func pickPort() net.Port {
|
||||
@ -70,6 +73,7 @@ func InitializeServerConfig(config *core.Config) (*exec.Cmd, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config = withDefaultApps(config)
|
||||
configBytes, err := proto.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -128,3 +132,10 @@ func CloseAllServers(servers []*exec.Cmd) {
|
||||
Content: "All server closed.",
|
||||
})
|
||||
}
|
||||
|
||||
func withDefaultApps(config *core.Config) *core.Config {
|
||||
config.App = append(config.App, serial.ToTypedMessage(&dispatcher.Config{}))
|
||||
config.App = append(config.App, serial.ToTypedMessage(&proxyman.InboundConfig{}))
|
||||
config.App = append(config.App, serial.ToTypedMessage(&proxyman.OutboundConfig{}))
|
||||
return config
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ func TestResolveIP(t *testing.T) {
|
||||
},
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -67,7 +67,7 @@ func TestResolveIP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&blackhole.Config{}),
|
||||
},
|
||||
|
@ -40,7 +40,7 @@ func TestDokodemoTCP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -57,7 +57,7 @@ func TestDokodemoTCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -73,7 +73,7 @@ func TestDokodemoTCP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: &net.PortRange{From: clientPort, To: clientPort + clientPortRange},
|
||||
@ -88,7 +88,7 @@ func TestDokodemoTCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -147,7 +147,7 @@ func TestDokodemoUDP(t *testing.T) {
|
||||
userID := protocol.NewID(uuid.New())
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -164,7 +164,7 @@ func TestDokodemoUDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -174,7 +174,7 @@ func TestDokodemoUDP(t *testing.T) {
|
||||
clientPort := uint32(pickPort())
|
||||
clientPortRange := uint32(5)
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: &net.PortRange{From: clientPort, To: clientPort + clientPortRange},
|
||||
@ -189,7 +189,7 @@ func TestDokodemoUDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
|
@ -44,7 +44,7 @@ func TestPassiveConnection(t *testing.T) {
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -59,7 +59,7 @@ func TestPassiveConnection(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -115,7 +115,7 @@ func TestProxy(t *testing.T) {
|
||||
serverUserID := protocol.NewID(uuid.New())
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -132,7 +132,7 @@ func TestProxy(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -142,7 +142,7 @@ func TestProxy(t *testing.T) {
|
||||
proxyUserID := protocol.NewID(uuid.New())
|
||||
proxyPort := pickPort()
|
||||
proxyConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(proxyPort),
|
||||
@ -159,7 +159,7 @@ func TestProxy(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -168,7 +168,7 @@ func TestProxy(t *testing.T) {
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -183,7 +183,7 @@ func TestProxy(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -263,7 +263,7 @@ func TestProxyOverKCP(t *testing.T) {
|
||||
serverUserID := protocol.NewID(uuid.New())
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -283,7 +283,7 @@ func TestProxyOverKCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -293,7 +293,7 @@ func TestProxyOverKCP(t *testing.T) {
|
||||
proxyUserID := protocol.NewID(uuid.New())
|
||||
proxyPort := pickPort()
|
||||
proxyConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(proxyPort),
|
||||
@ -310,7 +310,7 @@ func TestProxyOverKCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
|
||||
@ -324,7 +324,7 @@ func TestProxyOverKCP(t *testing.T) {
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -339,7 +339,7 @@ func TestProxyOverKCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -429,7 +429,7 @@ func TestBlackhole(t *testing.T) {
|
||||
serverPort := pickPort()
|
||||
serverPort2 := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -457,7 +457,7 @@ func TestBlackhole(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
Tag: "direct",
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
@ -519,7 +519,7 @@ func TestForward(t *testing.T) {
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -535,7 +535,7 @@ func TestForward(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{
|
||||
DestinationOverride: &freedom.DestinationOverride{
|
||||
@ -585,7 +585,7 @@ func TestUDPConnection(t *testing.T) {
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -600,7 +600,7 @@ func TestUDPConnection(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -662,7 +662,7 @@ func TestDomainSniffing(t *testing.T) {
|
||||
sniffingPort := pickPort()
|
||||
httpPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
Tag: "snif",
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
@ -689,7 +689,7 @@ func TestDomainSniffing(t *testing.T) {
|
||||
ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
Tag: "redir",
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{
|
||||
|
@ -37,7 +37,7 @@ func TestHttpConformance(t *testing.T) {
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -46,7 +46,7 @@ func TestHttpConformance(t *testing.T) {
|
||||
ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -92,7 +92,7 @@ func TestHttpConnectMethod(t *testing.T) {
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -101,7 +101,7 @@ func TestHttpConnectMethod(t *testing.T) {
|
||||
ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -171,7 +171,7 @@ func TestHttpPost(t *testing.T) {
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -180,7 +180,7 @@ func TestHttpPost(t *testing.T) {
|
||||
ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -237,7 +237,7 @@ func TestHttpBasicAuth(t *testing.T) {
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -250,7 +250,7 @@ func TestHttpBasicAuth(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
|
@ -49,7 +49,7 @@ func TestShadowsocksAES256TCP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -63,7 +63,7 @@ func TestShadowsocksAES256TCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -78,7 +78,7 @@ func TestShadowsocksAES256TCP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -93,7 +93,7 @@ func TestShadowsocksAES256TCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{
|
||||
Server: []*protocol.ServerEndpoint{
|
||||
@ -167,7 +167,7 @@ func TestShadowsocksAES128UDP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -182,7 +182,7 @@ func TestShadowsocksAES128UDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -197,7 +197,7 @@ func TestShadowsocksAES128UDP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -212,7 +212,7 @@ func TestShadowsocksAES128UDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{
|
||||
Server: []*protocol.ServerEndpoint{
|
||||
@ -286,7 +286,7 @@ func TestShadowsocksChacha20TCP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -300,7 +300,7 @@ func TestShadowsocksChacha20TCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -315,7 +315,7 @@ func TestShadowsocksChacha20TCP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -330,7 +330,7 @@ func TestShadowsocksChacha20TCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{
|
||||
Server: []*protocol.ServerEndpoint{
|
||||
@ -403,7 +403,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -417,7 +417,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -432,7 +432,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -447,7 +447,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{
|
||||
Server: []*protocol.ServerEndpoint{
|
||||
@ -520,7 +520,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -535,7 +535,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -550,7 +550,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -565,7 +565,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{
|
||||
Server: []*protocol.ServerEndpoint{
|
||||
@ -638,7 +638,7 @@ func TestShadowsocksAES256GCMConformance(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -652,7 +652,7 @@ func TestShadowsocksAES256GCMConformance(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -716,7 +716,7 @@ func TestShadowsocksChacha20Poly1305UDPConformance(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -731,7 +731,7 @@ func TestShadowsocksChacha20Poly1305UDPConformance(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -799,7 +799,7 @@ func TestShadowsocksChacha20Conformance(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -813,7 +813,7 @@ func TestShadowsocksChacha20Conformance(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
|
@ -30,7 +30,7 @@ func TestSocksBridgeTCP(t *testing.T) {
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -46,7 +46,7 @@ func TestSocksBridgeTCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -55,7 +55,7 @@ func TestSocksBridgeTCP(t *testing.T) {
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -70,7 +70,7 @@ func TestSocksBridgeTCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&socks.ClientConfig{
|
||||
Server: []*protocol.ServerEndpoint{
|
||||
@ -127,7 +127,7 @@ func TestSocksBridageUDP(t *testing.T) {
|
||||
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -143,7 +143,7 @@ func TestSocksBridageUDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -152,7 +152,7 @@ func TestSocksBridageUDP(t *testing.T) {
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -167,7 +167,7 @@ func TestSocksBridageUDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&socks.ClientConfig{
|
||||
Server: []*protocol.ServerEndpoint{
|
||||
@ -225,7 +225,7 @@ func TestSocksConformance(t *testing.T) {
|
||||
authPort := pickPort()
|
||||
noAuthPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(authPort),
|
||||
@ -255,7 +255,7 @@ func TestSocksConformance(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
|
@ -38,7 +38,7 @@ func TestSimpleTLSConnection(t *testing.T) {
|
||||
userID := protocol.NewID(uuid.New())
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -63,7 +63,7 @@ func TestSimpleTLSConnection(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -72,7 +72,7 @@ func TestSimpleTLSConnection(t *testing.T) {
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -87,7 +87,7 @@ func TestSimpleTLSConnection(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -152,7 +152,7 @@ func TestTLSOverKCP(t *testing.T) {
|
||||
userID := protocol.NewID(uuid.New())
|
||||
serverPort := udp.PickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -178,7 +178,7 @@ func TestTLSOverKCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -187,7 +187,7 @@ func TestTLSOverKCP(t *testing.T) {
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -202,7 +202,7 @@ func TestTLSOverKCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -268,7 +268,7 @@ func TestTLSOverWebSocket(t *testing.T) {
|
||||
userID := protocol.NewID(uuid.New())
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -294,7 +294,7 @@ func TestTLSOverWebSocket(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -303,7 +303,7 @@ func TestTLSOverWebSocket(t *testing.T) {
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -318,7 +318,7 @@ func TestTLSOverWebSocket(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
|
@ -35,7 +35,7 @@ func TestHttpConnectionHeader(t *testing.T) {
|
||||
userID := protocol.NewID(uuid.New())
|
||||
serverPort := pickPort()
|
||||
serverConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -62,7 +62,7 @@ func TestHttpConnectionHeader(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -71,7 +71,7 @@ func TestHttpConnectionHeader(t *testing.T) {
|
||||
|
||||
clientPort := pickPort()
|
||||
clientConfig := &core.Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -86,7 +86,7 @@ func TestHttpConnectionHeader(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
|
@ -44,7 +44,7 @@ func TestVMessDynamicPort(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -84,7 +84,7 @@ func TestVMessDynamicPort(t *testing.T) {
|
||||
Tag: "detour",
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -99,7 +99,7 @@ func TestVMessDynamicPort(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -114,7 +114,7 @@ func TestVMessDynamicPort(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -179,7 +179,7 @@ func TestVMessGCM(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -197,7 +197,7 @@ func TestVMessGCM(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -212,7 +212,7 @@ func TestVMessGCM(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -227,7 +227,7 @@ func TestVMessGCM(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -302,7 +302,7 @@ func TestVMessGCMUDP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -320,7 +320,7 @@ func TestVMessGCMUDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -335,7 +335,7 @@ func TestVMessGCMUDP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -350,7 +350,7 @@ func TestVMessGCMUDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -435,7 +435,7 @@ func TestVMessChacha20(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -453,7 +453,7 @@ func TestVMessChacha20(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -468,7 +468,7 @@ func TestVMessChacha20(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -483,7 +483,7 @@ func TestVMessChacha20(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -558,7 +558,7 @@ func TestVMessNone(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -576,7 +576,7 @@ func TestVMessNone(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -591,7 +591,7 @@ func TestVMessNone(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -606,7 +606,7 @@ func TestVMessNone(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -683,7 +683,7 @@ func TestVMessKCP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -704,7 +704,7 @@ func TestVMessKCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -719,7 +719,7 @@ func TestVMessKCP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -734,7 +734,7 @@ func TestVMessKCP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -816,7 +816,7 @@ func TestVMessIPv6(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -834,7 +834,7 @@ func TestVMessIPv6(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -849,7 +849,7 @@ func TestVMessIPv6(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -864,7 +864,7 @@ func TestVMessIPv6(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
@ -931,7 +931,7 @@ func TestVMessGCMMux(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -949,7 +949,7 @@ func TestVMessGCMMux(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -964,7 +964,7 @@ func TestVMessGCMMux(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -979,7 +979,7 @@ func TestVMessGCMMux(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
|
||||
MultiplexSettings: &proxyman.MultiplexingConfig{
|
||||
@ -1073,7 +1073,7 @@ func TestVMessGCMMuxUDP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(serverPort),
|
||||
@ -1091,7 +1091,7 @@ func TestVMessGCMMuxUDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
||||
},
|
||||
@ -1107,7 +1107,7 @@ func TestVMessGCMMuxUDP(t *testing.T) {
|
||||
ErrorLogType: log.LogType_Console,
|
||||
}),
|
||||
},
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(clientPort),
|
||||
@ -1135,7 +1135,7 @@ func TestVMessGCMMuxUDP(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
|
||||
MultiplexSettings: &proxyman.MultiplexingConfig{
|
||||
|
@ -46,7 +46,7 @@ func (TransportProtocol) EnumDescriptor() ([]byte, []int) { return fileDescripto
|
||||
type TransportConfig struct {
|
||||
// Type of network that this settings supports.
|
||||
Protocol TransportProtocol `protobuf:"varint,1,opt,name=protocol,enum=v2ray.core.transport.internet.TransportProtocol" json:"protocol,omitempty"`
|
||||
// Specific settings.
|
||||
// Specific settings. Must be of the transports.
|
||||
Settings *v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,opt,name=settings" json:"settings,omitempty"`
|
||||
}
|
||||
|
||||
@ -74,7 +74,8 @@ type StreamConfig struct {
|
||||
Protocol TransportProtocol `protobuf:"varint,1,opt,name=protocol,enum=v2ray.core.transport.internet.TransportProtocol" json:"protocol,omitempty"`
|
||||
TransportSettings []*TransportConfig `protobuf:"bytes,2,rep,name=transport_settings,json=transportSettings" json:"transport_settings,omitempty"`
|
||||
// Type of security. Must be a message name of the settings proto.
|
||||
SecurityType string `protobuf:"bytes,3,opt,name=security_type,json=securityType" json:"security_type,omitempty"`
|
||||
SecurityType string `protobuf:"bytes,3,opt,name=security_type,json=securityType" json:"security_type,omitempty"`
|
||||
// Settings for transport security. For now the only choice is TLS.
|
||||
SecuritySettings []*v2ray_core_common_serial.TypedMessage `protobuf:"bytes,4,rep,name=security_settings,json=securitySettings" json:"security_settings,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core"
|
||||
"v2ray.com/core/common/buf"
|
||||
"v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/signal"
|
||||
@ -23,10 +23,10 @@ type connEntry struct {
|
||||
type Dispatcher struct {
|
||||
sync.RWMutex
|
||||
conns map[net.Destination]*connEntry
|
||||
dispatcher dispatcher.Interface
|
||||
dispatcher core.Dispatcher
|
||||
}
|
||||
|
||||
func NewDispatcher(dispatcher dispatcher.Interface) *Dispatcher {
|
||||
func NewDispatcher(dispatcher core.Dispatcher) *Dispatcher {
|
||||
return &Dispatcher{
|
||||
conns: make(map[net.Destination]*connEntry),
|
||||
dispatcher: dispatcher,
|
||||
|
197
v2ray.go
197
v2ray.go
@ -3,139 +3,160 @@ package core
|
||||
import (
|
||||
"context"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/app/dispatcher"
|
||||
"v2ray.com/core/app/policy"
|
||||
"v2ray.com/core/app/proxyman"
|
||||
"v2ray.com/core/common"
|
||||
)
|
||||
|
||||
// Server is an instance of V2Ray. At any time, there must be at most one Server instance running.
|
||||
// Deprecated. Use Instance directly.
|
||||
type Server interface {
|
||||
// Start starts the V2Ray server, and return any error during the process.
|
||||
// In the case of any errors, the state of the server is unpredicatable.
|
||||
Start() error
|
||||
|
||||
// Close closes the V2Ray server. All inbound and outbound connections will be closed immediately.
|
||||
Close()
|
||||
common.Runnable
|
||||
}
|
||||
|
||||
// New creates a new V2Ray server with given config.
|
||||
func New(config *Config) (Server, error) {
|
||||
return newSimpleServer(config)
|
||||
// Feature is the interface for V2Ray features. All features must implement this interface.
|
||||
// All existing features have an implementation in app directory. These features can be replaced by third-party ones.
|
||||
type Feature interface {
|
||||
common.Runnable
|
||||
}
|
||||
|
||||
// simpleServer shell of V2Ray.
|
||||
type simpleServer struct {
|
||||
space app.Space
|
||||
// Instance combines all functionalities in V2Ray.
|
||||
type Instance struct {
|
||||
dnsClient syncDNSClient
|
||||
policyManager syncPolicyManager
|
||||
dispatcher syncDispatcher
|
||||
router syncRouter
|
||||
ihm syncInboundHandlerManager
|
||||
ohm syncOutboundHandlerManager
|
||||
|
||||
features []Feature
|
||||
}
|
||||
|
||||
// newSimpleServer returns a new Point server based on given configuration.
|
||||
// The server is not started at this point.
|
||||
func newSimpleServer(config *Config) (*simpleServer, error) {
|
||||
var server = new(simpleServer)
|
||||
// New returns a new V2Ray instance based on given configuration.
|
||||
// The instance is not started at this point.
|
||||
// To make sure V2Ray instance works properly, the config must contain one Dispatcher, one InboundHandlerManager and one OutboundHandlerManager. Other features are optional.
|
||||
func New(config *Config) (*Instance, error) {
|
||||
var server = new(Instance)
|
||||
|
||||
if err := config.Transport.Apply(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
space := app.NewSpace()
|
||||
ctx := app.ContextWithSpace(context.Background(), space)
|
||||
|
||||
server.space = space
|
||||
ctx := context.WithValue(context.Background(), v2rayKey, server)
|
||||
|
||||
for _, appSettings := range config.App {
|
||||
settings, err := appSettings.GetInstance()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
application, err := app.CreateAppFromConfig(ctx, settings)
|
||||
app, err := common.CreateObject(ctx, settings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := space.AddApplication(application); err != nil {
|
||||
return nil, err
|
||||
f, ok := app.(Feature)
|
||||
if !ok {
|
||||
return nil, newError("not a feature")
|
||||
}
|
||||
}
|
||||
|
||||
outboundHandlerManager := proxyman.OutboundHandlerManagerFromSpace(space)
|
||||
if outboundHandlerManager == nil {
|
||||
o, err := app.CreateAppFromConfig(ctx, new(proxyman.OutboundConfig))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := space.AddApplication(o); err != nil {
|
||||
return nil, newError("failed to add default outbound handler manager").Base(err)
|
||||
}
|
||||
outboundHandlerManager = o.(proxyman.OutboundHandlerManager)
|
||||
}
|
||||
|
||||
inboundHandlerManager := proxyman.InboundHandlerManagerFromSpace(space)
|
||||
if inboundHandlerManager == nil {
|
||||
o, err := app.CreateAppFromConfig(ctx, new(proxyman.InboundConfig))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := space.AddApplication(o); err != nil {
|
||||
return nil, newError("failed to add default inbound handler manager").Base(err)
|
||||
}
|
||||
inboundHandlerManager = o.(proxyman.InboundHandlerManager)
|
||||
}
|
||||
|
||||
if disp := dispatcher.FromSpace(space); disp == nil {
|
||||
d, err := app.CreateAppFromConfig(ctx, new(dispatcher.Config))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
common.Must(space.AddApplication(d))
|
||||
}
|
||||
|
||||
if p := policy.FromSpace(space); p == nil {
|
||||
p, err := app.CreateAppFromConfig(ctx, &policy.Config{
|
||||
Level: map[uint32]*policy.Policy{
|
||||
1: {
|
||||
Timeout: &policy.Policy_Timeout{
|
||||
ConnectionIdle: &policy.Second{
|
||||
Value: 600,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
common.Must(space.AddApplication(p))
|
||||
server.features = append(server.features, f)
|
||||
}
|
||||
|
||||
for _, inbound := range config.Inbound {
|
||||
if err := inboundHandlerManager.AddHandler(ctx, inbound); err != nil {
|
||||
rawHandler, err := common.CreateObject(ctx, inbound)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handler, ok := rawHandler.(InboundHandler)
|
||||
if !ok {
|
||||
return nil, newError("not an InboundHandler")
|
||||
}
|
||||
if err := server.InboundHandlerManager().AddHandler(ctx, handler); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, outbound := range config.Outbound {
|
||||
if err := outboundHandlerManager.AddHandler(ctx, outbound); err != nil {
|
||||
rawHandler, err := common.CreateObject(ctx, outbound)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handler, ok := rawHandler.(OutboundHandler)
|
||||
if !ok {
|
||||
return nil, newError("not an OutboundHandler")
|
||||
}
|
||||
if err := server.OutboundHandlerManager().AddHandler(ctx, handler); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := server.space.Initialize(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return server, nil
|
||||
}
|
||||
|
||||
func (s *simpleServer) Close() {
|
||||
s.space.Close()
|
||||
// Close shutdown the V2Ray instance.
|
||||
func (s *Instance) Close() {
|
||||
for _, f := range s.features {
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *simpleServer) Start() error {
|
||||
if err := s.space.Start(); err != nil {
|
||||
return err
|
||||
// Start starts the V2Ray instance, including all registered features. When Start returns error, the state of the instance is unknown.
|
||||
func (s *Instance) Start() error {
|
||||
for _, f := range s.features {
|
||||
if err := f.Start(); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
newError("V2Ray started").AtWarning().WriteToLog()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterFeature registers the given feature into V2Ray.
|
||||
// If feature is one of the following types, the corressponding feature in this Instance
|
||||
// will be replaced: DNSClient, PolicyManager, Router, Dispatcher, InboundHandlerManager, OutboundHandlerManager.
|
||||
func (s *Instance) RegisterFeature(feature interface{}, instance Feature) error {
|
||||
switch feature.(type) {
|
||||
case DNSClient, *DNSClient:
|
||||
s.dnsClient.Set(instance.(DNSClient))
|
||||
case PolicyManager, *PolicyManager:
|
||||
s.policyManager.Set(instance.(PolicyManager))
|
||||
case Router, *Router:
|
||||
s.router.Set(instance.(Router))
|
||||
case Dispatcher, *Dispatcher:
|
||||
s.dispatcher.Set(instance.(Dispatcher))
|
||||
case InboundHandlerManager, *InboundHandlerManager:
|
||||
s.ihm.Set(instance.(InboundHandlerManager))
|
||||
case OutboundHandlerManager, *OutboundHandlerManager:
|
||||
s.ohm.Set(instance.(OutboundHandlerManager))
|
||||
}
|
||||
s.features = append(s.features, instance)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DNSClient returns the DNSClient used by this Instance. The returned DNSClient is always functional.
|
||||
func (s *Instance) DNSClient() DNSClient {
|
||||
return &(s.dnsClient)
|
||||
}
|
||||
|
||||
// PolicyManager returns the PolicyManager used by this Instance. The returned PolicyManager is always functional.
|
||||
func (s *Instance) PolicyManager() PolicyManager {
|
||||
return &(s.policyManager)
|
||||
}
|
||||
|
||||
// Router returns the Router used by this Instance. The returned Router is always functional.
|
||||
func (s *Instance) Router() Router {
|
||||
return &(s.router)
|
||||
}
|
||||
|
||||
// Dispatcher returns the Dispatcher used by this Instance. If Dispatcher was not registered before, the returned value doesn't work, although it is not nil.
|
||||
func (s *Instance) Dispatcher() Dispatcher {
|
||||
return &(s.dispatcher)
|
||||
}
|
||||
|
||||
// InboundHandlerManager returns the InboundHandlerManager used by this Instance. If InboundHandlerManager was not registered before, the returned value doesn't work.
|
||||
func (s *Instance) InboundHandlerManager() InboundHandlerManager {
|
||||
return &(s.ihm)
|
||||
}
|
||||
|
||||
// OutboundHandlerManager returns the OutboundHandlerManager used by this Instance. If OutboundHandlerManager was not registered before, the returned value doesn't work.
|
||||
func (s *Instance) OutboundHandlerManager() OutboundHandlerManager {
|
||||
return &(s.ohm)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func TestV2RayClose(t *testing.T) {
|
||||
|
||||
port := net.Port(dice.RollUint16())
|
||||
config := &Config{
|
||||
Inbound: []*proxyman.InboundHandlerConfig{
|
||||
Inbound: []*core.InboundHandlerConfig{
|
||||
{
|
||||
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
||||
PortRange: net.SinglePortRange(port),
|
||||
@ -37,7 +37,7 @@ func TestV2RayClose(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
Outbound: []*proxyman.OutboundHandlerConfig{
|
||||
Outbound: []*core.OutboundHandlerConfig{
|
||||
{
|
||||
ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
||||
Receiver: []*protocol.ServerEndpoint{
|
||||
|
Loading…
Reference in New Issue
Block a user