summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--args.go16
-rw-r--r--digStatus.go314
-rw-r--r--dns-https.go64
-rw-r--r--dnsLookupStatus.go476
-rw-r--r--gui.go120
-rw-r--r--hostname.go70
-rw-r--r--hostnameStatus.go129
-rw-r--r--nsupdate.go2
-rw-r--r--resolverBox.go209
-rw-r--r--structs.go11
10 files changed, 700 insertions, 711 deletions
diff --git a/args.go b/args.go
index ba6ee85..6527c5b 100644
--- a/args.go
+++ b/args.go
@@ -18,11 +18,13 @@ var args struct {
VerboseDNS bool `arg:"--verbose-dns" help:"debug your dns settings"`
}
-var NET log.LogFlag
var NOW log.LogFlag
+var NET log.LogFlag
+var DNS log.LogFlag
var PROC log.LogFlag
var SPEW log.LogFlag
var CHANGE log.LogFlag
+var STATUS log.LogFlag
func init() {
arg.MustParse(&args)
@@ -40,6 +42,12 @@ func init() {
NET.Desc = "Network logging"
NET.Register()
+ DNS.B = false
+ DNS.Name = "DNS"
+ DNS.Subsystem = "cpdns"
+ DNS.Desc = "dnsStatus.update()"
+ DNS.Register()
+
PROC.B = false
PROC.Name = "PROC"
PROC.Subsystem = "cpdns"
@@ -58,6 +66,12 @@ func init() {
CHANGE.Desc = "show droplet state changes"
CHANGE.Register()
+ STATUS.B = false
+ STATUS.Name = "STATUS"
+ STATUS.Subsystem = "cpdns"
+ STATUS.Desc = "updateStatus()"
+ STATUS.Register()
+
if debugger.ArgDebug() {
log.Log(true, "INIT() gui debug == true")
} else {
diff --git a/digStatus.go b/digStatus.go
new file mode 100644
index 0000000..ffa9f2d
--- /dev/null
+++ b/digStatus.go
@@ -0,0 +1,314 @@
+/*
+ 'dig'
+
+ This is essentially doing what the command 'dig' does
+ It performing DNS queries on TCP and UDP
+ against localhost, cloudflare & google
+
+ IPv4() and IPv6() return true if they are working
+
+ with the 'gui' package, it can also display the results
+*/
+
+package main
+
+import (
+ "os"
+ "fmt"
+ "time"
+ "strings"
+ "reflect"
+ "errors"
+
+ "go.wit.com/log"
+ "go.wit.com/gui/gui"
+ "go.wit.com/gui/gadgets"
+ "go.wit.com/shell"
+)
+
+type digStatus struct {
+ ready bool
+ hidden bool
+ statusIPv4 string
+ statusIPv6 string
+
+ parent *gui.Node
+ window *gadgets.BasicWindow
+ group *gui.Node
+ grid *gui.Node
+
+ summary *gui.Node
+ status *gadgets.OneLiner
+ statusAAAA *gadgets.OneLiner
+ speed *gadgets.OneLiner
+ speedActual *gadgets.OneLiner
+
+ details *gui.Node
+ dsLocalhost *resolverStatus
+ dsLocalNetwork *resolverStatus
+ dsCloudflare *resolverStatus
+ dsGoogle *resolverStatus
+ DnsDigUDP *gui.Node
+ DnsDigTCP *gui.Node
+
+ httpGoWitCom *gadgets.OneLiner
+ statusHTTP *gadgets.OneLiner
+}
+
+func NewDigStatusWindow(p *gui.Node) *digStatus {
+ var ds *digStatus
+ ds = new(digStatus)
+
+ ds.ready = false
+ ds.hidden = true
+
+ ds.window = gadgets.NewBasicWindow(p, "DNS Resolver Status")
+ ds.window.Draw()
+ ds.window.Hide()
+
+ // summary of the current state of things
+ ds.summary = ds.window.Box().NewGroup("Summary")
+ g := ds.summary.NewGrid("LookupStatus", 2, 2)
+ g.Pad()
+
+ ds.status = gadgets.NewOneLiner(g, "status").Set("unknown")
+ ds.statusAAAA = gadgets.NewOneLiner(g, "IPv6 status").Set("unknown")
+ ds.statusHTTP = gadgets.NewOneLiner(g, "IPv6 via HTTP").Set("unknown")
+ ds.speed = gadgets.NewOneLiner(g, "speed").Set("unknown")
+ ds.speedActual = gadgets.NewOneLiner(g, "actual").Set("unknown")
+
+ // make the area to store the raw details
+ ds.details = ds.window.Box().NewGroup("Details")
+ ds.dsLocalhost = NewResolverStatus(ds.details, "(localhost)", "127.0.0.1:53", "go.wit.com")
+ ds.dsLocalNetwork = NewResolverStatus(ds.details, "(Local Network)", "192.168.86.1:53", "go.wit.com")
+ ds.dsCloudflare = NewResolverStatus(ds.details, "(cloudflare)", "1.1.1.1:53", "go.wit.com")
+ ds.dsGoogle = NewResolverStatus(ds.details, "(google)", "8.8.8.8:53", "go.wit.com")
+ ds.makeDnsStatusGrid()
+ ds.makeHttpStatusGrid()
+
+ ds.hidden = false
+ ds.ready = true
+ return ds
+}
+
+func (ds *digStatus) Update() {
+ log.Info("digStatus() Update() START")
+ if ds == nil {
+ log.Error(errors.New("digStatus() Update() ds == nil"))
+ return
+ }
+ duration := timeFunction(func () {
+ ds.updateDnsStatus()
+ })
+ s := fmt.Sprint(duration)
+ // ds.speedActual.Set(s)
+ me.digStatus.set(ds.speedActual, s)
+
+ if (duration > 500 * time.Millisecond ) {
+ me.digStatus.set(ds.speed, "SLOW")
+ } else if (duration > 100 * time.Millisecond ) {
+ me.digStatus.set(ds.speed, "OK")
+ } else {
+ me.digStatus.set(ds.speed, "FAST")
+ }
+ log.Info("digStatus() Update() END")
+}
+
+// Returns true if the status is valid
+func (ds *digStatus) Ready() bool {
+ if ds == nil {return false}
+ return ds.ready
+}
+
+// Returns true if IPv4 is working
+func (ds *digStatus) IPv4() bool {
+ if ! ds.Ready() {return false}
+ if (ds.statusIPv4 == "OK") {
+ return true
+ }
+ if (ds.statusIPv4 == "GOOD") {
+ return true
+ }
+ return false
+}
+
+// Returns true if IPv6 is working
+func (ds *digStatus) IPv6() bool {
+ if ! ds.Ready() {return false}
+ if (ds.statusIPv6 == "GOOD") {
+ return true
+ }
+ return false
+}
+
+func (ds *digStatus) setIPv4status(s string) {
+ ds.statusIPv4 = s
+ if ! ds.Ready() {return}
+ me.digStatus.set(ds.status, s)
+}
+
+func (ds *digStatus) setIPv6status(s string) {
+ ds.statusIPv6 = s
+ if ! ds.Ready() {return}
+ me.digStatus.set(ds.statusAAAA, s)
+}
+
+func (ds *digStatus) SetIPv6(s string) {
+ if ! ds.Ready() {return}
+ log.Warn("Should SetIPv6() here to", s)
+ log.Warn("Should SetIPv6() here to", s)
+ log.Warn("Should SetIPv6() here to", s)
+ log.Warn("Should SetIPv6() here to", s)
+ me.DnsAAAA.Set(s)
+ // me.digStatus.set(ds.httpGoWitCom, addr)
+}
+
+func (ds *digStatus) set(a any, s string) {
+ if ! ds.Ready() {return}
+ if ds.hidden {
+ return
+ }
+ if a == nil {
+ return
+ }
+ var n *gui.Node
+ if reflect.TypeOf(a) == reflect.TypeOf(n) {
+ n = a.(*gui.Node)
+ n.SetText(s)
+ return
+ }
+ var ol *gadgets.OneLiner
+ if reflect.TypeOf(a) == reflect.TypeOf(ol) {
+ ol = a.(*gadgets.OneLiner)
+ ol.Set(s)
+ return
+ }
+ log.Warn("unknown type TypeOf(a) =", reflect.TypeOf(a), "a =", a)
+ os.Exit(0)
+}
+
+func (ds *digStatus) updateDnsStatus() {
+ var cmd, out string
+ var ipv4, ipv6 bool
+
+ log.Info("updateDnsStatus() START")
+ if (ds == nil) {
+ log.Error(errors.New("updateDnsStatus() not initialized yet. ds == nil"))
+ return
+ }
+
+ if (! ds.ready) {
+ log.Error(errors.New("updateDnsStatus() not ready yet"))
+ return
+ }
+
+ ipv4, ipv6 = ds.dsLocalhost.update()
+ ipv4, ipv6 = ds.dsLocalNetwork.update()
+ ipv4, ipv6 = ds.dsCloudflare.update()
+ ipv4, ipv6 = ds.dsGoogle.update()
+
+ if me.status.ValidHostname() {
+ if ds.checkLookupDoH(me.status.GetHostname()) {
+ log.Log(DNS, "updateDnsStatus() HTTP DNS lookups working")
+ me.digStatus.set(ds.statusHTTP, "WORKING")
+ } else {
+ log.Log(DNS, "updateDnsStatus() HTTP DNS lookups not working")
+ log.Log(DNS, "updateDnsStatus() It's really unlikely you are on the internet")
+ me.digStatus.set(ds.statusHTTP, "BROKEN")
+ }
+ } else {
+ me.digStatus.set(ds.statusHTTP, "INVALID HOSTNAME")
+ }
+
+ if (ipv4) {
+ log.Log(DNS, "updateDnsStatus() IPv4 A lookups working")
+ ds.setIPv4status("OK")
+ } else {
+ log.Log(DNS, "updateDnsStatus() IPv4 A lookups not working. No internet?")
+ ds.setIPv4status("No Internet?")
+ }
+ if (ipv6) {
+ log.Log(DNS, "updateDnsStatus() IPv6 AAAA lookups working")
+ ds.setIPv4status("GOOD")
+ ds.setIPv6status("GOOD")
+ } else {
+ log.Log(DNS, "updateDnsStatus() IPv6 AAAA lookups are not working")
+ ds.setIPv6status("Need VPN")
+ }
+
+ cmd = "dig +noall +answer www.wit.com A"
+ out = shell.Run(cmd)
+ log.Log(DNS, "makeDnsStatusGrid() dig", out)
+ me.digStatus.set(ds.DnsDigUDP, out)
+
+ cmd = "dig +noall +answer www.wit.com AAAA"
+ out = shell.Run(cmd)
+ log.Log(DNS, "makeDnsStatusGrid() dig", out)
+ me.digStatus.set(ds.DnsDigTCP, out)
+}
+
+func (ds *digStatus) makeHttpStatusGrid() {
+ group := ds.details.NewGroup("dns.google.com via HTTPS")
+ grid := group.NewGrid("LookupStatus", 2, 2)
+
+ ds.httpGoWitCom = gadgets.NewOneLiner(grid, "go.wit.com")
+ me.digStatus.set(ds.httpGoWitCom, "unknown")
+
+ group.Pad()
+ grid.Pad()
+}
+
+func (ds *digStatus) makeDnsStatusGrid() {
+ var cmd, out string
+ group := ds.details.NewGroup("dig results")
+ grid := group.NewGrid("LookupStatus", 2, 2)
+
+ cmd = "dig +noall +answer go.wit.com A"
+ grid.NewLabel(cmd)
+ ds.DnsDigUDP = grid.NewLabel("?")
+ out = shell.Run(cmd)
+ log.Log(DNS, "makeDnsStatusGrid() dig", out)
+ me.digStatus.set(ds.DnsDigUDP, out)
+
+ cmd = "dig +noall +answer go.wit.com AAAA"
+ grid.NewLabel(cmd)
+ ds.DnsDigTCP = grid.NewLabel("?")
+ out = shell.Run(cmd)
+ log.Log(DNS, "makeDnsStatusGrid() dig", out)
+ me.digStatus.set(ds.DnsDigTCP, out)
+
+ group.Pad()
+ grid.Pad()
+}
+
+func (ds *digStatus) checkLookupDoH(hostname string) bool {
+ var status bool = false
+
+ ipv6Addresses := lookupDoH(hostname, "AAAA")
+
+ log.Log(DNS, "IPv6 Addresses for ", hostname)
+ var s []string
+ for _, addr := range ipv6Addresses {
+ log.Log(DNS, addr)
+ s = append(s, addr)
+ status = true
+ }
+ me.digStatus.SetIPv6(strings.Join(s, "\n"))
+ return status
+}
+
+func (ds *digStatus) Show() {
+ log.Info("digStatus.Show() window")
+ if me.digStatus.hidden {
+ me.digStatus.window.Show()
+ }
+ me.digStatus.hidden = false
+}
+
+func (ds *digStatus) Hide() {
+ log.Info("digStatus.Hide() window")
+ if ! me.digStatus.hidden {
+ me.digStatus.window.Hide()
+ }
+ me.digStatus.hidden = true
+}
diff --git a/dns-https.go b/dns-https.go
index 6579903..bd06d4c 100644
--- a/dns-https.go
+++ b/dns-https.go
@@ -8,70 +8,18 @@ import (
"net/http"
)
-/*
-func getAAAArecords() {
- hostname := "go.wit.com"
- ipv6Addresses, err := dnsLookupDoH(hostname)
- if err != nil {
- log.Error(err, "getAAAArecords")
- return
- }
-
- fmt.Printf("IPv6 Addresses for %s:\n", hostname)
- for _, addr := range ipv6Addresses {
- log.Println(addr)
- }
-}
-*/
-
-// dnsLookupDoH performs a DNS lookup for AAAA records over HTTPS.
-func dnsAAAAlookupDoH(domain string) ([]string, error) {
- var ipv6Addresses []string
-
- // Construct the URL for a DNS query with Google's DNS-over-HTTPS API
- url := fmt.Sprintf("https://dns.google/resolve?name=%s&type=AAAA", domain)
-
- log.Println("curl", url)
-
- // Perform the HTTP GET request
- resp, err := http.Get(url)
- if err != nil {
- return nil, fmt.Errorf("error performing DNS-over-HTTPS request: %w", err)
- }
- defer resp.Body.Close()
-
- // Read and unmarshal the response body
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return nil, fmt.Errorf("error reading response: %w", err)
- }
-
- var data struct {
- Answer []struct {
- Data string `json:"data"`
- } `json:"Answer"`
- }
-
- if err := json.Unmarshal(body, &data); err != nil {
- return nil, fmt.Errorf("error unmarshaling response: %w", err)
- }
-
- // Extract the IPv6 addresses
- for _, answer := range data.Answer {
- ipv6Addresses = append(ipv6Addresses, answer.Data)
- }
-
- return ipv6Addresses, nil
-}
-
// dnsLookupDoH performs a DNS lookup for AAAA records over HTTPS.
func lookupDoH(hostname string, rrType string) []string {
var values []string
// Construct the URL for a DNS query with Google's DNS-over-HTTPS API
- url := fmt.Sprintf("https://dns.google/resolve?name=%s&type=%s", hostname, rrType)
+ url := fmt.Sprintf("https://dns.google.com/resolve?name=%s&type=%s", hostname, rrType)
- log.Println("curl", url)
+ log.Log(DNS, "lookupDoH()", url)
+ if hostname == "" {
+ log.Warn("lookupDoH() was sent a empty hostname")
+ return nil
+ }
// Perform the HTTP GET request
resp, err := http.Get(url)
diff --git a/dnsLookupStatus.go b/dnsLookupStatus.go
deleted file mode 100644
index 6488635..0000000
--- a/dnsLookupStatus.go
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- 'dig'
-
- This is essentially doing what the command 'dig' does
- It performing DNS queries on TCP and UDP
- against localhost, cloudflare & google
-
- IPv4() and IPv6() return true if they are working
-
- with the 'gui' package, it can also display the results
-*/
-
-package main
-
-import (
- "os"
- "fmt"
- "time"
- "strconv"
- "reflect"
- "errors"
-
- "go.wit.com/log"
- "go.wit.com/gui/gui"
- "go.wit.com/gui/gadgets"
- "go.wit.com/shell"
-
- "github.com/miekg/dns"
-)
-
-type digStatus struct {
- ready bool
- hidden bool
- statusIPv4 string
- statusIPv6 string
-
- parent *gui.Node
- window *gadgets.BasicWindow
- group *gui.Node
- grid *gui.Node
-
- summary *gui.Node
- status *gadgets.OneLiner
- statusAAAA *gadgets.OneLiner
- speed *gadgets.OneLiner
- speedActual *gadgets.OneLiner
-
- details *gui.Node
- dsLocalhost *dnsStatus
- dsLocalNetwork *dnsStatus
- dsCloudflare *dnsStatus
- dsGoogle *dnsStatus
- DnsDigUDP *gui.Node
- DnsDigTCP *gui.Node
-
- httpGoWitCom *gadgets.OneLiner
- statusHTTP *gadgets.OneLiner
-}
-
-type dnsStatus struct {
- title string
- server string // The DNS server. Example: "127.0.0.1:53" or "1.1.1.1:53"
- hostname string // the hostname to lookup. Example: "www.google.com" or "go.wit.com"
-
- parent *gui.Node
- group *gui.Node
- grid *gui.Node
-
- // DNS setup options
- udpA *gui.Node
- tcpA *gui.Node
- udpAAAA *gui.Node
- tcpAAAA *gui.Node
-
- // show the display
- aFail *gui.Node
- aSuccess *gui.Node
- aaaaFail *gui.Node
- aaaaSuccess *gui.Node
-
- // interger counters
- aFailc int
- aSuccessc int
- aaaaFailc int
- aaaaSuccessc int
-}
-
-func NewDigStatusWindow(p *gui.Node) *digStatus {
- var ds *digStatus
- ds = new(digStatus)
-
- ds.ready = false
- ds.hidden = true
-
- ds.window = gadgets.NewBasicWindow(p, "DNS Resolver Status")
- ds.window.Draw()
- ds.window.Hide()
-
- // summary of the current state of things
- ds.summary = ds.window.Box().NewGroup("Summary")
- g := ds.summary.NewGrid("LookupStatus", 2, 2)
- g.Pad()
-
- ds.status = gadgets.NewOneLiner(g, "status").Set("unknown")
- ds.statusAAAA = gadgets.NewOneLiner(g, "IPv6 status").Set("unknown")
- ds.statusHTTP = gadgets.NewOneLiner(g, "IPv6 via HTTP").Set("unknown")
- ds.speed = gadgets.NewOneLiner(g, "speed").Set("unknown")
- ds.speedActual = gadgets.NewOneLiner(g, "actual").Set("unknown")
-
- // make the area to store the raw details
- ds.details = ds.window.Box().NewGroup("Details")
- ds.dsLocalhost = NewDnsStatus(ds.details, "(localhost)", "127.0.0.1:53", "go.wit.com")
- ds.dsLocalNetwork = NewDnsStatus(ds.details, "(Local Network)", "172.22.0.1:53", "go.wit.com")
- ds.dsCloudflare = NewDnsStatus(ds.details, "(cloudflare)", "1.1.1.1:53", "go.wit.com")
- ds.dsGoogle = NewDnsStatus(ds.details, "(google)", "8.8.8.8:53", "go.wit.com")
- ds.makeDnsStatusGrid()
- ds.makeHttpStatusGrid()
-
- ds.hidden = false
- ds.ready = true
- return ds
-}
-
-func (ds *digStatus) Update() {
- log.Info("digStatus() Update() START")
- if ds == nil {
- log.Error(errors.New("digStatus() Update() ds == nil"))
- return
- }
- duration := timeFunction(func () {
- ds.updateDnsStatus()
- })
- s := fmt.Sprint(duration)
- // ds.speedActual.Set(s)
- me.digStatus.set(ds.speedActual, s)
-
- if (duration > 500 * time.Millisecond ) {
- me.digStatus.set(ds.speed, "SLOW")
- } else if (duration > 100 * time.Millisecond ) {
- me.digStatus.set(ds.speed, "OK")
- } else {
- me.digStatus.set(ds.speed, "FAST")
- }
- log.Info("digStatus() Update() END")
-}
-
-// Returns true if the status is valid
-func (ds *digStatus) Ready() bool {
- if ds == nil {return false}
- return ds.ready
-}
-
-// Returns true if IPv4 is working
-func (ds *digStatus) IPv4() bool {
- if ! ds.Ready() {return false}
- if (ds.statusIPv4 == "OK") {
- return true
- }
- if (ds.statusIPv4 == "GOOD") {
- return true
- }
- return false
-}
-
-// Returns true if IPv6 is working
-func (ds *digStatus) IPv6() bool {
- if ! ds.Ready() {return false}
- if (ds.statusIPv6 == "GOOD") {
- return true
- }
- return false
-}
-
-func (ds *digStatus) setIPv4(s string) {
- ds.statusIPv4 = s
- if ! ds.Ready() {return}
- me.digStatus.set(ds.status, s)
-}
-
-func (ds *digStatus) setIPv6(s string) {
- ds.statusIPv6 = s
- if ! ds.Ready() {return}
- me.digStatus.set(ds.statusAAAA, s)
-}
-
-func (ds *digStatus) set(a any, s string) {
- if ! ds.Ready() {return}
- if ds.hidden {
- return
- }
- if a == nil {
- return
- }
- var n *gui.Node
- if reflect.TypeOf(a) == reflect.TypeOf(n) {
- n = a.(*gui.Node)
- n.SetText(s)
- return
- }
- var ol *gadgets.OneLiner
- if reflect.TypeOf(a) == reflect.TypeOf(ol) {
- ol = a.(*gadgets.OneLiner)
- ol.Set(s)
- return
- }
- log.Warn("unknown type TypeOf(a) =", reflect.TypeOf(a), "a =", a)
- os.Exit(0)
-}
-
-func (ds *digStatus) updateDnsStatus() {
- var cmd, out string
- var ipv4, ipv6 bool
-
- log.Info("updateDnsStatus() START")
- if (ds == nil) {
- log.Error(errors.New("updateDnsStatus() not initialized yet. ds == nil"))
- return
- }
-
- if (! ds.ready) {
- log.Error(errors.New("updateDnsStatus() not ready yet"))
- return
- }
-
- ipv4, ipv6 = ds.dsLocalhost.update()
- ipv4, ipv6 = ds.dsLocalNetwork.update()
- ipv4, ipv6 = ds.dsCloudflare.update()
- ipv4, ipv6 = ds.dsGoogle.update()
-
- if ds.checkLookupDoH("go.wit.com") {
- log.Println("updateDnsStatus() HTTP DNS lookups working")
- me.digStatus.set(ds.statusHTTP, "WORKING")
- } else {
- log.Println("updateDnsStatus() HTTP DNS lookups not working")
- log.Println("updateDnsStatus() It's really unlikely you are on the internet")
- me.digStatus.set(ds.statusHTTP, "BROKEN")
- }
-
- if (ipv4) {
- log.Println("updateDnsStatus() IPv4 A lookups working")
- ds.setIPv4("OK")
- } else {
- log.Println("updateDnsStatus() IPv4 A lookups not working. No internet?")
- ds.setIPv4("No Internet?")
- }
- if (ipv6) {
- log.Println("updateDnsStatus() IPv6 AAAA lookups working")
- ds.setIPv4("GOOD")
- ds.setIPv6("GOOD")
- } else {
- log.Println("updateDnsStatus() IPv6 AAAA lookups are not working")
- ds.setIPv6("Need VPN")
- }
-
- cmd = "dig +noall +answer www.wit.com A"
- out = shell.Run(cmd)
- log.Println("makeDnsStatusGrid() dig", out)
- me.digStatus.set(ds.DnsDigUDP, out)
-
- cmd = "dig +noall +answer www.wit.com AAAA"
- out = shell.Run(cmd)
- log.Println("makeDnsStatusGrid() dig", out)
- me.digStatus.set(ds.DnsDigTCP, out)
-}
-
-// Makes a DNS Status Grid
-func NewDnsStatus(p *gui.Node, title string, server string, hostname string) *dnsStatus {
- var ds *dnsStatus
- ds = new(dnsStatus)
- ds.parent = p
- ds.group = p.NewGroup(server + " " + title + " lookup")
- ds.grid = ds.group.NewGrid("LookupStatus", 5, 2)
-
- ds.server = server
- ds.hostname = hostname
-
- ds.grid.NewLabel("")
- ds.grid.NewLabel("UDP")
- ds.grid.NewLabel("TCP")
- ds.grid.NewLabel("Success")
- ds.grid.NewLabel("Fail")
-
- ds.grid.NewLabel("A")
- ds.udpA = ds.grid.NewLabel("?")
- ds.tcpA = ds.grid.NewLabel("?")
- ds.aSuccess = ds.grid.NewLabel("?")
- ds.aFail = ds.grid.NewLabel("?")
-
- ds.grid.NewLabel("AAAA")
- ds.udpAAAA = ds.grid.NewLabel("?")
- ds.tcpAAAA = ds.grid.NewLabel("?")
- ds.aaaaSuccess = ds.grid.NewLabel("?")
- ds.aaaaFail = ds.grid.NewLabel("?")
-
- ds.group.Margin()
- ds.grid.Margin()
- ds.group.Pad()
- ds.grid.Pad()
-
- return ds
-}
-
-// special thanks to the Element Hotel wifi in Philidelphia that allowed me to
-// easily debug this code since the internet connection here blocks port 53 traffic
-func (ds *dnsStatus) update() (bool, bool) {
- var results []string
- var a bool = false
- var aaaa bool = false
-
- log.Println("dnsStatus.update() For server", ds.server, "on", ds.hostname)
- results, _ = dnsUdpLookup(ds.server, ds.hostname, dns.TypeA)
- log.Println("dnsStatus.update() UDP type A =", results)
-
- if (len(results) == 0) {
- me.digStatus.set(ds.udpA, "BROKEN")
- ds.aFailc += 1
- } else {
- me.digStatus.set(ds.udpA, "WORKING")
- ds.aSuccessc += 1
- a = true
- }
-
- results, _ = dnsTcpLookup(ds.server, ds.hostname, dns.TypeA)
- log.Println("dnsStatus.update() TCP type A =", results)
-
- if (len(results) == 0) {
- me.digStatus.set(ds.tcpA, "BROKEN")
- ds.aFailc += 1
- } else {
- me.digStatus.set(ds.tcpA, "WORKING")
- ds.aSuccessc += 1
- a = true
- }
-
- me.digStatus.set(ds.aFail, strconv.Itoa(ds.aFailc))
- me.digStatus.set(ds.aSuccess,strconv.Itoa(ds.aSuccessc))
-
- results, _ = dnsUdpLookup(ds.server, ds.hostname, dns.TypeAAAA)
- log.Println("dnsStatus.update() UDP type AAAA =", results)
-
- if (len(results) == 0) {
- me.digStatus.set(ds.udpAAAA, "BROKEN")
- ds.aaaaFailc += 1
- me.digStatus.set(ds.aaaaFail, strconv.Itoa(ds.aaaaFailc))
- } else {
- me.digStatus.set(ds.udpAAAA, "WORKING")
- ds.aaaaSuccessc += 1
- aaaa = true
- }
-
- results, _ = dnsTcpLookup(ds.server, ds.hostname, dns.TypeAAAA)
- log.Println("dnsStatus.update() UDP type AAAA =", results)
-
- if (len(results) == 0) {
- me.digStatus.set(ds.tcpAAAA, "BROKEN")
- ds.aaaaFailc += 1
- me.digStatus.set(ds.aaaaFail, strconv.Itoa(ds.aaaaFailc))
- } else {
- me.digStatus.set(ds.tcpAAAA, "WORKING")
- ds.aaaaSuccessc += 1
- aaaa = true
- }
-
- me.digStatus.set(ds.aaaaFail, strconv.Itoa(ds.aaaaFailc))
- me.digStatus.set(ds.aaaaSuccess,strconv.Itoa(ds.aaaaSuccessc))
-
- return a, aaaa
-}
-
-func (ds *digStatus) makeHttpStatusGrid() {
- group := ds.details.NewGroup("dns.google.com via HTTPS")
- grid := group.NewGrid("LookupStatus", 2, 2)
-
- ds.httpGoWitCom = gadgets.NewOneLiner(grid, "go.wit.com")
- me.digStatus.set(ds.httpGoWitCom, "unknown")
-
- group.Pad()
- grid.Pad()
-}
-
-func (ds *digStatus) makeDnsStatusGrid() {
- var cmd, out string
- group := ds.details.NewGroup("dig results")
- grid := group.NewGrid("LookupStatus", 2, 2)
-
- cmd = "dig +noall +answer go.wit.com A"
- grid.NewLabel(cmd)
- ds.DnsDigUDP = grid.NewLabel("?")
- out = shell.Run(cmd)
- log.Println("makeDnsStatusGrid() dig", out)
- me.digStatus.set(ds.DnsDigUDP, out)
-
- cmd = "dig +noall +answer go.wit.com AAAA"
- grid.NewLabel(cmd)
- ds.DnsDigTCP = grid.NewLabel("?")
- out = shell.Run(cmd)
- log.Println("makeDnsStatusGrid() dig", out)
- me.digStatus.set(ds.DnsDigTCP, out)
-
- group.Pad()
- grid.Pad()
-}
-
-// dnsLookup performs a DNS lookup for the specified record type (e.g., "TXT", "AAAA") for a given domain.
-func dnsUdpLookup(server string, domain string, recordType uint16) ([]string, error) {
- var records []string
-
- c := new(dns.Client)
- m := new(dns.Msg)
- m.SetQuestion(dns.Fqdn(domain), recordType)
- r, _, err := c.Exchange(m, server) // If server = "1.1.1.1:53" then use Cloudflare's DNS server
- if err != nil {
- return nil, err
- }
-
- for _, ans := range r.Answer {
- records = append(records, ans.String())
- }
-
- return records, nil
-}
-
-func dnsTcpLookup(server string, domain string, recordType uint16) ([]string, error) {
- var records []string
-
- c := new(dns.Client)
- c.Net = "tcp" // Specify to use TCP for the query
- c.Timeout = time.Second * 5 // Set a 5-second timeout
- m := new(dns.Msg)
- m.SetQuestion(dns.Fqdn(domain), recordType)
- r, _, err := c.Exchange(m, server) // If server = "1.1.1.1:53" then use Cloudflare's DNS server
- if err != nil {
- return nil, err
- }
-
- for _, ans := range r.Answer {
- records = append(records, ans.String())
- }
-
- return records, nil
-}
-
-func (ds *digStatus) checkLookupDoH(hostname string) bool {
- var status bool = false
-
- domain := "go.wit.com"
- ipv6Addresses, err := dnsAAAAlookupDoH(domain)
- if err != nil {
- log.Error(err, "checkLookupDoH()")
- return status
- }
-
- log.Println("IPv6 Addresses for %s:\n", domain)
- for _, addr := range ipv6Addresses {
- log.Println(addr)
- me.digStatus.set(ds.httpGoWitCom, addr)
- status = true
- }
- return status
-}
-
-func (ds *digStatus) Show() {
- log.Info("digStatus.Show() window")
- if me.digStatus.hidden {
- me.digStatus.window.Show()
- }
- me.digStatus.hidden = false
-}
-
-func (ds *digStatus) Hide() {
- log.Info("digStatus.Hide() window")
- if ! me.digStatus.hidden {
- me.digStatus.window.Hide()
- }
- me.digStatus.hidden = true
-}
diff --git a/gui.go b/gui.go
index 9498fa3..8aa3659 100644
--- a/gui.go
+++ b/gui.go
@@ -6,11 +6,9 @@ import (
"os"
"os/user"
"strconv"
-// "net"
"strings"
"go.wit.com/log"
- "go.wit.com/shell"
"go.wit.com/gui/gui"
"go.wit.com/gui/gadgets"
@@ -27,8 +25,6 @@ func setupControlPanelWindow() {
mainWindow("DNS and IPv6 Control Panel")
detailsTab("OS Details")
debugTab("Debug")
-
- // me.digStatus = NewDigStatusWindow(me.window)
}
func detailsTab(title string) {
@@ -100,8 +96,9 @@ func debugTab(title string) {
})
g2.NewButton("dig +trace", func () {
- o := shell.Run("dig +trace +noadditional DS " + me.hostname + " @8.8.8.8")
- log.Println(o)
+ log.Log(NOW, "TODO: redo this")
+ // o := shell.Run("dig +trace +noadditional DS " + me.hostname + " @8.8.8.8")
+ // log.Println(o)
})
g2 = me.debug.Box().NewGroup("debugging options")
@@ -149,14 +146,14 @@ func missingAAAA() string {
func displayDNS() string {
var aaaa []string
aaaa = dhcpAAAA() // your AAAA records right now
- h := me.hostname
+ // h := me.hostname
var all string
var broken string = "unknown"
for _, s := range aaaa {
- log.Log(NOW, "host", h, "DNS AAAA =", s, "ipmap[s] =", me.ipmap[s])
+ log.Log(STATUS, "host", "fixme", "DNS AAAA =", s, "ipmap[s] =", me.ipmap[s])
all += s + "\n"
if ( me.ipmap[s] == nil) {
- log.Warn("THIS IS THE WRONG AAAA DNS ENTRY: host", h, "DNS AAAA =", s)
+ log.Warn("THIS IS THE WRONG AAAA DNS ENTRY: host", "fixme", "DNS AAAA =", s)
broken = "wrong AAAA entry"
} else {
if (broken == "unknown") {
@@ -166,7 +163,7 @@ func displayDNS() string {
}
all = sortLines(all)
if (me.workingIPv6.S != all) {
- log.Warn("workingIPv6.SetText() to:", all)
+ log.Log(NOW, "workingIPv6.SetText() to:", all)
me.workingIPv6.SetText(all)
}
@@ -174,11 +171,11 @@ func displayDNS() string {
a = realA()
all = sortLines(strings.Join(a, "\n"))
if (all == "") {
- log.Info("THERE IS NOT a real A DNS ENTRY")
+ log.Log(NOW, "THERE IS NOT a real A DNS ENTRY")
all = "CNAME ipv6.wit.com"
}
if (me.DnsA.S != all) {
- log.Warn("DnsA.SetText() to:", all)
+ log.Log(NOW, "DnsA.SetText() to:", all)
me.DnsA.SetText(all)
}
return broken
@@ -199,19 +196,18 @@ func mainWindow(title string) {
grid.NewLabel("hostname =")
me.fqdn = grid.NewLabel("?")
- me.hostname = ""
- grid.NewLabel("DNS AAAA =")
- me.DnsAAAA = grid.NewLabel("?")
+ // grid.NewLabel("DNS AAAA =")
+ me.DnsAAAA = gadgets.NewOneLiner(grid, "DNS AAAA =").Set("unknown")
grid.NewLabel("DNS A =")
me.DnsA = grid.NewLabel("?")
me.digStatus = NewDigStatusWindow(me.myGui)
- me.hostnameStatus = NewHostnameStatusWindow(me.myGui)
+ me.status = NewHostnameStatusWindow(me.myGui)
me.hostnameStatusButton = me.mainStatus.NewButton("Fix hostname DNS", func () {
- me.hostnameStatus.window.Toggle()
+ me.status.window.Toggle()
})
grid.Margin()
@@ -220,19 +216,16 @@ func mainWindow(title string) {
statusGrid(me.window.Box())
gr := me.window.Box().NewGroup("debugging")
- gr.NewButton("GO GUI Debugger", func () {
- debugger.DebugWindow(me.myGui)
- })
gr.NewButton("OS Details", func () {
me.details.Toggle()
})
- gr.NewButton("DNS Debug", func () {
- me.debug.Toggle()
- })
gr.NewButton("Resolver Status", func () {
if ! me.digStatus.Ready() {return}
me.digStatus.window.Toggle()
})
+ gr.NewButton("Control Panel Debug", func () {
+ me.debug.Toggle()
+ })
}
func statusGrid(n *gui.Node) {
@@ -240,15 +233,15 @@ func statusGrid(n *gui.Node) {
gridP := problems.NewGrid("nuts", 2, 2)
+ gridP.NewLabel("hostname =")
+ me.hostnameStatus = gridP.NewLabel("invalid")
+
gridP.NewLabel("DNS Status =")
me.DnsStatus = gridP.NewLabel("unknown")
me.statusIPv6 = gadgets.NewOneLiner(gridP, "IPv6 working")
me.statusIPv6.Set("known")
- gridP.NewLabel("hostname =")
- me.hostnameStatusOLD = gridP.NewLabel("invalid")
-
gridP.NewLabel("dns resolution")
me.DnsSpeed = gridP.NewLabel("unknown")
@@ -279,52 +272,51 @@ func statusGrid(n *gui.Node) {
// run everything because something has changed
func updateDNS() {
- var aaaa []string
- h := me.hostname
- if (h == "") {
- h = "test.wit.com"
- }
-
me.digStatus.Update()
- me.hostnameStatus.Update()
+ me.status.Update()
// log.Println("digAAAA()")
- aaaa = digAAAA(h)
- log.Log(NOW, "digAAAA() =", aaaa)
- // log.Println(SPEW, me)
- if (aaaa == nil) {
- log.Warn("There are no DNS AAAA records for hostname: ", h)
- me.DnsAAAA.SetText("(none)")
- if (cloudflare.CFdialog.TypeNode != nil) {
- cloudflare.CFdialog.TypeNode.SetText("AAAA new")
- }
+ if me.status.ValidHostname() {
+ var aaaa []string
+ h := me.status.GetHostname()
+ aaaa = digAAAA(h)
+ log.Log(NOW, "digAAAA() for", h, "=", aaaa)
- if (cloudflare.CFdialog.NameNode != nil) {
- cloudflare.CFdialog.NameNode.SetText(me.hostname)
- }
-
- d := deleteAAA()
- if (d != "") {
- if (cloudflare.CFdialog.ValueNode != nil) {
- cloudflare.CFdialog.ValueNode.SetText(d)
+ // log.Println(SPEW, me)
+ if (aaaa == nil) {
+ log.Warn("There are no DNS AAAA records for hostname: ", h)
+ me.DnsAAAA.Set("(none)")
+ if (cloudflare.CFdialog.TypeNode != nil) {
+ cloudflare.CFdialog.TypeNode.SetText("AAAA new")
}
- }
- m := missingAAAA()
- if (m != "") {
- if (cloudflare.CFdialog.ValueNode != nil) {
- cloudflare.CFdialog.ValueNode.SetText(m)
+
+ if (cloudflare.CFdialog.NameNode != nil) {
+ cloudflare.CFdialog.NameNode.SetText(h)
+ }
+
+ d := deleteAAA()
+ if (d != "") {
+ if (cloudflare.CFdialog.ValueNode != nil) {
+ cloudflare.CFdialog.ValueNode.SetText(d)
+ }
}
- /*
- rr := &cloudflare.RRT{
- Type: "AAAA",
- Name: me.hostname,
- Ttl: "Auto",
- Proxied: false,
- Content: m,
+ m := missingAAAA()
+ if (m != "") {
+ if (cloudflare.CFdialog.ValueNode != nil) {
+ cloudflare.CFdialog.ValueNode.SetText(m)
+ }
+ /*
+ rr := &cloudflare.RRT{
+ Type: "AAAA",
+ Name: me.hostname,
+ Ttl: "Auto",
+ Proxied: false,
+ Content: m,
+ }
+ cloudflare.Update(rr)
+ */
}
- cloudflare.Update(rr)
- */
}
}
status := displayDNS() // update the GUI based on dig results
diff --git a/hostname.go b/hostname.go
index 9eb1a65..10211ba 100644
--- a/hostname.go
+++ b/hostname.go
@@ -22,14 +22,7 @@ func getHostname() {
log.Error(err, "FQDN hostname error")
return
}
- if (me.fqdn != nil) {
- if (me.hostname != s) {
- me.fqdn.SetText(s)
- me.hostname = s
- me.changed = true
- }
- }
- log.Log(NET, "FQDN =", s)
+ me.status.SetHostname(s)
dn := run("domainname")
if (me.domainname.S != dn) {
@@ -47,17 +40,17 @@ func getHostname() {
var test string
test = hshort + "." + dn
- if (me.hostname != test) {
- log.Info("me.hostname", me.hostname, "does not equal", test)
- if (me.hostnameStatusOLD.S != "BROKEN") {
- log.Log(CHANGE, "me.hostname", me.hostname, "does not equal", test)
+ if (me.status.GetHostname() != test) {
+ log.Log(CHANGE, "me.hostname", me.status.GetHostname(), "does not equal", test)
+ if (me.hostnameStatus.S != "BROKEN") {
+ log.Log(CHANGE, "me.hostname", me.status.GetHostname(), "does not equal", test)
me.changed = true
- me.hostnameStatusOLD.SetText("BROKEN")
+ me.hostnameStatus.SetText("BROKEN")
}
} else {
- if (me.hostnameStatusOLD.S != "VALID") {
- log.Log(CHANGE, "me.hostname", me.hostname, "is valid")
- me.hostnameStatusOLD.SetText("VALID")
+ if (me.hostnameStatus.S != "VALID") {
+ log.Log(CHANGE, "me.hostname", me.status.GetHostname(), "is valid")
+ me.hostnameStatus.SetText("VALID")
me.changed = true
}
// enable the cloudflare button if the provider is cloudflare
@@ -76,7 +69,7 @@ func getHostname() {
// check that all the OS settings are correct here
// On Linux, /etc/hosts, /etc/hostname
// and domainname and hostname
-func goodHostname(h string) bool {
+func goodHostname() bool {
hostname := shell.Chomp(shell.Cat("/etc/hostname"))
log.Log(NOW, "hostname =", hostname)
@@ -93,30 +86,6 @@ func goodHostname(h string) bool {
return false
}
-/*
-func digAAAA(s string) []string {
- var aaaa []string
- // lookup the IP address from DNS
- rrset := dnssecsocket.Dnstrace(s, "AAAA")
- // log.Spew(args.VerboseDNS, SPEW, rrset)
- for i, rr := range rrset {
- ipaddr := dns.Field(rr, 1)
- // how the hell do you detect a RRSIG AAAA record here?
- if (ipaddr == "28") {
- continue
- }
- log.Log(NOW, "r.Answer =", i, "rr =", rr, "ipaddr =", ipaddr)
- aaaa = append(aaaa, ipaddr)
- me.ipv6s[ipaddr] = rr
- }
- log.Info(args.VerboseDNS, "aaaa =", aaaa)
- log.Println("digAAAA() returned =", aaaa)
- log.Println("digAAAA() me.ipv6s =", me.ipv6s)
- os.Exit(0)
- return aaaa
-}
-*/
-
func digAAAA(hostname string) []string {
var blah, ipv6Addresses []string
// domain := hostname
@@ -128,7 +97,7 @@ func digAAAA(hostname string) []string {
if (len(blah) == 0) {
log.Println("digAAAA() RUNNING dnsAAAAlookupDoH(domain)")
- ipv6Addresses, _ = dnsAAAAlookupDoH(hostname)
+ ipv6Addresses = lookupDoH(hostname, "AAAA")
log.Println("digAAAA() has ipv6Addresses =", strings.Join(ipv6Addresses, " "))
for _, addr := range ipv6Addresses {
log.Println(addr)
@@ -141,20 +110,3 @@ func digAAAA(hostname string) []string {
return blah
}
-
-/*
-func dnsHttpsLookup(domain string, recordType uint16) ([]string, error) {
- domain := "google.com"
- dnsLookupDoH(domain string) ([]string, error) {
- ipv6Addresses, err := dnsLookupDoH(domain)
- if err != nil {
- log.Println("Error:", err)
- return
- }
-
- log.Printf("IPv6 Addresses for %s:\n", domain)
- for _, addr := range ipv6Addresses {
- log.Println(addr)
- }
-}
-*/
diff --git a/hostnameStatus.go b/hostnameStatus.go
index eb158bf..2fd9bdd 100644
--- a/hostnameStatus.go
+++ b/hostnameStatus.go
@@ -23,7 +23,8 @@ type hostnameStatus struct {
ready bool
hidden bool
- hostname string // my hostname. Example: "test.wit.com"
+ // hostname string // my hostname. Example: "test.wit.com"
+ lastname string // used to watch for changes in the hostname
window *gadgets.BasicWindow
@@ -60,9 +61,9 @@ func NewHostnameStatusWindow(p *gui.Node) *hostnameStatus {
hs.ready = false
hs.hidden = true
- hs.hostname = me.hostname
+ // hs.hostname = me.hostname
- hs.window = gadgets.NewBasicWindow(p, hs.hostname + " Status")
+ hs.window = gadgets.NewBasicWindow(p, "fix hostname here" + " Status")
hs.window.Draw()
hs.window.Hide()
@@ -116,6 +117,25 @@ func NewHostnameStatusWindow(p *gui.Node) *hostnameStatus {
return hs
}
+func (hs *hostnameStatus) ValidHostname() bool {
+ return goodHostname()
+}
+
+func (hs *hostnameStatus) GetHostname() string {
+ return hs.lastname
+}
+
+func (hs *hostnameStatus) SetHostname(hostname string) {
+ if hostname == hs.lastname {return}
+ log.Log(CHANGE, "the hostname is changing from", hs.lastname, "to", hostname)
+ hs.lastname = hostname
+ me.changed = true
+
+ if (me.fqdn != nil) {
+ me.fqdn.SetText(hostname)
+ }
+}
+
func (hs *hostnameStatus) Domain() string {
if ! hs.Ready() {return ""}
return hs.domainname.Get()
@@ -128,26 +148,26 @@ func (hs *hostnameStatus) API() string {
func (hs *hostnameStatus) deleteDNSrecord(value string) bool {
log.Info("deleteDNSrecord() START for", value)
- log.Info("deleteDNSrecord() hostname =", me.hostname)
+ log.Info("deleteDNSrecord() hostname =", me.status.GetHostname())
log.Info("deleteDNSrecord() domain =", hs.Domain())
log.Info("deleteDNSrecord() DNS API Provider =", hs.API())
if (hs.API() == "cloudflare") {
log.Info("deleteDNSrecord() Try to delete via cloudflare")
- return cloudflare.Delete(hs.Domain(), me.hostname, value)
+ return cloudflare.Delete(hs.Domain(), me.status.GetHostname(), value)
}
return false
}
func (hs *hostnameStatus) createDNSrecord(value string) bool {
log.Info("createDNSrecord() START for", value)
- log.Info("createDNSrecord() hostname =", me.hostname)
+ log.Info("createDNSrecord() hostname =", me.status.GetHostname())
log.Info("createDNSrecord() domain =", hs.Domain())
log.Info("createDNSrecord() DNS API Provider =", hs.API())
if (hs.API() == "cloudflare") {
- log.Warn("createDNSrecord() Try to delete via cloudflare:", me.hostname, value)
- return cloudflare.Create(hs.Domain(), me.hostname, value)
+ log.Warn("createDNSrecord() Try to create via cloudflare:", me.status.GetHostname(), value)
+ return cloudflare.Create(hs.Domain(), me.status.GetHostname(), value)
}
return false
}
@@ -229,10 +249,10 @@ func (hs *hostnameStatus) set(a any, s string) {
if reflect.TypeOf(a) == reflect.TypeOf(ol) {
ol = a.(*gadgets.OneLiner)
if ol == nil {
- log.Println("ol = nil", reflect.TypeOf(a), "a =", a)
+ // log.Println("ol = nil", reflect.TypeOf(a), "a =", a)
return
}
- log.Println("SETTING ol:", ol)
+ // log.Println("SETTING ol:", ol)
ol.Set(s)
return
}
@@ -240,69 +260,82 @@ func (hs *hostnameStatus) set(a any, s string) {
os.Exit(0)
}
+// returns true if AAAA record already exists in DNS
+func (hs *hostnameStatus) existsAAAA(s string) bool {
+ log.Log(NOW, "existsAAAA() try to see if AAAA is already set", s)
+ return false
+}
+
// figure out if I'm missing any IPv6 address in DNS
func (hs *hostnameStatus) missingAAAA() bool {
var aaaa []string
aaaa = dhcpAAAA()
for _, s := range aaaa {
log.Log(NET, "my actual AAAA = ",s)
- hs.dnsValue.SetText(s)
- hs.dnsAction.SetText("CREATE")
- return true
+ if hs.existsAAAA(s) {
+ log.Log(NOW, "my actual AAAA already exists in DNS =",s)
+ } else {
+ log.Log(NOW, "my actual AAAA is missing from DNS",s)
+ hs.dnsValue.SetText(s)
+ hs.dnsAction.SetText("CREATE")
+ return true
+ }
}
return false
}
func (hs *hostnameStatus) updateStatus() {
+ if ! hs.Ready() { return }
var s string
var vals []string
- log.Info("updateStatus() START")
- if ! hs.Ready() { return }
+ log.Log(STATUS, "updateStatus() START")
hs.hostShort.Set(me.hostshort.S)
hs.domainname.Set(me.domainname.S)
- vals = lookupDoH(hs.hostname, "AAAA")
+ if hs.ValidHostname() {
+ vals = lookupDoH(hs.GetHostname(), "AAAA")
- log.Println("DNS IPv6 Addresses for ", hs.hostname, "=", vals)
- if len(vals) == 0 {
- s = "(none)"
- hs.setIPv6("Check for real IPv6 addresses here")
- if hs.missingAAAA() {
- hs.setIPv6("Add the missing IPv6 address")
- }
- } else {
- for _, addr := range vals {
- log.Println(addr)
- s += addr + " (DELETE)"
- hs.setIPv6("NEEDS DELETE")
- hs.dnsValue.SetText(addr)
- hs.dnsAction.SetText("DELETE")
+ log.Log(STATUS, "DNS IPv6 Addresses for ", hs.GetHostname(), "=", vals)
+ if len(vals) == 0 {
+ s = "(none)"
+ } else {
+ hs.setIPv6("Check for real IPv6 addresses here")
+ if hs.missingAAAA() {
+ hs.setIPv6("Add the missing IPv6 address")
+ }
+ for _, addr := range vals {
+ log.Log(STATUS, addr)
+ s += addr + " (DELETE)" + "\n"
+ hs.setIPv6("NEEDS DELETE")
+ hs.dnsValue.SetText(addr)
+ hs.dnsAction.SetText("DELETE")
+ }
}
- }
- hs.set(hs.dnsAAAA, s)
+ hs.set(hs.dnsAAAA, s)
- vals = lookupDoH(hs.hostname, "A")
- log.Println("IPv4 Addresses for ", hs.hostname, "=", vals)
- s = strings.Join(vals, "\n")
- if (s == "") {
- s = "(none)"
- hs.setIPv4("NEEDS CNAME")
- }
- hs.set(hs.dnsA, s)
+ vals = lookupDoH(hs.GetHostname(), "A")
+ log.Log(STATUS, "IPv4 Addresses for ", hs.GetHostname(), "=", vals)
+ s = strings.Join(vals, "\n")
+ if (s == "") {
+ s = "(none)"
+ hs.setIPv4("NEEDS CNAME")
+ }
+ hs.set(hs.dnsA, s)
- vals = lookupDoH(hs.hostname, "CNAME")
- s = strings.Join(vals, "\n")
- if (s != "") {
- hs.set(hs.dnsA, "CNAME " + s)
- hs.setIPv4("GOOD")
+ vals = lookupDoH(hs.GetHostname(), "CNAME")
+ s = strings.Join(vals, "\n")
+ if (s != "") {
+ hs.set(hs.dnsA, "CNAME " + s)
+ hs.setIPv4("GOOD")
+ }
}
hs.currentIPv4.Set(me.IPv4.S)
hs.currentIPv6.Set(me.IPv6.S)
- if hs.IPv4() && hs.IPv4() {
+ if hs.IPv4() && hs.IPv6() {
hs.status.Set("GOOD")
} else {
hs.status.Set("BROKEN")
@@ -312,7 +345,7 @@ func (hs *hostnameStatus) updateStatus() {
}
func (hs *hostnameStatus) Show() {
- log.Info("hostnameStatus.Show() window")
+ log.Log(STATUS, "hostnameStatus.Show() window")
if hs.hidden {
hs.window.Show()
}
@@ -320,7 +353,7 @@ func (hs *hostnameStatus) Show() {
}
func (hs *hostnameStatus) Hide() {
- log.Info("hostnameStatus.Hide() window")
+ log.Log(STATUS, "hostnameStatus.Hide() window")
if ! hs.hidden {
hs.window.Hide()
}
diff --git a/nsupdate.go b/nsupdate.go
index d86178f..2757b75 100644
--- a/nsupdate.go
+++ b/nsupdate.go
@@ -22,7 +22,7 @@ func nsupdate() {
cmd := "go-nsupdate --tsig-algorithm=hmac-sha512"
tsigSecret = os.Getenv("TIG_SECRET")
cmd += " --tig-secret=\"" + tsigSecret + "\""
- cmd += " -i wlo1 " + me.hostname
+ cmd += " -i wlo1 " + me.status.GetHostname()
log.Log(NET, "nsupdate() RUN:", cmd)
for s, t := range me.ipmap {
diff --git a/resolverBox.go b/resolverBox.go
new file mode 100644
index 0000000..8a7e2f3
--- /dev/null
+++ b/resolverBox.go
@@ -0,0 +1,209 @@
+/*
+ Performs DNS queries on TCP and UDP
+*/
+
+package main
+
+import (
+ "os"
+ "time"
+ "strconv"
+ "reflect"
+
+ "go.wit.com/log"
+ "go.wit.com/gui/gui"
+ "go.wit.com/gui/gadgets"
+
+ "github.com/miekg/dns"
+)
+
+type resolverStatus struct {
+ title string
+ server string // The DNS server. Example: "127.0.0.1:53" or "1.1.1.1:53"
+ hostname string // the hostname to lookup. Example: "www.google.com" or "go.wit.com"
+
+ parent *gui.Node
+ group *gui.Node
+ grid *gui.Node
+
+ // DNS setup options
+ udpA *gui.Node
+ tcpA *gui.Node
+ udpAAAA *gui.Node
+ tcpAAAA *gui.Node
+
+ // show the display
+ aFail *gui.Node
+ aSuccess *gui.Node
+ aaaaFail *gui.Node
+ aaaaSuccess *gui.Node
+
+ // interger counters
+ aFailc int
+ aSuccessc int
+ aaaaFailc int
+ aaaaSuccessc int
+}
+
+func (rs *resolverStatus) set(a any, s string) {
+ if a == nil {
+ return
+ }
+ var n *gui.Node
+ if reflect.TypeOf(a) == reflect.TypeOf(n) {
+ n = a.(*gui.Node)
+ n.SetText(s)
+ return
+ }
+ var ol *gadgets.OneLiner
+ if reflect.TypeOf(a) == reflect.TypeOf(ol) {
+ ol = a.(*gadgets.OneLiner)
+ ol.Set(s)
+ return
+ }
+ log.Warn("unknown type TypeOf(a) =", reflect.TypeOf(a), "a =", a)
+ os.Exit(0)
+}
+
+// Makes a DNS Status Grid
+func NewResolverStatus(p *gui.Node, title string, server string, hostname string) *resolverStatus {
+ var rs *resolverStatus
+ rs = new(resolverStatus)
+ rs.parent = p
+ rs.group = p.NewGroup(server + " " + title + " lookup")
+ rs.grid = rs.group.NewGrid("LookupStatus", 5, 2)
+
+ rs.server = server
+ rs.hostname = hostname
+
+ rs.grid.NewLabel("")
+ rs.grid.NewLabel("UDP")
+ rs.grid.NewLabel("TCP")
+ rs.grid.NewLabel("Success")
+ rs.grid.NewLabel("Fail")
+
+ rs.grid.NewLabel("A")
+ rs.udpA = rs.grid.NewLabel("?")
+ rs.tcpA = rs.grid.NewLabel("?")
+ rs.aSuccess = rs.grid.NewLabel("?")
+ rs.aFail = rs.grid.NewLabel("?")
+
+ rs.grid.NewLabel("AAAA")
+ rs.udpAAAA = rs.grid.NewLabel("?")
+ rs.tcpAAAA = rs.grid.NewLabel("?")
+ rs.aaaaSuccess = rs.grid.NewLabel("?")
+ rs.aaaaFail = rs.grid.NewLabel("?")
+
+ rs.group.Margin()
+ rs.grid.Margin()
+ rs.group.Pad()
+ rs.grid.Pad()
+
+ return rs
+}
+
+// special thanks to the Element Hotel wifi in Philidelphia that allowed me to
+// easily debug this code since the internet connection here blocks port 53 traffic
+func (rs *resolverStatus) update() (bool, bool) {
+ var results []string
+ var a bool = false
+ var aaaa bool = false
+
+ log.Log(DNS, "resolverStatus.update() For server", rs.server, "on", rs.hostname)
+ results, _ = dnsUdpLookup(rs.server, rs.hostname, dns.TypeA)
+ log.Log(DNS, "resolverStatus.update() UDP type A =", results)
+
+ if (len(results) == 0) {
+ rs.set(rs.udpA, "BROKEN")
+ rs.aFailc += 1
+ } else {
+ rs.set(rs.udpA, "WORKING")
+ rs.aSuccessc += 1
+ a = true
+ }
+
+ results, _ = dnsTcpLookup(rs.server, rs.hostname, dns.TypeA)
+ log.Log(DNS, "resolverStatus.update() TCP type A =", results)
+
+ if (len(results) == 0) {
+ rs.set(rs.tcpA, "BROKEN")
+ rs.aFailc += 1
+ } else {
+ me.digStatus.set(rs.tcpA, "WORKING")
+ rs.aSuccessc += 1
+ a = true
+ }
+
+ me.digStatus.set(rs.aFail, strconv.Itoa(rs.aFailc))
+ me.digStatus.set(rs.aSuccess,strconv.Itoa(rs.aSuccessc))
+
+ results, _ = dnsUdpLookup(rs.server, rs.hostname, dns.TypeAAAA)
+ log.Log(DNS, "resolverStatus.update() UDP type AAAA =", results)
+
+ if (len(results) == 0) {
+ me.digStatus.set(rs.udpAAAA, "BROKEN")
+ rs.aaaaFailc += 1
+ me.digStatus.set(rs.aaaaFail, strconv.Itoa(rs.aaaaFailc))
+ } else {
+ me.digStatus.set(rs.udpAAAA, "WORKING")
+ rs.aaaaSuccessc += 1
+ aaaa = true
+ }
+
+ results, _ = dnsTcpLookup(rs.server, rs.hostname, dns.TypeAAAA)
+ log.Log(DNS, "resolverStatus.update() UDP type AAAA =", results)
+
+ if (len(results) == 0) {
+ me.digStatus.set(rs.tcpAAAA, "BROKEN")
+ rs.aaaaFailc += 1
+ me.digStatus.set(rs.aaaaFail, strconv.Itoa(rs.aaaaFailc))
+ } else {
+ me.digStatus.set(rs.tcpAAAA, "WORKING")
+ rs.aaaaSuccessc += 1
+ aaaa = true
+ }
+
+ me.digStatus.set(rs.aaaaFail, strconv.Itoa(rs.aaaaFailc))
+ me.digStatus.set(rs.aaaaSuccess,strconv.Itoa(rs.aaaaSuccessc))
+
+ return a, aaaa
+}
+
+// dnsLookup performs a DNS lookup for the specified record type (e.g., "TXT", "AAAA") for a given domain.
+func dnsUdpLookup(server string, domain string, recordType uint16) ([]string, error) {
+ var records []string
+
+ c := new(dns.Client)
+ m := new(dns.Msg)
+ m.SetQuestion(dns.Fqdn(domain), recordType)
+ r, _, err := c.Exchange(m, server) // If server = "1.1.1.1:53" then use Cloudflare's DNS server
+ if err != nil {
+ return nil, err
+ }
+
+ for _, ans := range r.Answer {
+ records = append(records, ans.String())
+ }
+
+ return records, nil
+}
+
+func dnsTcpLookup(server string, domain string, recordType uint16) ([]string, error) {
+ var records []string
+
+ c := new(dns.Client)
+ c.Net = "tcp" // Specify to use TCP for the query
+ c.Timeout = time.Second * 5 // Set a 5-second timeout
+ m := new(dns.Msg)
+ m.SetQuestion(dns.Fqdn(domain), recordType)
+ r, _, err := c.Exchange(m, server) // If server = "1.1.1.1:53" then use Cloudflare's DNS server
+ if err != nil {
+ return nil, err
+ }
+
+ for _, ans := range r.Answer {
+ records = append(records, ans.String())
+ }
+
+ return records, nil
+}
diff --git a/structs.go b/structs.go
index 3d4e153..f794773 100644
--- a/structs.go
+++ b/structs.go
@@ -6,6 +6,7 @@ import (
"time"
"go.wit.com/gui/gui"
"go.wit.com/gui/gadgets"
+
"github.com/miekg/dns"
)
@@ -13,10 +14,13 @@ import (
var me Host
type Host struct {
- hostname string // mirrors
+ status *hostnameStatus // keeps track of the hostname and it's status
+
+ hostnameStatus *gui.Node // a summary for the user of where things are
+
+ // hostname string // mirrors
domainname *gui.Node // kernel.org
hostshort *gui.Node // hostname -s
- hostnameStatusOLD *gui.Node // is the hostname configured correctly in the OS?
// fqdn string // mirrors.kernel.org
// dnsTTL int `default:"3"` // Recheck DNS is working every TTL (in seconds)
@@ -59,7 +63,7 @@ type Host struct {
// DNS stuff
NSrr *gui.Node // NS resource records for the domain name
DnsAPI *gui.Node // what DNS API to use?
- DnsAAAA *gui.Node // the actual DNS AAAA results
+ DnsAAAA *gadgets.OneLiner // the actual DNS AAAA results
workingIPv6 *gui.Node // currently working AAAA
DnsA *gui.Node // the actual DNS A results (ignore for status since mostly never happens?)
DnsStatus *gui.Node // the current state of DNS
@@ -81,7 +85,6 @@ type Host struct {
statusIPv6 *gadgets.OneLiner
digStatusButton *gui.Node
- hostnameStatus *hostnameStatus
hostnameStatusButton *gui.Node
myDebug *gui.Node