-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroute.go
128 lines (110 loc) · 2.54 KB
/
route.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"strings"
"sync"
"github.com/astaxie/beego/logs"
)
type RouteCtrl struct {
sync.RWMutex
cache map[string]string
domain []string
}
var routeCtrl *RouteCtrl
func RouteInit() {
routeCtrl = new(RouteCtrl)
routeCtrl.cache = make(map[string]string, 2048)
routeCtrl.domain = StringClone(ConfigGet().DomainList)
}
func AddressToDomain(address string) string {
domain := address
idx := strings.Index(address, ":")
if idx != -1 {
domain = address[:idx]
}
return domain
}
func stringCompare(domain string, match string) bool {
begin := strings.Index(match, "*")
end := strings.Index(match[begin+1:], "*")
if end != -1 {
end += begin + 1
}
if begin != -1 && end == -1 {
// suffix match
return strings.HasSuffix(domain, match[begin+1:])
}
if begin == -1 && end != -1 {
// prefix match
return strings.HasPrefix(domain, match[:end])
}
if begin == -1 && end == -1 {
// full match
if domain == match {
return true
} else {
return false
}
}
idx := strings.Index(domain, match[begin+1:end])
if idx == -1 {
return false
}
return true
}
func RouteUpdate() {
routeCtrl.Lock()
defer routeCtrl.Unlock()
newList := StringClone(ConfigGet().DomainList)
oldList := routeCtrl.domain
delList, addList := StringDiff(oldList, newList)
logs.Info("route update, domain %s delete", delList)
logs.Info("route update, domain %s add", addList)
for _, v := range delList {
for address, value := range routeCtrl.cache {
if value == v {
delete(routeCtrl.cache, address)
logs.Info("domain %s delete, address %s no match", v, address)
}
}
}
for _, v := range addList {
for address, value := range routeCtrl.cache {
if value == "" {
domain := AddressToDomain(address)
if stringCompare(domain, v) {
routeCtrl.cache[address] = v
logs.Info("domain %s add, address %s match", address, v)
}
}
}
}
routeCtrl.domain = newList
}
// address: www.baidu.com:80 or www.baidu.com:443
func routeMatch(address string) string {
domain := AddressToDomain(address)
for _, v := range routeCtrl.domain {
if stringCompare(domain, v) {
routeCtrl.cache[address] = v
logs.Info("route address %s match to domain %s", address, v)
return v
}
}
logs.Info("route address %s no match", address)
routeCtrl.cache[address] = ""
return ""
}
func RouteCheck(address string) bool {
routeCtrl.RLock()
result, flag := routeCtrl.cache[address]
routeCtrl.RUnlock()
if !flag {
routeCtrl.Lock()
result = routeMatch(address)
routeCtrl.Unlock()
}
if result == "" {
return false
}
return true
}