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为最低限制值 } } } }