1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-21 09:36:34 -05:00

customizable policy

This commit is contained in:
Darien Raymond 2017-11-27 22:09:30 +01:00
parent d4f8934aa4
commit 3214a5078c
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
26 changed files with 554 additions and 159 deletions

View File

@ -9,6 +9,8 @@ import (
_ "v2ray.com/core/app/dispatcher/impl" _ "v2ray.com/core/app/dispatcher/impl"
. "v2ray.com/core/app/dns" . "v2ray.com/core/app/dns"
_ "v2ray.com/core/app/dns/server" _ "v2ray.com/core/app/dns/server"
"v2ray.com/core/app/policy"
_ "v2ray.com/core/app/policy/manager"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
_ "v2ray.com/core/app/proxyman/outbound" _ "v2ray.com/core/app/proxyman/outbound"
"v2ray.com/core/common" "v2ray.com/core/common"
@ -74,6 +76,7 @@ func TestUDPServer(t *testing.T) {
common.Must(app.AddApplicationToSpace(ctx, config)) common.Must(app.AddApplicationToSpace(ctx, config))
common.Must(app.AddApplicationToSpace(ctx, &dispatcher.Config{})) common.Must(app.AddApplicationToSpace(ctx, &dispatcher.Config{}))
common.Must(app.AddApplicationToSpace(ctx, &proxyman.OutboundConfig{})) common.Must(app.AddApplicationToSpace(ctx, &proxyman.OutboundConfig{}))
common.Must(app.AddApplicationToSpace(ctx, &policy.Config{}))
om := proxyman.OutboundHandlerManagerFromSpace(space) om := proxyman.OutboundHandlerManagerFromSpace(space)
om.AddHandler(ctx, &proxyman.OutboundHandlerConfig{ om.AddHandler(ctx, &proxyman.OutboundHandlerConfig{

15
app/policy/config.go Normal file
View File

@ -0,0 +1,15 @@
package policy
import (
"time"
"github.com/golang/protobuf/proto"
)
func (s *Second) Duration() time.Duration {
return time.Second * time.Duration(s.Value)
}
func (p *Policy) OverrideWith(another *Policy) {
proto.Merge(p, another)
}

140
app/policy/config.pb.go Normal file
View File

@ -0,0 +1,140 @@
package policy
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Second struct {
Value uint32 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"`
}
func (m *Second) Reset() { *m = Second{} }
func (m *Second) String() string { return proto.CompactTextString(m) }
func (*Second) ProtoMessage() {}
func (*Second) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Second) GetValue() uint32 {
if m != nil {
return m.Value
}
return 0
}
type Policy struct {
Timeout *Policy_Timeout `protobuf:"bytes,1,opt,name=timeout" json:"timeout,omitempty"`
}
func (m *Policy) Reset() { *m = Policy{} }
func (m *Policy) String() string { return proto.CompactTextString(m) }
func (*Policy) ProtoMessage() {}
func (*Policy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *Policy) GetTimeout() *Policy_Timeout {
if m != nil {
return m.Timeout
}
return nil
}
// Timeout is a message for timeout settings in various stages, in seconds.
type Policy_Timeout struct {
Handshake *Second `protobuf:"bytes,1,opt,name=handshake" json:"handshake,omitempty"`
ConnectionIdle *Second `protobuf:"bytes,2,opt,name=connection_idle,json=connectionIdle" json:"connection_idle,omitempty"`
UplinkOnly *Second `protobuf:"bytes,3,opt,name=uplink_only,json=uplinkOnly" json:"uplink_only,omitempty"`
DownlinkOnly *Second `protobuf:"bytes,4,opt,name=downlink_only,json=downlinkOnly" json:"downlink_only,omitempty"`
}
func (m *Policy_Timeout) Reset() { *m = Policy_Timeout{} }
func (m *Policy_Timeout) String() string { return proto.CompactTextString(m) }
func (*Policy_Timeout) ProtoMessage() {}
func (*Policy_Timeout) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} }
func (m *Policy_Timeout) GetHandshake() *Second {
if m != nil {
return m.Handshake
}
return nil
}
func (m *Policy_Timeout) GetConnectionIdle() *Second {
if m != nil {
return m.ConnectionIdle
}
return nil
}
func (m *Policy_Timeout) GetUplinkOnly() *Second {
if m != nil {
return m.UplinkOnly
}
return nil
}
func (m *Policy_Timeout) GetDownlinkOnly() *Second {
if m != nil {
return m.DownlinkOnly
}
return nil
}
type Config struct {
Level map[uint32]*Policy `protobuf:"bytes,1,rep,name=level" json:"level,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
}
func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *Config) GetLevel() map[uint32]*Policy {
if m != nil {
return m.Level
}
return nil
}
func init() {
proto.RegisterType((*Second)(nil), "v2ray.core.app.policy.Second")
proto.RegisterType((*Policy)(nil), "v2ray.core.app.policy.Policy")
proto.RegisterType((*Policy_Timeout)(nil), "v2ray.core.app.policy.Policy.Timeout")
proto.RegisterType((*Config)(nil), "v2ray.core.app.policy.Config")
}
func init() { proto.RegisterFile("v2ray.com/core/app/policy/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 349 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xc1, 0x4a, 0xeb, 0x40,
0x14, 0x86, 0x49, 0x7a, 0x9b, 0x72, 0x4f, 0x6f, 0xaf, 0x32, 0x58, 0x88, 0x05, 0xa5, 0x14, 0x94,
0xae, 0x26, 0x90, 0x6e, 0x44, 0xb1, 0x62, 0x45, 0x41, 0x10, 0x2c, 0x51, 0x14, 0xdc, 0x94, 0x71,
0x32, 0xda, 0xd0, 0xe9, 0x9c, 0x21, 0xa6, 0x95, 0xbc, 0x86, 0x6f, 0xe0, 0xd6, 0x87, 0xf2, 0x59,
0x24, 0x99, 0x84, 0x6c, 0x5a, 0xe9, 0x6e, 0x72, 0xf8, 0xfe, 0x8f, 0x43, 0xfe, 0x03, 0x87, 0x4b,
0x3f, 0x66, 0x29, 0xe5, 0x38, 0xf7, 0x38, 0xc6, 0xc2, 0x63, 0x5a, 0x7b, 0x1a, 0x65, 0xc4, 0x53,
0x8f, 0xa3, 0x7a, 0x89, 0x5e, 0xa9, 0x8e, 0x31, 0x41, 0xd2, 0x2e, 0xb9, 0x58, 0x50, 0xa6, 0x35,
0x35, 0x4c, 0x6f, 0x1f, 0x9c, 0x3b, 0xc1, 0x51, 0x85, 0x64, 0x07, 0xea, 0x4b, 0x26, 0x17, 0xc2,
0xb5, 0xba, 0x56, 0xbf, 0x15, 0x98, 0x8f, 0xde, 0xb7, 0x0d, 0xce, 0x38, 0x47, 0xc9, 0x19, 0x34,
0x92, 0x68, 0x2e, 0x70, 0x91, 0xe4, 0x48, 0xd3, 0x3f, 0xa0, 0x2b, 0x9d, 0xd4, 0xf0, 0xf4, 0xde,
0xc0, 0x41, 0x99, 0xea, 0x7c, 0xd8, 0xd0, 0x28, 0x86, 0xe4, 0x04, 0xfe, 0x4e, 0x99, 0x0a, 0xdf,
0xa6, 0x6c, 0x26, 0x0a, 0xdd, 0xde, 0x1a, 0x9d, 0xd9, 0x2f, 0xa8, 0x78, 0x72, 0x05, 0x5b, 0x1c,
0x95, 0x12, 0x3c, 0x89, 0x50, 0x4d, 0xa2, 0x50, 0x0a, 0xd7, 0xde, 0x44, 0xf1, 0xbf, 0x4a, 0x5d,
0x87, 0x52, 0x90, 0x21, 0x34, 0x17, 0x5a, 0x46, 0x6a, 0x36, 0x41, 0x25, 0x53, 0xb7, 0xb6, 0x89,
0x03, 0x4c, 0xe2, 0x56, 0xc9, 0x94, 0x8c, 0xa0, 0x15, 0xe2, 0xbb, 0xaa, 0x0c, 0x7f, 0x36, 0x31,
0xfc, 0x2b, 0x33, 0x99, 0xa3, 0xf7, 0x69, 0x81, 0x73, 0x91, 0x17, 0x45, 0x86, 0x50, 0x97, 0x62,
0x29, 0xa4, 0x6b, 0x75, 0x6b, 0xfd, 0xa6, 0xdf, 0x5f, 0xa3, 0x31, 0x34, 0xbd, 0xc9, 0xd0, 0x4b,
0x95, 0xc4, 0x69, 0x60, 0x62, 0x9d, 0x47, 0x80, 0x6a, 0x48, 0xb6, 0xa1, 0x36, 0x13, 0x69, 0xd1,
0x66, 0xf6, 0x24, 0x83, 0xb2, 0xe1, 0xdf, 0x7f, 0x96, 0xa9, 0xaf, 0x38, 0x80, 0x63, 0xfb, 0xc8,
0x1a, 0x9d, 0xc2, 0x2e, 0xc7, 0xf9, 0x6a, 0x7c, 0x6c, 0x3d, 0x39, 0xe6, 0xf5, 0x65, 0xb7, 0x1f,
0xfc, 0x80, 0x65, 0x0b, 0xc6, 0x82, 0x9e, 0x6b, 0x5d, 0x98, 0x9e, 0x9d, 0xfc, 0x02, 0x07, 0x3f,
0x01, 0x00, 0x00, 0xff, 0xff, 0xcf, 0x25, 0x25, 0xc2, 0xab, 0x02, 0x00, 0x00,
}

27
app/policy/config.proto Normal file
View File

@ -0,0 +1,27 @@
syntax = "proto3";
package v2ray.core.app.policy;
option csharp_namespace = "V2Ray.Core.App.Policy";
option go_package = "policy";
option java_package = "com.v2ray.core.app.policy";
option java_multiple_files = true;
message Second {
uint32 value = 1;
}
message Policy {
// Timeout is a message for timeout settings in various stages, in seconds.
message Timeout {
Second handshake = 1;
Second connection_idle = 2;
Second uplink_only = 3;
Second downlink_only = 4;
}
Timeout timeout = 1;
}
message Config {
map<uint32, Policy> level = 1;
}

View File

@ -0,0 +1,62 @@
package manager
import (
"context"
"v2ray.com/core/app/policy"
"v2ray.com/core/common"
)
type Instance struct {
levels map[uint32]*policy.Policy
}
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},
},
}
}
func (m *Instance) GetPolicy(level uint32) policy.Policy {
if p, ok := m.levels[level]; ok {
return *p
}
return global()
}
func (m *Instance) Start() error {
return nil
}
func (m *Instance) Close() {
}
func (m *Instance) Interface() interface{} {
return (*policy.Interface)(nil)
}
func init() {
common.Must(common.RegisterConfig((*policy.Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*policy.Config))
}))
}

17
app/policy/policy.go Normal file
View File

@ -0,0 +1,17 @@
package policy
import (
"v2ray.com/core/app"
)
type Interface interface {
GetPolicy(level uint32) Policy
}
func PolicyFromSpace(space app.Space) Interface {
app := space.GetApplication((*Interface)(nil))
if app == nil {
return nil
}
return app.(Interface)
}

View File

@ -1,7 +1,5 @@
package protocol package protocol
import "time"
func (u *User) GetTypedAccount() (Account, error) { func (u *User) GetTypedAccount() (Account, error) {
if u.GetAccount() == nil { if u.GetAccount() == nil {
return nil, newError("Account missing").AtWarning() return nil, newError("Account missing").AtWarning()
@ -19,20 +17,3 @@ func (u *User) GetTypedAccount() (Account, error) {
} }
return nil, newError("Unknown account type: ", u.Account.Type) return nil, newError("Unknown account type: ", u.Account.Type)
} }
func (u *User) GetSettings() UserSettings {
settings := UserSettings{}
switch u.Level {
case 0:
settings.PayloadTimeout = time.Second * 30
case 1:
settings.PayloadTimeout = time.Minute * 2
default:
settings.PayloadTimeout = time.Minute * 5
}
return settings
}
type UserSettings struct {
PayloadTimeout time.Duration
}

View File

@ -4,6 +4,7 @@ import (
// The following are necessary as they register handlers in their init functions. // The following are necessary as they register handlers in their init functions.
_ "v2ray.com/core/app/dispatcher/impl" _ "v2ray.com/core/app/dispatcher/impl"
_ "v2ray.com/core/app/dns/server" _ "v2ray.com/core/app/dns/server"
_ "v2ray.com/core/app/policy/manager"
_ "v2ray.com/core/app/proxyman/inbound" _ "v2ray.com/core/app/proxyman/inbound"
_ "v2ray.com/core/app/proxyman/outbound" _ "v2ray.com/core/app/proxyman/outbound"
_ "v2ray.com/core/app/router" _ "v2ray.com/core/app/router"

View File

@ -23,6 +23,7 @@ type Config struct {
NetworkList *v2ray_core_common_net1.NetworkList `protobuf:"bytes,3,opt,name=network_list,json=networkList" json:"network_list,omitempty"` NetworkList *v2ray_core_common_net1.NetworkList `protobuf:"bytes,3,opt,name=network_list,json=networkList" json:"network_list,omitempty"`
Timeout uint32 `protobuf:"varint,4,opt,name=timeout" json:"timeout,omitempty"` Timeout uint32 `protobuf:"varint,4,opt,name=timeout" json:"timeout,omitempty"`
FollowRedirect bool `protobuf:"varint,5,opt,name=follow_redirect,json=followRedirect" json:"follow_redirect,omitempty"` FollowRedirect bool `protobuf:"varint,5,opt,name=follow_redirect,json=followRedirect" json:"follow_redirect,omitempty"`
UserLevel uint32 `protobuf:"varint,6,opt,name=user_level,json=userLevel" json:"user_level,omitempty"`
} }
func (m *Config) Reset() { *m = Config{} } func (m *Config) Reset() { *m = Config{} }
@ -65,6 +66,13 @@ func (m *Config) GetFollowRedirect() bool {
return false return false
} }
func (m *Config) GetUserLevel() uint32 {
if m != nil {
return m.UserLevel
}
return 0
}
func init() { func init() {
proto.RegisterType((*Config)(nil), "v2ray.core.proxy.dokodemo.Config") proto.RegisterType((*Config)(nil), "v2ray.core.proxy.dokodemo.Config")
} }
@ -72,23 +80,25 @@ func init() {
func init() { proto.RegisterFile("v2ray.com/core/proxy/dokodemo/config.proto", fileDescriptor0) } func init() { proto.RegisterFile("v2ray.com/core/proxy/dokodemo/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 286 bytes of a gzipped FileDescriptorProto // 310 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xcf, 0x4a, 0x03, 0x31, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xcf, 0x4e, 0xc2, 0x40,
0x10, 0x87, 0x49, 0xad, 0x6d, 0x49, 0xfd, 0x03, 0x39, 0xa5, 0x82, 0x50, 0x7b, 0x69, 0xf1, 0x90, 0x10, 0x87, 0xd3, 0x8a, 0x80, 0x8b, 0x7f, 0x92, 0x3d, 0x2d, 0x46, 0x12, 0xe4, 0x02, 0xf1, 0xb0,
0x40, 0x3d, 0x7a, 0xb3, 0x15, 0x11, 0x44, 0x97, 0x1c, 0x3c, 0x78, 0x29, 0x6b, 0x36, 0x95, 0xd0, 0x4d, 0xf0, 0xe8, 0x0d, 0x30, 0xc6, 0x84, 0x28, 0xd9, 0x83, 0x07, 0x2f, 0xa4, 0xb6, 0x83, 0x69,
0x4d, 0x66, 0x99, 0x8d, 0xd6, 0x7d, 0x25, 0x5f, 0xcb, 0x17, 0x11, 0xb3, 0xbb, 0x28, 0x42, 0xbd, 0xe8, 0xee, 0x90, 0xe9, 0x02, 0xf6, 0x05, 0x7c, 0x18, 0x9f, 0xd2, 0x74, 0xdb, 0x46, 0x63, 0x82,
0xcd, 0x4c, 0xbe, 0x7c, 0x33, 0xfc, 0xe8, 0xf9, 0xdb, 0x1c, 0xd3, 0x4a, 0x68, 0x70, 0x52, 0x03, 0xb7, 0xd9, 0xdf, 0x7e, 0xf3, 0xcd, 0x64, 0xd8, 0xcd, 0x6e, 0x4c, 0x61, 0x2e, 0x23, 0xd4, 0x41,
0x1a, 0x59, 0x20, 0xbc, 0x57, 0x32, 0x83, 0x0d, 0x64, 0xc6, 0x81, 0xd4, 0xe0, 0xd7, 0xf6, 0x45, 0x84, 0x04, 0xc1, 0x86, 0xf0, 0x23, 0x0f, 0x62, 0x5c, 0x63, 0x0c, 0x1a, 0x83, 0x08, 0xcd, 0x2a,
0x14, 0x08, 0x01, 0xd8, 0xa8, 0x65, 0xd1, 0x88, 0xc8, 0x89, 0x96, 0x3b, 0x99, 0xfe, 0xd1, 0x68, 0x79, 0x97, 0x1b, 0x42, 0x8b, 0xbc, 0x5b, 0xb3, 0x04, 0xd2, 0x71, 0xb2, 0xe6, 0x2e, 0x87, 0x7f,
0x70, 0x0e, 0xbc, 0xf4, 0x26, 0xc8, 0x34, 0xcb, 0xd0, 0x94, 0x65, 0xed, 0xf8, 0x0f, 0xf4, 0x26, 0x34, 0x11, 0x6a, 0x8d, 0x26, 0x30, 0x60, 0x83, 0x30, 0x8e, 0x09, 0xb2, 0xac, 0x74, 0xfc, 0x07,
0x6c, 0x01, 0x37, 0x35, 0x38, 0xf9, 0x24, 0xb4, 0xb7, 0x88, 0xdb, 0xd9, 0x25, 0xed, 0x37, 0x12, 0x1a, 0xb0, 0x7b, 0xa4, 0x75, 0x09, 0x0e, 0x3e, 0x7d, 0xd6, 0x9c, 0xba, 0xe9, 0xfc, 0x8e, 0xb5,
0x4e, 0xc6, 0x64, 0x36, 0x9c, 0x9f, 0x89, 0x5f, 0x97, 0xd4, 0x06, 0xe1, 0x4d, 0x10, 0xb7, 0xc9, 0x2a, 0x89, 0xf0, 0xfa, 0xde, 0xa8, 0x33, 0xbe, 0x96, 0xbf, 0x36, 0x29, 0x0d, 0xd2, 0x80, 0x95,
0x03, 0x2e, 0xc1, 0xa5, 0xd6, 0xab, 0xf6, 0x07, 0x63, 0xb4, 0x5b, 0x00, 0x06, 0xde, 0x19, 0x93, 0x8f, 0x8b, 0x67, 0x9a, 0xa1, 0x0e, 0x13, 0xa3, 0xea, 0x0e, 0xce, 0x59, 0x63, 0x83, 0x64, 0x85,
0xd9, 0xa1, 0x8a, 0x35, 0xbb, 0xa6, 0x07, 0xcd, 0xb2, 0x55, 0x6e, 0xcb, 0xc0, 0xf7, 0xa2, 0x75, 0xdf, 0xf7, 0x46, 0x67, 0xca, 0xd5, 0xfc, 0x9e, 0x9d, 0x56, 0xc3, 0x96, 0x69, 0x92, 0x59, 0x71,
0xb2, 0xc3, 0x7a, 0x5f, 0xa3, 0x77, 0xb6, 0x0c, 0x6a, 0xe8, 0x7f, 0x1a, 0xc6, 0x69, 0x3f, 0x58, 0xe4, 0xac, 0x83, 0x03, 0xd6, 0xa7, 0x12, 0x9d, 0x27, 0x99, 0x55, 0x1d, 0xf3, 0xf3, 0xe0, 0x57,
0x67, 0xe0, 0x35, 0xf0, 0x6e, 0xb4, 0xb7, 0x2d, 0x9b, 0xd2, 0xe3, 0x35, 0xe4, 0x39, 0x6c, 0x57, 0xac, 0x65, 0x13, 0x0d, 0xb8, 0xb5, 0xa2, 0x51, 0xd8, 0x27, 0xbe, 0xf0, 0x54, 0x1d, 0xf1, 0x21,
0x68, 0x32, 0x8b, 0x46, 0x07, 0xbe, 0x3f, 0x26, 0xb3, 0x81, 0x3a, 0xaa, 0xc7, 0xaa, 0x99, 0x5e, 0xbb, 0x58, 0x61, 0x9a, 0xe2, 0x7e, 0x49, 0x10, 0x27, 0x04, 0x91, 0x15, 0xc7, 0x7d, 0x6f, 0xd4,
0xdd, 0xd0, 0x53, 0x0d, 0x4e, 0xec, 0x0c, 0x36, 0x21, 0x4f, 0x83, 0xb6, 0xfe, 0xe8, 0x8c, 0x1e, 0x56, 0xe7, 0x65, 0xac, 0xaa, 0x94, 0xf7, 0x18, 0xdb, 0x66, 0x40, 0xcb, 0x14, 0x76, 0x90, 0x8a,
0xe7, 0x2a, 0xad, 0xc4, 0xe2, 0x9b, 0x4b, 0x22, 0xb7, 0x6c, 0xde, 0x9e, 0x7b, 0x31, 0xb5, 0x8b, 0xa6, 0xdb, 0xf3, 0xa4, 0x48, 0xe6, 0x45, 0x30, 0x79, 0x60, 0xbd, 0x08, 0xb5, 0x3c, 0x78, 0xfb,
0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x1c, 0xb0, 0xd9, 0xd0, 0x01, 0x00, 0x00, 0x85, 0xf7, 0xda, 0xae, 0xeb, 0x2f, 0xbf, 0xfb, 0x32, 0x56, 0x61, 0x2e, 0xa7, 0x05, 0xb7, 0x70,
0xdc, 0xac, 0xfa, 0x7b, 0x6b, 0xba, 0xc3, 0xde, 0x7e, 0x07, 0x00, 0x00, 0xff, 0xff, 0x33, 0x8e,
0x70, 0xce, 0xf3, 0x01, 0x00, 0x00,
} }

View File

@ -13,6 +13,7 @@ message Config {
v2ray.core.common.net.IPOrDomain address = 1; v2ray.core.common.net.IPOrDomain address = 1;
uint32 port = 2; uint32 port = 2;
v2ray.core.common.net.NetworkList network_list = 3; v2ray.core.common.net.NetworkList network_list = 3;
uint32 timeout = 4; uint32 timeout = 4 [deprecated = true];
bool follow_redirect = 5; bool follow_redirect = 5;
uint32 user_level = 6;
} }

View File

@ -4,11 +4,11 @@ package dokodemo
import ( import (
"context" "context"
"time"
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/app/policy"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
@ -22,6 +22,7 @@ type DokodemoDoor struct {
config *Config config *Config
address net.Address address net.Address
port net.Port port net.Port
policy policy.Policy
} }
func New(ctx context.Context, config *Config) (*DokodemoDoor, error) { func New(ctx context.Context, config *Config) (*DokodemoDoor, error) {
@ -37,6 +38,17 @@ func New(ctx context.Context, config *Config) (*DokodemoDoor, error) {
address: config.GetPredefinedAddress(), address: config.GetPredefinedAddress(),
port: net.Port(config.Port), port: net.Port(config.Port),
} }
space.OnInitialize(func() error {
pm := policy.PolicyFromSpace(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
})
return d, nil return d, nil
} }
@ -60,13 +72,8 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
return newError("unable to get destination") return newError("unable to get destination")
} }
timeout := time.Second * time.Duration(d.config.Timeout)
if timeout == 0 {
timeout = time.Minute * 5
}
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, timeout) timer := signal.CancelAfterInactivity(ctx, cancel, d.policy.Timeout.ConnectionIdle.Duration())
inboundRay, err := dispatcher.Dispatch(ctx, dest) inboundRay, err := dispatcher.Dispatch(ctx, dest)
if err != nil { if err != nil {
@ -82,6 +89,8 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
return newError("failed to transport request").Base(err) return newError("failed to transport request").Base(err)
} }
timer.SetTimeout(d.policy.Timeout.DownlinkOnly.Duration())
return nil return nil
}) })
@ -107,7 +116,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
return newError("failed to transport response").Base(err) return newError("failed to transport response").Base(err)
} }
timer.SetTimeout(time.Second * 2) timer.SetTimeout(d.policy.Timeout.UplinkOnly.Duration())
return nil return nil
}) })

View File

@ -57,6 +57,7 @@ type Config struct {
DomainStrategy Config_DomainStrategy `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,enum=v2ray.core.proxy.freedom.Config_DomainStrategy" json:"domain_strategy,omitempty"` DomainStrategy Config_DomainStrategy `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,enum=v2ray.core.proxy.freedom.Config_DomainStrategy" json:"domain_strategy,omitempty"`
Timeout uint32 `protobuf:"varint,2,opt,name=timeout" json:"timeout,omitempty"` Timeout uint32 `protobuf:"varint,2,opt,name=timeout" json:"timeout,omitempty"`
DestinationOverride *DestinationOverride `protobuf:"bytes,3,opt,name=destination_override,json=destinationOverride" json:"destination_override,omitempty"` DestinationOverride *DestinationOverride `protobuf:"bytes,3,opt,name=destination_override,json=destinationOverride" json:"destination_override,omitempty"`
UserLevel uint32 `protobuf:"varint,4,opt,name=user_level,json=userLevel" json:"user_level,omitempty"`
} }
func (m *Config) Reset() { *m = Config{} } func (m *Config) Reset() { *m = Config{} }
@ -85,6 +86,13 @@ func (m *Config) GetDestinationOverride() *DestinationOverride {
return nil return nil
} }
func (m *Config) GetUserLevel() uint32 {
if m != nil {
return m.UserLevel
}
return 0
}
func init() { func init() {
proto.RegisterType((*DestinationOverride)(nil), "v2ray.core.proxy.freedom.DestinationOverride") proto.RegisterType((*DestinationOverride)(nil), "v2ray.core.proxy.freedom.DestinationOverride")
proto.RegisterType((*Config)(nil), "v2ray.core.proxy.freedom.Config") proto.RegisterType((*Config)(nil), "v2ray.core.proxy.freedom.Config")
@ -94,25 +102,27 @@ func init() {
func init() { proto.RegisterFile("v2ray.com/core/proxy/freedom/config.proto", fileDescriptor0) } func init() { proto.RegisterFile("v2ray.com/core/proxy/freedom/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 318 bytes of a gzipped FileDescriptorProto // 340 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0xcf, 0x4a, 0xc3, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x6f, 0x4b, 0x83, 0x50,
0x10, 0xc6, 0x4d, 0xc5, 0x14, 0x47, 0xac, 0x65, 0xeb, 0x21, 0x88, 0x87, 0xd2, 0x8b, 0x55, 0x70, 0x14, 0xc6, 0xd3, 0xca, 0xb1, 0x13, 0xad, 0xe1, 0x7a, 0x21, 0xb1, 0x60, 0xec, 0x4d, 0x2b, 0xe8,
0x23, 0xf1, 0x09, 0xec, 0x1f, 0xa1, 0x27, 0x4b, 0x82, 0xa2, 0x5e, 0x62, 0xcc, 0x4e, 0xcb, 0x82, 0x1a, 0xf6, 0x09, 0xda, 0x9f, 0x60, 0x10, 0x34, 0x94, 0xa2, 0x7a, 0x63, 0xa6, 0x67, 0x43, 0x98,
0xd9, 0x09, 0x9b, 0xb5, 0x98, 0x27, 0xf0, 0x5d, 0x7c, 0x4a, 0x71, 0x93, 0xa2, 0x55, 0x73, 0xdb, 0xf7, 0xc8, 0xf5, 0x4e, 0xf2, 0x2b, 0xed, 0x53, 0x86, 0x57, 0x47, 0x2d, 0xb6, 0x77, 0xfa, 0xf8,
0x99, 0xfd, 0x7d, 0xdf, 0xcc, 0x37, 0x70, 0xba, 0x0a, 0x74, 0x52, 0xf2, 0x94, 0x32, 0x3f, 0x25, 0x7b, 0x9e, 0x73, 0x9e, 0x23, 0x5c, 0xe7, 0x8e, 0x08, 0x0a, 0x16, 0x52, 0x62, 0x87, 0x24, 0xd0,
0x8d, 0x7e, 0xae, 0xe9, 0xad, 0xf4, 0x17, 0x1a, 0x51, 0xd8, 0x96, 0x5a, 0xc8, 0x25, 0xcf, 0x35, 0x4e, 0x05, 0x7d, 0x17, 0xf6, 0x5c, 0x20, 0x46, 0x4a, 0xe2, 0xf3, 0x78, 0xc1, 0x52, 0x41, 0x92,
0x19, 0x62, 0xde, 0x1a, 0xd5, 0xc8, 0x2d, 0xc6, 0x6b, 0xec, 0xe8, 0xe2, 0x97, 0x49, 0x4a, 0x59, 0x4c, 0x6b, 0x83, 0x0a, 0x64, 0x0a, 0x63, 0x35, 0x76, 0x71, 0xf7, 0x2f, 0x24, 0xa4, 0x24, 0x21,
0x46, 0xca, 0xb7, 0xb2, 0x94, 0x5e, 0xfc, 0x02, 0xf5, 0x0a, 0x75, 0x5c, 0xe4, 0x98, 0x56, 0x5e, 0x6e, 0x2b, 0x5b, 0x48, 0x4b, 0x3b, 0x43, 0x91, 0xa3, 0xf0, 0xb3, 0x14, 0xc3, 0x2a, 0xab, 0xff,
0x83, 0x07, 0xe8, 0x4d, 0xb0, 0x30, 0x52, 0x25, 0x46, 0x92, 0xba, 0x59, 0xa1, 0xd6, 0x52, 0x20, 0x0e, 0x9d, 0x31, 0x66, 0x32, 0xe6, 0x81, 0x8c, 0x89, 0x3f, 0xe7, 0x28, 0x44, 0x1c, 0xa1, 0x39,
0x1b, 0x81, 0x5b, 0xb1, 0x9e, 0xd3, 0x77, 0x86, 0x7b, 0xc1, 0x19, 0xff, 0x31, 0xb3, 0x72, 0xe5, 0x04, 0xa3, 0x62, 0x2d, 0xad, 0xa7, 0x0d, 0x4e, 0x9c, 0x1b, 0xf6, 0x67, 0x66, 0x95, 0xca, 0x36,
0x6b, 0x57, 0x1e, 0x59, 0x72, 0xaa, 0x44, 0x4e, 0x52, 0x99, 0xb0, 0x56, 0x0e, 0xde, 0x5b, 0xe0, 0xa9, 0xcc, 0x53, 0xe4, 0x84, 0x47, 0x29, 0xc5, 0x5c, 0xba, 0xb5, 0xb3, 0xbf, 0xd6, 0xc1, 0x18,
0x8e, 0xed, 0xde, 0xec, 0x1e, 0x0e, 0x04, 0x65, 0x89, 0x54, 0x71, 0x61, 0x74, 0x62, 0x70, 0x59, 0xa9, 0xbd, 0xcd, 0x37, 0x38, 0x8b, 0x28, 0x09, 0x62, 0xee, 0x67, 0x52, 0x04, 0x12, 0x17, 0x85,
0x5a, 0xdf, 0x4e, 0xe0, 0xf3, 0xa6, 0x2c, 0xbc, 0x92, 0xf2, 0x89, 0xd5, 0x45, 0xb5, 0x2c, 0xec, 0xca, 0x6d, 0x39, 0x36, 0xdb, 0xd7, 0x85, 0x55, 0x56, 0x36, 0x56, 0x3e, 0xaf, 0xb6, 0xb9, 0xad,
0x88, 0x8d, 0x9a, 0x79, 0xd0, 0x36, 0x32, 0x43, 0x7a, 0x35, 0x5e, 0xab, 0xef, 0x0c, 0xf7, 0xc3, 0x68, 0xeb, 0xdd, 0xec, 0x42, 0x43, 0xc6, 0x09, 0xd2, 0x4a, 0x5a, 0x7a, 0x4f, 0x1b, 0x9c, 0x0e,
0x75, 0xc9, 0x9e, 0xe0, 0x50, 0x7c, 0x27, 0x8b, 0xa9, 0x8e, 0xe6, 0x6d, 0xdb, 0x40, 0xe7, 0xcd, 0x75, 0x4b, 0x73, 0x37, 0x92, 0xf9, 0x09, 0xe7, 0xd1, 0x6f, 0x3b, 0x9f, 0xea, 0x7a, 0xd6, 0xa1,
0x83, 0xff, 0xb9, 0x47, 0xd8, 0x13, 0x7f, 0x9b, 0x83, 0x13, 0xe8, 0x6c, 0x6e, 0xc7, 0x76, 0x61, 0x2a, 0x75, 0xbb, 0x7f, 0xf8, 0x8e, 0x9b, 0xb8, 0x9d, 0x68, 0xc7, 0xa1, 0x2e, 0x01, 0x56, 0x19,
0xe7, 0x2a, 0x8a, 0x67, 0x51, 0x77, 0x8b, 0x01, 0xb8, 0xb7, 0xd1, 0x34, 0x9e, 0xcd, 0xbb, 0xce, 0x0a, 0x7f, 0x89, 0x39, 0x2e, 0xad, 0xa3, 0x72, 0x05, 0xb7, 0x59, 0x2a, 0x4f, 0xa5, 0xd0, 0xbf,
0x68, 0x02, 0xc7, 0x29, 0x65, 0x8d, 0x13, 0xe7, 0xce, 0x63, 0xbb, 0x7e, 0x7e, 0xb4, 0xbc, 0xbb, 0x82, 0xd6, 0x76, 0x01, 0xb3, 0x09, 0xc7, 0x0f, 0x9e, 0x3f, 0xf5, 0xda, 0x07, 0x26, 0x80, 0xf1,
0x20, 0x4c, 0x4a, 0x3e, 0xfe, 0xa2, 0xe6, 0x96, 0xba, 0xae, 0xbe, 0x9e, 0x5d, 0x7b, 0xf0, 0xcb, 0xe2, 0x4d, 0xfc, 0xe9, 0xac, 0xad, 0x0d, 0xc7, 0xd0, 0x0d, 0x29, 0xd9, 0xbb, 0xd0, 0x4c, 0xfb,
0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x45, 0xb3, 0x84, 0x2e, 0x2a, 0x02, 0x00, 0x00, 0x68, 0xd4, 0x8f, 0x6b, 0xdd, 0x7a, 0x75, 0xdc, 0xa0, 0x60, 0xa3, 0x92, 0x9a, 0x29, 0xea, 0xb1,
0xfa, 0xf4, 0x65, 0xa8, 0x7f, 0x72, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x5e, 0xda, 0x4d,
0x4d, 0x02, 0x00, 0x00,
} }

View File

@ -18,6 +18,7 @@ message Config {
USE_IP = 1; USE_IP = 1;
} }
DomainStrategy domain_strategy = 1; DomainStrategy domain_strategy = 1;
uint32 timeout = 2; uint32 timeout = 2 [deprecated = true];
DestinationOverride destination_override = 3; DestinationOverride destination_override = 3;
uint32 user_level = 4;
} }

View File

@ -4,11 +4,11 @@ package freedom
import ( import (
"context" "context"
"time"
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/dns" "v2ray.com/core/app/dns"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/app/policy"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/dice" "v2ray.com/core/common/dice"
@ -26,6 +26,7 @@ type Handler struct {
timeout uint32 timeout uint32
dns dns.Server dns dns.Server
destOverride *DestinationOverride destOverride *DestinationOverride
policy policy.Policy
} }
// New creates a new Freedom handler. // New creates a new Freedom handler.
@ -46,6 +47,14 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
return newError("DNS server is not found in the space") return newError("DNS server is not found in the space")
} }
} }
pm := policy.PolicyFromSpace(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 nil
}) })
return f, nil return f, nil
@ -109,12 +118,8 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
} }
defer conn.Close() defer conn.Close()
timeout := time.Second * time.Duration(h.timeout)
if timeout == 0 {
timeout = time.Minute * 5
}
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, timeout) timer := signal.CancelAfterInactivity(ctx, cancel, h.policy.Timeout.ConnectionIdle.Duration())
requestDone := signal.ExecuteAsync(func() error { requestDone := signal.ExecuteAsync(func() error {
var writer buf.Writer var writer buf.Writer
@ -126,6 +131,7 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
if err := buf.Copy(input, writer, buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(input, writer, buf.UpdateActivity(timer)); err != nil {
return newError("failed to process request").Base(err) return newError("failed to process request").Base(err)
} }
timer.SetTimeout(h.policy.Timeout.DownlinkOnly.Duration())
return nil return nil
}) })
@ -136,6 +142,7 @@ func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
if err := buf.Copy(v2reader, output, buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(v2reader, output, buf.UpdateActivity(timer)); err != nil {
return newError("failed to process response").Base(err) return newError("failed to process response").Base(err)
} }
timer.SetTimeout(h.policy.Timeout.UplinkOnly.Duration())
return nil return nil
}) })

View File

@ -20,6 +20,7 @@ type ServerConfig struct {
Timeout uint32 `protobuf:"varint,1,opt,name=timeout" json:"timeout,omitempty"` Timeout uint32 `protobuf:"varint,1,opt,name=timeout" json:"timeout,omitempty"`
Accounts map[string]string `protobuf:"bytes,2,rep,name=accounts" json:"accounts,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` Accounts map[string]string `protobuf:"bytes,2,rep,name=accounts" json:"accounts,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
AllowTransparent bool `protobuf:"varint,3,opt,name=allow_transparent,json=allowTransparent" json:"allow_transparent,omitempty"` AllowTransparent bool `protobuf:"varint,3,opt,name=allow_transparent,json=allowTransparent" json:"allow_transparent,omitempty"`
UserLevel uint32 `protobuf:"varint,4,opt,name=user_level,json=userLevel" json:"user_level,omitempty"`
} }
func (m *ServerConfig) Reset() { *m = ServerConfig{} } func (m *ServerConfig) Reset() { *m = ServerConfig{} }
@ -48,6 +49,13 @@ func (m *ServerConfig) GetAllowTransparent() bool {
return false return false
} }
func (m *ServerConfig) GetUserLevel() uint32 {
if m != nil {
return m.UserLevel
}
return 0
}
// ClientConfig for HTTP proxy client. // ClientConfig for HTTP proxy client.
type ClientConfig struct { type ClientConfig struct {
} }
@ -65,22 +73,24 @@ func init() {
func init() { proto.RegisterFile("v2ray.com/core/proxy/http/config.proto", fileDescriptor0) } func init() { proto.RegisterFile("v2ray.com/core/proxy/http/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 271 bytes of a gzipped FileDescriptorProto // 296 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x5d, 0x4b, 0xc3, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xcf, 0x4a, 0x33, 0x31,
0x14, 0x86, 0x49, 0xe7, 0xc7, 0x8c, 0x9b, 0xcc, 0xe0, 0xa0, 0x7a, 0x55, 0x76, 0x21, 0x05, 0x21, 0x14, 0xc5, 0x99, 0x69, 0xbf, 0xcf, 0xf6, 0xda, 0x4a, 0x0d, 0x16, 0x46, 0x51, 0x28, 0x5d, 0x48,
0xc5, 0x7a, 0x23, 0xee, 0x4a, 0x8b, 0xe0, 0x8d, 0x30, 0xaa, 0x78, 0xe1, 0x8d, 0xc4, 0x10, 0xb5, 0x41, 0xc8, 0x60, 0xdd, 0x88, 0x5d, 0xd9, 0x22, 0xb8, 0x50, 0x28, 0x51, 0x5c, 0xb8, 0x29, 0x31,
0xd8, 0xe6, 0x94, 0xb3, 0xd3, 0x6a, 0xfe, 0x92, 0xff, 0xca, 0x7f, 0x22, 0xcd, 0x9c, 0x1f, 0xb0, 0x5c, 0xb5, 0x98, 0x26, 0x43, 0xe6, 0xce, 0xe8, 0xec, 0x7d, 0x1a, 0x9f, 0x52, 0x92, 0x5a, 0xff,
0xab, 0xe4, 0x9c, 0xf7, 0xc9, 0xc3, 0x4b, 0xf8, 0x61, 0x9b, 0xa2, 0x72, 0x52, 0x43, 0x95, 0x68, 0x40, 0x57, 0x49, 0x7e, 0xe7, 0xe4, 0xe4, 0x9e, 0xc0, 0x61, 0x39, 0x74, 0xb2, 0xe2, 0xca, 0x2e,
0x40, 0x93, 0xd4, 0x08, 0xef, 0x2e, 0x79, 0x21, 0xaa, 0x13, 0x0d, 0xf6, 0xa9, 0x78, 0x96, 0x35, 0x52, 0x65, 0x1d, 0xa6, 0x99, 0xb3, 0x6f, 0x55, 0xfa, 0x4c, 0x94, 0xa5, 0xca, 0x9a, 0xc7, 0xf9,
0x02, 0x81, 0x18, 0x2f, 0x39, 0x34, 0xd2, 0x33, 0xb2, 0x63, 0x26, 0x9f, 0x8c, 0x0f, 0x6e, 0x0c, 0x13, 0xcf, 0x9c, 0x25, 0xcb, 0xba, 0x2b, 0x9f, 0x43, 0x1e, 0x3c, 0xdc, 0x7b, 0xfa, 0xef, 0x31,
0xb6, 0x06, 0x33, 0x4f, 0x8b, 0x90, 0x6f, 0x52, 0x51, 0x19, 0x68, 0x28, 0x64, 0x11, 0x8b, 0x87, 0xb4, 0x6e, 0xd0, 0x95, 0xe8, 0x26, 0xc1, 0xcd, 0xf6, 0x61, 0x83, 0xe6, 0x0b, 0xb4, 0x05, 0x25,
0xf9, 0x72, 0x14, 0xd7, 0xbc, 0xaf, 0xb4, 0x86, 0xc6, 0xd2, 0x3c, 0x0c, 0xa2, 0x5e, 0xbc, 0x9d, 0x51, 0x2f, 0x1a, 0xb4, 0xc7, 0x71, 0x12, 0x89, 0x15, 0x62, 0xd7, 0xd0, 0x90, 0x4a, 0xd9, 0xc2,
0x1e, 0xcb, 0x95, 0x52, 0xf9, 0x57, 0x28, 0xcf, 0xbf, 0xdf, 0x5c, 0x5a, 0x42, 0x97, 0xff, 0x28, 0x50, 0x9e, 0xc4, 0xbd, 0xda, 0x60, 0x73, 0x78, 0xcc, 0xd7, 0x06, 0xf3, 0xdf, 0xa1, 0xfc, 0xfc,
0xc4, 0x11, 0xdf, 0x55, 0x65, 0x09, 0x6f, 0x0f, 0x84, 0xca, 0xce, 0x6b, 0x85, 0xc6, 0x52, 0xd8, 0xeb, 0xce, 0x85, 0x21, 0x57, 0x89, 0xef, 0x08, 0x76, 0x04, 0xdb, 0x52, 0x6b, 0xfb, 0x3a, 0x23,
0x8b, 0x58, 0xdc, 0xcf, 0x47, 0x3e, 0xb8, 0xfd, 0xdd, 0x1f, 0x4c, 0xf9, 0xf0, 0x9f, 0x47, 0x8c, 0x27, 0x4d, 0x9e, 0x49, 0x87, 0x86, 0x92, 0x5a, 0x2f, 0x1a, 0x34, 0x44, 0x27, 0x08, 0xb7, 0x3f,
0x78, 0xef, 0xd5, 0x38, 0x5f, 0x71, 0x2b, 0xef, 0xae, 0x62, 0x8f, 0xaf, 0xb7, 0xaa, 0x6c, 0x4c, 0x9c, 0x1d, 0x00, 0x14, 0x39, 0xba, 0x99, 0xc6, 0x12, 0x75, 0x52, 0xf7, 0xc3, 0x89, 0xa6, 0x27,
0x18, 0xf8, 0xdd, 0x62, 0x38, 0x0b, 0x4e, 0xd9, 0x64, 0x87, 0x0f, 0xb2, 0xb2, 0x30, 0x96, 0x16, 0x57, 0x1e, 0xec, 0x8d, 0xa0, 0xfd, 0xe7, 0x19, 0xd6, 0x81, 0xda, 0x0b, 0x56, 0xa1, 0x45, 0x53,
0x8d, 0x2e, 0xa6, 0x7c, 0x5f, 0x43, 0xb5, 0xba, 0xfb, 0x8c, 0xdd, 0xaf, 0x75, 0xe7, 0x47, 0x30, 0xf8, 0x2d, 0xdb, 0x81, 0x7f, 0xa5, 0xd4, 0x05, 0x26, 0x71, 0x60, 0xcb, 0xc3, 0x59, 0x7c, 0x1a,
0xbe, 0x4b, 0x73, 0xe5, 0x64, 0xd6, 0xe5, 0x33, 0x9f, 0x5f, 0x11, 0xd5, 0x8f, 0x1b, 0xfe, 0x3b, 0xf5, 0xb7, 0xa0, 0x35, 0xd1, 0x73, 0x34, 0xb4, 0x1c, 0x78, 0x3c, 0x82, 0x5d, 0x65, 0x17, 0xeb,
0x4f, 0xbe, 0x02, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x08, 0xbc, 0x0a, 0x78, 0x01, 0x00, 0x00, 0xab, 0x4d, 0xa3, 0xfb, 0xba, 0x5f, 0x3f, 0xe2, 0xee, 0xdd, 0x50, 0xc8, 0x8a, 0x4f, 0xbc, 0x3e,
0x0d, 0xfa, 0x25, 0x51, 0xf6, 0xf0, 0x3f, 0xfc, 0xf8, 0xc9, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff,
0x69, 0x94, 0x9f, 0xa7, 0x9b, 0x01, 0x00, 0x00,
} }

View File

@ -8,9 +8,10 @@ option java_multiple_files = true;
// Config for HTTP proxy server. // Config for HTTP proxy server.
message ServerConfig { message ServerConfig {
uint32 timeout = 1; uint32 timeout = 1 [deprecated = true];
map<string, string> accounts = 2; map<string, string> accounts = 2;
bool allow_transparent = 3; bool allow_transparent = 3;
uint32 user_level = 4;
} }
// ClientConfig for HTTP proxy client. // ClientConfig for HTTP proxy client.

View File

@ -13,6 +13,7 @@ import (
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/app/policy"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
@ -24,6 +25,7 @@ import (
// Server is a HTTP proxy server. // Server is a HTTP proxy server.
type Server struct { type Server struct {
config *ServerConfig config *ServerConfig
policy policy.Policy
} }
// NewServer creates a new HTTP inbound handler. // NewServer creates a new HTTP inbound handler.
@ -35,6 +37,17 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
s := &Server{ s := &Server{
config: config, config: config,
} }
space.OnInitialize(func() error {
pm := policy.PolicyFromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
}
s.policy = pm.GetPolicy(config.UserLevel)
if config.Timeout > 0 && config.UserLevel == 0 {
s.policy.Timeout.ConnectionIdle.Value = config.Timeout
}
return nil
})
return s, nil return s, nil
} }
@ -94,7 +107,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
reader := bufio.NewReaderSize(readerOnly{conn}, buf.Size) reader := bufio.NewReaderSize(readerOnly{conn}, buf.Size)
Start: Start:
conn.SetReadDeadline(time.Now().Add(time.Second * 16)) conn.SetReadDeadline(time.Now().Add(s.policy.Timeout.Handshake.Duration()))
request, err := http.ReadRequest(reader) request, err := http.ReadRequest(reader)
if err != nil { if err != nil {
@ -157,12 +170,8 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
return newError("failed to write back OK response").Base(err) return newError("failed to write back OK response").Base(err)
} }
timeout := time.Second * time.Duration(s.config.Timeout)
if timeout == 0 {
timeout = time.Minute * 5
}
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, timeout) timer := signal.CancelAfterInactivity(ctx, cancel, s.policy.Timeout.ConnectionIdle.Duration())
ray, err := dispatcher.Dispatch(ctx, dest) ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil { if err != nil {
return err return err
@ -181,6 +190,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
requestDone := signal.ExecuteAsync(func() error { requestDone := signal.ExecuteAsync(func() error {
defer ray.InboundInput().Close() defer ray.InboundInput().Close()
defer timer.SetTimeout(s.policy.Timeout.DownlinkOnly.Duration())
v2reader := buf.NewReader(conn) v2reader := buf.NewReader(conn)
return buf.Copy(v2reader, ray.InboundInput(), buf.UpdateActivity(timer)) return buf.Copy(v2reader, ray.InboundInput(), buf.UpdateActivity(timer))
@ -191,7 +201,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
if err := buf.Copy(ray.InboundOutput(), v2writer, buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(ray.InboundOutput(), v2writer, buf.UpdateActivity(timer)); err != nil {
return err return err
} }
timer.SetTimeout(time.Second * 2) timer.SetTimeout(s.policy.Timeout.UplinkOnly.Duration())
return nil return nil
}) })

View File

@ -2,9 +2,10 @@ package shadowsocks
import ( import (
"context" "context"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/app/policy"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
@ -18,7 +19,8 @@ import (
// Client is a inbound handler for Shadowsocks protocol // Client is a inbound handler for Shadowsocks protocol
type Client struct { type Client struct {
serverPicker protocol.ServerPicker serverPicker protocol.ServerPicker
policyManager policy.Interface
} }
// NewClient create a new Shadowsocks client. // NewClient create a new Shadowsocks client.
@ -33,6 +35,18 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
client := &Client{ client := &Client{
serverPicker: protocol.NewRoundRobinServerPicker(serverList), serverPicker: protocol.NewRoundRobinServerPicker(serverList),
} }
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("Space not found.")
}
space.OnInitialize(func() error {
pm := policy.PolicyFromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
}
client.policyManager = pm
return nil
})
return client, nil return client, nil
} }
@ -90,8 +104,9 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
request.Option |= RequestOptionOneTimeAuth request.Option |= RequestOptionOneTimeAuth
} }
sessionPolicy := v.policyManager.GetPolicy(user.Level)
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, time.Minute*5) timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
if request.Command == protocol.RequestCommandTCP { if request.Command == protocol.RequestCommandTCP {
bufferedWriter := buf.NewBufferedWriter(buf.NewWriter(conn)) bufferedWriter := buf.NewBufferedWriter(buf.NewWriter(conn))
@ -105,11 +120,13 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
} }
requestDone := signal.ExecuteAsync(func() error { requestDone := signal.ExecuteAsync(func() error {
defer timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
return buf.Copy(outboundRay.OutboundInput(), bodyWriter, buf.UpdateActivity(timer)) return buf.Copy(outboundRay.OutboundInput(), bodyWriter, buf.UpdateActivity(timer))
}) })
responseDone := signal.ExecuteAsync(func() error { responseDone := signal.ExecuteAsync(func() error {
defer outboundRay.OutboundOutput().Close() defer outboundRay.OutboundOutput().Close()
defer timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
responseReader, err := ReadTCPResponse(user, conn) responseReader, err := ReadTCPResponse(user, conn)
if err != nil { if err != nil {

View File

@ -38,4 +38,4 @@ message ServerConfig {
message ClientConfig { message ClientConfig {
repeated v2ray.core.common.protocol.ServerEndpoint server = 1; repeated v2ray.core.common.protocol.ServerEndpoint server = 1;
} }

View File

@ -7,6 +7,7 @@ import (
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/app/policy"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
@ -18,9 +19,10 @@ import (
) )
type Server struct { type Server struct {
config *ServerConfig config *ServerConfig
user *protocol.User user *protocol.User
account *ShadowsocksAccount account *ShadowsocksAccount
policyManager policy.Interface
} }
// NewServer create a new Shadowsocks server. // NewServer create a new Shadowsocks server.
@ -45,6 +47,15 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
account: account, account: account,
} }
space.OnInitialize(func() error {
pm := policy.PolicyFromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
}
s.policyManager = pm
return nil
})
return s, nil return s, nil
} }
@ -128,7 +139,8 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
} }
func (s *Server) handleConnection(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error { func (s *Server) handleConnection(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
conn.SetReadDeadline(time.Now().Add(time.Second * 8)) sessionPolicy := s.policyManager.GetPolicy(s.user.Level)
conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeout.Handshake.Duration()))
bufferedReader := buf.NewBufferedReader(buf.NewReader(conn)) bufferedReader := buf.NewBufferedReader(buf.NewReader(conn))
request, bodyReader, err := ReadTCPSession(s.user, bufferedReader) request, bodyReader, err := ReadTCPSession(s.user, bufferedReader)
if err != nil { if err != nil {
@ -145,9 +157,8 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
ctx = protocol.ContextWithUser(ctx, request.User) ctx = protocol.ContextWithUser(ctx, request.User)
userSettings := s.user.GetSettings()
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, userSettings.PayloadTimeout) timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
ray, err := dispatcher.Dispatch(ctx, dest) ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil { if err != nil {
return err return err
@ -177,7 +188,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
return newError("failed to transport all TCP response").Base(err) return newError("failed to transport all TCP response").Base(err)
} }
timer.SetTimeout(time.Second * 2) timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
return nil return nil
}) })
@ -188,6 +199,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
if err := buf.Copy(bodyReader, ray.InboundInput(), buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(bodyReader, ray.InboundInput(), buf.UpdateActivity(timer)); err != nil {
return newError("failed to transport all TCP request").Base(err) return newError("failed to transport all TCP request").Base(err)
} }
timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
return nil return nil
}) })

