From 95583b5031376b17055290912155e3c6a55d0d93 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Sun, 24 Feb 2019 23:43:00 +0100 Subject: [PATCH] support range list in routing rule --- app/router/condition.go | 6 +- app/router/condition_test.go | 28 ++++++++ app/router/config.go | 7 +- app/router/config.pb.go | 131 +++++++++++++++++++---------------- app/router/config.proto | 9 ++- common/net/port.go | 28 ++++++++ common/net/port.pb.go | 53 ++++++++++++-- common/net/port.proto | 5 ++ infra/conf/common.go | 60 +++++++++++++--- infra/conf/router.go | 4 +- infra/conf/router_test.go | 17 +++++ 11 files changed, 267 insertions(+), 81 deletions(-) diff --git a/app/router/condition.go b/app/router/condition.go index ec8f5bb8..7ff0db27 100644 --- a/app/router/condition.go +++ b/app/router/condition.go @@ -177,12 +177,12 @@ func (m *MultiGeoIPMatcher) Apply(ctx context.Context) bool { } type PortMatcher struct { - port net.PortRange + port net.MemoryPortList } -func NewPortMatcher(portRange net.PortRange) *PortMatcher { +func NewPortMatcher(list *net.PortList) *PortMatcher { return &PortMatcher{ - port: portRange, + port: net.PortListFromProto(list), } } diff --git a/app/router/condition_test.go b/app/router/condition_test.go index 796f4a14..bb193e00 100644 --- a/app/router/condition_test.go +++ b/app/router/condition_test.go @@ -237,6 +237,34 @@ func TestRoutingRule(t *testing.T) { }, }, }, + { + rule: &RoutingRule{ + PortList: &net.PortList{ + Range: []*net.PortRange{ + {From: 443, To: 443}, + {From: 1000, To: 1100}, + }, + }, + }, + test: []ruleTest{ + { + input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 443)}), + output: true, + }, + { + input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 1100)}), + output: true, + }, + { + input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 1005)}), + output: true, + }, + { + input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 53)}), + output: false, + }, + }, + }, } for _, test := range cases { diff --git a/app/router/config.go b/app/router/config.go index 46363cce..7cb163a8 100644 --- a/app/router/config.go +++ b/app/router/config.go @@ -5,6 +5,7 @@ package router import ( "context" + net "v2ray.com/core/common/net" "v2ray.com/core/features/outbound" ) @@ -83,8 +84,10 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) { conds.Add(NewInboundTagMatcher(rr.InboundTag)) } - if rr.PortRange != nil { - conds.Add(NewPortMatcher(*rr.PortRange)) + if rr.PortList != nil { + conds.Add(NewPortMatcher(rr.PortList)) + } else if rr.PortRange != nil { + conds.Add(NewPortMatcher(&net.PortList{Range: []*net.PortRange{rr.PortRange}})) } if len(rr.Networks) > 0 { diff --git a/app/router/config.pb.go b/app/router/config.pb.go index 1d72d3b7..20850d23 100644 --- a/app/router/config.pb.go +++ b/app/router/config.pb.go @@ -466,13 +466,17 @@ type RoutingRule struct { // List of domains for target domain matching. Domain []*Domain `protobuf:"bytes,2,rep,name=domain,proto3" json:"domain,omitempty"` // List of CIDRs for target IP address matching. - // The list must be sorted beforehand. + // Deprecated. Use geoip below. Cidr []*CIDR `protobuf:"bytes,3,rep,name=cidr,proto3" json:"cidr,omitempty"` // Deprecated: Do not use. // List of GeoIPs for target IP address matching. If this entry exists, the cidr above will have no effect. // GeoIP fields with the same country code are supposed to contain exactly same content. They will be merged during runtime. // For customized GeoIPs, please leave country code empty. - Geoip []*GeoIP `protobuf:"bytes,10,rep,name=geoip,proto3" json:"geoip,omitempty"` - PortRange *net.PortRange `protobuf:"bytes,4,opt,name=port_range,json=portRange,proto3" json:"port_range,omitempty"` + Geoip []*GeoIP `protobuf:"bytes,10,rep,name=geoip,proto3" json:"geoip,omitempty"` + // A range of port [from, to]. If the destination port is in this range, this rule takes effect. + // Deprecated. Use port_list. + PortRange *net.PortRange `protobuf:"bytes,4,opt,name=port_range,json=portRange,proto3" json:"port_range,omitempty"` // Deprecated: Do not use. + // List of ports. + PortList *net.PortList `protobuf:"bytes,14,opt,name=port_list,json=portList,proto3" json:"port_list,omitempty"` // List of networks. Deprecated. Use networks. NetworkList *net.NetworkList `protobuf:"bytes,5,opt,name=network_list,json=networkList,proto3" json:"network_list,omitempty"` // Deprecated: Do not use. // List of networks for matching. @@ -573,6 +577,7 @@ func (m *RoutingRule) GetGeoip() []*GeoIP { return nil } +// Deprecated: Do not use. func (m *RoutingRule) GetPortRange() *net.PortRange { if m != nil { return m.PortRange @@ -580,6 +585,13 @@ func (m *RoutingRule) GetPortRange() *net.PortRange { return nil } +func (m *RoutingRule) GetPortList() *net.PortList { + if m != nil { + return m.PortList + } + return nil +} + // Deprecated: Do not use. func (m *RoutingRule) GetNetworkList() *net.NetworkList { if m != nil { @@ -761,61 +773,62 @@ func init() { } var fileDescriptor_6b1608360690c5fc = []byte{ - // 881 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xef, 0x6e, 0x1b, 0x45, - 0x10, 0xcf, 0xdd, 0xd9, 0xae, 0x6f, 0xce, 0x31, 0xc7, 0x8a, 0xa2, 0x23, 0x10, 0x6a, 0x4e, 0x85, - 0x5a, 0x02, 0x9d, 0x25, 0x17, 0xf8, 0x80, 0x84, 0x42, 0xe2, 0x94, 0xc4, 0x02, 0x42, 0xb4, 0x69, - 0xfb, 0x01, 0x3e, 0x58, 0xe7, 0xf3, 0xe6, 0x58, 0xf5, 0xbc, 0xbb, 0xda, 0xdb, 0x2b, 0xf5, 0xc3, - 0xf0, 0x02, 0x48, 0x3c, 0x03, 0xaf, 0x86, 0xf6, 0x8f, 0xe3, 0x18, 0xea, 0x12, 0xf5, 0xdb, 0xee, - 0xcc, 0x6f, 0x66, 0x7f, 0xfb, 0x9b, 0x99, 0x5d, 0xf8, 0xec, 0xe5, 0x58, 0xe6, 0xab, 0xac, 0xe0, - 0xcb, 0x51, 0xc1, 0x25, 0x19, 0xe5, 0x42, 0x8c, 0x24, 0x6f, 0x14, 0x91, 0xa3, 0x82, 0xb3, 0x6b, - 0x5a, 0x66, 0x42, 0x72, 0xc5, 0xd1, 0xfd, 0x35, 0x4e, 0x92, 0x2c, 0x17, 0x22, 0xb3, 0x98, 0x83, - 0x87, 0xff, 0x0a, 0x2f, 0xf8, 0x72, 0xc9, 0xd9, 0x88, 0x11, 0x35, 0x12, 0x5c, 0x2a, 0x1b, 0x7c, - 0xf0, 0x68, 0x37, 0x8a, 0x11, 0xf5, 0x3b, 0x97, 0x2f, 0x2c, 0x30, 0xfd, 0xdb, 0x87, 0xce, 0x29, - 0x5f, 0xe6, 0x94, 0xa1, 0xaf, 0xa1, 0xa5, 0x56, 0x82, 0x24, 0xde, 0xc0, 0x1b, 0xf6, 0xc7, 0x69, - 0xf6, 0xda, 0xf3, 0x33, 0x0b, 0xce, 0x9e, 0xae, 0x04, 0xc1, 0x06, 0x8f, 0xde, 0x83, 0xf6, 0xcb, - 0xbc, 0x6a, 0x48, 0xe2, 0x0f, 0xbc, 0x61, 0x88, 0xed, 0x06, 0x3d, 0x81, 0x30, 0x57, 0x4a, 0xd2, - 0x79, 0xa3, 0x48, 0x12, 0x0c, 0x82, 0x61, 0x34, 0x7e, 0xf4, 0xe6, 0x94, 0xc7, 0x6b, 0x38, 0xde, - 0x44, 0x1e, 0x54, 0x10, 0xde, 0xd8, 0x51, 0x0c, 0xc1, 0x0b, 0xb2, 0x32, 0x04, 0x43, 0xac, 0x97, - 0xe8, 0x01, 0xc0, 0x9c, 0xf3, 0x6a, 0xb6, 0x21, 0xd0, 0x3d, 0xdf, 0xc3, 0xa1, 0xb6, 0x3d, 0x37, - 0x34, 0x0e, 0x21, 0xa4, 0x4c, 0x39, 0x7f, 0x30, 0xf0, 0x86, 0xc1, 0xf9, 0x1e, 0xee, 0x52, 0xa6, - 0x8c, 0xfb, 0x64, 0x1f, 0x22, 0x7d, 0x87, 0x85, 0x05, 0xa4, 0x63, 0x68, 0xe9, 0x8b, 0xa1, 0x10, - 0xda, 0x97, 0x55, 0x4e, 0x59, 0xbc, 0xa7, 0x97, 0x98, 0x94, 0xe4, 0x55, 0xec, 0x21, 0x58, 0x4b, - 0x15, 0xfb, 0xa8, 0x0b, 0xad, 0xef, 0x9b, 0xaa, 0x8a, 0x83, 0x34, 0x83, 0xd6, 0x64, 0x7a, 0x8a, - 0x51, 0x1f, 0x7c, 0x2a, 0x0c, 0xb7, 0x1e, 0xf6, 0xa9, 0x40, 0xef, 0x43, 0x47, 0x48, 0x72, 0x4d, - 0x5f, 0x19, 0x5a, 0xfb, 0xd8, 0xed, 0xd2, 0x5f, 0xa1, 0x7d, 0x46, 0xf8, 0xf4, 0x12, 0x7d, 0x02, - 0xbd, 0x82, 0x37, 0x4c, 0xc9, 0xd5, 0xac, 0xe0, 0x0b, 0xe2, 0xae, 0x15, 0x39, 0xdb, 0x84, 0x2f, - 0x08, 0x1a, 0x41, 0xab, 0xa0, 0x0b, 0x99, 0xf8, 0x46, 0xbf, 0x0f, 0x77, 0xe8, 0xa7, 0x8f, 0xc7, - 0x06, 0x98, 0x1e, 0x41, 0x68, 0x92, 0xff, 0x48, 0x6b, 0x85, 0xc6, 0xd0, 0x26, 0x3a, 0x55, 0xe2, - 0x99, 0xf0, 0x8f, 0x76, 0x84, 0x9b, 0x00, 0x6c, 0xa1, 0x69, 0x01, 0xf7, 0xce, 0x08, 0xbf, 0xa2, - 0x8a, 0xdc, 0x85, 0xdf, 0x57, 0xd0, 0x59, 0x18, 0x45, 0x1c, 0xc3, 0xc3, 0x37, 0x56, 0x18, 0x3b, - 0x70, 0x3a, 0x81, 0xc8, 0x1d, 0x62, 0x78, 0x7e, 0xb9, 0xcd, 0xf3, 0xe3, 0xdd, 0x3c, 0x75, 0xc8, - 0x9a, 0xe9, 0x1f, 0x6d, 0x88, 0x30, 0x6f, 0x14, 0x65, 0x25, 0x6e, 0x2a, 0x82, 0x10, 0x04, 0x2a, - 0x2f, 0x2d, 0xcb, 0xf3, 0x3d, 0xac, 0x37, 0xe8, 0x53, 0xd8, 0x9f, 0xe7, 0x55, 0xce, 0x0a, 0xca, - 0xca, 0x99, 0xf6, 0xf6, 0x9c, 0xb7, 0x77, 0x63, 0x7e, 0x9a, 0x97, 0x6f, 0x79, 0x0d, 0xf4, 0xd8, - 0x55, 0x27, 0xf8, 0xdf, 0xea, 0x9c, 0xf8, 0x89, 0x67, 0x2b, 0xa4, 0x8b, 0x52, 0x12, 0x4e, 0x45, - 0x02, 0x77, 0x29, 0x8a, 0x81, 0xa2, 0x23, 0x00, 0x3d, 0xdb, 0x33, 0x99, 0xb3, 0x92, 0x24, 0xad, - 0x81, 0x37, 0x8c, 0xc6, 0x83, 0xdb, 0x81, 0x76, 0xbc, 0x33, 0x46, 0x54, 0x76, 0xc9, 0xa5, 0xc2, - 0x1a, 0x87, 0x43, 0xb1, 0x5e, 0xa2, 0x29, 0xf4, 0xdc, 0xd8, 0xcf, 0x2a, 0x5a, 0xab, 0xa4, 0x6d, - 0x52, 0xa4, 0x3b, 0x52, 0x5c, 0x58, 0xa8, 0xae, 0x8d, 0x21, 0x1e, 0xb1, 0x8d, 0x01, 0x7d, 0x03, - 0x5d, 0xb7, 0xad, 0x93, 0xfd, 0x41, 0x30, 0xec, 0x6f, 0xd7, 0xeb, 0xbf, 0x69, 0xf0, 0x0d, 0x1e, - 0x7d, 0x07, 0x51, 0xcd, 0x1b, 0x59, 0x90, 0x99, 0xd1, 0xad, 0x73, 0x37, 0xdd, 0xc0, 0xc6, 0x4c, - 0xb4, 0x7a, 0x47, 0xd0, 0x73, 0x19, 0xac, 0x88, 0xd1, 0x1d, 0x44, 0x74, 0x67, 0x9e, 0x19, 0x29, - 0x0f, 0x01, 0x9a, 0x9a, 0xc8, 0x19, 0x59, 0xe6, 0xb4, 0x4a, 0xee, 0x0d, 0x82, 0x61, 0x88, 0x43, - 0x6d, 0x79, 0xa2, 0x0d, 0xe8, 0x01, 0x44, 0x94, 0xcd, 0x79, 0xc3, 0x16, 0xa6, 0x5d, 0xba, 0xc6, - 0x0f, 0xce, 0xa4, 0x5b, 0xe5, 0x00, 0xba, 0xe6, 0xe1, 0x2c, 0x78, 0x95, 0x84, 0xc6, 0x7b, 0xb3, - 0x3f, 0xe9, 0x01, 0xa8, 0x5c, 0x96, 0x44, 0xe9, 0xd8, 0xf4, 0x02, 0xf6, 0x4f, 0xd6, 0x4d, 0x66, - 0x1a, 0x34, 0xbe, 0xd5, 0xa0, 0xb6, 0x3d, 0x3f, 0x87, 0x77, 0x79, 0xa3, 0xec, 0x71, 0x35, 0xa9, - 0x48, 0xa1, 0xb8, 0x9d, 0xf5, 0x10, 0xc7, 0x6b, 0xc7, 0x95, 0xb3, 0xa7, 0x7f, 0xf9, 0xd0, 0x99, - 0x98, 0x0f, 0x02, 0x3d, 0x83, 0x77, 0x6c, 0x0b, 0xce, 0x6a, 0x25, 0x73, 0x45, 0xca, 0x95, 0x7b, - 0xb4, 0xbf, 0xd8, 0xa5, 0xa5, 0xfd, 0x58, 0x6c, 0xff, 0x5e, 0xb9, 0x18, 0xdc, 0x5f, 0x6c, 0xed, - 0xf5, 0x07, 0x20, 0x9b, 0x8a, 0xb8, 0x21, 0xd8, 0xf5, 0x01, 0xdc, 0x9a, 0x39, 0x6c, 0xf0, 0xe8, - 0x07, 0xe8, 0x6f, 0xa6, 0xcc, 0x64, 0xb0, 0x13, 0xf1, 0x70, 0x47, 0x86, 0x2d, 0x59, 0xf0, 0x66, - 0x42, 0xf5, 0x36, 0x3d, 0x83, 0xfe, 0x36, 0x4d, 0xfd, 0xd4, 0x1e, 0xd7, 0xd3, 0xda, 0xbe, 0xc5, - 0xcf, 0x6a, 0x32, 0x15, 0xb1, 0x87, 0x62, 0xe8, 0x4d, 0xc5, 0xf4, 0xfa, 0x82, 0xb3, 0x9f, 0x72, - 0x55, 0xfc, 0x16, 0xfb, 0xa8, 0x0f, 0x30, 0x15, 0x3f, 0xb3, 0x53, 0xb2, 0xcc, 0xd9, 0x22, 0x0e, - 0x4e, 0xbe, 0x85, 0x0f, 0x0a, 0xbe, 0x7c, 0x3d, 0x85, 0x4b, 0xef, 0x97, 0x8e, 0x5d, 0xfd, 0xe9, - 0xdf, 0x7f, 0x3e, 0xc6, 0xf9, 0x2a, 0x9b, 0x68, 0xc4, 0xb1, 0x10, 0xe6, 0x7e, 0x44, 0xce, 0x3b, - 0xa6, 0xac, 0x8f, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x8e, 0x85, 0x22, 0xaf, 0x07, 0x00, + // 897 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x6e, 0xe3, 0x44, + 0x14, 0xae, 0xed, 0x24, 0x1b, 0x1f, 0x27, 0xc1, 0x8c, 0x58, 0x64, 0x0a, 0xa5, 0xc1, 0x5a, 0xd8, + 0x48, 0x20, 0x47, 0xca, 0x02, 0x17, 0x08, 0xb4, 0x34, 0xe9, 0xd2, 0x46, 0x40, 0xa9, 0xa6, 0xbb, + 0x7b, 0x01, 0x17, 0x91, 0xe3, 0x4c, 0x8d, 0xb5, 0xce, 0xcc, 0x68, 0x3c, 0x5e, 0x36, 0xaf, 0x84, + 0xc4, 0x33, 0xf0, 0x28, 0xbc, 0x0a, 0x9a, 0x9f, 0x34, 0x0d, 0x34, 0x25, 0xe2, 0x6e, 0xce, 0x39, + 0xdf, 0x39, 0xf3, 0xcd, 0xf9, 0x1b, 0xf8, 0xe4, 0xf5, 0x48, 0xa4, 0xab, 0x24, 0x63, 0xcb, 0x61, + 0xc6, 0x04, 0x19, 0xa6, 0x9c, 0x0f, 0x05, 0xab, 0x25, 0x11, 0xc3, 0x8c, 0xd1, 0xeb, 0x22, 0x4f, + 0xb8, 0x60, 0x92, 0xa1, 0x87, 0x6b, 0x9c, 0x20, 0x49, 0xca, 0x79, 0x62, 0x30, 0x87, 0x8f, 0xfe, + 0xe1, 0x9e, 0xb1, 0xe5, 0x92, 0xd1, 0x21, 0x25, 0x72, 0xc8, 0x99, 0x90, 0xc6, 0xf9, 0xf0, 0xf1, + 0x6e, 0x14, 0x25, 0xf2, 0x37, 0x26, 0x5e, 0x19, 0x60, 0xfc, 0xa7, 0x0b, 0xad, 0x53, 0xb6, 0x4c, + 0x0b, 0x8a, 0xbe, 0x84, 0x86, 0x5c, 0x71, 0x12, 0x39, 0x7d, 0x67, 0xd0, 0x1b, 0xc5, 0xc9, 0x9d, + 0xf7, 0x27, 0x06, 0x9c, 0x3c, 0x5f, 0x71, 0x82, 0x35, 0x1e, 0xbd, 0x03, 0xcd, 0xd7, 0x69, 0x59, + 0x93, 0xc8, 0xed, 0x3b, 0x03, 0x1f, 0x1b, 0x01, 0x3d, 0x03, 0x3f, 0x95, 0x52, 0x14, 0xf3, 0x5a, + 0x92, 0xc8, 0xeb, 0x7b, 0x83, 0x60, 0xf4, 0xf8, 0xfe, 0x90, 0x27, 0x6b, 0x38, 0xde, 0x78, 0x1e, + 0x96, 0xe0, 0xdf, 0xe8, 0x51, 0x08, 0xde, 0x2b, 0xb2, 0xd2, 0x04, 0x7d, 0xac, 0x8e, 0xe8, 0x18, + 0x60, 0xce, 0x58, 0x39, 0xdb, 0x10, 0x68, 0x9f, 0x1f, 0x60, 0x5f, 0xe9, 0x5e, 0x6a, 0x1a, 0x47, + 0xe0, 0x17, 0x54, 0x5a, 0xbb, 0xd7, 0x77, 0x06, 0xde, 0xf9, 0x01, 0x6e, 0x17, 0x54, 0x6a, 0xf3, + 0xb8, 0x0b, 0x81, 0x7a, 0xc3, 0xc2, 0x00, 0xe2, 0x11, 0x34, 0xd4, 0xc3, 0x90, 0x0f, 0xcd, 0xcb, + 0x32, 0x2d, 0x68, 0x78, 0xa0, 0x8e, 0x98, 0xe4, 0xe4, 0x4d, 0xe8, 0x20, 0x58, 0xa7, 0x2a, 0x74, + 0x51, 0x1b, 0x1a, 0xdf, 0xd5, 0x65, 0x19, 0x7a, 0x71, 0x02, 0x8d, 0xc9, 0xf4, 0x14, 0xa3, 0x1e, + 0xb8, 0x05, 0xd7, 0xdc, 0x3a, 0xd8, 0x2d, 0x38, 0x7a, 0x17, 0x5a, 0x5c, 0x90, 0xeb, 0xe2, 0x8d, + 0xa6, 0xd5, 0xc5, 0x56, 0x8a, 0x7f, 0x81, 0xe6, 0x19, 0x61, 0xd3, 0x4b, 0xf4, 0x11, 0x74, 0x32, + 0x56, 0x53, 0x29, 0x56, 0xb3, 0x8c, 0x2d, 0x88, 0x7d, 0x56, 0x60, 0x75, 0x13, 0xb6, 0x20, 0x68, + 0x08, 0x8d, 0xac, 0x58, 0x88, 0xc8, 0xd5, 0xf9, 0x7b, 0x7f, 0x47, 0xfe, 0xd4, 0xf5, 0x58, 0x03, + 0xe3, 0xa7, 0xe0, 0xeb, 0xe0, 0x3f, 0x14, 0x95, 0x44, 0x23, 0x68, 0x12, 0x15, 0x2a, 0x72, 0xb4, + 0xfb, 0x07, 0x3b, 0xdc, 0xb5, 0x03, 0x36, 0xd0, 0x38, 0x83, 0x07, 0x67, 0x84, 0x5d, 0x15, 0x92, + 0xec, 0xc3, 0xef, 0x0b, 0x68, 0x2d, 0x74, 0x46, 0x2c, 0xc3, 0xa3, 0x7b, 0x2b, 0x8c, 0x2d, 0x38, + 0x9e, 0x40, 0x60, 0x2f, 0xd1, 0x3c, 0x3f, 0xdf, 0xe6, 0xf9, 0xe1, 0x6e, 0x9e, 0xca, 0x65, 0xcd, + 0xf4, 0xaf, 0x26, 0x04, 0x98, 0xd5, 0xb2, 0xa0, 0x39, 0xae, 0x4b, 0x82, 0x10, 0x78, 0x32, 0xcd, + 0x0d, 0xcb, 0xf3, 0x03, 0xac, 0x04, 0xf4, 0x31, 0x74, 0xe7, 0x69, 0x99, 0xd2, 0xac, 0xa0, 0xf9, + 0x4c, 0x59, 0x3b, 0xd6, 0xda, 0xb9, 0x51, 0x3f, 0x4f, 0xf3, 0xff, 0xf9, 0x0c, 0xf4, 0xc4, 0x56, + 0xc7, 0xfb, 0xcf, 0xea, 0x8c, 0xdd, 0xc8, 0x31, 0x15, 0x52, 0x45, 0xc9, 0x09, 0x2b, 0x78, 0x04, + 0xfb, 0x14, 0x45, 0x43, 0xd1, 0x04, 0x40, 0xcd, 0xf6, 0x4c, 0xa4, 0x34, 0x27, 0x51, 0xa3, 0xef, + 0x0c, 0x82, 0x51, 0xff, 0xb6, 0xa3, 0x19, 0xef, 0x84, 0x12, 0x99, 0x5c, 0x32, 0x21, 0xb1, 0xc2, + 0xe9, 0x3b, 0x7d, 0xbe, 0x16, 0xd1, 0xd7, 0xa0, 0x85, 0x59, 0x59, 0x54, 0x32, 0xea, 0xe9, 0x18, + 0xc7, 0xf7, 0xc4, 0x50, 0x95, 0xc1, 0x6d, 0x6e, 0x4f, 0x68, 0x0a, 0x1d, 0xbb, 0x38, 0x4c, 0x80, + 0xa6, 0x0e, 0x10, 0xef, 0x08, 0x70, 0x61, 0xa0, 0xca, 0x53, 0xd3, 0x08, 0xe8, 0x46, 0x81, 0xbe, + 0x82, 0xb6, 0x15, 0xab, 0xa8, 0xdb, 0xf7, 0x06, 0xbd, 0xed, 0x8a, 0xff, 0x3b, 0x0c, 0xbe, 0xc1, + 0xa3, 0x6f, 0x21, 0xa8, 0x58, 0x2d, 0x32, 0x32, 0xd3, 0x99, 0x6f, 0xed, 0x97, 0x79, 0x30, 0x3e, + 0x13, 0x95, 0xff, 0xa7, 0xd0, 0xb1, 0x11, 0x4c, 0x19, 0x82, 0x3d, 0xca, 0x60, 0xef, 0x3c, 0xd3, + 0xc5, 0x38, 0x02, 0xa8, 0x2b, 0x22, 0x66, 0x64, 0x99, 0x16, 0x65, 0xf4, 0xa0, 0xef, 0x0d, 0x7c, + 0xec, 0x2b, 0xcd, 0x33, 0xa5, 0x40, 0xc7, 0x10, 0x14, 0x74, 0xce, 0x6a, 0xba, 0xd0, 0x0d, 0xd7, + 0xd6, 0x76, 0xb0, 0x2a, 0xd5, 0x6c, 0x87, 0xd0, 0xd6, 0xab, 0x37, 0x63, 0x65, 0xe4, 0x6b, 0xeb, + 0x8d, 0x3c, 0xee, 0x00, 0xc8, 0x54, 0xe4, 0x44, 0x2a, 0xdf, 0xf8, 0x02, 0xba, 0xe3, 0x75, 0x9b, + 0xea, 0x16, 0x0f, 0x6f, 0xb5, 0xb8, 0x69, 0xf0, 0x4f, 0xe1, 0x6d, 0x56, 0x4b, 0x73, 0x5d, 0x45, + 0x4a, 0x92, 0x49, 0x66, 0xb6, 0x85, 0x8f, 0xc3, 0xb5, 0xe1, 0xca, 0xea, 0xe3, 0x3f, 0x5c, 0x68, + 0x4d, 0xf4, 0x17, 0x83, 0x5e, 0xc0, 0x5b, 0xa6, 0x89, 0x67, 0x95, 0x14, 0xa9, 0x24, 0xf9, 0xca, + 0xae, 0xfd, 0xcf, 0x76, 0xe5, 0xd2, 0x7c, 0x4d, 0x66, 0x02, 0xae, 0xac, 0x0f, 0xee, 0x2d, 0xb6, + 0x64, 0xf5, 0x85, 0x88, 0xba, 0x24, 0x76, 0x8c, 0x76, 0x7d, 0x21, 0xb7, 0xa6, 0x16, 0x6b, 0x3c, + 0xfa, 0x1e, 0x7a, 0x9b, 0x39, 0xd5, 0x11, 0xcc, 0x4c, 0x3d, 0xda, 0x11, 0x61, 0x2b, 0x2d, 0x78, + 0x33, 0xe3, 0x4a, 0x8c, 0xcf, 0xa0, 0xb7, 0x4d, 0x53, 0x2d, 0xeb, 0x93, 0x6a, 0x5a, 0x99, 0x6d, + 0xfe, 0xa2, 0x22, 0x53, 0x1e, 0x3a, 0x28, 0x84, 0xce, 0x94, 0x4f, 0xaf, 0x2f, 0x18, 0xfd, 0x31, + 0x95, 0xd9, 0xaf, 0xa1, 0x8b, 0x7a, 0x00, 0x53, 0xfe, 0x13, 0x3d, 0x25, 0xcb, 0x94, 0x2e, 0x42, + 0x6f, 0xfc, 0x0d, 0xbc, 0x97, 0xb1, 0xe5, 0xdd, 0x14, 0x2e, 0x9d, 0x9f, 0x5b, 0xe6, 0xf4, 0xbb, + 0xfb, 0xf0, 0xe5, 0x08, 0xa7, 0xab, 0x64, 0xa2, 0x10, 0x27, 0x9c, 0xeb, 0xf7, 0x11, 0x31, 0x6f, + 0xe9, 0xb2, 0x3e, 0xf9, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x28, 0x0d, 0x41, 0xf1, 0x07, 0x00, 0x00, } diff --git a/app/router/config.proto b/app/router/config.proto index 09a1fc77..dcf2e6cd 100644 --- a/app/router/config.proto +++ b/app/router/config.proto @@ -83,7 +83,7 @@ message RoutingRule { repeated Domain domain = 2; // List of CIDRs for target IP address matching. - // The list must be sorted beforehand. + // Deprecated. Use geoip below. repeated CIDR cidr = 3 [deprecated = true]; // List of GeoIPs for target IP address matching. If this entry exists, the cidr above will have no effect. @@ -91,7 +91,12 @@ message RoutingRule { // For customized GeoIPs, please leave country code empty. repeated GeoIP geoip = 10; - v2ray.core.common.net.PortRange port_range = 4; + // A range of port [from, to]. If the destination port is in this range, this rule takes effect. + // Deprecated. Use port_list. + v2ray.core.common.net.PortRange port_range = 4 [deprecated = true]; + + // List of ports. + v2ray.core.common.net.PortList port_list = 14; // List of networks. Deprecated. Use networks. v2ray.core.common.net.NetworkList network_list = 5 [deprecated = true]; diff --git a/common/net/port.go b/common/net/port.go index 1fdd5256..69368509 100644 --- a/common/net/port.go +++ b/common/net/port.go @@ -65,3 +65,31 @@ func SinglePortRange(p Port) *PortRange { To: uint32(p), } } + +type MemoryPortRange struct { + From Port + To Port +} + +func (r MemoryPortRange) Contains(port Port) bool { + return r.From <= port && port <= r.To +} + +type MemoryPortList []MemoryPortRange + +func PortListFromProto(l *PortList) MemoryPortList { + mpl := make(MemoryPortList, 0, len(l.Range)) + for _, r := range l.Range { + mpl = append(mpl, MemoryPortRange{From: Port(r.From), To: Port(r.To)}) + } + return mpl +} + +func (mpl MemoryPortList) Contains(port Port) bool { + for _, pr := range mpl { + if pr.Contains(port) { + return true + } + } + return false +} diff --git a/common/net/port.pb.go b/common/net/port.pb.go index a82214db..f6f4ccf4 100644 --- a/common/net/port.pb.go +++ b/common/net/port.pb.go @@ -67,8 +67,49 @@ func (m *PortRange) GetTo() uint32 { return 0 } +// PortList is a list of ports. +type PortList struct { + Range []*PortRange `protobuf:"bytes,1,rep,name=range,proto3" json:"range,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PortList) Reset() { *m = PortList{} } +func (m *PortList) String() string { return proto.CompactTextString(m) } +func (*PortList) ProtoMessage() {} +func (*PortList) Descriptor() ([]byte, []int) { + return fileDescriptor_166067e37a39f913, []int{1} +} + +func (m *PortList) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PortList.Unmarshal(m, b) +} +func (m *PortList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PortList.Marshal(b, m, deterministic) +} +func (m *PortList) XXX_Merge(src proto.Message) { + xxx_messageInfo_PortList.Merge(m, src) +} +func (m *PortList) XXX_Size() int { + return xxx_messageInfo_PortList.Size(m) +} +func (m *PortList) XXX_DiscardUnknown() { + xxx_messageInfo_PortList.DiscardUnknown(m) +} + +var xxx_messageInfo_PortList proto.InternalMessageInfo + +func (m *PortList) GetRange() []*PortRange { + if m != nil { + return m.Range + } + return nil +} + func init() { proto.RegisterType((*PortRange)(nil), "v2ray.core.common.net.PortRange") + proto.RegisterType((*PortList)(nil), "v2ray.core.common.net.PortList") } func init() { @@ -76,15 +117,17 @@ func init() { } var fileDescriptor_166067e37a39f913 = []byte{ - // 158 bytes of a gzipped FileDescriptorProto + // 192 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x29, 0x33, 0x2a, 0x4a, 0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcd, 0xcd, 0xcf, 0xd3, 0xcf, 0x4b, 0x2d, 0xd1, 0x2f, 0xc8, 0x2f, 0x2a, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x85, 0xa9, 0x2a, 0x4a, 0xd5, 0x83, 0xa8, 0xd0, 0xcb, 0x4b, 0x2d, 0x51, 0xd2, 0xe7, 0xe2, 0x0c, 0xc8, 0x2f, 0x2a, 0x09, 0x4a, 0xcc, 0x4b, 0x4f, 0x15, 0x12, 0xe2, 0x62, 0x71, 0x2b, 0xca, 0xcf, 0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0d, 0x02, 0xb3, 0x85, 0xf8, 0xb8, 0x98, 0x42, - 0xf2, 0x25, 0x98, 0xc0, 0x22, 0x4c, 0x21, 0xf9, 0x4e, 0x56, 0x5c, 0x92, 0xc9, 0xf9, 0xb9, 0x7a, - 0x58, 0x4d, 0x0b, 0x60, 0x8c, 0x62, 0xce, 0x4b, 0x2d, 0x59, 0xc5, 0x24, 0x1a, 0x66, 0x14, 0x94, - 0x58, 0xa9, 0xe7, 0x0c, 0x92, 0x76, 0x86, 0x48, 0xfb, 0xa5, 0x96, 0x24, 0xb1, 0x81, 0x9d, 0x62, - 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x0f, 0x6a, 0xc0, 0xb2, 0x00, 0x00, 0x00, + 0xf2, 0x25, 0x98, 0xc0, 0x22, 0x4c, 0x21, 0xf9, 0x4a, 0x4e, 0x5c, 0x1c, 0x20, 0x0d, 0x3e, 0x99, + 0xc5, 0x25, 0x42, 0x66, 0x5c, 0xac, 0x45, 0x20, 0x8d, 0x12, 0x8c, 0x0a, 0xcc, 0x1a, 0xdc, 0x46, + 0x0a, 0x7a, 0x58, 0xed, 0xd0, 0x83, 0x5b, 0x10, 0x04, 0x51, 0xee, 0x64, 0xc5, 0x25, 0x99, 0x9c, + 0x9f, 0x8b, 0x5d, 0x75, 0x00, 0x63, 0x14, 0x73, 0x5e, 0x6a, 0xc9, 0x2a, 0x26, 0xd1, 0x30, 0xa3, + 0xa0, 0xc4, 0x4a, 0x3d, 0x67, 0x90, 0xb4, 0x33, 0x44, 0xda, 0x2f, 0xb5, 0x24, 0x89, 0x0d, 0xec, + 0x1d, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xba, 0xd0, 0x7b, 0xfa, 0xf6, 0x00, 0x00, 0x00, } diff --git a/common/net/port.proto b/common/net/port.proto index fc3fcfdb..eeffa02e 100644 --- a/common/net/port.proto +++ b/common/net/port.proto @@ -13,3 +13,8 @@ message PortRange { // The port that this range ends with (inclusive). uint32 To = 2; } + +// PortList is a list of ports. +message PortList { + repeated PortRange range = 1; +} diff --git a/infra/conf/common.go b/infra/conf/common.go index 958b5336..cc439c3d 100644 --- a/infra/conf/common.go +++ b/infra/conf/common.go @@ -111,12 +111,7 @@ func parseIntPort(data []byte) (net.Port, error) { return net.PortFromInt(intPort) } -func parseStringPort(data []byte) (net.Port, net.Port, error) { - var s string - err := json.Unmarshal(data, &s) - if err != nil { - return net.Port(0), net.Port(0), err - } +func parseStringPort(s string) (net.Port, net.Port, error) { if strings.HasPrefix(s, "env:") { s = s[4:] s = os.Getenv(s) @@ -124,7 +119,7 @@ func parseStringPort(data []byte) (net.Port, net.Port, error) { pair := strings.SplitN(s, "-", 2) if len(pair) == 0 { - return net.Port(0), net.Port(0), newError("Config: Invalid port range: ", s) + return net.Port(0), net.Port(0), newError("invalid port range: ", s) } if len(pair) == 1 { port, err := net.PortFromString(pair[0]) @@ -142,6 +137,15 @@ func parseStringPort(data []byte) (net.Port, net.Port, error) { return fromPort, toPort, nil } +func parseJSONStringPort(data []byte) (net.Port, net.Port, error) { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return net.Port(0), net.Port(0), err + } + return parseStringPort(s) +} + type PortRange struct { From uint32 To uint32 @@ -163,7 +167,7 @@ func (v *PortRange) UnmarshalJSON(data []byte) error { return nil } - from, to, err := parseStringPort(data) + from, to, err := parseJSONStringPort(data) if err == nil { v.From = uint32(from) v.To = uint32(to) @@ -176,6 +180,46 @@ func (v *PortRange) UnmarshalJSON(data []byte) error { return newError("invalid port range: ", string(data)) } +type PortList struct { + Range []PortRange +} + +func (list *PortList) Build() *net.PortList { + portList := new(net.PortList) + for _, r := range list.Range { + portList.Range = append(portList.Range, r.Build()) + } + return portList +} + +// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON +func (list *PortList) UnmarshalJSON(data []byte) error { + var listStr string + if err := json.Unmarshal(data, &listStr); err != nil { + return newError("invalid port list: ", string(data)).Base(err) + } + rangelist := strings.Split(listStr, ",") + for _, rangeStr := range rangelist { + trimmed := strings.TrimSpace(rangeStr) + if len(trimmed) > 0 { + if strings.Contains(trimmed, "-") { + from, to, err := parseStringPort(trimmed) + if err != nil { + return newError("invalid port range: ", trimmed).Base(err) + } + list.Range = append(list.Range, PortRange{From: uint32(from), To: uint32(to)}) + } else { + port, err := parseIntPort([]byte(trimmed)) + if err != nil { + return newError("invalid port: ", trimmed).Base(err) + } + list.Range = append(list.Range, PortRange{From: uint32(port), To: uint32(port)}) + } + } + } + return nil +} + type User struct { EmailString string `json:"email"` LevelByte byte `json:"level"` diff --git a/infra/conf/router.go b/infra/conf/router.go index 38eda6bf..d79f486f 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -354,7 +354,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { RouterRule Domain *StringList `json:"domain"` IP *StringList `json:"ip"` - Port *PortRange `json:"port"` + Port *PortList `json:"port"` Network *NetworkList `json:"network"` SourceIP *StringList `json:"source"` User *StringList `json:"user"` @@ -399,7 +399,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { } if rawFieldRule.Port != nil { - rule.PortRange = rawFieldRule.Port.Build() + rule.PortList = rawFieldRule.Port.Build() } if rawFieldRule.Network != nil { diff --git a/infra/conf/router_test.go b/infra/conf/router_test.go index b6d0aa94..52676ad2 100644 --- a/infra/conf/router_test.go +++ b/infra/conf/router_test.go @@ -7,6 +7,7 @@ import ( "github.com/golang/protobuf/proto" "v2ray.com/core/app/router" + "v2ray.com/core/common/net" . "v2ray.com/core/infra/conf" ) @@ -43,6 +44,10 @@ func TestRouterConfig(t *testing.T) { "::1/128" ], "outboundTag": "test" + },{ + "type": "field", + "port": "53, 443, 1000-2000", + "outboundTag": "test" } ] }, @@ -97,6 +102,18 @@ func TestRouterConfig(t *testing.T) { Tag: "test", }, }, + { + PortList: &net.PortList{ + Range: []*net.PortRange{ + {From: 53, To: 53}, + {From: 443, To: 443}, + {From: 1000, To: 2000}, + }, + }, + TargetTag: &router.RoutingRule_Tag{ + Tag: "test", + }, + }, }, }, },