forked from sipt/shuttle
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrule.go
More file actions
120 lines (107 loc) · 2.14 KB
/
Copy pathrule.go
File metadata and controls
120 lines (107 loc) · 2.14 KB
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
package shuttle
import (
"strings"
"net"
"fmt"
)
const (
PolicyReject = "REJECT"
PolicyDirect = "DIRECT"
PolicyGlobal = "GLOBAL"
PolicyNone = "NONE"
RuleDomainSuffix = "DOMAIN-SUFFIX"
RuleDomain = "DOMAIN"
RuleDomainKeyword = "DOMAIN-KEYWORD"
RuleGeoIP = "GEOIP"
RuleFinal = "FINAL"
RuleIPCIDR = "IP-CIDR"
ConnModeDirect = "DIRECT"
ConnModeRemote = "REMOTE"
ConnModeRule = "RULE"
ConnModeReject = "REJECT"
)
var rules []*Rule
var connMode = ConnModeRule
var ipCidrMap map[string]*net.IPNet
func InitRule(rs []*Rule) error {
rules = rs
ipCidrMap = make(map[string]*net.IPNet)
for _, v := range rs {
if v.Type == RuleIPCIDR {
_, ipNet, err := net.ParseCIDR(v.Value)
if err != nil {
return fmt.Errorf("[Rule] [IP-CIDR] [%s] error: %v", v.Value, err)
}
ipCidrMap[v.Value] = ipNet
}
}
return nil
}
func SetConnMode(mode string) error {
switch connMode {
case ConnModeDirect, ConnModeRemote, ConnModeRule, ConnModeReject:
connMode = mode
return nil
default:
return nil
}
}
func GetConnMode() string {
return connMode
}
type Rule struct {
Type string
Value string
Policy string
Options []string
Comment string
}
func filter(req *Request) (*Rule, error) {
switch connMode {
case ConnModeDirect:
return directRule, nil
case ConnModeRemote:
return remoteRule, nil
case ConnModeReject:
return rejectRule, nil
}
for _, v := range rules {
switch v.Type {
case RuleDomainSuffix:
if req.Addr == v.Value || strings.HasSuffix(req.Addr, "."+v.Value) {
return v, nil
}
case RuleDomain:
if req.Addr == v.Value {
return v, nil
}
case RuleDomainKeyword:
if strings.Index(req.Addr, v.Value) >= 0 {
return v, nil
}
case RuleIPCIDR:
if ipCidrMap[v.Value].Contains(req.IP) {
return v, nil
}
case RuleGeoIP:
if v.Value == req.DomainHost.Country {
return v, nil
}
case RuleFinal:
return v, nil
}
}
return nil, nil
}
var directRule = &Rule{
Type: "GLOBAL",
Policy: PolicyDirect,
}
var remoteRule = &Rule{
Type: "GLOBAL",
Policy: PolicyGlobal,
}
var rejectRule = &Rule{
Type: "GLOBAL",
Policy: PolicyReject,
}