157 lines
3.8 KiB
Go
157 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"net"
|
|
"os/exec"
|
|
"strings"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
// DutiesNet 保证PPPoe可行
|
|
type DutiesNet struct {
|
|
PW *PingWorker
|
|
|
|
NetProtectTime int64 // 当前时间大于保护时间,才能进行重启的计算操作(pppoe最大重启保护时间, 保证重启后不会重复接受重启命令而造成不停重启 )
|
|
MaxProtectTime int64 // NetProtectTime保护时间的最大值
|
|
CmdRestart int64 // 只要大于MaxRestart就重启
|
|
MaxRestart int64 // 达到这个值就重启
|
|
}
|
|
|
|
// Default 设置默认值
|
|
func (duties *DutiesNet) Default(pw *PingWorker) {
|
|
duties.PW = pw
|
|
atomic.StoreInt64(&duties.MaxProtectTime, 15)
|
|
atomic.StoreInt64(&duties.CmdRestart, 0)
|
|
duties.MaxRestart = 4
|
|
go duties.Duties()
|
|
}
|
|
|
|
// IsPPP0Up Pppoe是否是UP的状态
|
|
func (duties *DutiesNet) IsPPP0Up() bool {
|
|
ifaces, err := net.Interfaces()
|
|
if ErrorLog(err) {
|
|
return false
|
|
}
|
|
|
|
for _, i := range ifaces {
|
|
if i.Name == "ppp0" {
|
|
flags := strings.Split(i.Flags.String(), "|")
|
|
if len(flags) > 0 {
|
|
log.Println(flags)
|
|
if flags[0] != "up" {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// IsPPP1Exist ppp1是否是UP的状态
|
|
func (duties *DutiesNet) IsPPP1Exist() bool {
|
|
ifaces, err := net.Interfaces()
|
|
if ErrorLog(err) {
|
|
return false
|
|
}
|
|
|
|
for _, i := range ifaces {
|
|
if i.Name == "ppp1" {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// PPP0Restart ppp0 重启
|
|
func (duties *DutiesNet) PPP0Restart() {
|
|
log.Println("PPP0Restart")
|
|
_, err := exec.Command("ifdown", "ppp1").Output()
|
|
ErrorLog(err)
|
|
_, err = exec.Command("ifdown", "ppp0").Output()
|
|
ErrorLog(err)
|
|
time.Sleep(time.Second * 1)
|
|
_, err = exec.Command("ifdown", "ppp0").Output()
|
|
ErrorLog(err)
|
|
time.Sleep(time.Second * 1)
|
|
_, err = exec.Command("ifup", "ppp0").Output()
|
|
ErrorLog(err)
|
|
time.Sleep(time.Second * 5)
|
|
_, err = exec.Command("ip", "route", "replace", "default", "dev", "ppp0").CombinedOutput()
|
|
ErrorLog(err)
|
|
|
|
atomic.StoreInt64(&duties.NetProtectTime, time.Now().Unix()+duties.MaxProtectTime)
|
|
atomic.StoreInt64(&duties.CmdRestart, 0)
|
|
}
|
|
|
|
// SetRestart 设置重启 异步
|
|
func (duties *DutiesNet) SetRestart() {
|
|
log.Println("SetRestart")
|
|
now := time.Now().Unix()
|
|
// 当前时间大于保护时间,才能进行重启的计算操作
|
|
if now >= duties.NetProtectTime {
|
|
log.Println("SetRestart Success")
|
|
atomic.AddInt64(&duties.CmdRestart, duties.MaxRestart+20) // 设置超过最大的值的20, 保证重启.
|
|
}
|
|
}
|
|
|
|
func (duties *DutiesNet) checkError1() bool {
|
|
if duties.IsPPP1Exist() {
|
|
log.Println("IsPPP1Exist not")
|
|
duties.PPP0Restart()
|
|
return true
|
|
}
|
|
return false // 检测错误才返回true 否则 false
|
|
}
|
|
|
|
func (duties *DutiesNet) checkError2() bool {
|
|
// 检测3次ppp0是否处于Up的状态(pppoe有可能存在Down的状态, 这种错误. 但是判断为已经成功拨号)
|
|
for i := 0; i < 4; i++ {
|
|
if duties.IsPPP0Up() {
|
|
return false
|
|
}
|
|
if i == 3 {
|
|
log.Println("IsPPP0Up not")
|
|
duties.PPP0Restart() // 强制重启, 不受最大值的限制
|
|
return true
|
|
}
|
|
time.Sleep(time.Second * 1)
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
//Duties 核心循环过程, 保证pppoe的网络可行
|
|
func (duties *DutiesNet) Duties() {
|
|
for {
|
|
// 如果超过MaxRestart也会重启
|
|
if atomic.LoadInt64(&duties.CmdRestart) > duties.MaxRestart {
|
|
log.Println("CmdRestart ", atomic.LoadInt64(&duties.CmdRestart))
|
|
duties.PPP0Restart()
|
|
}
|
|
|
|
time.Sleep(time.Second * 2)
|
|
|
|
// 如果网络不能ping通 执行下面的处理
|
|
if !duties.PW.PingNet() {
|
|
time.Sleep(time.Second * 1)
|
|
atomic.AddInt64(&duties.CmdRestart, 1) // 重启因素的积累, 出一次错误就积累一次. 达到最大值后重启
|
|
|
|
if duties.checkError1() {
|
|
continue
|
|
}
|
|
|
|
if duties.checkError2() {
|
|
continue
|
|
}
|
|
|
|
} else {
|
|
if atomic.LoadInt64(&duties.CmdRestart) > 0 {
|
|
atomic.AddInt64(&duties.CmdRestart, -1) // 如果Ping成功就减少重启因素积累. 0为最低限制值
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|