measure dns resolution speed

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2023-12-16 22:49:35 -06:00
parent 2286ece452
commit a417cb2930
6 changed files with 126 additions and 55 deletions

22
gui.go
View File

@ -152,8 +152,10 @@ func dnsTab(title string) {
grid.NewLabel("interfaces =") grid.NewLabel("interfaces =")
me.Interfaces = grid.NewCombobox("Interfaces") me.Interfaces = grid.NewCombobox("Interfaces")
/*
grid.NewLabel("DNS Status =") grid.NewLabel("DNS Status =")
me.DnsStatus = grid.NewLabel("unknown") me.DnsStatus = grid.NewLabel("unknown")
*/
me.fix = g.NewButton("Fix", func () { me.fix = g.NewButton("Fix", func () {
if (goodHostname(me.hostname)) { if (goodHostname(me.hostname)) {
@ -166,6 +168,9 @@ func dnsTab(title string) {
}) })
me.fix.Disable() me.fix.Disable()
grid.Margin()
grid.Pad()
statusGrid(tab) statusGrid(tab)
} }
@ -176,11 +181,18 @@ func statusGrid(n *gui.Node) {
gridP := problems.NewGrid("nuts", 2, 2) gridP := problems.NewGrid("nuts", 2, 2)
gridP.NewLabel("DNS Status =") gridP.NewLabel("DNS Status =")
gridP.NewLabel("unknown") me.DnsStatus = gridP.NewLabel("unknown")
gridP.NewLabel("hostname =") gridP.NewLabel("hostname =")
gridP.NewLabel("invalid") gridP.NewLabel("invalid")
gridP.NewLabel("dns resolution speed")
me.DnsSpeed = gridP.NewLabel("unknown")
gridP.Margin()
gridP.Pad()
// TODO: these are notes for me things to figure out
ng := n.NewGroup("TODO:") ng := n.NewGroup("TODO:")
gridP = ng.NewGrid("nut2", 2, 2) gridP = ng.NewGrid("nut2", 2, 2)
@ -190,14 +202,16 @@ func statusGrid(n *gui.Node) {
gridP.NewLabel("IPv6 working =") gridP.NewLabel("IPv6 working =")
gridP.NewLabel("unknown") gridP.NewLabel("unknown")
gridP.NewLabel("dns resolution =")
gridP.NewLabel("unknown")
gridP.NewLabel("ping.wit.com =") gridP.NewLabel("ping.wit.com =")
gridP.NewLabel("unknown") gridP.NewLabel("unknown")
gridP.NewLabel("ping6.wit.com =") gridP.NewLabel("ping6.wit.com =")
gridP.NewLabel("unknown") gridP.NewLabel("unknown")
problems.Margin()
problems.Pad()
gridP.Margin()
gridP.Pad()
} }
/* /*

22
log.go
View File

@ -2,6 +2,7 @@ package main
import ( import (
"log" "log"
"reflect"
witlog "git.wit.org/wit/gui/log" witlog "git.wit.org/wit/gui/log"
) )
@ -12,6 +13,8 @@ var logWarn bool = false
var logInfo bool = false var logInfo bool = false
var logVerbose bool = false var logVerbose bool = false
var DEBUGOFF bool = true
var SPEW witlog.Spewt var SPEW witlog.Spewt
// var log interface{} // var log interface{}
@ -31,3 +34,22 @@ func exit(a ...any) {
log.Println(logError, "got to log() exit") log.Println(logError, "got to log() exit")
witlog.Exit(a...) witlog.Exit(a...)
} }
func debug(a ...any) {
if (DEBUGOFF) {
return
}
if (a == nil) {
return
}
var tbool bool
if (reflect.TypeOf(a[0]) == reflect.TypeOf(tbool)) {
if (a[0] == false) {
return
}
a[0] = "ipv6 cp" // ipv6 control panel debugging line
}
log.Println(a...)
}

43
main.go
View File

@ -5,6 +5,7 @@
package main package main
import ( import (
"fmt"
"log" "log"
"strconv" "strconv"
"runtime" "runtime"
@ -17,6 +18,7 @@ var myGui *gui.Node
//go:embed plugins/*.so //go:embed plugins/*.so
var resToolkit embed.FS var resToolkit embed.FS
var tenth time.Duration = 1 // in tenths of seconds
func main() { func main() {
// parsedown() // parsedown()
@ -32,15 +34,19 @@ func main() {
// myGui = gui.New().InitEmbed(resToolkit).LoadToolkit("gocui") // myGui = gui.New().InitEmbed(resToolkit).LoadToolkit("gocui")
myGui = gui.New().Default() myGui = gui.New().Default()
sleep(me.artificialSleep) sleep(me.artificialSleep)
setupControlPanelWindow() setupControlPanelWindow()
sleep(me.artificialSleep)
/*
if (args.GuiDebug) { if (args.GuiDebug) {
gui.DebugWindow() gui.DebugWindow()
} }
gui.ShowDebugValues() gui.ShowDebugValues()
*/
// forever monitor for network and dns changes // forever monitor for network and dns changes
sleep(me.artificialSleep)
checkNetworkChanges() checkNetworkChanges()
} }
@ -54,7 +60,20 @@ func checkNetworkChanges() {
ttl -= 1 ttl -= 1
if (ttl < 0) { if (ttl < 0) {
if (runtime.GOOS == "linux") { if (runtime.GOOS == "linux") {
dnsTTL() duration := timeFunction(dnsTTL)
log.Println("dnsTTL() execution Time: ", duration)
var s string
if (duration > 50 * tenth) {
s = fmt.Sprint("VERY BAD\n", duration)
} else if (duration > 20 * tenth) {
s = fmt.Sprint("BAD\n", duration)
} else if (duration > 5 * tenth) {
s = fmt.Sprint("SLOW\n", duration)
} else {
s = fmt.Sprint("OK\n", duration)
}
log.Println(true, "getHostname()", s)
me.DnsSpeed.SetText(s)
} else { } else {
log.Println("Windows and MacOS don't work yet") log.Println("Windows and MacOS don't work yet")
} }
@ -68,8 +87,11 @@ func checkNetworkChanges() {
func dnsTTL() { func dnsTTL() {
me.changed = false me.changed = false
log.Println("FQDN =", me.fqdn.GetText()) log.Println("FQDN =", me.fqdn.GetText())
getHostname() duration := timeFunction(getHostname)
scanInterfaces() debug(true, "getHostname() execution Time: ", duration)
duration = timeFunction(scanInterfaces)
log.Println("scanInterfaces() execution Time: ", duration)
for i, t := range me.ifmap { for i, t := range me.ifmap {
log.Println(strconv.Itoa(i) + " iface = " + t.iface.Name) log.Println(strconv.Itoa(i) + " iface = " + t.iface.Name)
} }
@ -89,3 +111,16 @@ func dnsTTL() {
updateDNS() updateDNS()
} }
} }
/*
// 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
}

86
net.go
View File

@ -2,7 +2,7 @@
package main package main
import ( import (
"log" // "log"
"net" "net"
"strings" "strings"
) )
@ -18,21 +18,21 @@ func watchNetworkInterfaces() {
// Set up a notification channel // Set up a notification channel
notification := make(chan net.Interface) notification := make(chan net.Interface)
log.Println(DEBUGNET, "watchNet()") debug(DEBUGNET, "watchNet()")
// Start goroutine to watch for changes // Start goroutine to watch for changes
go func() { go func() {
log.Println(DEBUGNET, "watchNet() func") debug(DEBUGNET, "watchNet() func")
for { for {
log.Println(DEBUGNET, "forever loop start") debug(DEBUGNET, "forever loop start")
// Check for changes in each interface // Check for changes in each interface
for _, i := range interfaces { for _, i := range interfaces {
log.Println(DEBUGNET, "something on i =", i) debug(DEBUGNET, "something on i =", i)
if status := i.Flags & net.FlagUp; status != 0 { if status := i.Flags & net.FlagUp; status != 0 {
notification <- i notification <- i
log.Println(DEBUGNET, "something on i =", i) debug(DEBUGNET, "something on i =", i)
} }
} }
log.Println(DEBUGNET, "forever loop end") debug(DEBUGNET, "forever loop end")
} }
}() }()
} }
@ -44,20 +44,20 @@ func IsIPv6(address string) bool {
func (t *IPtype) IsReal() bool { func (t *IPtype) IsReal() bool {
if (t.ip.IsPrivate() || t.ip.IsLoopback() || t.ip.IsLinkLocalUnicast()) { if (t.ip.IsPrivate() || t.ip.IsLoopback() || t.ip.IsLinkLocalUnicast()) {
log.Println(DEBUGNET, "\t\tIP is Real = false") debug(DEBUGNET, "\t\tIP is Real = false")
return false return false
} else { } else {
log.Println(DEBUGNET, "\t\tIP is Real = true") debug(DEBUGNET, "\t\tIP is Real = true")
return true return true
} }
} }
func IsReal(ip *net.IP) bool { func IsReal(ip *net.IP) bool {
if (ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast()) { if (ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast()) {
log.Println(DEBUGNET, "\t\tIP is Real = false") debug(DEBUGNET, "\t\tIP is Real = false")
return false return false
} else { } else {
log.Println(DEBUGNET, "\t\tIP is Real = true") debug(DEBUGNET, "\t\tIP is Real = true")
return true return true
} }
} }
@ -74,7 +74,7 @@ func renameInterface(i *net.Interface) {
func checkInterface(i net.Interface) { func checkInterface(i net.Interface) {
val, ok := me.ifmap[i.Index] val, ok := me.ifmap[i.Index]
if ! ok { if ! ok {
log.Println(i.Name, "is a new network interface. The linux kernel index =", i.Index) debug(i.Name, "is a new network interface. The linux kernel index =", i.Index)
me.ifmap[i.Index] = new(IFtype) me.ifmap[i.Index] = new(IFtype)
me.ifmap[i.Index].gone = false me.ifmap[i.Index].gone = false
me.ifmap[i.Index].iface = &i me.ifmap[i.Index].iface = &i
@ -86,9 +86,9 @@ func checkInterface(i net.Interface) {
return return
} }
me.ifmap[i.Index].gone = false me.ifmap[i.Index].gone = false
log.Println(args.VerboseNet, "me.ifmap[i] does exist. Need to compare everything.", i.Index, i.Name, val.iface.Index, val.iface.Name) debug(args.VerboseNet, "me.ifmap[i] does exist. Need to compare everything.", i.Index, i.Name, val.iface.Index, val.iface.Name)
if (val.iface.Name != i.Name) { if (val.iface.Name != i.Name) {
log.Println(val.iface.Name, "has changed to it's name to", i.Name) debug(val.iface.Name, "has changed to it's name to", i.Name)
me.ifmap[i.Index].iface = &i me.ifmap[i.Index].iface = &i
me.changed = true me.changed = true
if (me.Interfaces != nil) { if (me.Interfaces != nil) {
@ -126,14 +126,14 @@ func checkDNS() (map[string]*IPtype, map[string]*IPtype) {
ipt = "IPv6" ipt = "IPv6"
} }
if (t.IsReal()) { if (t.IsReal()) {
log.Println("\tIP is Real ", ipt, i.Index, i.Name, s) debug("\tIP is Real ", ipt, i.Index, i.Name, s)
if (t.ipv6) { if (t.ipv6) {
ipv6s[s] = t ipv6s[s] = t
} else { } else {
ipv4s[s] = t ipv4s[s] = t
} }
} else { } else {
log.Println("\tIP is not Real", ipt, i.Index, i.Name, s) debug("\tIP is not Real", ipt, i.Index, i.Name, s)
} }
} }
return ipv6s, ipv4s return ipv6s, ipv4s
@ -141,14 +141,14 @@ func checkDNS() (map[string]*IPtype, map[string]*IPtype) {
// Will figure out if an IP address is new // Will figure out if an IP address is new
func checkIP(ip *net.IPNet, i net.Interface) bool { func checkIP(ip *net.IPNet, i net.Interface) bool {
log.Println(args.VerboseNet, "\t\taddr.(type) = *net.IPNet") debug(args.VerboseNet, "\t\taddr.(type) = *net.IPNet")
log.Println(args.VerboseNet, "\t\taddr.(type) =", ip) debug(args.VerboseNet, "\t\taddr.(type) =", ip)
var realip string var realip string
realip = ip.IP.String() realip = ip.IP.String()
val, ok := me.ipmap[realip] val, ok := me.ipmap[realip]
if ok { if ok {
log.Println(args.VerboseNet, val.ipnet.IP.String(), "is already a defined IP address") debug(args.VerboseNet, val.ipnet.IP.String(), "is already a defined IP address")
me.ipmap[realip].gone = false me.ipmap[realip].gone = false
return false return false
} }
@ -175,14 +175,14 @@ func checkIP(ip *net.IPNet, i net.Interface) bool {
} }
} }
if (IsReal(&ip.IP)) { if (IsReal(&ip.IP)) {
log.Println("\tIP is Real ", t, i.Index, i.Name, realip) debug("\tIP is Real ", t, i.Index, i.Name, realip)
} else { } else {
log.Println("\tIP is not Real", t, i.Index, i.Name, realip) debug("\tIP is not Real", t, i.Index, i.Name, realip)
} }
log.Println(args.VerboseNet, "\t\tIP is IsPrivate() =", ip.IP.IsPrivate()) debug(args.VerboseNet, "\t\tIP is IsPrivate() =", ip.IP.IsPrivate())
log.Println(args.VerboseNet, "\t\tIP is IsLoopback() =", ip.IP.IsLoopback()) debug(args.VerboseNet, "\t\tIP is IsLoopback() =", ip.IP.IsLoopback())
log.Println(args.VerboseNet, "\t\tIP is IsLinkLocalUnicast() =", ip.IP.IsLinkLocalUnicast()) debug(args.VerboseNet, "\t\tIP is IsLinkLocalUnicast() =", ip.IP.IsLinkLocalUnicast())
// log.Println("HERE HERE", "realip =", realip, "me.ip[realip]=", me.ipmap[realip]) // debug("HERE HERE", "realip =", realip, "me.ip[realip]=", me.ipmap[realip])
return true return true
} }
@ -190,25 +190,25 @@ func scanInterfaces() {
me.changed = false me.changed = false
ifaces, _ := net.Interfaces() ifaces, _ := net.Interfaces()
// me.ifnew = ifaces // me.ifnew = ifaces
log.Println(DEBUGNET, SPEW, ifaces) debug(DEBUGNET, SPEW, ifaces)
for _, i := range ifaces { for _, i := range ifaces {
addrs, _ := i.Addrs() addrs, _ := i.Addrs()
// log.Println("range ifaces = ", i) // debug("range ifaces = ", i)
checkInterface(i) checkInterface(i)
log.Println(args.VerboseNet, "*net.Interface.Name = ", i.Name, i.Index) debug(args.VerboseNet, "*net.Interface.Name = ", i.Name, i.Index)
log.Println(args.VerboseNet, SPEW, i) debug(args.VerboseNet, SPEW, i)
log.Println(DEBUGNET, SPEW, addrs) debug(DEBUGNET, SPEW, addrs)
for _, addr := range addrs { for _, addr := range addrs {
log.Println(DEBUGNET, "\taddr =", addr) debug(DEBUGNET, "\taddr =", addr)
log.Println(DEBUGNET, SPEW, addrs) debug(DEBUGNET, SPEW, addrs)
ips, _ := net.LookupIP(addr.String()) ips, _ := net.LookupIP(addr.String())
log.Println(DEBUGNET, "\tLookupIP(addr) =", ips) debug(DEBUGNET, "\tLookupIP(addr) =", ips)
switch v := addr.(type) { switch v := addr.(type) {
case *net.IPNet: case *net.IPNet:
checkIP(v, i) checkIP(v, i)
// log.Println("\t\tIP is () =", ip.()) // debug("\t\tIP is () =", ip.())
default: default:
log.Println(DEBUGNET, "\t\taddr.(type) = NO IDEA WHAT TO DO HERE v =", v) debug(DEBUGNET, "\t\taddr.(type) = NO IDEA WHAT TO DO HERE v =", v)
} }
} }
} }
@ -218,12 +218,12 @@ func scanInterfaces() {
for s, t := range me.ipmap { for s, t := range me.ipmap {
if (t.ipv4) { if (t.ipv4) {
all4 += s + "\n" all4 += s + "\n"
log.Println("IPv4 =", s) debug("IPv4 =", s)
} else if (t.ipv6) { } else if (t.ipv6) {
all6 += s + "\n" all6 += s + "\n"
log.Println("IPv6 =", s) debug("IPv6 =", s)
} else { } else {
log.Println("???? =", s) debug("???? =", s)
} }
} }
all4 = strings.TrimSpace(all4) all4 = strings.TrimSpace(all4)
@ -236,7 +236,7 @@ func scanInterfaces() {
func deleteChanges() { func deleteChanges() {
for i, t := range me.ifmap { for i, t := range me.ifmap {
if (t.gone) { if (t.gone) {
log.Println("DELETE int =", i, "name =", t.name, t.iface) debug("DELETE int =", i, "name =", t.name, t.iface)
delete(me.ifmap, i) delete(me.ifmap, i)
me.changed = true me.changed = true
} }
@ -244,10 +244,10 @@ func deleteChanges() {
} }
for s, t := range me.ipmap { for s, t := range me.ipmap {
if (t.gone) { if (t.gone) {
log.Println("DELETE name =", s, "IPv4 =", t.ipv4) debug("DELETE name =", s, "IPv4 =", t.ipv4)
log.Println("DELETE name =", s, "IPv6 =", t.ipv6) debug("DELETE name =", s, "IPv6 =", t.ipv6)
log.Println("DELETE name =", s, "iface =", t.iface) debug("DELETE name =", s, "iface =", t.iface)
log.Println("DELETE name =", s, "ip =", t.ip) debug("DELETE name =", s, "ip =", t.ip)
delete(me.ipmap, s) delete(me.ipmap, s)
me.changed = true me.changed = true
} }

View File

@ -6,7 +6,6 @@
package main package main
import ( import (
"log"
"os" "os"
) )
@ -17,17 +16,17 @@ import (
func nsupdate() { func nsupdate() {
var tsigSecret string var tsigSecret string
log.Println(true, "nsupdate() START") debug(true, "nsupdate() START")
cmd := "go-nsupdate --tsig-algorithm=hmac-sha512" cmd := "go-nsupdate --tsig-algorithm=hmac-sha512"
tsigSecret = os.Getenv("TIG_SECRET") tsigSecret = os.Getenv("TIG_SECRET")
cmd += " --tig-secret=\"" + tsigSecret + "\"" cmd += " --tig-secret=\"" + tsigSecret + "\""
cmd += " -i wlo1 " + me.hostname cmd += " -i wlo1 " + me.hostname
log.Println(true, "nsupdate() RUN:", cmd) debug(true, "nsupdate() RUN:", cmd)
for s, t := range me.ipmap { for s, t := range me.ipmap {
if (t.IsReal()) { if (t.IsReal()) {
if (t.ipv6) { if (t.ipv6) {
log.Println(true, "nsupdate() found real AAAA =", s, "on iface", t.iface.Name) debug(true, "nsupdate() found real AAAA =", s, "on iface", t.iface.Name)
} }
} }
} }

View File

@ -37,6 +37,7 @@ type Host struct {
DnsAAAA *gui.Node // the actual DNS AAAA results DnsAAAA *gui.Node // the actual DNS AAAA results
DnsA *gui.Node // the actual DNS A results (ignore for status since mostly never happens?) DnsA *gui.Node // the actual DNS A results (ignore for status since mostly never happens?)
DnsStatus *gui.Node // the current state of DNS DnsStatus *gui.Node // the current state of DNS
DnsSpeed *gui.Node // the current state of DNS
fix *gui.Node // button for the user to click fix *gui.Node // button for the user to click
} }