View File

@ -68,6 +68,7 @@ type ServerConfig struct {
Address *v2ray_core_common_net.IPOrDomain `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"` Address *v2ray_core_common_net.IPOrDomain `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"`
UdpEnabled bool `protobuf:"varint,4,opt,name=udp_enabled,json=udpEnabled" json:"udp_enabled,omitempty"` UdpEnabled bool `protobuf:"varint,4,opt,name=udp_enabled,json=udpEnabled" json:"udp_enabled,omitempty"`
Timeout uint32 `protobuf:"varint,5,opt,name=timeout" json:"timeout,omitempty"` Timeout uint32 `protobuf:"varint,5,opt,name=timeout" json:"timeout,omitempty"`
UserLevel uint32 `protobuf:"varint,6,opt,name=user_level,json=userLevel" json:"user_level,omitempty"`
} }
func (m *ServerConfig) Reset() { *m = ServerConfig{} } func (m *ServerConfig) Reset() { *m = ServerConfig{} }
@ -110,6 +111,13 @@ func (m *ServerConfig) GetTimeout() uint32 {
return 0 return 0
} }
func (m *ServerConfig) GetUserLevel() uint32 {
if m != nil {
return m.UserLevel
}
return 0
}
type ClientConfig struct { type ClientConfig struct {
Server []*v2ray_core_common_protocol1.ServerEndpoint `protobuf:"bytes,1,rep,name=server" json:"server,omitempty"` Server []*v2ray_core_common_protocol1.ServerEndpoint `protobuf:"bytes,1,rep,name=server" json:"server,omitempty"`
} }
@ -136,34 +144,35 @@ func init() {
func init() { proto.RegisterFile("v2ray.com/core/proxy/socks/config.proto", fileDescriptor0) } func init() { proto.RegisterFile("v2ray.com/core/proxy/socks/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 449 bytes of a gzipped FileDescriptorProto // 470 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xd1, 0x6e, 0xd3, 0x3e, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0x5d, 0x8b, 0xd3, 0x40,
0x14, 0xc6, 0xff, 0x49, 0xff, 0x5d, 0xb3, 0xd3, 0x0e, 0x55, 0x16, 0x9a, 0xa2, 0xdc, 0x10, 0x2a, 0x14, 0x75, 0xb2, 0xb6, 0x4d, 0x6f, 0xbb, 0x52, 0x06, 0x59, 0x42, 0x51, 0x8c, 0x05, 0xb1, 0xec,
0x21, 0xa2, 0x5d, 0x38, 0x28, 0xdc, 0x20, 0x26, 0x90, 0xb2, 0xae, 0x12, 0xdc, 0xac, 0x95, 0x3b, 0xc3, 0x44, 0xe2, 0x8b, 0xb8, 0x28, 0xb4, 0xdd, 0x82, 0x82, 0x6c, 0xcb, 0x74, 0x55, 0xf0, 0x25,
0x40, 0xe2, 0xa6, 0xf2, 0x1c, 0xc3, 0xa2, 0x35, 0x76, 0x64, 0x3b, 0x85, 0xbc, 0x12, 0x8f, 0xc3, 0xcc, 0x4e, 0x46, 0x37, 0x6c, 0x32, 0x13, 0x66, 0x26, 0xd5, 0xfc, 0x25, 0xff, 0x9f, 0xef, 0x92,
0x13, 0xa1, 0xda, 0xc9, 0x34, 0x50, 0x77, 0x77, 0x4e, 0xce, 0x77, 0xbe, 0x9c, 0xef, 0x67, 0x78, 0xaf, 0x65, 0x95, 0xee, 0xdb, 0xfd, 0x38, 0xf7, 0xcc, 0x3d, 0xe7, 0x0e, 0xbc, 0xdc, 0x87, 0x9a,
0xb9, 0xcb, 0x14, 0x6d, 0x31, 0x93, 0x55, 0xca, 0xa4, 0xe2, 0x69, 0xad, 0xe4, 0xcf, 0x36, 0xd5, 0x95, 0x84, 0xab, 0x2c, 0xe0, 0x4a, 0x8b, 0x20, 0xd7, 0xea, 0x57, 0x19, 0x18, 0xc5, 0x6f, 0x4c,
0x92, 0xdd, 0xe9, 0x94, 0x49, 0xf1, 0xad, 0xfc, 0x8e, 0x6b, 0x25, 0x8d, 0x44, 0xa7, 0xbd, 0x50, 0xc0, 0x95, 0xfc, 0x9e, 0xfc, 0x20, 0xb9, 0x56, 0x56, 0xe1, 0x93, 0x0e, 0xa8, 0x05, 0xa9, 0x41,
0x71, 0x6c, 0x45, 0xd8, 0x8a, 0xa2, 0x7f, 0x0d, 0x98, 0xac, 0x2a, 0x29, 0x52, 0xc1, 0x4d, 0x4a, 0xa4, 0x06, 0x4d, 0xff, 0x27, 0xe0, 0x2a, 0xcb, 0x94, 0x0c, 0xa4, 0xb0, 0x01, 0x8b, 0x63, 0x2d,
0x8b, 0x42, 0x71, 0xad, 0x9d, 0x41, 0xf4, 0xea, 0xb0, 0xd0, 0x0e, 0x99, 0xdc, 0xa6, 0x9a, 0xab, 0x8c, 0x69, 0x08, 0xa6, 0xaf, 0x0e, 0x03, 0xeb, 0x26, 0x57, 0x69, 0x60, 0x84, 0xde, 0x0b, 0x1d,
0x1d, 0x57, 0x1b, 0x5d, 0x73, 0xe6, 0x36, 0x66, 0x39, 0x8c, 0x72, 0xc6, 0x64, 0x23, 0x0c, 0x8a, 0x99, 0x5c, 0xf0, 0x66, 0x62, 0xb6, 0x80, 0xc1, 0x82, 0x73, 0x55, 0x48, 0x8b, 0xa7, 0xe0, 0x16,
0x20, 0x68, 0x34, 0x57, 0x82, 0x56, 0x3c, 0xf4, 0x62, 0x2f, 0x39, 0x26, 0xf7, 0xfd, 0x7e, 0x56, 0x46, 0x68, 0xc9, 0x32, 0xe1, 0x21, 0x1f, 0xcd, 0x87, 0xf4, 0x36, 0xaf, 0x7a, 0x39, 0x33, 0xe6,
0x53, 0xad, 0x7f, 0x48, 0x55, 0x84, 0xbe, 0x9b, 0xf5, 0xfd, 0xec, 0xb7, 0x0f, 0x93, 0xb5, 0x35, 0xa7, 0xd2, 0xb1, 0xe7, 0x34, 0xbd, 0x2e, 0x9f, 0xfd, 0x71, 0x60, 0xbc, 0xab, 0x89, 0x57, 0xb5,
0x9e, 0xdb, 0x30, 0xe8, 0x1d, 0x1c, 0xd3, 0xc6, 0xdc, 0x6e, 0x4c, 0x5b, 0x3b, 0xa7, 0x27, 0x59, 0x18, 0xfc, 0x0e, 0x86, 0xac, 0xb0, 0xd7, 0x91, 0x2d, 0xf3, 0x86, 0xe9, 0x51, 0xe8, 0x93, 0xc3,
0x8c, 0x0f, 0x47, 0xc3, 0x79, 0x63, 0x6e, 0xaf, 0xdb, 0x9a, 0x93, 0x80, 0x76, 0x15, 0xba, 0x82, 0xd2, 0xc8, 0xa2, 0xb0, 0xd7, 0x97, 0x65, 0x2e, 0xa8, 0xcb, 0xda, 0x08, 0x5f, 0x80, 0xcb, 0x9a,
0x80, 0xba, 0x93, 0x74, 0xe8, 0xc7, 0x83, 0x64, 0x9c, 0x65, 0x8f, 0x6d, 0x3f, 0xfc, 0x2d, 0xee, 0x95, 0x8c, 0xe7, 0xf8, 0x47, 0xf3, 0x51, 0x18, 0xde, 0x37, 0x7d, 0xf7, 0x59, 0xd2, 0xea, 0x30,
0x72, 0xe8, 0x85, 0x30, 0xaa, 0x25, 0xf7, 0x1e, 0xe8, 0x1c, 0x46, 0x1d, 0xa5, 0x70, 0x10, 0x7b, 0x6b, 0x69, 0x75, 0x49, 0x6f, 0x39, 0xf0, 0x19, 0x0c, 0x5a, 0x97, 0xbc, 0x23, 0x1f, 0xcd, 0x47,
0xc9, 0x38, 0x7b, 0xfe, 0xd0, 0xce, 0x21, 0xc2, 0x82, 0x1b, 0xfc, 0x71, 0xb5, 0x54, 0x97, 0xb2, 0xe1, 0xf3, 0xbb, 0x74, 0x8d, 0x45, 0x44, 0x0a, 0x4b, 0x3e, 0x6e, 0x37, 0xfa, 0x5c, 0x65, 0x2c,
0xa2, 0xa5, 0x20, 0xfd, 0x06, 0x7a, 0x06, 0xe3, 0xa6, 0xa8, 0x37, 0x5c, 0xd0, 0x9b, 0x2d, 0x2f, 0x91, 0xb4, 0x9b, 0xc0, 0xcf, 0x60, 0x54, 0xc4, 0x79, 0x24, 0x24, 0xbb, 0x4a, 0x45, 0xec, 0x3d,
0xc2, 0xff, 0x63, 0x2f, 0x09, 0x08, 0x34, 0x45, 0xbd, 0x70, 0x5f, 0x50, 0x08, 0x23, 0x53, 0x56, 0xf4, 0xd1, 0xdc, 0xa5, 0x50, 0xc4, 0xf9, 0xba, 0xa9, 0xe0, 0x27, 0x30, 0xb0, 0x49, 0x26, 0x54,
0x5c, 0x36, 0x26, 0x1c, 0xc6, 0x5e, 0x72, 0x42, 0xfa, 0x36, 0x3a, 0x87, 0x93, 0xbf, 0x4e, 0x42, 0x61, 0xbd, 0x9e, 0x8f, 0xe6, 0xc7, 0x4b, 0xc7, 0x43, 0xb4, 0x2b, 0xe1, 0xa7, 0x00, 0x95, 0x87,
0x53, 0x18, 0xdc, 0xf1, 0xb6, 0x63, 0xbb, 0x2f, 0xd1, 0x53, 0x18, 0xee, 0xe8, 0xb6, 0xe1, 0x1d, 0x51, 0x2a, 0xf6, 0x22, 0xf5, 0xfa, 0x15, 0x80, 0x0e, 0xab, 0xca, 0xa7, 0xaa, 0x30, 0x3d, 0x83,
0x53, 0xd7, 0xbc, 0xf5, 0xdf, 0x78, 0x33, 0x02, 0x93, 0xf9, 0xb6, 0xe4, 0xc2, 0x74, 0x4c, 0x2f, 0xe3, 0x7f, 0xb6, 0xc6, 0x13, 0x38, 0xba, 0x11, 0x65, 0x6b, 0x7f, 0x15, 0xe2, 0xc7, 0xd0, 0xdb,
0xe0, 0xc8, 0x3d, 0x5e, 0xe8, 0x59, 0x24, 0x67, 0x07, 0x32, 0xf4, 0xcf, 0xdc, 0x61, 0x59, 0x88, 0xb3, 0xb4, 0x10, 0xad, 0xed, 0x4d, 0xf2, 0xd6, 0x79, 0x83, 0x66, 0x14, 0xc6, 0xab, 0x34, 0x11,
0xa2, 0x96, 0xa5, 0x30, 0xa4, 0xdb, 0x3c, 0x7b, 0x01, 0x41, 0x8f, 0x1b, 0x8d, 0x61, 0x74, 0xb5, 0xd2, 0xb6, 0xb6, 0x2f, 0xa1, 0xdf, 0xdc, 0xd7, 0x43, 0xb5, 0x6b, 0xa7, 0x07, 0x64, 0x76, 0x3f,
0xdc, 0xe4, 0x9f, 0xae, 0x3f, 0x4c, 0xff, 0x43, 0x13, 0x08, 0x56, 0xf9, 0x7a, 0xfd, 0x65, 0x49, 0xa1, 0x75, 0x6e, 0x2d, 0xe3, 0x5c, 0x25, 0xd2, 0xd2, 0x76, 0xf2, 0xf4, 0x05, 0xb8, 0xdd, 0x45,
0x2e, 0xa7, 0xde, 0xc5, 0x7b, 0x88, 0x98, 0xac, 0x1e, 0x41, 0xbe, 0xf2, 0xbe, 0x0e, 0x6d, 0xf1, 0xf0, 0x08, 0x06, 0x17, 0x9b, 0x68, 0xf1, 0xf9, 0xf2, 0xc3, 0xe4, 0x01, 0x1e, 0x83, 0xbb, 0x5d,
0xcb, 0x3f, 0xfd, 0x9c, 0x11, 0xda, 0xe2, 0xf9, 0x5e, 0xb1, 0xb2, 0x8a, 0xf5, 0x7e, 0x70, 0x73, 0xec, 0x76, 0x5f, 0x37, 0xf4, 0x7c, 0x82, 0x96, 0xef, 0x61, 0xca, 0x55, 0x76, 0xcf, 0x55, 0xb6,
0x64, 0xef, 0x78, 0xfd, 0x27, 0x00, 0x00, 0xff, 0xff, 0x57, 0x01, 0x54, 0x95, 0xf7, 0x02, 0x00, 0xe8, 0x5b, 0xaf, 0x0e, 0x7e, 0x3b, 0x27, 0x5f, 0x42, 0xca, 0x4a, 0xb2, 0xaa, 0x10, 0xdb, 0x1a,
0x00, 0xb1, 0xab, 0x1a, 0x57, 0xfd, 0x7a, 0x8f, 0xd7, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x23, 0xac,
0x72, 0x71, 0x1a, 0x03, 0x00, 0x00,
} }

View File

@ -24,9 +24,10 @@ message ServerConfig {
map<string, string> accounts = 2; map<string, string> accounts = 2;
v2ray.core.common.net.IPOrDomain address = 3; v2ray.core.common.net.IPOrDomain address = 3;
bool udp_enabled = 4; bool udp_enabled = 4;
uint32 timeout = 5; uint32 timeout = 5 [deprecated = true];
uint32 user_level = 6;
} }
message ClientConfig { message ClientConfig {
repeated v2ray.core.common.protocol.ServerEndpoint server = 1; repeated v2ray.core.common.protocol.ServerEndpoint server = 1;
} }

