1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-12-29 05:25:21 -05:00

Extract session information during routing as routing context

This commit is contained in:
Vigilans
2020-09-04 11:32:19 +08:00
parent 6981711fe5
commit f9d37b724c
10 changed files with 263 additions and 133 deletions

View File

@@ -10,10 +10,11 @@ import (
"v2ray.com/core/common/net"
"v2ray.com/core/common/strmatcher"
"v2ray.com/core/features/routing"
)
type Condition interface {
Apply(ctx *Context) bool
Apply(ctx routing.Context) bool
}
type ConditionChan []Condition
@@ -28,7 +29,8 @@ func (v *ConditionChan) Add(cond Condition) *ConditionChan {
return v
}
func (v *ConditionChan) Apply(ctx *Context) bool {
// Apply applies all conditions registered in this chan.
func (v *ConditionChan) Apply(ctx routing.Context) bool {
for _, cond := range *v {
if !cond.Apply(ctx) {
return false
@@ -85,36 +87,18 @@ func (m *DomainMatcher) ApplyDomain(domain string) bool {
return len(m.matchers.Match(domain)) > 0
}
func (m *DomainMatcher) Apply(ctx *Context) bool {
if ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {
// Apply implements Condition.
func (m *DomainMatcher) Apply(ctx routing.Context) bool {
domain := ctx.GetTargetDomain()
if len(domain) == 0 {
return false
}
dest := ctx.Outbound.Target
if !dest.Address.Family().IsDomain() {
return false
}
return m.ApplyDomain(dest.Address.Domain())
}
func getIPsFromSource(ctx *Context) []net.IP {
if ctx.Inbound == nil || !ctx.Inbound.Source.IsValid() {
return nil
}
dest := ctx.Inbound.Source
if dest.Address.Family().IsDomain() {
return nil
}
return []net.IP{dest.Address.IP()}
}
func getIPsFromTarget(ctx *Context) []net.IP {
return ctx.GetTargetIPs()
return m.ApplyDomain(domain)
}
type MultiGeoIPMatcher struct {
matchers []*GeoIPMatcher
ipFunc func(*Context) []net.IP
onSource bool
}
func NewMultiGeoIPMatcher(geoips []*GeoIP, onSource bool) (*MultiGeoIPMatcher, error) {
@@ -129,20 +113,20 @@ func NewMultiGeoIPMatcher(geoips []*GeoIP, onSource bool) (*MultiGeoIPMatcher, e
matcher := &MultiGeoIPMatcher{
matchers: matchers,
}
if onSource {
matcher.ipFunc = getIPsFromSource
} else {
matcher.ipFunc = getIPsFromTarget
onSource: onSource,
}
return matcher, nil
}
func (m *MultiGeoIPMatcher) Apply(ctx *Context) bool {
ips := m.ipFunc(ctx)
// Apply implements Condition.
func (m *MultiGeoIPMatcher) Apply(ctx routing.Context) bool {
var ips []net.IP
if m.onSource {
ips = ctx.GetSourceIPs()
} else {
ips = ctx.GetTargetIPs()
}
for _, ip := range ips {
for _, matcher := range m.matchers {
if matcher.Match(ip) {
@@ -166,20 +150,13 @@ func NewPortMatcher(list *net.PortList, onSource bool) *PortMatcher {
}
}
func (v *PortMatcher) Apply(ctx *Context) bool {
var port net.Port
// Apply implements Condition.
func (v *PortMatcher) Apply(ctx routing.Context) bool {
if v.onSource {
if ctx.Inbound == nil || !ctx.Inbound.Source.IsValid() {
return false
}
port = ctx.Inbound.Source.Port
return v.port.Contains(ctx.GetSourcePort())
} else {
if ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {
return false
}
port = ctx.Outbound.Target.Port
return v.port.Contains(ctx.GetTargetPort())
}
return v.port.Contains(port)
}
type NetworkMatcher struct {
@@ -194,11 +171,9 @@ func NewNetworkMatcher(network []net.Network) NetworkMatcher {
return matcher
}
func (v NetworkMatcher) Apply(ctx *Context) bool {
if ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {
return false
}
return v.list[int(ctx.Outbound.Target.Network)]
// Apply implements Condition.
func (v NetworkMatcher) Apply(ctx routing.Context) bool {
return v.list[int(ctx.GetNetwork())]
}
type UserMatcher struct {
@@ -217,17 +192,14 @@ func NewUserMatcher(users []string) *UserMatcher {
}
}
func (v *UserMatcher) Apply(ctx *Context) bool {
if ctx.Inbound == nil {
return false
}
user := ctx.Inbound.User
if user == nil {
// Apply implements Condition.
func (v *UserMatcher) Apply(ctx routing.Context) bool {
user := ctx.GetUser()
if len(user) == 0 {
return false
}
for _, u := range v.user {
if u == user.Email {
if u == user {
return true
}
}
@@ -250,11 +222,12 @@ func NewInboundTagMatcher(tags []string) *InboundTagMatcher {
}
}
func (v *InboundTagMatcher) Apply(ctx *Context) bool {
if ctx.Inbound == nil || len(ctx.Inbound.Tag) == 0 {
// Apply implements Condition.
func (v *InboundTagMatcher) Apply(ctx routing.Context) bool {
tag := ctx.GetInboundTag()
if len(tag) == 0 {
return false
}
tag := ctx.Inbound.Tag
for _, t := range v.tags {
if t == tag {
return true
@@ -281,18 +254,17 @@ func NewProtocolMatcher(protocols []string) *ProtocolMatcher {
}
}
func (m *ProtocolMatcher) Apply(ctx *Context) bool {
if ctx.Content == nil {
// Apply implements Condition.
func (m *ProtocolMatcher) Apply(ctx routing.Context) bool {
protocol := ctx.GetProtocol()
if len(protocol) == 0 {
return false
}
protocol := ctx.Content.Protocol
for _, p := range m.protocols {
if strings.HasPrefix(protocol, p) {
return true
}
}
return false
}
@@ -343,9 +315,11 @@ func (m *AttributeMatcher) Match(attrs map[string]interface{}) bool {
return satisfied != nil && bool(satisfied.Truth())
}
func (m *AttributeMatcher) Apply(ctx *Context) bool {
if ctx.Content == nil {
// Apply implements Condition.
func (m *AttributeMatcher) Apply(ctx routing.Context) bool {
attributes := ctx.GetAttributes()
if attributes == nil {
return false
}
return m.Match(ctx.Content.Attributes)
return m.Match(attributes)
}