package lib import ( "fmt" "net" "os" "strings" "time" ) // UpdateVPNStatus periodically update status of openvpn daemon. func (c *MyConfig) UpdateVPNStatus() { var ( vpnCStatus string vpnCheck string b strings.Builder InitialDelay = 100 * time.Millisecond LoopIterationDelay = 3 * time.Second Delay = InitialDelay ticker = time.NewTicker(Delay) ) for range ticker.C { if Delay == InitialDelay { Delay = LoopIterationDelay ticker.Reset(Delay) } if c.VPNFileCheck() { if c.Vpn.UpColor == "" { b.WriteRune('⍋') } else { b.WriteString("⍋") } } else { if c.Vpn.DownColor == "" { b.WriteRune('⍒') } else { b.WriteString("⍒") } } vpnCheck = b.String() b.Reset() if c.Vpn.TCPCheck.Enabled { if c.VPNTCPCheck() { if c.Vpn.UpColor == "" { b.WriteRune('✔') } else { b.WriteString("✔") } } else { if c.Vpn.DownColor == "" { b.WriteRune('✘') } else { b.WriteString("✘") } } vpnCStatus = "VPN:" + vpnCheck + ":" + b.String() } else { vpnCStatus = "VPN:" + vpnCheck } if c.Values.VPNStatus != vpnCStatus { c.Values.VPNStatus = vpnCStatus c.Channels.UpdateReady <- true } } } // VPNTCPCheck intended to check arbitrary service inside vpn segment, to indicate that openvpn service not stoned. func (c *MyConfig) VPNTCPCheck() bool { conn, err := net.DialTimeout( //nolint: noctx "tcp", fmt.Sprintf("%s:%d", c.Vpn.TCPCheck.Host, c.Vpn.TCPCheck.Port), //nolint: hostport time.Second*time.Duration(c.Vpn.TCPCheck.Timeout), ) if err == nil { _ = conn.Close() return true } return false } // VPNFileCheck checks modification time of openvpn-status file. func (c *MyConfig) VPNFileCheck() bool { var ( fi os.FileInfo err error ) if fi, err = os.Stat(c.Vpn.StatusFile); err != nil { return false } if time.Since(fi.ModTime()).Seconds() > float64(c.Vpn.MtimeThreshold) { return false } return true } /* vim: set ft=go noet ai ts=4 sw=4 sts=4: */