Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e7dc3c73e3 | ||
|
dae7521e26 | ||
|
1f84d5ec79 | ||
|
5882bab2f3 | ||
|
b52adf23f3 | ||
|
9b61c8bae3 | ||
|
de5ee33866 | ||
|
7733db1744 | ||
|
aaa53b54e4 | ||
|
a00de486e4 | ||
|
abbfb5fbd9 | ||
|
627cca4dbf | ||
67cf4bc888 | |||
4149ea8d0f | |||
c5bb70cf52 | |||
1918bc3328 | |||
e25b10d931 | |||
ad881c1338 | |||
d66bfc0ee9 | |||
|
e498b1adc5 | ||
|
6cd7c96230 | ||
|
3c32236374 | ||
|
0490f5124b | ||
|
6d4c94e49e |
35
actives.yaml
35
actives.yaml
|
@ -17,7 +17,40 @@ switch:
|
||||||
192.168.6.100:8088:
|
192.168.6.100:8088:
|
||||||
group: ["10.10.10.86", "10.10.10.87"] # 海口
|
group: ["10.10.10.86", "10.10.10.87"] # 海口
|
||||||
city: "4601"
|
city: "4601"
|
||||||
|
192.168.6.100:8090:
|
||||||
|
group: ["10.10.10.90", "10.10.10.91"] # 济南
|
||||||
|
city: "3701"
|
||||||
192.168.6.100:8091:
|
192.168.6.100:8091:
|
||||||
group: ["10.10.10.92", "10.10.10.93"] # 三亚
|
group: ["10.10.10.92", "10.10.10.93"] # 三亚
|
||||||
city: "4602"
|
city: "4602"
|
||||||
restart: 50
|
192.168.6.100:8092:
|
||||||
|
group: ["10.10.21.26", "10.10.21.27"] # 昆明
|
||||||
|
city: "5301"
|
||||||
|
192.168.6.100:8093:
|
||||||
|
group: ["10.10.21.28", "10.10.21.29"] # 福州
|
||||||
|
city: "3501"
|
||||||
|
192.168.6.100:8094:
|
||||||
|
group: ["10.10.21.10", "10.10.21.11"] # 武汉
|
||||||
|
city: "4201"
|
||||||
|
192.168.6.100:8095:
|
||||||
|
group: ["10.10.21.12", "10.10.21.14"] # 郑州
|
||||||
|
city: "4101"
|
||||||
|
192.168.6.100:8096:
|
||||||
|
group: ["10.10.21.13", "10.10.21.15"] # 宁波
|
||||||
|
city: "3302"
|
||||||
|
192.168.6.100:8097:
|
||||||
|
group: ["10.10.21.16", "10.10.21.17"] # 无锡
|
||||||
|
city: "3202"
|
||||||
|
192.168.6.100:8098:
|
||||||
|
group: ["10.10.21.18", "10.10.21.19"] # 南京
|
||||||
|
city: "3201"
|
||||||
|
192.168.6.100:8099:
|
||||||
|
group: ["10.10.21.20", "10.10.21.21"] # 石家庄
|
||||||
|
city: "1301"
|
||||||
|
192.168.6.100:8100:
|
||||||
|
group: ["10.10.21.22", "10.10.21.23"] # 合肥
|
||||||
|
city: "3401"
|
||||||
|
192.168.6.100:8101:
|
||||||
|
group: ["10.10.21.24", "10.10.21.25"] # 南昌
|
||||||
|
city: "3601"
|
||||||
|
restart: 65
|
||||||
|
|
60
dip.go
60
dip.go
|
@ -34,8 +34,8 @@ func (worker *DIPWorker) ShowGroupInfo() string {
|
||||||
overtimeLabel = "<☠?>"
|
overtimeLabel = "<☠?>"
|
||||||
}
|
}
|
||||||
tm := time.Unix(dhost.ActiveTime, 0)
|
tm := time.Unix(dhost.ActiveTime, 0)
|
||||||
tm.Format("2006-01-02 15:04:05") //2018-07-11 15:10:19
|
// tm.Format(time.RFC3339) //2018-07-11 15:10:19
|
||||||
content += dhost.Host + "(" + tm.Format("2006-01-02 15:04:05") + overtimeLabel + "),"
|
content += dhost.Host + "(" + tm.Format(time.RFC3339) + overtimeLabel + "),"
|
||||||
}
|
}
|
||||||
content = strings.TrimRight(content, ",") + "]\n"
|
content = strings.TrimRight(content, ",") + "]\n"
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ func (worker *DIPWorker) ShowGroupInfo() string {
|
||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DIPGroup 动态ip组, 一个组指的是一条可动态切换的线
|
||||||
type DIPGroup struct {
|
type DIPGroup struct {
|
||||||
Group map[string]*DHost // 原始参照
|
Group map[string]*DHost // 原始参照
|
||||||
Waitor map[string]*DHost
|
Waitor map[string]*DHost
|
||||||
|
@ -54,6 +55,7 @@ type DIPGroup struct {
|
||||||
Mutex *sync.Mutex
|
Mutex *sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDIPGroup 创建一个,动态ip组, 一个组指的是一条可动态切换的线
|
||||||
func NewDIPGroup() *DIPGroup {
|
func NewDIPGroup() *DIPGroup {
|
||||||
group := DIPGroup{}
|
group := DIPGroup{}
|
||||||
group.Group = make(map[string]*DHost)
|
group.Group = make(map[string]*DHost)
|
||||||
|
@ -69,36 +71,59 @@ func (group *DIPGroup) Choose(addr string) {
|
||||||
for ip, dhost := range group.Ready {
|
for ip, dhost := range group.Ready {
|
||||||
// 设置转换的iptable
|
// 设置转换的iptable
|
||||||
if group.Current == nil {
|
if group.Current == nil {
|
||||||
group.Current = dhost
|
log.Println(addr, " Current is nil")
|
||||||
group.Current.ActiveTime = now
|
|
||||||
SetAddrForward(group.IPTableNum, addr, ip)
|
|
||||||
} else {
|
} else {
|
||||||
restartAddr := "http://" + group.Current.Host + ":8800/pppoe/restart"
|
|
||||||
if resp, err := requests.NewSession().Get(restartAddr).Execute(); err != nil {
|
i := 0
|
||||||
log.Println(err)
|
for ; i < 2; i++ {
|
||||||
group.Current.ActiveTime += 12
|
|
||||||
defer resp.GResponse.Body.Close()
|
imokURL := "http://" + dhost.Host + ":8800/pppoe/imok"
|
||||||
} else {
|
ses := requests.NewSession()
|
||||||
defer resp.GResponse.Body.Close()
|
ses.SetConfig(requests.CRequestTimeout, 4)
|
||||||
group.Current = dhost
|
|
||||||
group.Current.ActiveTime = now
|
if _, err := ses.Get(imokURL).Execute(); err != nil {
|
||||||
// log.Println("new set addr:", group.Current.Host, "restartAddr:", restartAddr, "resp", resp.Content())
|
log.Println(err)
|
||||||
SetAddrForward(group.IPTableNum, addr, ip)
|
if i == 2 {
|
||||||
|
// 下个需要切换的DHost错误
|
||||||
|
group.Current.ActiveTime = now + 15
|
||||||
|
delete(group.Ready, ip)
|
||||||
|
return // 不执行下面的 切换操作 for ip, dhost := range group.Ready
|
||||||
|
}
|
||||||
|
} else { // 如果ping 通下个切换的主机就切换
|
||||||
|
for ii := 0; ii < 3; ii++ {
|
||||||
|
restartURL := "http://" + group.Current.Host + ":8800/pppoe/restart"
|
||||||
|
if _, err := ses.Get(restartURL).Execute(); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
} else {
|
||||||
|
break // 可以切换 ii := 0; ii < 3; ii++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break // for ; i < 3; i++ {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group.Current = dhost
|
||||||
|
group.Current.ActiveTime = now
|
||||||
|
|
||||||
|
SetAddrForward(group.IPTableNum, addr, ip)
|
||||||
group.Waitor[ip] = group.Ready[ip]
|
group.Waitor[ip] = group.Ready[ip]
|
||||||
delete(group.Ready, ip)
|
delete(group.Ready, ip)
|
||||||
|
|
||||||
break
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DHost 动态IP的一个vps
|
||||||
|
// Host vps的host属性 指定ip
|
||||||
|
// ActiveTime ActiveTime活跃时间
|
||||||
type DHost struct {
|
type DHost struct {
|
||||||
Host string
|
Host string
|
||||||
ActiveTime int64
|
ActiveTime int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDHost 创建一个DHost host 为 ip
|
||||||
func NewDHost(host string) *DHost {
|
func NewDHost(host string) *DHost {
|
||||||
dh := DHost{}
|
dh := DHost{}
|
||||||
dh.ActiveTime = time.Now().Unix()
|
dh.ActiveTime = time.Now().Unix()
|
||||||
|
@ -106,6 +131,7 @@ func NewDHost(host string) *DHost {
|
||||||
return &dh
|
return &dh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OverTime dhost对比时间是否超过limit的限制, 超时判断
|
||||||
func (dh *DHost) OverTime(now int64, limit int64) int64 {
|
func (dh *DHost) OverTime(now int64, limit int64) int64 {
|
||||||
if now-dh.ActiveTime >= limit {
|
if now-dh.ActiveTime >= limit {
|
||||||
return 1
|
return 1
|
||||||
|
|
40
readme.md
Normal file
40
readme.md
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
说明:
|
||||||
|
====
|
||||||
|
####
|
||||||
|
根据actives.yaml配置, 添加adsl拨号的主机. eg:
|
||||||
|
```yaml
|
||||||
|
switch:
|
||||||
|
192.168.6.100:8080:
|
||||||
|
group: ["10.10.10.70", "10.10.10.71"] # 苏州
|
||||||
|
city: "3205"
|
||||||
|
192.168.6.100:8082:
|
||||||
|
group: ["10.10.10.74", "10.10.10.75"] # 天津
|
||||||
|
city: "12"
|
||||||
|
192.168.6.100:8083:
|
||||||
|
group: ["10.10.10.76", "10.10.10.77"] # 滨州
|
||||||
|
city: "3716"
|
||||||
|
restart: 50
|
||||||
|
```
|
||||||
|
192.168.6.100:8080 为代理的ip地址
|
||||||
|
group: 内为adsl主机的vpn节点ip
|
||||||
|
city: 为城市代码
|
||||||
|
restart: 为切换时间
|
||||||
|
####
|
||||||
|
----
|
||||||
|
#####
|
||||||
|
http:/{ipcenter_host}/ippool/switch/actives 可以获取当前可用ip地址的json信息. eg:
|
||||||
|
```json
|
||||||
|
{"192.168.6.100:8080":{"city":"3205","group":["10.10.10.70","10.10.10.71"]},"192.168.6.100:8082":{"city":"12","group":["10.10.10.74","10.10.10.75"]},"192.168.6.100:8083":{"city":"3716","group":["10.10.10.76","10.10.10.77"]},"192.168.6.100:8085":{"city":"5328","group":["10.10.10.80","10.10.10.81"]},"192.168.6.100:8087":{"city":"1506","group":["10.10.10.84","10.10.10.85"]},"192.168.6.100:8088":{"city":"4601","group":["10.10.10.86","10.10.10.87"]},"192.168.6.100:8091":{"city":"4602","group":["10.10.10.93","10.10.10.92"]}}
|
||||||
|
```
|
||||||
|
#####
|
||||||
|
|
||||||
|
----
|
||||||
|
启动例子:
|
||||||
|
====
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone http:...
|
||||||
|
go build
|
||||||
|
sh start.sh
|
||||||
|
```
|
||||||
|
|
71
switch.go
71
switch.go
|
@ -44,6 +44,7 @@ func NewSwitch() *Switch {
|
||||||
http.HandleFunc("/ippool/switch/imactive", swi.imActive)
|
http.HandleFunc("/ippool/switch/imactive", swi.imActive)
|
||||||
http.HandleFunc("/ippool/switch/update", swi.updateActives)
|
http.HandleFunc("/ippool/switch/update", swi.updateActives)
|
||||||
http.HandleFunc("/ippool/switch/actives", swi.switchActives)
|
http.HandleFunc("/ippool/switch/actives", swi.switchActives)
|
||||||
|
http.HandleFunc("/ippool/switch/allproxies", swi.allProxies)
|
||||||
|
|
||||||
return &swi
|
return &swi
|
||||||
}
|
}
|
||||||
|
@ -55,9 +56,15 @@ func (swi *Switch) Run(addr string, ipregion string) {
|
||||||
|
|
||||||
cmd := exec.Command("/bin/sh", "-c", "sudo iptables -t nat -N IPSWITCH")
|
cmd := exec.Command("/bin/sh", "-c", "sudo iptables -t nat -N IPSWITCH")
|
||||||
cmd.Run()
|
cmd.Run()
|
||||||
|
if err := cmd.Process.Release(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
cmd = exec.Command("/bin/sh", "-c", "sudo iptables -t nat -F IPSWITCH")
|
cmd = exec.Command("/bin/sh", "-c", "sudo iptables -t nat -F IPSWITCH")
|
||||||
cmd.Run()
|
cmd.Run()
|
||||||
|
if err := cmd.Process.Release(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
for range swi.Worker.ForLoop {
|
for range swi.Worker.ForLoop {
|
||||||
cmd := exec.Command("/bin/sh", "-c", "sudo iptables -t nat -A IPSWITCH -p icmp -s 1.1.1.1 -j DNAT --to 1.1.1.1:8885")
|
cmd := exec.Command("/bin/sh", "-c", "sudo iptables -t nat -A IPSWITCH -p icmp -s 1.1.1.1 -j DNAT --to 1.1.1.1:8885")
|
||||||
|
@ -65,10 +72,15 @@ func (swi *Switch) Run(addr string, ipregion string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := cmd.Process.Release(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
http.ListenAndServe(addr, nil)
|
server := &http.Server{Addr: addr, Handler: nil}
|
||||||
|
server.SetKeepAlivesEnabled(false)
|
||||||
|
server.ListenAndServe()
|
||||||
}
|
}
|
||||||
|
|
||||||
// timeToSwitch 计算是否到切换时间
|
// timeToSwitch 计算是否到切换时间
|
||||||
|
@ -85,21 +97,38 @@ func (swi *Switch) timeToSwitch(now int64) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (swi *Switch) clearReady(now int64) {
|
||||||
|
|
||||||
|
for _, dipg := range swi.Worker.ForMatch {
|
||||||
|
var delIPList []string
|
||||||
|
|
||||||
|
for ip, dhost := range dipg.Ready {
|
||||||
|
if now >= dhost.ActiveTime+150 {
|
||||||
|
delIPList = append(delIPList, ip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ip := range delIPList {
|
||||||
|
delete(dipg.Ready, ip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// checkInReady 签到的IP(vps的vpn节点IP))
|
// checkInReady 签到的IP(vps的vpn节点IP))
|
||||||
func (swi *Switch) checkInReady(ip string, now int64) {
|
func (swi *Switch) checkInReady(ip string, now int64) {
|
||||||
|
|
||||||
if dipg, ok := swi.Worker.ForMatch[ip]; ok {
|
if dipg, ok := swi.Worker.ForMatch[ip]; ok {
|
||||||
|
|
||||||
dipg.Group[ip].ActiveTime = now
|
|
||||||
|
|
||||||
if dh, ok := dipg.Waitor[ip]; ok {
|
if dh, ok := dipg.Waitor[ip]; ok {
|
||||||
if dh.OverTime(now, 30) > 0 {
|
if dh.OverTime(now, 20) > 0 {
|
||||||
delete(dipg.Waitor, ip)
|
delete(dipg.Waitor, ip)
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dipg.Group[ip].ActiveTime = now
|
||||||
|
|
||||||
if dipg.Current == nil {
|
if dipg.Current == nil {
|
||||||
dhost := NewDHost(ip)
|
dhost := NewDHost(ip)
|
||||||
dhost.ActiveTime = now
|
dhost.ActiveTime = now
|
||||||
|
@ -135,6 +164,7 @@ func (swi *Switch) imActive(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
// 60秒show一次日志
|
// 60秒show一次日志
|
||||||
if now >= swi.lastShow+60 {
|
if now >= swi.lastShow+60 {
|
||||||
|
swi.clearReady(now)
|
||||||
swi.lastShow = now
|
swi.lastShow = now
|
||||||
log.Println("\n" + swi.Worker.ShowGroupInfo())
|
log.Println("\n" + swi.Worker.ShowGroupInfo())
|
||||||
}
|
}
|
||||||
|
@ -171,7 +201,6 @@ func (swi *Switch) switchActives(w http.ResponseWriter, req *http.Request) {
|
||||||
for addr, group := range swi.Worker.ForLoop {
|
for addr, group := range swi.Worker.ForLoop {
|
||||||
|
|
||||||
addrmap := make(map[string]interface{})
|
addrmap := make(map[string]interface{})
|
||||||
content[addr] = addrmap
|
|
||||||
|
|
||||||
isappend := int64(0)
|
isappend := int64(0)
|
||||||
var hosts []string
|
var hosts []string
|
||||||
|
@ -182,6 +211,7 @@ func (swi *Switch) switchActives(w http.ResponseWriter, req *http.Request) {
|
||||||
hosts = append(hosts, dhost.Host)
|
hosts = append(hosts, dhost.Host)
|
||||||
}
|
}
|
||||||
if isappend > 1 {
|
if isappend > 1 {
|
||||||
|
content[addr] = addrmap
|
||||||
addrmap["group"] = hosts
|
addrmap["group"] = hosts
|
||||||
addrmap["city"] = group.City
|
addrmap["city"] = group.City
|
||||||
}
|
}
|
||||||
|
@ -192,3 +222,32 @@ func (swi *Switch) switchActives(w http.ResponseWriter, req *http.Request) {
|
||||||
ErrorLog(err)
|
ErrorLog(err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (swi *Switch) allProxies(w http.ResponseWriter, req *http.Request) {
|
||||||
|
defer req.Body.Close()
|
||||||
|
|
||||||
|
swi.Worker.Mutex.Lock()
|
||||||
|
defer swi.Worker.Mutex.Unlock()
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
|
||||||
|
content := make(map[string]map[string]interface{})
|
||||||
|
for addr, group := range swi.Worker.ForLoop {
|
||||||
|
|
||||||
|
addrmap := make(map[string]interface{})
|
||||||
|
content[addr] = addrmap
|
||||||
|
|
||||||
|
isappend := int64(0)
|
||||||
|
var hosts []string
|
||||||
|
for _, dhost := range group.Group {
|
||||||
|
hosts = append(hosts, dhost.Host)
|
||||||
|
}
|
||||||
|
addrmap["group"] = hosts
|
||||||
|
addrmap["city"] = group.City
|
||||||
|
}
|
||||||
|
jdata, err := json.Marshal(content)
|
||||||
|
ErrorLog(err)
|
||||||
|
_, err = w.Write(jdata)
|
||||||
|
ErrorLog(err)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSwitchYaml(t *testing.T) {
|
func TestSwitchYaml(t *testing.T) {
|
||||||
t.Error()
|
|
||||||
|
|
||||||
swi := NewSwitch()
|
swi := NewSwitch()
|
||||||
if swi == nil {
|
if swi == nil {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user