|
|
@@ -4,6 +4,8 @@ import (
|
|
|
"errors"
|
|
|
"time"
|
|
|
|
|
|
+ "github.com/v2ray/v2ray-core/app"
|
|
|
+ "github.com/v2ray/v2ray-core/app/dns"
|
|
|
"github.com/v2ray/v2ray-core/app/router"
|
|
|
"github.com/v2ray/v2ray-core/common/collect"
|
|
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
|
@@ -40,21 +42,54 @@ func (this *cacheEntry) Extend() {
|
|
|
type Router struct {
|
|
|
config *RouterRuleConfig
|
|
|
cache *collect.ValidityMap
|
|
|
+ space app.Space
|
|
|
}
|
|
|
|
|
|
-func NewRouter(config *RouterRuleConfig) *Router {
|
|
|
+func NewRouter(config *RouterRuleConfig, space app.Space) *Router {
|
|
|
return &Router{
|
|
|
config: config,
|
|
|
cache: collect.NewValidityMap(3600),
|
|
|
+ space: space,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// @Private
|
|
|
+func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
|
|
|
+ dnsServer := this.space.GetApp(dns.APP_ID).(dns.Server)
|
|
|
+ ips := dnsServer.Get(dest.Address().Domain())
|
|
|
+ if len(ips) == 0 {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ dests := make([]v2net.Destination, len(ips))
|
|
|
+ for idx, ip := range ips {
|
|
|
+ if dest.IsTCP() {
|
|
|
+ dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port())
|
|
|
+ } else {
|
|
|
+ dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return dests
|
|
|
+}
|
|
|
+
|
|
|
func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
|
|
|
for _, rule := range this.config.Rules {
|
|
|
if rule.Apply(dest) {
|
|
|
return rule.Tag, nil
|
|
|
}
|
|
|
}
|
|
|
+ if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().IsDomain() {
|
|
|
+ ipDests := this.ResolveIP(dest)
|
|
|
+ if ipDests != nil {
|
|
|
+ for _, ipDest := range ipDests {
|
|
|
+ for _, rule := range this.config.Rules {
|
|
|
+ if rule.Apply(ipDest) {
|
|
|
+ return rule.Tag, nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return "", ErrorNoRuleApplicable
|
|
|
}
|
|
|
|
|
|
@@ -72,8 +107,8 @@ func (this *Router) TakeDetour(dest v2net.Destination) (string, error) {
|
|
|
type RouterFactory struct {
|
|
|
}
|
|
|
|
|
|
-func (this *RouterFactory) Create(rawConfig interface{}) (router.Router, error) {
|
|
|
- return NewRouter(rawConfig.(*RouterRuleConfig)), nil
|
|
|
+func (this *RouterFactory) Create(rawConfig interface{}, space app.Space) (router.Router, error) {
|
|
|
+ return NewRouter(rawConfig.(*RouterRuleConfig), space), nil
|
|
|
}
|
|
|
|
|
|
func init() {
|