forked from netheril96/MEOW
-
Notifications
You must be signed in to change notification settings - Fork 0
/
directlist.go
129 lines (115 loc) · 3 KB
/
directlist.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
129
package main
import (
"net"
"os"
"strings"
"sync"
"github.com/cyfdecyf/bufio"
)
type DomainList struct {
Domain map[string]DomainType
sync.RWMutex
}
type DomainType byte
const (
domainTypeUnknown DomainType = iota
domainTypeDirect
domainTypeProxy
domainTypeReject
)
func newDomainList() *DomainList {
return &DomainList{
Domain: map[string]DomainType{},
}
}
func (domainList *DomainList) judge(url *URL) (domainType DomainType) {
debug.Printf("judging host: %s", url.Host)
if domainList.Domain[url.Host] == domainTypeReject || domainList.Domain[url.Domain] == domainTypeReject {
debug.Printf("host or domain should reject")
return domainTypeReject
}
if parentProxy.empty() { // no way to retry, so always visit directly
return domainTypeDirect
}
if url.Domain == "" { // simple host or private ip
return domainTypeDirect
}
if domainList.Domain[url.Host] == domainTypeDirect || domainList.Domain[url.Domain] == domainTypeDirect {
debug.Printf("host or domain should direct")
return domainTypeDirect
}
if domainList.Domain[url.Host] == domainTypeProxy || domainList.Domain[url.Domain] == domainTypeProxy {
debug.Printf("host or domain should using proxy")
return domainTypeProxy
}
if !config.JudgeByIP {
return domainTypeProxy
}
debug.Printf("judging by ip")
var ip string
isIP, isPrivate := hostIsIP(url.Host)
if isIP {
if isPrivate {
domainList.add(url.Host, domainTypeDirect)
return domainTypeDirect
}
ip = url.Host
} else {
hostIPs, err := net.LookupIP(url.Host)
if err != nil {
errl.Printf("error looking up host ip %s, err %s", url.Host, err)
return domainTypeProxy
}
ip = hostIPs[0].String()
}
if ipShouldDirect(ip) {
domainList.add(url.Host, domainTypeDirect)
debug.Printf("host or domain should direct")
return domainTypeDirect
} else {
domainList.add(url.Host, domainTypeProxy)
debug.Printf("host or domain should using proxy")
return domainTypeProxy
}
}
func (domainList *DomainList) add(host string, domainType DomainType) {
domainList.Lock()
defer domainList.Unlock()
domainList.Domain[host] = domainType
}
func (domainList *DomainList) GetDomainList() []string {
lst := make([]string, 0)
for site, domainType := range domainList.Domain {
if domainType == domainTypeDirect {
lst = append(lst, site)
}
}
return lst
}
var domainList = newDomainList()
func initDomainList(domainListFile string, domainType DomainType) {
var err error
if err = isFileExists(domainListFile); err != nil {
return
}
f, err := os.Open(domainListFile)
if err != nil {
errl.Println("Error opening domain list:", err)
return
}
defer f.Close()
domainList.Lock()
defer domainList.Unlock()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
domain := strings.TrimSpace(scanner.Text())
if domain == "" {
continue
}
debug.Printf("Loaded domain %s as type %v", domain, domainType)
domainList.Domain[domain] = domainType
}
if scanner.Err() != nil {
errl.Printf("Error reading domain list %s: %v\n", domainListFile, scanner.Err())
}
}