Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
igoogolx committed Oct 19, 2023
2 parents 0a552aa + 6bc5ae2 commit d1dcf38
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 76 deletions.
6 changes: 3 additions & 3 deletions api/routes/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package routes
import (
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
configuration2 "github.com/igoogolx/itun2socks/internal/configuration"
"github.com/igoogolx/itun2socks/internal/configuration"
"net/http"
)

Expand All @@ -14,13 +14,13 @@ func ruleRouter() http.Handler {
}

func getRules(w http.ResponseWriter, r *http.Request) {
rules, err := configuration2.GetRules()
rules, err := configuration.GetRuleIds()
if err != nil {
render.Status(r, http.StatusBadRequest)
render.JSON(w, r, ErrBadRequest)
return
}
selectId, err := configuration2.GetSelectedId("rule")
selectId, err := configuration.GetSelectedId("rule")
if err != nil {
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, NewError(err.Error()))
Expand Down
1 change: 1 addition & 0 deletions internal/cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func New(defaultInterfaceName string) (*Config, error) {
rawConfig.Setting.Dns.Remote.Value,
rawConfig.Setting.Dns.Local.Value,
selectedRule,
rawConfig.Rules,
device.Name,
defaultInterfaceName)
if err != nil {
Expand Down
56 changes: 26 additions & 30 deletions internal/cfg/distribution/distribution.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,31 @@ package distribution

import (
"fmt"
"github.com/Dreamacro/clash/component/resolver"
lru "github.com/hashicorp/golang-lru"
"github.com/igoogolx/itun2socks/internal/cfg/distribution/ruleEngine"
"github.com/igoogolx/itun2socks/internal/constants"
"github.com/igoogolx/itun2socks/pkg/log"
"strings"
)

var dnsCache, _ = lru.New(1000)
var dnsDomainCache, _ = lru.New(4 * 1024)
var dnsRuleCache, _ = lru.New(4 * 1024)

func GetCachedDnsItem(ip string) (CacheItem, bool) {
cacheItem, ok := dnsCache.Get(ip)
if ok {
cacheResult, ok := cacheItem.(CacheItem)
return cacheResult, ok
func GetCachedDnsItem(ip string) (string, constants.DnsType, bool) {
rawCachedDomain, ok := dnsDomainCache.Get(ip)
if !ok {
return "", constants.DistributionLocalDns, false
}
rawCachedRule, ok := dnsRuleCache.Get(ip)
if !ok {
return "", constants.DistributionLocalDns, false
}
return CacheItem{}, false
return rawCachedDomain.(string), constants.DnsType(rawCachedRule.(string)), true
}

func AddCachedDnsItem(ip, domain string, rule constants.DnsType) {
dnsCache.Add(ip, CacheItem{
Domain: domain,
Rule: rule,
})
}

type CacheItem struct {
Domain string
Rule constants.DnsType
dnsDomainCache.Add(ip, domain)
dnsRuleCache.Add(ip, rule)
}

type Config struct {
Expand All @@ -53,9 +49,9 @@ func (c Config) GetDnsServerRule(ip string) (constants.RuleType, error) {

func (c Config) GetDnsRule(ip string) (constants.RuleType, error) {
result := constants.DistributionBypass
cacheItem, ok := GetCachedDnsItem(ip)
_, cachedRule, ok := GetCachedDnsItem(ip)
if ok {
if cacheItem.Rule == constants.DistributionLocalDns {
if cachedRule == constants.DistributionLocalDns {
result = constants.DistributionBypass
} else {
result = constants.DistributionProxy
Expand All @@ -72,10 +68,10 @@ func (c Config) GetRule(ip string) constants.RuleType {
defer func(latestIp string) {
domain := "unknown"
dnsRule := "unknown"
cacheItem, ok := GetCachedDnsItem(latestIp)
cacheDomain, cachedRule, ok := GetCachedDnsItem(latestIp)
if ok {
domain = cacheItem.Domain
dnsRule = string(cacheItem.Rule)
domain = cacheDomain
dnsRule = string(cachedRule)
}
log.Infoln(log.FormatLog(log.RulePrefix, "ip:%v, rule:%v; domain:%v, rule:%v"), latestIp, result, domain, dnsRule)
}(ip)
Expand Down Expand Up @@ -105,7 +101,7 @@ func (c Config) GetRule(ip string) constants.RuleType {

}

func (c Config) GetDns(domain string) (resolver.Resolver, constants.DnsType) {
func (c Config) GetDns(domain string) SubDnsDistribution {
result := constants.DistributionRemoteDns
if strings.Contains(c.Dns.Remote.Address, domain) {
result = constants.DistributionBoostDns
Expand All @@ -122,24 +118,24 @@ func (c Config) GetDns(domain string) (resolver.Resolver, constants.DnsType) {

switch result {
case constants.DistributionLocalDns:
return c.Dns.Local.Client, constants.DistributionLocalDns
return c.Dns.Local
case constants.DistributionRemoteDns:
return c.Dns.Remote.Client, constants.DistributionRemoteDns
return c.Dns.Remote
default:
return c.Dns.Boost.Client, constants.DistributionBoostDns

return c.Dns.Boost
}
}

func New(
boostDns string,
remoteDns string,
localDns string,
rule string,
ruleId string,
rules []string,
tunInterfaceName string,
defaultInterfaceName string,
) (Config, error) {
ruleEngine, err := ruleEngine.New(rule)
rEngine, err := ruleEngine.New(ruleId, rules)
if err != nil {
return Config{}, err
}
Expand All @@ -148,6 +144,6 @@ func New(
return Config{}, err
}
return Config{
Dns: dns, dnsTable: dnsCache, RuleEngine: ruleEngine,
Dns: dns, RuleEngine: rEngine,
}, nil
}
5 changes: 5 additions & 0 deletions internal/cfg/distribution/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package distribution

import (
cResolver "github.com/Dreamacro/clash/component/resolver"
"github.com/igoogolx/itun2socks/internal/constants"
"github.com/igoogolx/itun2socks/internal/resolver"
)

Expand All @@ -27,6 +28,7 @@ func NewDnsDistribution(
dd.Local = SubDnsDistribution{
Address: localDns,
Client: localDnsClient,
Type: constants.DistributionLocalDns,
}
remoteDns = remoteDns + "#" + tunInterfaceName
remoteDnsClient, err := resolver.New([]string{remoteDns}, []string{"udp://8.8.8.8#" + tunInterfaceName}, defaultInterfaceName)
Expand All @@ -36,11 +38,13 @@ func NewDnsDistribution(
dd.Remote = SubDnsDistribution{
Client: remoteDnsClient,
Address: remoteDns,
Type: constants.DistributionRemoteDns,
}

dd.Boost = SubDnsDistribution{
Client: boostDnsClient,
Address: bootDns,
Type: constants.DistributionBoostDns,
}

cResolver.DefaultResolver = boostDnsClient
Expand All @@ -49,6 +53,7 @@ func NewDnsDistribution(

type SubDnsDistribution struct {
Address string
Type constants.DnsType
Client cResolver.Resolver
}

Expand Down
6 changes: 4 additions & 2 deletions internal/cfg/distribution/ruleEngine/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package ruleEngine
import (
"fmt"
lru "github.com/hashicorp/golang-lru"
"github.com/igoogolx/itun2socks/internal/constants"
)

type Rule interface {
Match(value string) bool
Value() string
Policy() string
Type() constants.RuleConfig
}

type Engine struct {
Expand All @@ -30,8 +32,8 @@ func (e *Engine) Match(value string) (Rule, error) {
return nil, fmt.Errorf("not found")
}

func New(name string) (*Engine, error) {
rules, err := Parse(name)
func New(name string, extraRules []string) (*Engine, error) {
rules, err := Parse(name, extraRules)
if err != nil {
return nil, err
}
Expand Down
5 changes: 5 additions & 0 deletions internal/cfg/distribution/ruleEngine/domain.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ruleEngine

import (
"github.com/igoogolx/itun2socks/internal/constants"
"regexp"
"strings"
)
Expand All @@ -14,6 +15,10 @@ func (d Domain) Policy() string {
return d.policy
}

func (d Domain) Type() constants.RuleConfig {
return constants.RuleDomain
}

func (d Domain) Match(value string) bool {
return isContainsDomain(d.payload, value)
}
Expand Down
9 changes: 8 additions & 1 deletion internal/cfg/distribution/ruleEngine/ipcidr.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package ruleEngine

import "net/netip"
import (
"github.com/igoogolx/itun2socks/internal/constants"
"net/netip"
)

type IpCidr struct {
prefix netip.Prefix
policy string
}

func (i IpCidr) Type() constants.RuleConfig {
return constants.RuleIpCidr
}

func (i IpCidr) Match(value string) bool {
ip, err := netip.ParseAddr(value)
if err != nil {
Expand Down
62 changes: 39 additions & 23 deletions internal/cfg/distribution/ruleEngine/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func trimArr(arr []string) (r []string) {
return
}

func GetRules() ([]string, error) {
func GetRuleIds() ([]string, error) {
ruleFiles, err := data.ReadDir("rules")
var rules []string
if err != nil {
Expand All @@ -32,39 +32,55 @@ func GetRules() ([]string, error) {
return rules, err
}

func Parse(name string) ([]Rule, error) {
items, err := readFile("rules/" + name)
func Parse(name string, extraRules []string) ([]Rule, error) {
var err error
var rules []Rule
builtInItems, err := readFile("rules/" + name)
if err != nil {
return nil, err
}
var rules []Rule
for _, line := range items {
chunks := trimArr(strings.Split(strings.TrimSpace(line), ","))
if len(chunks) != 3 {
break
}
ruleType := constants.RuleConfig(chunks[0])

var rule Rule
var err error
switch ruleType {
case constants.RuleIpCidr:
rule, err = NewIpCidrRule(chunks[1], chunks[2])
break
case constants.RuleDomain:
rule, err = NewDomainRule(chunks[1], chunks[2])
break
default:
err = fmt.Errorf("rule type not match: %v", ruleType)

for _, line := range extraRules {
rule, err := parseLine(line)
if err == nil {
rules = append(rules, rule)
}
}
for _, line := range builtInItems {
rule, err := parseLine(line)
if err == nil {
rules = append(rules, rule)
}
}
return rules, nil
}

func parseLine(line string) (Rule, error) {
chunks := trimArr(strings.Split(strings.TrimSpace(line), ","))
if len(chunks) != 3 {
return nil, fmt.Errorf("invald rule line")
}
return ParseItem(chunks[0], chunks[1], chunks[2])

}

func ParseItem(rawRuleType, value, policy string) (Rule, error) {
ruleType := constants.RuleConfig(rawRuleType)

var rule Rule
var err error
switch ruleType {
case constants.RuleIpCidr:
rule, err = NewIpCidrRule(value, policy)
break
case constants.RuleDomain:
rule, err = NewDomainRule(value, policy)
break
default:
err = fmt.Errorf("rule type not match: %v", ruleType)
}
return rule, err
}

func readFile(path string) ([]string, error) {
file, err := data.Open(path)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/configuration/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package configuration
type Config struct {
ClashYamlUrl string `json:"clashYamlUrl"`
Proxy []map[string]interface{} `json:"proxy"`

Selected struct {
Selected struct {
Proxy string `json:"proxy"`
Rule string `json:"rule"`
} `json:"selected"`
Setting SettingCfg `json:"setting"`
Rules []string
}

type SettingCfg struct {
Expand Down
26 changes: 25 additions & 1 deletion internal/configuration/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,30 @@ func GetSelectedRule() (string, error) {
return c.Selected.Rule, nil
}

func GetRuleIds() ([]string, error) {
return ruleEngine.GetRuleIds()
}

func SetRules(rules []string) error {
c, err := Read()
if err != nil {
return err
}
return Write(c)
}

func GetRules() ([]string, error) {
return ruleEngine.GetRules()
c, err := Read()
if err != nil {
return nil, err
}
return c.Rules, nil
}

func GetBuiltInRules(id string) ([]string, error) {
c, err := Read()
if err != nil {
return nil, err
}
return c.Rules, nil
}
Loading

0 comments on commit d1dcf38

Please sign in to comment.