-
Notifications
You must be signed in to change notification settings - Fork 27
/
helperFunc.go
230 lines (216 loc) · 6.92 KB
/
helperFunc.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
package main
import (
"errors"
"github.com/joyanhui/ikuai-bypass/router"
"io"
"log"
"net/http"
"strconv"
"strings"
"time"
"github.com/joyanhui/ikuai-bypass/api"
)
// 读取配置文件 到 conf
// updateCustomIsp 更新运营商分流规则
func updateCustomIsp(iKuai *api.IKuai, name string, tag string, url string) (err error) {
log.Println("运营商/IP分流== http.get ...", url)
resp, err := http.Get(url)
if err != nil {
return
}
if resp.StatusCode != 200 {
err = errors.New(resp.Status)
return
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return
}
ips := strings.Split(string(body), "\n")
ips = removeIpv6AndRemoveEmptyLine(ips)
log.Println("运营商/IP分流== ", name, tag, " 获取到", len(ips), "个ip")
ipGroups := group(ips, 5000) //5000条
for _, ig := range ipGroups {
ipGroup := strings.Join(ig, ",")
err = iKuai.AddCustomIsp(name, tag, ipGroup)
if err != nil {
log.Println("运营商/IP分流== ", name, tag, "添加失败,可能是列表太多了,添加太快,爱快没响应。", conf.AddErrRetryWait, "秒后重试", err)
time.Sleep(conf.AddErrRetryWait)
err = iKuai.AddCustomIsp(name, tag, ipGroup)
if err != nil {
log.Println("运营商/IP分流== ", name, tag, "重试失败,可能是列表太多了,添加太快,爱快没响应。已经重试过一次,所以跳过此次操作")
break
}
}
log.Println("运营商/IP分流== 添加ip:", len(ig), " 个,等待", conf.AddWait, "秒继续处理")
time.Sleep(conf.AddWait)
}
return
}
// updateStreamDomain 更新域名分流规则
func updateStreamDomain(iKuai *api.IKuai, iface, tag, srcAddr, url string) (err error) {
log.Println("域名分流== http.get ...", url)
resp, err := http.Get(url)
if err != nil {
return
}
if resp.StatusCode != 200 {
err = errors.New(resp.Status)
return
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return
}
domains := strings.Split(string(body), "\n")
log.Println("域名分流== ", iface, tag, "获取到", len(domains), "个域名")
domainGroup := group(domains, 1000) //1000条
var countFor int = 0
for _, d := range domainGroup {
countFor = countFor + 1
log.Println("域名分流== ", countFor, "/", len(domainGroup), iface, tag, " 正在添加 .... ")
domain := strings.Join(d, ",")
err = iKuai.AddStreamDomain(iface, tag, srcAddr, domain)
if err != nil {
log.Println("域名分流== ", countFor, "/", len(domainGroup), iface, tag, "添加失败,可能是列表太多了,添加太快,爱快没响应。", conf.AddErrRetryWait, "秒后重试", err)
time.Sleep(conf.AddErrRetryWait)
err = iKuai.AddStreamDomain(iface, tag, srcAddr, domain)
if err != nil {
log.Println("域名分流= ", countFor, "/", len(domainGroup), iface, tag, "重试失败,可能是列表太多了,添加太快,爱快没响应。已经重试过一次,所以跳过此次操作")
break
}
} else {
log.Println("域名分流== ", iface, tag, " 添加域名:", len(d), " 个成功,等待", conf.AddWait, "秒继续处理")
time.Sleep(conf.AddWait)
}
}
return
}
func removeIpv6AndRemoveEmptyLine(ips []string) []string {
log.Println("移除ipv6地址 和删除空行....")
i := 0
for _, ip := range ips {
if !strings.Contains(ip, ":") {
//删除空行
ip = strings.Trim(strings.Trim(ip, "\n"), "\r")
if ip != "" {
ips[i] = ip
i++
}
}
}
return ips[:i]
}
func group(arr []string, subGroupLength int64) [][]string {
groupMax := int64(len(arr))
var segmens = make([][]string, 0)
quantity := groupMax / subGroupLength
remainder := groupMax % subGroupLength
i := int64(0)
for i = int64(0); i < quantity; i++ {
segmens = append(segmens, arr[i*subGroupLength:(i+1)*subGroupLength])
}
if quantity == 0 || remainder != 0 {
segmens = append(segmens, arr[i*subGroupLength:i*subGroupLength+remainder])
}
return segmens
}
// 更新ip分组
func updateIpGroup(iKuai *api.IKuai, name, url string) (err error) {
log.Println("ip分组== http.get ...", url)
resp, err := http.Get(url)
if err != nil {
return
}
if resp.StatusCode != 200 {
err = errors.New(resp.Status)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return
}
ips := strings.Split(string(body), "\n")
ips = removeIpv6AndRemoveEmptyLine(ips)
ipGroups := group(ips, 1000)
for index, ig := range ipGroups {
log.Println("ip分组== ", index, " 正在添加 .... ")
ipGroup := strings.Join(ig, ",")
err := iKuai.AddIpGroup(name+"_"+strconv.Itoa(index), ipGroup)
if err != nil {
log.Println("ip分组== ", index, "添加失败,可能是列表太多了,添加太快,爱快没响应。", conf.AddErrRetryWait, "秒后重试", err)
time.Sleep(conf.AddWait)
}
}
return
}
// 更新ip端口分流
func updateStreamIpPort(iKuai *api.IKuai, forwardType string, iface string, nexthop string, srcAddr string, ipGroup string) (err error) {
var ipGroupList []string
for _, ipGroupItem := range strings.Split(ipGroup, ",") {
var data []string
data, err = iKuai.GetAllIKuaiBypassIpGroupNamesByName(ipGroupItem)
if err != nil {
return
}
ipGroupList = append(ipGroupList, data...)
}
err = iKuai.AddStreamIpPort(forwardType, iface, strings.Join(ipGroupList, ","), srcAddr, nexthop, ipGroup)
if err != nil {
log.Println("ip端口分流== 添加失败,可能是列表太多了,添加太快,爱快没响应。", conf.AddErrRetryWait, "秒后重试", err)
time.Sleep(conf.AddErrRetryWait)
}
return
}
// 登陆爱快
func loginToIkuai() (*api.IKuai, error) {
err := readConf(*confPath)
if err != nil {
log.Println("读取配置文件失败:", err)
return nil, err
}
if *ikuaiLoginInfo != "" {
log.Println("使用命令行参数登陆爱快")
ikuaiLoginInfoArr := strings.Split(*ikuaiLoginInfo, ",")
if len(ikuaiLoginInfoArr) != 3 {
log.Println(*ikuaiLoginInfo)
log.Println("命令行参数格式错误,请使用 -login http://ip|username|password ")
return nil, errors.New("命令行参数格式错误,请使用 -login=\"ip|username|password\"")
}
iKuai := api.NewIKuai(ikuaiLoginInfoArr[0])
err = iKuai.Login(ikuaiLoginInfoArr[1], ikuaiLoginInfoArr[2])
if err != nil {
log.Println("ikuai 登陆失败:", *ikuaiLoginInfo, err)
return nil, err
} else {
log.Println("ikuai 登录成功", ikuaiLoginInfoArr[0])
return iKuai, nil
}
} else {
baseurl := conf.IkuaiURL
if baseurl == "" {
gateway, err := router.GetGateway()
if err != nil {
log.Println("获取默认网关失败:", err)
return nil, err
}
baseurl = "http://" + gateway
log.Println("使用默认网关地址:", baseurl)
}
iKuai := api.NewIKuai(baseurl)
err = iKuai.Login(conf.Username, conf.Password)
if err != nil {
log.Println("ikuai 登陆失败:", baseurl, err)
return iKuai, err
} else {
log.Println("ikuai 登录成功", baseurl)
return iKuai, nil
}
}
}