// GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 // Copyright (c) 2023 WIT.COM, Inc. // This is a control panel for DNS package main import ( "fmt" "strings" "sort" "strconv" "runtime" "time" "embed" "go.wit.com/log" "go.wit.com/gui/gui" "go.wit.com/gui/debugger" "github.com/miekg/dns" ) //go:embed plugins/*.so var resToolkit embed.FS func main() { // parsedown() // initialize the maps to track IP addresses and network interfaces me.ipmap = make(map[string]*IPtype) me.dnsmap = make(map[string]*IPtype) me.ifmap = make(map[int]*IFtype) me.nsmap = make(map[string]string) // initialize maps for the returned DNS records me.ipv4s = make(map[string]dns.RR) me.ipv6s = make(map[string]dns.RR) // send all log() output to a file in /tmp log.SetTmp() me.myGui = gui.New().Default() log.Sleep(me.artificialSleep) setupControlPanelWindow() if debugger.ArgDebug() { log.Sleep(2) debugger.DebugWindow(me.myGui) } // forever monitor for network and dns changes log.Sleep(me.artificialSleep) checkNetworkChanges() } /* Poll for changes to the networking settings */ /* https://github.com/robfig/cron/blob/master/cron.go // Run the cron scheduler, or no-op if already running. func (c *Cron) Run() { c.runningMu.Lock() if c.running { c.runningMu.Unlock() return } c.running = true c.runningMu.Unlock() c.run() } // run the scheduler.. this is private just due to the need to synchronize // access to the 'running' state variable. func (c *Cron) run() { c.logger.Info("start") */ func checkNetworkChanges() { var lastLocal time.Time = time.Now() var lastDNS time.Time = time.Now() timer2 := time.NewTimer(time.Second) go func() { <-timer2.C fmt.Println("Timer 2 fired") }() for { time.Sleep(me.ttl.Duration) if (time.Since(lastLocal) > me.localSleep) { if (runtime.GOOS == "linux") { duration := timeFunction(linuxLoop) s := fmt.Sprint(duration) me.LocalSpeedActual.SetText(s) } else { // TODO: make windows and macos diagnostics log.Warn("Windows and MacOS don't work yet") } lastLocal = time.Now() } if (time.Since(lastDNS) > me.dnsTtl.Duration) { DNSloop() lastDNS = time.Now() } /* stop2 := timer2.Stop() if stop2 { fmt.Println("Timer 2 stopped") } */ } } // run this on each timeout func DNSloop() { duration := timeFunction(dnsTTL) log.Info("dnsTTL() execution Time: ", duration) var s, newSpeed string if (duration > 5000 * time.Millisecond ) { newSpeed = "VERY BAD" suggestProcDebugging() } else if (duration > 2000 * time.Millisecond ) { newSpeed = "BAD" suggestProcDebugging() } else if (duration > 500 * time.Millisecond ) { suggestProcDebugging() newSpeed = "SLOW" } else if (duration > 100 * time.Millisecond ) { newSpeed = "OK" if (me.fixProc != nil) { // me.fixProc.Disable() } } else { newSpeed = "FAST" if (me.fixProc != nil) { // me.fixProc.Disable() } } if (newSpeed != me.DnsSpeedLast) { log.Log(CHANGE, "dns lookup speed changed =", newSpeed) log.Log(CHANGE, "dnsTTL() execution Time: ", duration) me.DnsSpeed.SetText(newSpeed) me.DnsSpeedLast = newSpeed } s = fmt.Sprint(duration) me.DnsSpeedActual.SetText(s) } // This checks for changes to the network settings // and verifies that DNS is working or not working func dnsTTL() { updateDNS() } func linuxLoop() { me.changed = false log.Log(NET, "FQDN =", me.fqdn.GetText()) duration := timeFunction(getHostname) log.Info("getHostname() execution Time: ", duration, "me.changed =", me.changed) duration = timeFunction(scanInterfaces) log.Log(NET, "scanInterfaces() execution Time: ", duration) for i, t := range me.ifmap { log.Log(NET, strconv.Itoa(i) + " iface = " + t.iface.Name) } var aaaa []string aaaa = dhcpAAAA() var all string for _, s := range aaaa { log.Log(NET, "my actual AAAA = ",s) all += s + "\n" } // me.IPv6.SetText(all) if (me.changed) { stamp := time.Now().Format("2006/01/02 15:04:05") log.Log(CHANGE, "Network things changed on", stamp) duration := timeFunction(updateDNS) log.Log(CHANGE, "updateDNS() execution Time: ", duration) } /* processName := getProcessNameByPort(53) fmt.Println("Process with port 53:", processName) commPath := filepath.Join("/proc", proc.Name(), "comm") comm, err := ioutil.ReadFile(commPath) if err != nil { return "", err // Error reading the process name } return strings.TrimSpace(string(comm)), nil */ } /* // Example usage duration := timeFunction(FunctionToTime) log.Println("Execution Time: ", duration) */ // timeFunction takes a function as an argument and returns the execution time. func timeFunction(f func()) time.Duration { startTime := time.Now() // Record the start time f() // Execute the function return time.Since(startTime) // Calculate the elapsed time } // sortLines takes a string, splits it on newlines, sorts the lines, // and rejoins them with newlines. func sortLines(input string) string { lines := strings.Split(input, "\n") // Trim leading and trailing whitespace from each line for i, line := range lines { lines[i] = strings.TrimSpace(line) } sort.Strings(lines) tmp := strings.Join(lines, "\n") tmp = strings.TrimLeft(tmp, "\n") tmp = strings.TrimRight(tmp, "\n") return tmp }