pppoe_control/dutiesnet.go
2018-12-22 23:31:13 +08:00

171 lines
4.1 KiB
Go

package main
import (
"log"
"net"
"os"
"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
}
// IsPPPNExist ppp1是否是UP的状态
func (duties *DutiesNet) IsPPPNExist(pppname string) bool {
ifaces, err := net.Interfaces()
if ErrorLog(err) {
return false
}
for _, i := range ifaces {
if i.Name == pppname {
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.IsPPPNExist("ppp1") {
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
}
func (duties *DutiesNet) checkError3() bool {
if duties.IsPPPNExist("ppp2") {
log.Println("IsPPP2Exist not")
os.Exit(2)
return true
}
return false // 检测错误才返回true 否则 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.checkError3() {
continue
}
if duties.checkError1() {
continue
}
if duties.checkError2() {
continue
}
} else {
if atomic.LoadInt64(&duties.CmdRestart) > 0 {
atomic.AddInt64(&duties.CmdRestart, -1) // 如果Ping成功就减少重启因素积累. 0为最低限制值
}
}
}
}