View File

@ -8,6 +8,7 @@ import (
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/app/policy"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
@ -21,6 +22,7 @@ import (
// Server is a SOCKS 5 proxy server // Server is a SOCKS 5 proxy server
type Server struct { type Server struct {
config *ServerConfig config *ServerConfig
policy policy.Policy
} }
// NewServer creates a new Server object. // NewServer creates a new Server object.
@ -32,6 +34,17 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
s := &Server{ s := &Server{
config: config, config: config,
} }
space.OnInitialize(func() error {
pm := policy.PolicyFromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
}
s.policy = pm.GetPolicy(config.UserLevel)
if config.Timeout > 0 && config.UserLevel == 0 {
s.policy.Timeout.ConnectionIdle.Value = config.Timeout
}
return nil
})
return s, nil return s, nil
} }
@ -57,7 +70,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
} }
func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error { func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
conn.SetReadDeadline(time.Now().Add(time.Second * 8)) conn.SetReadDeadline(time.Now().Add(s.policy.Timeout.Handshake.Duration()))
reader := buf.NewBufferedReader(buf.NewReader(conn)) reader := buf.NewBufferedReader(buf.NewReader(conn))
inboundDest, ok := proxy.InboundEntryPointFromContext(ctx) inboundDest, ok := proxy.InboundEntryPointFromContext(ctx)
@ -103,12 +116,8 @@ func (*Server) handleUDP(c net.Conn) error {
} }
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 dispatcher.Interface) error {
timeout := time.Second * time.Duration(v.config.Timeout)
if timeout == 0 {
timeout = time.Minute * 5
}
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, timeout) timer := signal.CancelAfterInactivity(ctx, cancel, v.policy.Timeout.ConnectionIdle.Duration())
ray, err := dispatcher.Dispatch(ctx, dest) ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil { if err != nil {
@ -125,6 +134,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
if err := buf.Copy(v2reader, input, buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(v2reader, input, buf.UpdateActivity(timer)); err != nil {
return newError("failed to transport all TCP request").Base(err) return newError("failed to transport all TCP request").Base(err)
} }
timer.SetTimeout(v.policy.Timeout.DownlinkOnly.Duration())
return nil return nil
}) })
@ -133,7 +143,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
if err := buf.Copy(output, v2writer, buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(output, v2writer, buf.UpdateActivity(timer)); err != nil {
return newError("failed to transport all TCP response").Base(err) return newError("failed to transport all TCP response").Base(err)
} }
timer.SetTimeout(time.Second * 2) timer.SetTimeout(v.policy.Timeout.UplinkOnly.Duration())
return nil return nil
}) })

