From 973f3da54fe3582a09afc4849b9a50bfb769519f Mon Sep 17 00:00:00 2001 From: amir-devman Date: Mon, 5 Feb 2024 20:05:20 +0000 Subject: [PATCH] chore(restriction): move config to policies Fixed a panic on worker.go --- app/policy/config.go | 11 ++ app/policy/config.pb.go | 238 +++++++++++++++++--------- app/policy/config.proto | 5 + app/proxyman/inbound/worker.go | 27 ++- common/protocol/user.go | 2 - common/protocol/user.proto | 3 - features/policy/policy.go | 22 ++- infra/conf/common.go | 2 - infra/conf/policy.go | 7 + proxy/dokodemo/dokodemo.go | 3 +- proxy/proxy.go | 3 +- proxy/trojan/server.go | 7 +- proxy/vless/inbound/inbound.go | 31 +--- proxy/vmess/inbound/inbound.go | 7 +- transport/internet/restriction/ip.go | 11 ++ transport/internet/stat/connection.go | 6 - 16 files changed, 245 insertions(+), 140 deletions(-) create mode 100644 transport/internet/restriction/ip.go diff --git a/app/policy/config.go b/app/policy/config.go index 267307b7..836b2324 100644 --- a/app/policy/config.go +++ b/app/policy/config.go @@ -27,6 +27,9 @@ func defaultPolicy() *Policy { Buffer: &Policy_Buffer{ Connection: p.Buffer.PerConnection, }, + Restriction: &Policy_Restriction{ + MaxIPs: p.Restriction.MaxIPs, + }, } } @@ -58,6 +61,11 @@ func (p *Policy) overrideWith(another *Policy) { Connection: another.Buffer.Connection, } } + if another.Restriction != nil { + p.Restriction = &Policy_Restriction{ + MaxIPs: another.Restriction.MaxIPs, + } + } } // ToCorePolicy converts this Policy to policy.Session. @@ -77,6 +85,9 @@ func (p *Policy) ToCorePolicy() policy.Session { if p.Buffer != nil { cp.Buffer.PerConnection = p.Buffer.Connection } + if p.Restriction != nil { + cp.Restriction.MaxIPs = p.Restriction.MaxIPs + } return cp } diff --git a/app/policy/config.pb.go b/app/policy/config.pb.go index c8b4311c..96c3fa0c 100644 --- a/app/policy/config.pb.go +++ b/app/policy/config.pb.go @@ -72,9 +72,10 @@ type Policy struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Timeout *Policy_Timeout `protobuf:"bytes,1,opt,name=timeout,proto3" json:"timeout,omitempty"` - Stats *Policy_Stats `protobuf:"bytes,2,opt,name=stats,proto3" json:"stats,omitempty"` - Buffer *Policy_Buffer `protobuf:"bytes,3,opt,name=buffer,proto3" json:"buffer,omitempty"` + Timeout *Policy_Timeout `protobuf:"bytes,1,opt,name=timeout,proto3" json:"timeout,omitempty"` + Stats *Policy_Stats `protobuf:"bytes,2,opt,name=stats,proto3" json:"stats,omitempty"` + Buffer *Policy_Buffer `protobuf:"bytes,3,opt,name=buffer,proto3" json:"buffer,omitempty"` + Restriction *Policy_Restriction `protobuf:"bytes,4,opt,name=restriction,proto3" json:"restriction,omitempty"` } func (x *Policy) Reset() { @@ -130,6 +131,13 @@ func (x *Policy) GetBuffer() *Policy_Buffer { return nil } +func (x *Policy) GetRestriction() *Policy_Restriction { + if x != nil { + return x.Restriction + } + return nil +} + type SystemPolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -407,6 +415,53 @@ func (x *Policy_Buffer) GetConnection() int32 { return 0 } +type Policy_Restriction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MaxIPs int32 `protobuf:"varint,1,opt,name=maxIPs,proto3" json:"maxIPs,omitempty"` +} + +func (x *Policy_Restriction) Reset() { + *x = Policy_Restriction{} + if protoimpl.UnsafeEnabled { + mi := &file_app_policy_config_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Policy_Restriction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Policy_Restriction) ProtoMessage() {} + +func (x *Policy_Restriction) ProtoReflect() protoreflect.Message { + mi := &file_app_policy_config_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Policy_Restriction.ProtoReflect.Descriptor instead. +func (*Policy_Restriction) Descriptor() ([]byte, []int) { + return file_app_policy_config_proto_rawDescGZIP(), []int{1, 3} +} + +func (x *Policy_Restriction) GetMaxIPs() int32 { + if x != nil { + return x.MaxIPs + } + return 0 +} + type SystemPolicy_Stats struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -421,7 +476,7 @@ type SystemPolicy_Stats struct { func (x *SystemPolicy_Stats) Reset() { *x = SystemPolicy_Stats{} if protoimpl.UnsafeEnabled { - mi := &file_app_policy_config_proto_msgTypes[7] + mi := &file_app_policy_config_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -434,7 +489,7 @@ func (x *SystemPolicy_Stats) String() string { func (*SystemPolicy_Stats) ProtoMessage() {} func (x *SystemPolicy_Stats) ProtoReflect() protoreflect.Message { - mi := &file_app_policy_config_proto_msgTypes[7] + mi := &file_app_policy_config_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -485,7 +540,7 @@ var file_app_policy_config_proto_rawDesc = []byte{ 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x1e, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa6, 0x04, 0x0a, 0x06, 0x50, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x94, 0x05, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x39, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, @@ -496,65 +551,72 @@ var file_app_policy_config_proto_rawDesc = []byte{ 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x06, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x42, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x52, 0x06, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x1a, 0xfa, 0x01, - 0x0a, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x35, 0x0a, 0x09, 0x68, 0x61, 0x6e, - 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x52, 0x09, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, - 0x12, 0x40, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x64, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x6c, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6f, 0x6e, 0x6c, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, - 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, - 0x52, 0x0a, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x3c, 0x0a, 0x0d, - 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x04, 0x20, + 0x75, 0x66, 0x66, 0x65, 0x72, 0x52, 0x06, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x12, 0x45, 0x0a, + 0x0b, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x74, + 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xfa, 0x01, 0x0a, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x12, 0x35, 0x0a, 0x09, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x52, 0x0c, 0x64, 0x6f, - 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4f, 0x6e, 0x6c, 0x79, 0x1a, 0x4d, 0x0a, 0x05, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x75, 0x70, 0x6c, 0x69, - 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x55, 0x70, - 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x64, 0x6f, 0x77, - 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x65, - 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x1a, 0x28, 0x0a, 0x06, 0x42, 0x75, 0x66, - 0x66, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0xfb, 0x01, 0x0a, 0x0c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x1a, - 0xaf, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, - 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e, - 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x27, 0x0a, 0x0f, 0x6f, - 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x55, 0x70, - 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, - 0x6b, 0x22, 0xcc, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x05, - 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x1a, 0x51, 0x0a, - 0x0a, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xaa, - 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x52, 0x09, 0x68, 0x61, + 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x40, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x6c, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x75, 0x70, 0x6c, + 0x69, 0x6e, 0x6b, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x52, 0x0a, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4f, + 0x6e, 0x6c, 0x79, 0x12, 0x3c, 0x0a, 0x0d, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, + 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x52, 0x0c, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4f, 0x6e, 0x6c, + 0x79, 0x1a, 0x4d, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0a, 0x75, 0x73, 0x65, 0x72, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, + 0x1a, 0x28, 0x0a, 0x06, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x25, 0x0a, 0x0b, 0x52, 0x65, + 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x78, + 0x49, 0x50, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x49, 0x50, + 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x0c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x1a, 0xaf, 0x01, + 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x62, 0x6f, 0x75, + 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x29, + 0x0a, 0x10, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, + 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, + 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x75, 0x74, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x55, 0x70, 0x6c, 0x69, + 0x6e, 0x6b, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x64, + 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6f, + 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x22, + 0xcc, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x05, 0x6c, 0x65, + 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x1a, 0x51, 0x0a, 0x0a, 0x4c, + 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x4f, + 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, + 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xaa, 0x02, 0x0f, + 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -569,7 +631,7 @@ func file_app_policy_config_proto_rawDescGZIP() []byte { return file_app_policy_config_proto_rawDescData } -var file_app_policy_config_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_app_policy_config_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_app_policy_config_proto_goTypes = []interface{}{ (*Second)(nil), // 0: xray.app.policy.Second (*Policy)(nil), // 1: xray.app.policy.Policy @@ -578,26 +640,28 @@ var file_app_policy_config_proto_goTypes = []interface{}{ (*Policy_Timeout)(nil), // 4: xray.app.policy.Policy.Timeout (*Policy_Stats)(nil), // 5: xray.app.policy.Policy.Stats (*Policy_Buffer)(nil), // 6: xray.app.policy.Policy.Buffer - (*SystemPolicy_Stats)(nil), // 7: xray.app.policy.SystemPolicy.Stats - nil, // 8: xray.app.policy.Config.LevelEntry + (*Policy_Restriction)(nil), // 7: xray.app.policy.Policy.Restriction + (*SystemPolicy_Stats)(nil), // 8: xray.app.policy.SystemPolicy.Stats + nil, // 9: xray.app.policy.Config.LevelEntry } var file_app_policy_config_proto_depIdxs = []int32{ 4, // 0: xray.app.policy.Policy.timeout:type_name -> xray.app.policy.Policy.Timeout 5, // 1: xray.app.policy.Policy.stats:type_name -> xray.app.policy.Policy.Stats 6, // 2: xray.app.policy.Policy.buffer:type_name -> xray.app.policy.Policy.Buffer - 7, // 3: xray.app.policy.SystemPolicy.stats:type_name -> xray.app.policy.SystemPolicy.Stats - 8, // 4: xray.app.policy.Config.level:type_name -> xray.app.policy.Config.LevelEntry - 2, // 5: xray.app.policy.Config.system:type_name -> xray.app.policy.SystemPolicy - 0, // 6: xray.app.policy.Policy.Timeout.handshake:type_name -> xray.app.policy.Second - 0, // 7: xray.app.policy.Policy.Timeout.connection_idle:type_name -> xray.app.policy.Second - 0, // 8: xray.app.policy.Policy.Timeout.uplink_only:type_name -> xray.app.policy.Second - 0, // 9: xray.app.policy.Policy.Timeout.downlink_only:type_name -> xray.app.policy.Second - 1, // 10: xray.app.policy.Config.LevelEntry.value:type_name -> xray.app.policy.Policy - 11, // [11:11] is the sub-list for method output_type - 11, // [11:11] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 7, // 3: xray.app.policy.Policy.restriction:type_name -> xray.app.policy.Policy.Restriction + 8, // 4: xray.app.policy.SystemPolicy.stats:type_name -> xray.app.policy.SystemPolicy.Stats + 9, // 5: xray.app.policy.Config.level:type_name -> xray.app.policy.Config.LevelEntry + 2, // 6: xray.app.policy.Config.system:type_name -> xray.app.policy.SystemPolicy + 0, // 7: xray.app.policy.Policy.Timeout.handshake:type_name -> xray.app.policy.Second + 0, // 8: xray.app.policy.Policy.Timeout.connection_idle:type_name -> xray.app.policy.Second + 0, // 9: xray.app.policy.Policy.Timeout.uplink_only:type_name -> xray.app.policy.Second + 0, // 10: xray.app.policy.Policy.Timeout.downlink_only:type_name -> xray.app.policy.Second + 1, // 11: xray.app.policy.Config.LevelEntry.value:type_name -> xray.app.policy.Policy + 12, // [12:12] is the sub-list for method output_type + 12, // [12:12] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_app_policy_config_proto_init() } @@ -691,6 +755,18 @@ func file_app_policy_config_proto_init() { } } file_app_policy_config_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Policy_Restriction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_policy_config_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SystemPolicy_Stats); i { case 0: return &v.state @@ -709,7 +785,7 @@ func file_app_policy_config_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_app_policy_config_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 10, NumExtensions: 0, NumServices: 0, }, diff --git a/app/policy/config.proto b/app/policy/config.proto index e5f29547..a0f37f96 100644 --- a/app/policy/config.proto +++ b/app/policy/config.proto @@ -29,9 +29,14 @@ message Policy { int32 connection = 1; } + message Restriction { + int32 maxIPs = 1; + } + Timeout timeout = 1; Stats stats = 2; Buffer buffer = 3; + Restriction restriction = 4; } message SystemPolicy { diff --git a/app/proxyman/inbound/worker.go b/app/proxyman/inbound/worker.go index 18e38d65..199fd4c5 100644 --- a/app/proxyman/inbound/worker.go +++ b/app/proxyman/inbound/worker.go @@ -18,6 +18,7 @@ import ( "github.com/xtls/xray-core/features/stats" "github.com/xtls/xray-core/proxy" "github.com/xtls/xray-core/transport/internet" + "github.com/xtls/xray-core/transport/internet/restriction" "github.com/xtls/xray-core/transport/internet/stat" "github.com/xtls/xray-core/transport/internet/tcp" "github.com/xtls/xray-core/transport/internet/udp" @@ -32,6 +33,8 @@ type worker interface { } type tcpWorker struct { + sync.Mutex + address net.Address port net.Port proxy proxy.Inbound @@ -42,7 +45,7 @@ type tcpWorker struct { sniffingConfig *proxyman.SniffingConfig uplinkCounter stats.Counter downlinkCounter stats.Counter - ipLimitPool map[session.ID]*stat.UserIpRestriction + ipLimitPool map[session.ID]*restriction.UserMaxIp hub internet.Listener @@ -106,16 +109,20 @@ func (w *tcpWorker) callback(conn stat.Connection) { ctx = session.ContextWithContent(ctx, content) // Add this IP address to the pool for futher IP limit check - w.ipLimitPool[sid] = &stat.UserIpRestriction{ + w.Lock() + w.ipLimitPool[sid] = &restriction.UserMaxIp{ IpAddress: net.IP(conn.RemoteAddr().Network()), } + w.Unlock() if err := w.proxy.Process(ctx, net.Network_TCP, conn, w.dispatcher, &w.ipLimitPool, w.ipLimitPool[sid]); err != nil { newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx)) } - + // Deletes the IP address from the pool after the connection ends + w.Lock() delete(w.ipLimitPool, sid) + w.Unlock() cancel() conn.Close() @@ -127,7 +134,7 @@ func (w *tcpWorker) Proxy() proxy.Inbound { func (w *tcpWorker) Start() error { if len(w.ipLimitPool) == 0 { - w.ipLimitPool = make(map[session.ID]*stat.UserIpRestriction) + w.ipLimitPool = make(map[session.ID]*restriction.UserMaxIp) } ctx := context.Background() hub, err := internet.ListenTCP(ctx, w.address, w.port, w.stream, func(conn stat.Connection) { @@ -257,7 +264,7 @@ type udpWorker struct { sniffingConfig *proxyman.SniffingConfig uplinkCounter stats.Counter downlinkCounter stats.Counter - ipLimitPool map[session.ID]*stat.UserIpRestriction + ipLimitPool map[session.ID]*restriction.UserMaxIp checker *task.Periodic activeConn map[connID]*udpConn @@ -342,16 +349,20 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest ctx = session.ContextWithContent(ctx, content) // Add this IP address to the pool for futher IP limit check - w.ipLimitPool[sid] = &stat.UserIpRestriction{ + w.Lock() + w.ipLimitPool[sid] = &restriction.UserMaxIp{ IpAddress: net.IP(conn.RemoteAddr().Network()), } - + w.Unlock() + if err := w.proxy.Process(ctx, net.Network_UDP, conn, w.dispatcher, &w.ipLimitPool, w.ipLimitPool[sid]); err != nil { newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx)) } // Deletes the IP address from the pool after the connection ends + w.Lock() delete(w.ipLimitPool, sid) + w.Unlock() conn.Close() // conn not removed by checker TODO may be lock worker here is better @@ -404,7 +415,7 @@ func (w *udpWorker) clean() error { func (w *udpWorker) Start() error { if len(w.ipLimitPool) == 0 { - w.ipLimitPool = make(map[session.ID]*stat.UserIpRestriction) + w.ipLimitPool = make(map[session.ID]*restriction.UserMaxIp) } w.activeConn = make(map[connID]*udpConn, 16) ctx := context.Background() diff --git a/common/protocol/user.go b/common/protocol/user.go index 9006a4a0..8325f555 100644 --- a/common/protocol/user.go +++ b/common/protocol/user.go @@ -27,7 +27,6 @@ func (u *User) ToMemoryUser() (*MemoryUser, error) { Account: account, Email: u.Email, Level: u.Level, - IpLimit: u.Ips, }, nil } @@ -37,5 +36,4 @@ type MemoryUser struct { Account Account Email string Level uint32 - IpLimit uint32 } diff --git a/common/protocol/user.proto b/common/protocol/user.proto index 3632eeaa..44770edf 100644 --- a/common/protocol/user.proto +++ b/common/protocol/user.proto @@ -16,7 +16,4 @@ message User { // Protocol specific account information. Must be the account proto in one of // the proxies. xray.common.serial.TypedMessage account = 3; - - // Allowed IPs - uint32 ips = 4; } diff --git a/features/policy/policy.go b/features/policy/policy.go index 4d3f7ecf..b71e76c3 100644 --- a/features/policy/policy.go +++ b/features/policy/policy.go @@ -35,6 +35,12 @@ type Buffer struct { PerConnection int32 } +// Buffer contains settings for restriction such as ip restriction. +type Restriction struct { + // Maximum allowed ips, -1 for unlimited + MaxIPs int32 +} + // SystemStats contains stat policy settings on system level. type SystemStats struct { // Whether or not to enable stat counter for uplink traffic in inbound handlers. @@ -55,9 +61,10 @@ type System struct { // Session is session based settings for controlling Xray requests. It contains various settings (or limits) that may differ for different users in the context. type Session struct { - Timeouts Timeout // Timeout settings - Stats Stats - Buffer Buffer + Timeouts Timeout // Timeout settings + Stats Stats + Buffer Buffer + Restriction Restriction } // Manager is a feature that provides Policy for the given user by its id or level. @@ -109,6 +116,12 @@ func defaultBufferPolicy() Buffer { } } +func defaultRestrictionPolicy() Restriction { + return Restriction{ + MaxIPs: -1, + } +} + // SessionDefault returns the Policy when user is not specified. func SessionDefault() Session { return Session{ @@ -124,7 +137,8 @@ func SessionDefault() Session { UserUplink: false, UserDownlink: false, }, - Buffer: defaultBufferPolicy(), + Buffer: defaultBufferPolicy(), + Restriction: defaultRestrictionPolicy(), } } diff --git a/infra/conf/common.go b/infra/conf/common.go index 62876441..e755b70f 100644 --- a/infra/conf/common.go +++ b/infra/conf/common.go @@ -233,13 +233,11 @@ func (list *PortList) UnmarshalJSON(data []byte) error { type User struct { EmailString string `json:"email"` LevelByte byte `json:"level"` - IpLimitByte byte `json:"ips"` } func (v *User) Build() *protocol.User { return &protocol.User{ Email: v.EmailString, Level: uint32(v.LevelByte), - Ips: uint32(v.IpLimitByte), } } diff --git a/infra/conf/policy.go b/infra/conf/policy.go index 5fbf01e6..74809401 100644 --- a/infra/conf/policy.go +++ b/infra/conf/policy.go @@ -12,6 +12,7 @@ type Policy struct { StatsUserUplink bool `json:"statsUserUplink"` StatsUserDownlink bool `json:"statsUserDownlink"` BufferSize *int32 `json:"bufferSize"` + MaxIPs *int32 `json:"maxIPs"` } func (t *Policy) Build() (*policy.Policy, error) { @@ -47,6 +48,12 @@ func (t *Policy) Build() (*policy.Policy, error) { } } + if t.MaxIPs != nil { + p.Restriction = &policy.Policy_Restriction{ + MaxIPs: (*t.MaxIPs), + } + } + return p, nil } diff --git a/proxy/dokodemo/dokodemo.go b/proxy/dokodemo/dokodemo.go index 144748b5..8b882367 100644 --- a/proxy/dokodemo/dokodemo.go +++ b/proxy/dokodemo/dokodemo.go @@ -18,6 +18,7 @@ import ( "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/policy" "github.com/xtls/xray-core/features/routing" + "github.com/xtls/xray-core/transport/internet/restriction" "github.com/xtls/xray-core/transport/internet/stat" ) @@ -76,7 +77,7 @@ type hasHandshakeAddress interface { } // Process implements proxy.Inbound. -func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher, _ *map[session.ID]*stat.UserIpRestriction, _ *stat.UserIpRestriction) error { +func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher, _ *map[session.ID]*restriction.UserMaxIp, _ *restriction.UserMaxIp) error { newError("processing connection from: ", conn.RemoteAddr()).AtDebug().WriteToLog(session.ExportIDToError(ctx)) dest := net.Destination{ Network: network, diff --git a/proxy/proxy.go b/proxy/proxy.go index 3cc86d7e..4f493588 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -26,6 +26,7 @@ import ( "github.com/xtls/xray-core/transport" "github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet/reality" + "github.com/xtls/xray-core/transport/internet/restriction" "github.com/xtls/xray-core/transport/internet/stat" "github.com/xtls/xray-core/transport/internet/tls" ) @@ -60,7 +61,7 @@ type Inbound interface { Network() []net.Network // Process processes a connection of given network. If necessary, the Inbound can dispatch the connection to an Outbound. - Process(context.Context, net.Network, stat.Connection, routing.Dispatcher, *map[session.ID]*stat.UserIpRestriction, *stat.UserIpRestriction) error + Process(context.Context, net.Network, stat.Connection, routing.Dispatcher, *map[session.ID]*restriction.UserMaxIp, *restriction.UserMaxIp) error } // An Outbound process outbound connections. diff --git a/proxy/trojan/server.go b/proxy/trojan/server.go index 9244774f..244153cb 100644 --- a/proxy/trojan/server.go +++ b/proxy/trojan/server.go @@ -23,6 +23,7 @@ import ( "github.com/xtls/xray-core/features/policy" "github.com/xtls/xray-core/features/routing" "github.com/xtls/xray-core/transport/internet/reality" + "github.com/xtls/xray-core/transport/internet/restriction" "github.com/xtls/xray-core/transport/internet/stat" "github.com/xtls/xray-core/transport/internet/tls" "github.com/xtls/xray-core/transport/internet/udp" @@ -134,7 +135,7 @@ func (s *Server) Network() []net.Network { } // Process implements proxy.Inbound.Process(). -func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher, usrIpRstrct *map[session.ID]*stat.UserIpRestriction, connIp *stat.UserIpRestriction) error { +func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher, usrIpRstrct *map[session.ID]*restriction.UserMaxIp, connIp *restriction.UserMaxIp) error { sid := session.ExportIDToError(ctx) iConn := conn @@ -222,7 +223,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con inbound.User = user sessionPolicy = s.policyManager.ForLevel(user.Level) - if (user.IpLimit > 0) { + if sessionPolicy.Restriction.MaxIPs > 0 { addr := conn.RemoteAddr().(*net.TCPAddr) uniqueIps := make(map[string]bool) @@ -236,7 +237,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con } s.Unlock() - if (len(uniqueIps) >= int(user.IpLimit)) { + if len(uniqueIps) >= int(sessionPolicy.Restriction.MaxIPs) { return newError("User ", user, " has exceeded their allowed IPs.").AtWarning() } diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index 809276f4..597ecaed 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -33,6 +33,7 @@ import ( "github.com/xtls/xray-core/proxy/vless" "github.com/xtls/xray-core/proxy/vless/encoding" "github.com/xtls/xray-core/transport/internet/reality" + "github.com/xtls/xray-core/transport/internet/restriction" "github.com/xtls/xray-core/transport/internet/stat" "github.com/xtls/xray-core/transport/internet/tls" ) @@ -179,7 +180,7 @@ func (*Handler) Network() []net.Network { } // Process implements proxy.Inbound.Process(). -func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher, usrIpRstrct *map[session.ID]*stat.UserIpRestriction, connIp *stat.UserIpRestriction) error { +func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher, usrIpRstrct *map[session.ID]*restriction.UserMaxIp, connIp *restriction.UserMaxIp) error { sid := session.ExportIDToError(ctx) iConn := connection @@ -187,6 +188,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s iConn = statConn.Connection } + 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() @@ -447,7 +449,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s // Flow: requestAddons.Flow, } - if (request.User.IpLimit > 0) { + if sessionPolicy.Restriction.MaxIPs > 0 { addr := connection.RemoteAddr().(*net.TCPAddr) uniqueIps := make(map[string]bool) @@ -461,30 +463,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s } h.Unlock() - if (len(uniqueIps) >= int(request.User.IpLimit)) { - return newError("User ", request.User.Email, " has exceeded their allowed IPs.").AtWarning() - } - - connIp.IpAddress = addr.IP - connIp.User = request.User.Email - connIp.Time = time.Now().Unix() - } - - if (request.User.IpLimit > 0) { - addr := connection.RemoteAddr().(*net.TCPAddr) - - uniqueIps := make(map[string]bool) - - h.Lock() - // Iterate through the connections and find unique used IP addresses withing last 30 seconds. - for _, conn := range *usrIpRstrct { - if conn.User == request.User.Email && !conn.IpAddress.Equal(addr.IP) && ((time.Now().Unix() - conn.Time) < 30) { - uniqueIps[conn.IpAddress.String()] = true - } - } - h.Unlock() - - if (len(uniqueIps) >= int(request.User.IpLimit)) { + if len(uniqueIps) >= int(sessionPolicy.Restriction.MaxIPs) { return newError("User ", request.User.Email, " has exceeded their allowed IPs.").AtWarning() } diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index a13c299b..f6c3bfdd 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -25,6 +25,7 @@ import ( "github.com/xtls/xray-core/features/routing" "github.com/xtls/xray-core/proxy/vmess" "github.com/xtls/xray-core/proxy/vmess/encoding" + "github.com/xtls/xray-core/transport/internet/restriction" "github.com/xtls/xray-core/transport/internet/stat" ) @@ -210,7 +211,7 @@ func transferResponse(timer signal.ActivityUpdater, session *encoding.ServerSess } // Process implements proxy.Inbound.Process(). -func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher, usrIpRstrct *map[session.ID]*stat.UserIpRestriction, connIp *stat.UserIpRestriction) error { +func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher, usrIpRstrct *map[session.ID]*restriction.UserMaxIp, connIp *restriction.UserMaxIp) 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() @@ -264,7 +265,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s sessionPolicy = h.policyManager.ForLevel(request.User.Level) - if (request.User.IpLimit > 0) { + if sessionPolicy.Restriction.MaxIPs > 0 { addr := connection.RemoteAddr().(*net.TCPAddr) uniqueIps := make(map[string]bool) @@ -277,7 +278,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s } h.Unlock() - if (len(uniqueIps) >= int(request.User.IpLimit)) { + if len(uniqueIps) >= int(sessionPolicy.Restriction.MaxIPs) { return newError("User ", request.User.Email, " has exceeded their allowed IPs.").AtWarning() } diff --git a/transport/internet/restriction/ip.go b/transport/internet/restriction/ip.go new file mode 100644 index 00000000..05ff2fa3 --- /dev/null +++ b/transport/internet/restriction/ip.go @@ -0,0 +1,11 @@ +package restriction + +import ( + "net" +) + +type UserMaxIp struct { + User string + IpAddress net.IP + Time int64 +} diff --git a/transport/internet/stat/connection.go b/transport/internet/stat/connection.go index 4a3fd681..6921943d 100644 --- a/transport/internet/stat/connection.go +++ b/transport/internet/stat/connection.go @@ -6,12 +6,6 @@ import ( "github.com/xtls/xray-core/features/stats" ) -type UserIpRestriction struct { - User string - IpAddress net.IP - Time int64 -} - type Connection interface { net.Conn }