Skip to content

Commit

Permalink
Support source port matching in routing config
Browse files Browse the repository at this point in the history
  • Loading branch information
Vigilans committed Aug 9, 2020
1 parent 1664b4e commit 40c0bcc
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 61 deletions.
24 changes: 18 additions & 6 deletions app/router/condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,20 +154,32 @@ func (m *MultiGeoIPMatcher) Apply(ctx *Context) bool {
}

type PortMatcher struct {
port net.MemoryPortList
port net.MemoryPortList
onSource bool
}

func NewPortMatcher(list *net.PortList) *PortMatcher {
// NewPortMatcher create a new port matcher that can match source or destination port
func NewPortMatcher(list *net.PortList, onSource bool) *PortMatcher {
return &PortMatcher{
port: net.PortListFromProto(list),
port: net.PortListFromProto(list),
onSource: onSource,
}
}

func (v *PortMatcher) Apply(ctx *Context) bool {
if ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {
return false
var port net.Port
if v.onSource {
if ctx.Inbound == nil || !ctx.Inbound.Source.IsValid() {
return false
}
port = ctx.Inbound.Source.Port
} else {
if ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {
return false
}
port = ctx.Outbound.Target.Port
}
return v.port.Contains(ctx.Outbound.Target.Port)
return v.port.Contains(port)
}

type NetworkMatcher struct {
Expand Down
28 changes: 28 additions & 0 deletions app/router/condition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,34 @@ func TestRoutingRule(t *testing.T) {
},
},
},
{
rule: &RoutingRule{
SourcePortList: &net.PortList{
Range: []*net.PortRange{
{From: 123, To: 123},
{From: 9993, To: 9999},
},
},
},
test: []ruleTest{
{
input: withInbound(&session.Inbound{Source: net.UDPDestination(net.LocalHostIP, 123)}),
output: true,
},
{
input: withInbound(&session.Inbound{Source: net.UDPDestination(net.LocalHostIP, 9999)}),
output: true,
},
{
input: withInbound(&session.Inbound{Source: net.UDPDestination(net.LocalHostIP, 9994)}),
output: true,
},
{
input: withInbound(&session.Inbound{Source: net.UDPDestination(net.LocalHostIP, 53)}),
output: false,
},
},
},
{
rule: &RoutingRule{
Protocol: []string{"http"},
Expand Down
8 changes: 6 additions & 2 deletions app/router/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,13 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
}

if rr.PortList != nil {
conds.Add(NewPortMatcher(rr.PortList))
conds.Add(NewPortMatcher(rr.PortList, false))
} else if rr.PortRange != nil {
conds.Add(NewPortMatcher(&net.PortList{Range: []*net.PortRange{rr.PortRange}}))
conds.Add(NewPortMatcher(&net.PortList{Range: []*net.PortRange{rr.PortRange}}, false))
}

if rr.SourcePortList != nil {
conds.Add(NewPortMatcher(rr.SourcePortList, true))
}

if len(rr.Networks) > 0 {
Expand Down
120 changes: 70 additions & 50 deletions app/router/config.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions app/router/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ option java_multiple_files = true;
import "v2ray.com/core/common/net/port.proto";
import "v2ray.com/core/common/net/network.proto";

// Domain for routing decision.
// Domain for routing decision.
message Domain {
// Type of domain value.
enum Type {
Expand Down Expand Up @@ -77,15 +77,15 @@ message RoutingRule {
// Tag of routing balancer.
string balancing_tag = 12;
}


// List of domains for target domain matching.
repeated Domain domain = 2;

// List of CIDRs for target IP address matching.
// 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.
// 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.
Expand All @@ -110,6 +110,9 @@ message RoutingRule {
// List of GeoIPs for source IP address matching. If this entry exists, the source_cidr above will have no effect.
repeated GeoIP source_geoip = 11;

// List of ports for source port matching.
v2ray.core.common.net.PortList source_port_list = 16;

repeated string user_email = 7;
repeated string inbound_tag = 8;
repeated string protocol = 9;
Expand Down
5 changes: 5 additions & 0 deletions infra/conf/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
Port *PortList `json:"port"`
Network *NetworkList `json:"network"`
SourceIP *StringList `json:"source"`
SourcePort *PortList `json:"sourcePort"`
User *StringList `json:"user"`
InboundTag *StringList `json:"inboundTag"`
Protocols *StringList `json:"protocol"`
Expand Down Expand Up @@ -438,6 +439,10 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
rule.SourceGeoip = geoipList
}

if rawFieldRule.SourcePort != nil {
rule.SourcePortList = rawFieldRule.SourcePort.Build()
}

if rawFieldRule.User != nil {
for _, s := range *rawFieldRule.User {
rule.UserEmail = append(rule.UserEmail, s)
Expand Down

0 comments on commit 40c0bcc

Please sign in to comment.