View File

@ -11,6 +11,7 @@ import (
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/app/policy"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
@ -78,6 +79,7 @@ type Handler struct {
usersByEmail *userByEmail usersByEmail *userByEmail
detours *DetourConfig detours *DetourConfig
sessionHistory *encoding.SessionHistory sessionHistory *encoding.SessionHistory
policyManager policy.Interface
} }
// New creates a new VMess inbound handler. // New creates a new VMess inbound handler.
@ -104,7 +106,11 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
space.OnInitialize(func() error { space.OnInitialize(func() error {
handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space) handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space)
if handler.inboundHandlerManager == nil { if handler.inboundHandlerManager == nil {
return newError("InboundHandlerManager is not found is space") return newError("InboundHandlerManager is not found is space.")
}
handler.policyManager = policy.PolicyFromSpace(space)
if handler.policyManager == nil {
return newError("Policy is not found in space.")
} }
return nil return nil
}) })
@ -174,7 +180,8 @@ func transferResponse(timer signal.ActivityUpdater, session *encoding.ServerSess
// Process implements proxy.Inbound.Process(). // Process implements proxy.Inbound.Process().
func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher dispatcher.Interface) error { func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher dispatcher.Interface) error {
if err := connection.SetReadDeadline(time.Now().Add(time.Second * 8)); err != nil { sessionPolicy := h.policyManager.GetPolicy(0)
if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeout.Handshake.Duration())); err != nil {
return newError("unable to set read deadline").Base(err).AtWarning() return newError("unable to set read deadline").Base(err).AtWarning()
} }
@ -203,11 +210,11 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
log.Trace(newError("unable to set back read deadline").Base(err)) log.Trace(newError("unable to set back read deadline").Base(err))
} }
userSettings := request.User.GetSettings() sessionPolicy = h.policyManager.GetPolicy(request.User.Level)
ctx = protocol.ContextWithUser(ctx, request.User) ctx = protocol.ContextWithUser(ctx, request.User)
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, userSettings.PayloadTimeout) timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
ray, err := dispatcher.Dispatch(ctx, request.Destination()) ray, err := dispatcher.Dispatch(ctx, request.Destination())
if err != nil { if err != nil {
return newError("failed to dispatch request to ", request.Destination()).Base(err) return newError("failed to dispatch request to ", request.Destination()).Base(err)
@ -217,12 +224,14 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
output := ray.InboundOutput() output := ray.InboundOutput()
requestDone := signal.ExecuteAsync(func() error { requestDone := signal.ExecuteAsync(func() error {
defer timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
return transferRequest(timer, session, request, reader, input) return transferRequest(timer, session, request, reader, input)
}) })
responseDone := signal.ExecuteAsync(func() error { responseDone := signal.ExecuteAsync(func() error {
writer := buf.NewBufferedWriter(buf.NewWriter(connection)) writer := buf.NewBufferedWriter(buf.NewWriter(connection))
defer writer.Flush() defer writer.Flush()
defer timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
response := &protocol.ResponseHeader{ response := &protocol.ResponseHeader{
Command: h.generateCommand(ctx, request), Command: h.generateCommand(ctx, request),

View File

@ -8,6 +8,7 @@ import (
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/app/policy"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
@ -23,8 +24,9 @@ import (
// Handler is an outbound connection handler for VMess protocol. // Handler is an outbound connection handler for VMess protocol.
type Handler struct { type Handler struct {
serverList *protocol.ServerList serverList *protocol.ServerList
serverPicker protocol.ServerPicker serverPicker protocol.ServerPicker
policyManager policy.Interface
} }
func New(ctx context.Context, config *Config) (*Handler, error) { func New(ctx context.Context, config *Config) (*Handler, error) {
@ -42,6 +44,15 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
serverPicker: protocol.NewRoundRobinServerPicker(serverList), serverPicker: protocol.NewRoundRobinServerPicker(serverList),
} }
space.OnInitialize(func() error {
pm := policy.PolicyFromSpace(space)
if pm == nil {
return newError("Policy is not found in space.")
}
handler.policyManager = pm
return nil
})
return handler, nil return handler, nil
} }
@ -102,9 +113,10 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
output := outboundRay.OutboundOutput() output := outboundRay.OutboundOutput()
session := encoding.NewClientSession(protocol.DefaultIDHash) session := encoding.NewClientSession(protocol.DefaultIDHash)
sessionPolicy := v.policyManager.GetPolicy(request.User.Level)
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, time.Minute*5) timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeout.ConnectionIdle.Duration())
requestDone := signal.ExecuteAsync(func() error { requestDone := signal.ExecuteAsync(func() error {
writer := buf.NewBufferedWriter(buf.NewWriter(conn)) writer := buf.NewBufferedWriter(buf.NewWriter(conn))
@ -137,11 +149,13 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
return err return err
} }
} }
timer.SetTimeout(sessionPolicy.Timeout.DownlinkOnly.Duration())
return nil return nil
}) })
responseDone := signal.ExecuteAsync(func() error { responseDone := signal.ExecuteAsync(func() error {
defer output.Close() defer output.Close()
defer timer.SetTimeout(sessionPolicy.Timeout.UplinkOnly.Duration())
reader := buf.NewBufferedReader(buf.NewReader(conn)) reader := buf.NewBufferedReader(buf.NewReader(conn))
header, err := session.DecodeResponseHeader(reader) header, err := session.DecodeResponseHeader(reader)

View File

@ -7,6 +7,7 @@ import (
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/dns" "v2ray.com/core/app/dns"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/app/policy"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
@ -115,7 +116,24 @@ func newSimpleServer(config *Config) (*simpleServer, error) {
return nil, err return nil, err
} }
common.Must(space.AddApplication(d)) common.Must(space.AddApplication(d))
// disp = d.(dispatcher.Interface) }
if p := policy.PolicyFromSpace(space); p == nil {
p, err := app.CreateAppFromConfig(ctx, &policy.Config{
Level: map[uint32]*policy.Policy{
1: &policy.Policy{
Timeout: &policy.Policy_Timeout{
ConnectionIdle: &policy.Second{
Value: 600,
},
},
},
},
})
if err != nil {
return nil, err
}
common.Must(space.AddApplication(p))
} }
for _, inbound := range config.Inbound { for _, inbound := range config.Inbound {