Compare commits
No commits in common. "15d9f9769360b1cb8c748de8ee995030ade5eb35" and "2d1e3213261bee4640c11d8e1f526fcb6234e037" have entirely different histories.
15d9f97693
...
2d1e321326
25
args.go
25
args.go
|
@ -18,14 +18,11 @@ var args struct {
|
||||||
VerboseDNS bool `arg:"--verbose-dns" help:"debug your dns settings"`
|
VerboseDNS bool `arg:"--verbose-dns" help:"debug your dns settings"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var NOW log.LogFlag
|
|
||||||
var INFO log.LogFlag
|
|
||||||
var NET log.LogFlag
|
var NET log.LogFlag
|
||||||
var DNS log.LogFlag
|
var NOW log.LogFlag
|
||||||
var PROC log.LogFlag
|
var PROC log.LogFlag
|
||||||
var SPEW log.LogFlag
|
var SPEW log.LogFlag
|
||||||
var CHANGE log.LogFlag
|
var CHANGE log.LogFlag
|
||||||
var STATUS log.LogFlag
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
arg.MustParse(&args)
|
arg.MustParse(&args)
|
||||||
|
@ -37,24 +34,12 @@ func init() {
|
||||||
NOW.Desc = "temp debugging stuff"
|
NOW.Desc = "temp debugging stuff"
|
||||||
NOW.Register()
|
NOW.Register()
|
||||||
|
|
||||||
INFO.B = false
|
|
||||||
INFO.Name = "INFO"
|
|
||||||
INFO.Subsystem = "cpdns"
|
|
||||||
INFO.Desc = "normal debugging stuff"
|
|
||||||
INFO.Register()
|
|
||||||
|
|
||||||
NET.B = false
|
NET.B = false
|
||||||
NET.Name = "NET"
|
NET.Name = "NET"
|
||||||
NET.Subsystem = "cpdns"
|
NET.Subsystem = "cpdns"
|
||||||
NET.Desc = "Network logging"
|
NET.Desc = "Network logging"
|
||||||
NET.Register()
|
NET.Register()
|
||||||
|
|
||||||
DNS.B = false
|
|
||||||
DNS.Name = "DNS"
|
|
||||||
DNS.Subsystem = "cpdns"
|
|
||||||
DNS.Desc = "dnsStatus.update()"
|
|
||||||
DNS.Register()
|
|
||||||
|
|
||||||
PROC.B = false
|
PROC.B = false
|
||||||
PROC.Name = "PROC"
|
PROC.Name = "PROC"
|
||||||
PROC.Subsystem = "cpdns"
|
PROC.Subsystem = "cpdns"
|
||||||
|
@ -67,18 +52,12 @@ func init() {
|
||||||
SPEW.Desc = "spew logging"
|
SPEW.Desc = "spew logging"
|
||||||
SPEW.Register()
|
SPEW.Register()
|
||||||
|
|
||||||
CHANGE.B = true
|
CHANGE.B = false
|
||||||
CHANGE.Name = "CHANGE"
|
CHANGE.Name = "CHANGE"
|
||||||
CHANGE.Subsystem = "cpdns"
|
CHANGE.Subsystem = "cpdns"
|
||||||
CHANGE.Desc = "show droplet state changes"
|
CHANGE.Desc = "show droplet state changes"
|
||||||
CHANGE.Register()
|
CHANGE.Register()
|
||||||
|
|
||||||
STATUS.B = false
|
|
||||||
STATUS.Name = "STATUS"
|
|
||||||
STATUS.Subsystem = "cpdns"
|
|
||||||
STATUS.Desc = "updateStatus()"
|
|
||||||
STATUS.Register()
|
|
||||||
|
|
||||||
if debugger.ArgDebug() {
|
if debugger.ArgDebug() {
|
||||||
log.Log(true, "INIT() gui debug == true")
|
log.Log(true, "INIT() gui debug == true")
|
||||||
} else {
|
} else {
|
||||||
|
|
314
digStatus.go
314
digStatus.go
|
@ -1,314 +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"
|
|
||||||
"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.statusOS.ValidHostname() {
|
|
||||||
if ds.checkLookupDoH(me.statusOS.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
|
|
||||||
}
|
|
94
dns-https.go
94
dns-https.go
|
@ -2,27 +2,76 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"go.wit.com/log"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
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.
|
// dnsLookupDoH performs a DNS lookup for AAAA records over HTTPS.
|
||||||
func lookupDoH(hostname string, rrType string) []string {
|
func lookupDoH(hostname string, rrType string) []string {
|
||||||
var values []string
|
var values []string
|
||||||
|
|
||||||
// Construct the URL for a DNS query with Google's DNS-over-HTTPS API
|
// Construct the URL for a DNS query with Google's DNS-over-HTTPS API
|
||||||
url := fmt.Sprintf("https://dns.google.com/resolve?name=%s&type=%s", hostname, rrType)
|
url := fmt.Sprintf("https://dns.google/resolve?name=%s&type=%s", hostname, rrType)
|
||||||
|
|
||||||
log.Log(DNS, "lookupDoH()", url)
|
log.Println("curl", url)
|
||||||
if hostname == "" {
|
|
||||||
log.Warn("lookupDoH() was sent a empty hostname")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform the HTTP GET request
|
// Perform the HTTP GET request
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
|
@ -57,28 +106,3 @@ func lookupDoH(hostname string, rrType string) []string {
|
||||||
|
|
||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|
||||||
func digAAAA(hostname string) []string {
|
|
||||||
var blah, ipv6Addresses []string
|
|
||||||
// domain := hostname
|
|
||||||
recordType := dns.TypeAAAA // dns.TypeTXT
|
|
||||||
|
|
||||||
// Cloudflare's DNS server
|
|
||||||
blah, _ = dnsUdpLookup("1.1.1.1:53", hostname, recordType)
|
|
||||||
log.Println("digAAAA() has BLAH =", blah)
|
|
||||||
|
|
||||||
if (len(blah) == 0) {
|
|
||||||
log.Println("digAAAA() RUNNING dnsAAAAlookupDoH(domain)")
|
|
||||||
ipv6Addresses = lookupDoH(hostname, "AAAA")
|
|
||||||
log.Println("digAAAA() has ipv6Addresses =", strings.Join(ipv6Addresses, " "))
|
|
||||||
for _, addr := range ipv6Addresses {
|
|
||||||
log.Println(addr)
|
|
||||||
}
|
|
||||||
return ipv6Addresses
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: check digDoH vs blah, if so, then port 53 TCP and/or UDP is broken or blocked
|
|
||||||
log.Println("digAAAA() has BLAH =", blah)
|
|
||||||
|
|
||||||
return blah
|
|
||||||
}
|
|
||||||
|
|
4
dns.go
4
dns.go
|
@ -111,10 +111,10 @@ func lookupNS(domain string) {
|
||||||
}
|
}
|
||||||
tmp = shell.Chomp(tmp)
|
tmp = shell.Chomp(tmp)
|
||||||
|
|
||||||
if (tmp != me.status.NSrr.Get()) {
|
if (tmp != me.NSrr.S) {
|
||||||
me.changed = true
|
me.changed = true
|
||||||
log.Log(CHANGE, "lookupNS() setting me.NSrr =", tmp)
|
log.Log(CHANGE, "lookupNS() setting me.NSrr =", tmp)
|
||||||
me.status.NSrr.Set(tmp)
|
me.NSrr.SetText(tmp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,476 @@
|
||||||
|
/*
|
||||||
|
'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
|
||||||
|
}
|
44
fix.go
44
fix.go
|
@ -1,44 +0,0 @@
|
||||||
// This creates a simple hello world window
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func fix() bool {
|
|
||||||
log.Warn("")
|
|
||||||
if ! me.status.Ready() {
|
|
||||||
log.Warn("The IPv6 Control Panel is not Ready() yet")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if me.statusOS.ValidHostname() {
|
|
||||||
log.Warn("Your hostname is VALID:", me.statusOS.GetHostname())
|
|
||||||
} else {
|
|
||||||
log.Warn("You must first fix your hostname:", me.statusOS.GetHostname())
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if me.digStatus.IPv4() {
|
|
||||||
log.Warn("IPv4 addresses are resolving")
|
|
||||||
} else {
|
|
||||||
log.Warn("You must first figure out why you can't look up IPv4 addresses")
|
|
||||||
log.Warn("Are you on the internet at all?")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if me.digStatus.IPv6() {
|
|
||||||
log.Warn("IPv6 addresses are resolving")
|
|
||||||
} else {
|
|
||||||
log.Warn("You must first figure out why you can't look up IPv6 addresses")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if ! me.status.IPv4() {
|
|
||||||
log.Warn("You do not have real IPv4 addresses. Nothing to fix here")
|
|
||||||
}
|
|
||||||
if ! me.status.IPv6() {
|
|
||||||
log.Warn("IPv6 DNS is broken. Check what is broken here")
|
|
||||||
log.Warn("What are my IPv6 addresses?")
|
|
||||||
log.Warn("What are the AAAA resource records in DNS?")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
log.Warn("YOU SHOULD BE IN IPv6 BLISS")
|
|
||||||
return true
|
|
||||||
}
|
|
248
gui.go
248
gui.go
|
@ -4,15 +4,18 @@ package main
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
"os"
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"strconv"
|
||||||
|
// "net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/shell"
|
||||||
|
|
||||||
"go.wit.com/gui/gui"
|
"go.wit.com/gui/gui"
|
||||||
"go.wit.com/gui/gadgets"
|
"go.wit.com/gui/gadgets"
|
||||||
"go.wit.com/gui/cloudflare"
|
"go.wit.com/gui/cloudflare"
|
||||||
"go.wit.com/gui/debugger"
|
"go.wit.com/gui/debugger"
|
||||||
"go.wit.com/control-panels/dns/linuxstatus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// This setups up the dns control panel window
|
// This setups up the dns control panel window
|
||||||
|
@ -22,7 +25,56 @@ func setupControlPanelWindow() {
|
||||||
|
|
||||||
// setup the main tab
|
// setup the main tab
|
||||||
mainWindow("DNS and IPv6 Control Panel")
|
mainWindow("DNS and IPv6 Control Panel")
|
||||||
|
detailsTab("OS Details")
|
||||||
debugTab("Debug")
|
debugTab("Debug")
|
||||||
|
|
||||||
|
// me.digStatus = NewDigStatusWindow(me.window)
|
||||||
|
}
|
||||||
|
|
||||||
|
func detailsTab(title string) {
|
||||||
|
var g2 *gui.Node
|
||||||
|
|
||||||
|
me.details = gadgets.NewBasicWindow(me.myGui, title)
|
||||||
|
me.details.Draw()
|
||||||
|
me.details.Hide()
|
||||||
|
|
||||||
|
g2 = me.details.Box().NewGroup("Real Stuff")
|
||||||
|
|
||||||
|
grid := g2.NewGrid("gridnuts", 2, 2)
|
||||||
|
|
||||||
|
grid.SetNext(1,1)
|
||||||
|
|
||||||
|
grid.NewLabel("domainname =")
|
||||||
|
me.domainname = grid.NewLabel("domainname")
|
||||||
|
|
||||||
|
grid.NewLabel("hostname -s =")
|
||||||
|
me.hostshort = grid.NewLabel("hostname -s")
|
||||||
|
|
||||||
|
grid.NewLabel("NS records =")
|
||||||
|
me.NSrr = grid.NewLabel("NS RR's")
|
||||||
|
|
||||||
|
grid.NewLabel("UID =")
|
||||||
|
me.uid = grid.NewLabel("my uid")
|
||||||
|
|
||||||
|
grid.NewLabel("Current IPv4 =")
|
||||||
|
me.IPv4 = grid.NewLabel("?")
|
||||||
|
|
||||||
|
grid.NewLabel("Current IPv6 =")
|
||||||
|
me.IPv6 = grid.NewLabel("?")
|
||||||
|
|
||||||
|
grid.NewLabel("Working Real IPv6 =")
|
||||||
|
me.workingIPv6 = grid.NewLabel("?")
|
||||||
|
|
||||||
|
grid.NewLabel("interfaces =")
|
||||||
|
me.Interfaces = grid.NewCombobox("Interfaces")
|
||||||
|
|
||||||
|
grid.NewLabel("refresh speed")
|
||||||
|
me.LocalSpeedActual = grid.NewLabel("unknown")
|
||||||
|
|
||||||
|
grid.Margin()
|
||||||
|
grid.Pad()
|
||||||
|
|
||||||
|
me.details.Hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugTab(title string) {
|
func debugTab(title string) {
|
||||||
|
@ -38,20 +90,18 @@ func debugTab(title string) {
|
||||||
debugger.DebugWindow(me.myGui)
|
debugger.DebugWindow(me.myGui)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
g2.NewButton("getHostname() looks at the OS settings", func () {
|
||||||
|
getHostname()
|
||||||
|
})
|
||||||
|
|
||||||
g2.NewButton("dig A & AAAA DNS records", func () {
|
g2.NewButton("dig A & AAAA DNS records", func () {
|
||||||
log.Println("updateDNS()")
|
log.Println("updateDNS()")
|
||||||
updateDNS()
|
updateDNS()
|
||||||
})
|
})
|
||||||
|
|
||||||
g2.NewButton("dig +trace", func () {
|
g2.NewButton("dig +trace", func () {
|
||||||
log.Log(NOW, "TODO: redo this")
|
o := shell.Run("dig +trace +noadditional DS " + me.hostname + " @8.8.8.8")
|
||||||
// o := shell.Run("dig +trace +noadditional DS " + me.hostname + " @8.8.8.8")
|
log.Println(o)
|
||||||
// log.Println(o)
|
|
||||||
})
|
|
||||||
|
|
||||||
g2.NewButton("getProcessNameByPort()", func () {
|
|
||||||
processName := getProcessNameByPort(53)
|
|
||||||
log.Info("Process with port 53:", processName)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
g2 = me.debug.Box().NewGroup("debugging options")
|
g2 = me.debug.Box().NewGroup("debugging options")
|
||||||
|
@ -98,15 +148,15 @@ func missingAAAA() string {
|
||||||
// it just updates the GUI
|
// it just updates the GUI
|
||||||
func displayDNS() string {
|
func displayDNS() string {
|
||||||
var aaaa []string
|
var aaaa []string
|
||||||
aaaa = append(aaaa, "blah", "more")
|
aaaa = dhcpAAAA() // your AAAA records right now
|
||||||
// h := me.hostname
|
h := me.hostname
|
||||||
var all string
|
var all string
|
||||||
var broken string = "unknown"
|
var broken string = "unknown"
|
||||||
for _, s := range aaaa {
|
for _, s := range aaaa {
|
||||||
log.Log(STATUS, "host", "fixme", "DNS AAAA =", s, "ipmap[s] =", me.ipmap[s])
|
log.Log(NOW, "host", h, "DNS AAAA =", s, "ipmap[s] =", me.ipmap[s])
|
||||||
all += s + "\n"
|
all += s + "\n"
|
||||||
if ( me.ipmap[s] == nil) {
|
if ( me.ipmap[s] == nil) {
|
||||||
log.Warn("THIS IS THE WRONG AAAA DNS ENTRY: host", "fixme", "DNS AAAA =", s)
|
log.Warn("THIS IS THE WRONG AAAA DNS ENTRY: host", h, "DNS AAAA =", s)
|
||||||
broken = "wrong AAAA entry"
|
broken = "wrong AAAA entry"
|
||||||
} else {
|
} else {
|
||||||
if (broken == "unknown") {
|
if (broken == "unknown") {
|
||||||
|
@ -114,16 +164,21 @@ func displayDNS() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
all = sortLines(all)
|
||||||
|
if (me.workingIPv6.S != all) {
|
||||||
|
log.Warn("workingIPv6.SetText() to:", all)
|
||||||
|
me.workingIPv6.SetText(all)
|
||||||
|
}
|
||||||
|
|
||||||
var a []string
|
var a []string
|
||||||
a = realA()
|
a = realA()
|
||||||
all = sortLines(strings.Join(a, "\n"))
|
all = sortLines(strings.Join(a, "\n"))
|
||||||
if (all == "") {
|
if (all == "") {
|
||||||
log.Log(NOW, "THERE IS NOT a real A DNS ENTRY")
|
log.Info("THERE IS NOT a real A DNS ENTRY")
|
||||||
all = "CNAME ipv6.wit.com"
|
all = "CNAME ipv6.wit.com"
|
||||||
}
|
}
|
||||||
if (me.DnsA.S != all) {
|
if (me.DnsA.S != all) {
|
||||||
log.Log(NOW, "DnsA.SetText() to:", all)
|
log.Warn("DnsA.SetText() to:", all)
|
||||||
me.DnsA.SetText(all)
|
me.DnsA.SetText(all)
|
||||||
}
|
}
|
||||||
return broken
|
return broken
|
||||||
|
@ -137,20 +192,26 @@ func myDefaultExit(n *gui.Node) {
|
||||||
func mainWindow(title string) {
|
func mainWindow(title string) {
|
||||||
me.window = gadgets.NewBasicWindow(me.myGui, title)
|
me.window = gadgets.NewBasicWindow(me.myGui, title)
|
||||||
|
|
||||||
gr := me.window.Box().NewGroup("dns update")
|
me.mainStatus = me.window.Box().NewGroup("dns update")
|
||||||
grid := gr.NewGrid("gridnuts", 2, 2)
|
grid := me.mainStatus.NewGrid("gridnuts", 2, 2)
|
||||||
|
|
||||||
grid.SetNext(1,1)
|
grid.SetNext(1,1)
|
||||||
|
|
||||||
me.hostname = gadgets.NewOneLiner(grid, "hostname =").Set("unknown")
|
grid.NewLabel("hostname =")
|
||||||
me.DnsAAAA = gadgets.NewOneLiner(grid, "DNS AAAA =").Set("unknown")
|
me.fqdn = grid.NewLabel("?")
|
||||||
|
me.hostname = ""
|
||||||
|
|
||||||
|
grid.NewLabel("DNS AAAA =")
|
||||||
|
me.DnsAAAA = grid.NewLabel("?")
|
||||||
|
|
||||||
grid.NewLabel("DNS A =")
|
grid.NewLabel("DNS A =")
|
||||||
me.DnsA = grid.NewLabel("?")
|
me.DnsA = grid.NewLabel("?")
|
||||||
|
|
||||||
// This is where you figure out what to do next to fix the problems
|
me.digStatus = NewDigStatusWindow(me.myGui)
|
||||||
gr.NewButton("fix", func () {
|
me.hostnameStatus = NewHostnameStatusWindow(me.myGui)
|
||||||
fix()
|
|
||||||
|
me.hostnameStatusButton = me.mainStatus.NewButton("Fix hostname DNS", func () {
|
||||||
|
me.hostnameStatus.window.Toggle()
|
||||||
})
|
})
|
||||||
|
|
||||||
grid.Margin()
|
grid.Margin()
|
||||||
|
@ -158,44 +219,20 @@ func mainWindow(title string) {
|
||||||
|
|
||||||
statusGrid(me.window.Box())
|
statusGrid(me.window.Box())
|
||||||
|
|
||||||
gr = me.window.Box().NewGroup("debugging")
|
gr := me.window.Box().NewGroup("debugging")
|
||||||
gr.NewButton("hostname status", func () {
|
gr.NewButton("GO GUI Debugger", func () {
|
||||||
if ! me.status.Ready() {return}
|
debugger.DebugWindow(me.myGui)
|
||||||
me.status.window.Toggle()
|
|
||||||
})
|
})
|
||||||
|
gr.NewButton("OS Details", func () {
|
||||||
gr.NewButton("linuxstatus.New()", func () {
|
me.details.Toggle()
|
||||||
if (me.statusOS == nil) {
|
|
||||||
me.statusOS = linuxstatus.New()
|
|
||||||
}
|
|
||||||
me.statusOS.SetParent(me.myGui)
|
|
||||||
me.statusOS.InitWindow()
|
|
||||||
me.statusOS.Make()
|
|
||||||
me.statusOS.Draw2()
|
|
||||||
})
|
})
|
||||||
gr.NewButton("statusOS.Ready()", func () {
|
gr.NewButton("DNS Debug", func () {
|
||||||
me.statusOS.Ready()
|
me.debug.Toggle()
|
||||||
})
|
})
|
||||||
gr.NewButton("statusOS.Draw()", func () {
|
gr.NewButton("Resolver Status", func () {
|
||||||
me.statusOS.Draw()
|
|
||||||
me.statusOS.Draw2()
|
|
||||||
})
|
|
||||||
gr.NewButton("statusOS.Update()", func () {
|
|
||||||
me.statusOS.Update()
|
|
||||||
})
|
|
||||||
gr.NewButton("Linux Status", func () {
|
|
||||||
me.statusOS.Toggle()
|
|
||||||
})
|
|
||||||
gr.NewButton("resolver status", func () {
|
|
||||||
if ! me.digStatus.Ready() {return}
|
if ! me.digStatus.Ready() {return}
|
||||||
me.digStatus.window.Toggle()
|
me.digStatus.window.Toggle()
|
||||||
})
|
})
|
||||||
gr.NewButton("cloudflare wit.com", func () {
|
|
||||||
cloudflare.CreateRR(me.myGui, "wit.com", "3777302ac4a78cd7fa4f6d3f72086d06")
|
|
||||||
})
|
|
||||||
gr.NewButton("Debug", func () {
|
|
||||||
me.debug.Toggle()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func statusGrid(n *gui.Node) {
|
func statusGrid(n *gui.Node) {
|
||||||
|
@ -203,15 +240,15 @@ func statusGrid(n *gui.Node) {
|
||||||
|
|
||||||
gridP := problems.NewGrid("nuts", 2, 2)
|
gridP := problems.NewGrid("nuts", 2, 2)
|
||||||
|
|
||||||
gridP.NewLabel("hostname =")
|
|
||||||
me.hostnameStatus = gridP.NewLabel("invalid")
|
|
||||||
|
|
||||||
gridP.NewLabel("DNS Status =")
|
gridP.NewLabel("DNS Status =")
|
||||||
me.DnsStatus = gridP.NewLabel("unknown")
|
me.DnsStatus = gridP.NewLabel("unknown")
|
||||||
|
|
||||||
me.statusIPv6 = gadgets.NewOneLiner(gridP, "IPv6 working")
|
me.statusIPv6 = gadgets.NewOneLiner(gridP, "IPv6 working")
|
||||||
me.statusIPv6.Set("known")
|
me.statusIPv6.Set("known")
|
||||||
|
|
||||||
|
gridP.NewLabel("hostname =")
|
||||||
|
me.hostnameStatusOLD = gridP.NewLabel("invalid")
|
||||||
|
|
||||||
gridP.NewLabel("dns resolution")
|
gridP.NewLabel("dns resolution")
|
||||||
me.DnsSpeed = gridP.NewLabel("unknown")
|
me.DnsSpeed = gridP.NewLabel("unknown")
|
||||||
|
|
||||||
|
@ -242,51 +279,52 @@ func statusGrid(n *gui.Node) {
|
||||||
|
|
||||||
// run everything because something has changed
|
// run everything because something has changed
|
||||||
func updateDNS() {
|
func updateDNS() {
|
||||||
|
var aaaa []string
|
||||||
|
h := me.hostname
|
||||||
|
if (h == "") {
|
||||||
|
h = "test.wit.com"
|
||||||
|
}
|
||||||
|
|
||||||
me.digStatus.Update()
|
me.digStatus.Update()
|
||||||
me.status.Update()
|
me.hostnameStatus.Update()
|
||||||
|
|
||||||
// log.Println("digAAAA()")
|
// log.Println("digAAAA()")
|
||||||
|
aaaa = digAAAA(h)
|
||||||
|
log.Log(NOW, "digAAAA() =", aaaa)
|
||||||
|
|
||||||
if me.statusOS.ValidHostname() {
|
// log.Println(SPEW, me)
|
||||||
var aaaa []string
|
if (aaaa == nil) {
|
||||||
h := me.statusOS.GetHostname()
|
log.Warn("There are no DNS AAAA records for hostname: ", h)
|
||||||
aaaa = digAAAA(h)
|
me.DnsAAAA.SetText("(none)")
|
||||||
log.Log(NOW, "digAAAA() for", h, "=", aaaa)
|
if (cloudflare.CFdialog.TypeNode != nil) {
|
||||||
|
cloudflare.CFdialog.TypeNode.SetText("AAAA new")
|
||||||
|
}
|
||||||
|
|
||||||
// log.Println(SPEW, me)
|
if (cloudflare.CFdialog.NameNode != nil) {
|
||||||
if (aaaa == nil) {
|
cloudflare.CFdialog.NameNode.SetText(me.hostname)
|
||||||
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")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cloudflare.CFdialog.NameNode != nil) {
|
d := deleteAAA()
|
||||||
cloudflare.CFdialog.NameNode.SetText(h)
|
if (d != "") {
|
||||||
|
if (cloudflare.CFdialog.ValueNode != nil) {
|
||||||
|
cloudflare.CFdialog.ValueNode.SetText(d)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
d := deleteAAA()
|
m := missingAAAA()
|
||||||
if (d != "") {
|
if (m != "") {
|
||||||
if (cloudflare.CFdialog.ValueNode != nil) {
|
if (cloudflare.CFdialog.ValueNode != nil) {
|
||||||
cloudflare.CFdialog.ValueNode.SetText(d)
|
cloudflare.CFdialog.ValueNode.SetText(m)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m := missingAAAA()
|
/*
|
||||||
if (m != "") {
|
rr := &cloudflare.RRT{
|
||||||
if (cloudflare.CFdialog.ValueNode != nil) {
|
Type: "AAAA",
|
||||||
cloudflare.CFdialog.ValueNode.SetText(m)
|
Name: me.hostname,
|
||||||
}
|
Ttl: "Auto",
|
||||||
/*
|
Proxied: false,
|
||||||
rr := &cloudflare.RRT{
|
Content: m,
|
||||||
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
|
status := displayDNS() // update the GUI based on dig results
|
||||||
|
@ -303,10 +341,32 @@ func updateDNS() {
|
||||||
|
|
||||||
// me.fix.Enable()
|
// me.fix.Enable()
|
||||||
|
|
||||||
|
user, _ := user.Current()
|
||||||
|
log.Println("os.Getuid =", user.Username, os.Getuid())
|
||||||
|
if (me.uid != nil) {
|
||||||
|
me.uid.SetText(user.Username + " (" + strconv.Itoa(os.Getuid()) + ")")
|
||||||
|
}
|
||||||
|
|
||||||
// lookup the NS records for your domain
|
// lookup the NS records for your domain
|
||||||
// if your host is test.wit.com, find the NS resource records for wit.com
|
// if your host is test.wit.com, find the NS resource records for wit.com
|
||||||
lookupNS(me.statusOS.GetDomainName())
|
lookupNS(me.domainname.S)
|
||||||
|
|
||||||
log.Println("updateDNS() END")
|
log.Println("updateDNS() END")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func suggestProcDebugging() {
|
||||||
|
if (me.fixProc != nil) {
|
||||||
|
// me.fixProc.Disable()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
me.fixProc = me.mainStatus.NewButton("Try debugging Slow DNS lookups", func () {
|
||||||
|
log.Warn("You're DNS lookups are very slow")
|
||||||
|
me.dbOn.Set(true)
|
||||||
|
me.dbProc.Set(true)
|
||||||
|
|
||||||
|
processName := getProcessNameByPort(53)
|
||||||
|
log.Info("Process with port 53:", processName)
|
||||||
|
})
|
||||||
|
// me.fixProc.Disable()
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
// figures out if your hostname is valid
|
||||||
|
// then checks if your DNS is setup correctly
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/shell"
|
||||||
|
"go.wit.com/gui/cloudflare"
|
||||||
|
|
||||||
|
"github.com/miekg/dns"
|
||||||
|
// will try to get this hosts FQDN
|
||||||
|
"github.com/Showmax/go-fqdn"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getHostname() {
|
||||||
|
var err error
|
||||||
|
var s string = "gui.Label == nil"
|
||||||
|
s, err = fqdn.FqdnHostname()
|
||||||
|
if (err != nil) {
|
||||||
|
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)
|
||||||
|
|
||||||
|
dn := run("domainname")
|
||||||
|
if (me.domainname.S != dn) {
|
||||||
|
log.Log(CHANGE, "domainname has changed from", me.domainname.S, "to", dn)
|
||||||
|
me.domainname.SetText(dn)
|
||||||
|
me.changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
hshort := run("hostname -s")
|
||||||
|
if (me.hostshort.S != hshort) {
|
||||||
|
log.Log(CHANGE, "hostname -s has changed from", me.hostshort.S, "to", hshort)
|
||||||
|
me.hostshort.SetText(hshort)
|
||||||
|
me.changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
me.changed = true
|
||||||
|
me.hostnameStatusOLD.SetText("BROKEN")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (me.hostnameStatusOLD.S != "VALID") {
|
||||||
|
log.Log(CHANGE, "me.hostname", me.hostname, "is valid")
|
||||||
|
me.hostnameStatusOLD.SetText("VALID")
|
||||||
|
me.changed = true
|
||||||
|
}
|
||||||
|
// enable the cloudflare button if the provider is cloudflare
|
||||||
|
if (me.cloudflareB == nil) {
|
||||||
|
log.Log(CHANGE, "me.cloudflare == nil; me.DnsAPI.S =", me.DnsAPI.S)
|
||||||
|
if (me.DnsAPI.S == "cloudflare") {
|
||||||
|
me.cloudflareB = me.mainStatus.NewButton("cloudflare wit.com", func () {
|
||||||
|
cloudflare.CreateRR(me.myGui, "wit.com", "3777302ac4a78cd7fa4f6d3f72086d06")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns true if the hostname is good
|
||||||
|
// check that all the OS settings are correct here
|
||||||
|
// On Linux, /etc/hosts, /etc/hostname
|
||||||
|
// and domainname and hostname
|
||||||
|
func goodHostname(h string) bool {
|
||||||
|
hostname := shell.Chomp(shell.Cat("/etc/hostname"))
|
||||||
|
log.Log(NOW, "hostname =", hostname)
|
||||||
|
|
||||||
|
hs := run("hostname -s")
|
||||||
|
dn := run("domainname")
|
||||||
|
log.Log(NOW, "hostname short =", hs, "domainname =", dn)
|
||||||
|
|
||||||
|
tmp := hs + "." + dn
|
||||||
|
if (hostname == tmp) {
|
||||||
|
log.Log(NOW, "hostname seems to be good", hostname)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
recordType := dns.TypeAAAA // dns.TypeTXT
|
||||||
|
|
||||||
|
// Cloudflare's DNS server
|
||||||
|
blah, _ = dnsUdpLookup("1.1.1.1:53", hostname, recordType)
|
||||||
|
log.Println("digAAAA() has BLAH =", blah)
|
||||||
|
|
||||||
|
if (len(blah) == 0) {
|
||||||
|
log.Println("digAAAA() RUNNING dnsAAAAlookupDoH(domain)")
|
||||||
|
ipv6Addresses, _ = dnsAAAAlookupDoH(hostname)
|
||||||
|
log.Println("digAAAA() has ipv6Addresses =", strings.Join(ipv6Addresses, " "))
|
||||||
|
for _, addr := range ipv6Addresses {
|
||||||
|
log.Println(addr)
|
||||||
|
}
|
||||||
|
return ipv6Addresses
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check digDoH vs blah, if so, then port 53 TCP and/or UDP is broken or blocked
|
||||||
|
log.Println("digAAAA() has BLAH =", blah)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
|
@ -16,14 +16,14 @@ import (
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/gui"
|
"go.wit.com/gui/gui"
|
||||||
"go.wit.com/gui/gadgets"
|
"go.wit.com/gui/gadgets"
|
||||||
|
"go.wit.com/gui/cloudflare"
|
||||||
)
|
)
|
||||||
|
|
||||||
type hostnameStatus struct {
|
type hostnameStatus struct {
|
||||||
ready bool
|
ready bool
|
||||||
hidden 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
|
window *gadgets.BasicWindow
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ type hostnameStatus struct {
|
||||||
currentIPv6 *gadgets.OneLiner
|
currentIPv6 *gadgets.OneLiner
|
||||||
|
|
||||||
// what the DNS servers have
|
// what the DNS servers have
|
||||||
NSrr *gadgets.OneLiner
|
|
||||||
dnsA *gadgets.OneLiner
|
dnsA *gadgets.OneLiner
|
||||||
dnsAAAA *gadgets.OneLiner
|
dnsAAAA *gadgets.OneLiner
|
||||||
dnsAPI *gadgets.OneLiner
|
dnsAPI *gadgets.OneLiner
|
||||||
|
@ -51,8 +50,8 @@ type hostnameStatus struct {
|
||||||
speedActual *gadgets.OneLiner
|
speedActual *gadgets.OneLiner
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
// dnsValue *gui.Node
|
dnsValue *gui.Node
|
||||||
// dnsAction *gui.Node
|
dnsAction *gui.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHostnameStatusWindow(p *gui.Node) *hostnameStatus {
|
func NewHostnameStatusWindow(p *gui.Node) *hostnameStatus {
|
||||||
|
@ -61,9 +60,9 @@ func NewHostnameStatusWindow(p *gui.Node) *hostnameStatus {
|
||||||
|
|
||||||
hs.ready = false
|
hs.ready = false
|
||||||
hs.hidden = true
|
hs.hidden = true
|
||||||
// hs.hostname = me.hostname
|
hs.hostname = me.hostname
|
||||||
|
|
||||||
hs.window = gadgets.NewBasicWindow(p, "fix hostname here" + " Status")
|
hs.window = gadgets.NewBasicWindow(p, hs.hostname + " Status")
|
||||||
hs.window.Draw()
|
hs.window.Draw()
|
||||||
hs.window.Hide()
|
hs.window.Hide()
|
||||||
|
|
||||||
|
@ -85,7 +84,6 @@ func NewHostnameStatusWindow(p *gui.Node) *hostnameStatus {
|
||||||
hs.currentIPv4 = gadgets.NewOneLiner(grid, "Current IPv4")
|
hs.currentIPv4 = gadgets.NewOneLiner(grid, "Current IPv4")
|
||||||
hs.currentIPv6 = gadgets.NewOneLiner(grid, "Current IPv6")
|
hs.currentIPv6 = gadgets.NewOneLiner(grid, "Current IPv6")
|
||||||
|
|
||||||
hs.NSrr = gadgets.NewOneLiner(grid, "dns NS records").Set("unknown")
|
|
||||||
hs.dnsAPI = gadgets.NewOneLiner(grid, "dns API provider").Set("unknown")
|
hs.dnsAPI = gadgets.NewOneLiner(grid, "dns API provider").Set("unknown")
|
||||||
hs.dnsA = gadgets.NewOneLiner(grid, "dns IPv4 resource records").Set("unknown")
|
hs.dnsA = gadgets.NewOneLiner(grid, "dns IPv4 resource records").Set("unknown")
|
||||||
hs.dnsAAAA = gadgets.NewOneLiner(grid, "dns IPv6 resource records").Set("unknown")
|
hs.dnsAAAA = gadgets.NewOneLiner(grid, "dns IPv6 resource records").Set("unknown")
|
||||||
|
@ -96,7 +94,6 @@ func NewHostnameStatusWindow(p *gui.Node) *hostnameStatus {
|
||||||
group.Pad()
|
group.Pad()
|
||||||
grid.Pad()
|
grid.Pad()
|
||||||
|
|
||||||
/*
|
|
||||||
group = hs.window.Box().NewGroup("Actions")
|
group = hs.window.Box().NewGroup("Actions")
|
||||||
grid = group.NewGrid("LookupDetails", 2, 2)
|
grid = group.NewGrid("LookupDetails", 2, 2)
|
||||||
|
|
||||||
|
@ -110,7 +107,6 @@ func NewHostnameStatusWindow(p *gui.Node) *hostnameStatus {
|
||||||
hs.createDNSrecord(hs.dnsValue.S)
|
hs.createDNSrecord(hs.dnsValue.S)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
*/
|
|
||||||
|
|
||||||
group.Pad()
|
group.Pad()
|
||||||
grid.Pad()
|
grid.Pad()
|
||||||
|
@ -120,12 +116,6 @@ func NewHostnameStatusWindow(p *gui.Node) *hostnameStatus {
|
||||||
return hs
|
return hs
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func (hs *hostnameStatus) ValidHostname() bool {
|
|
||||||
return goodHostname()
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func (hs *hostnameStatus) Domain() string {
|
func (hs *hostnameStatus) Domain() string {
|
||||||
if ! hs.Ready() {return ""}
|
if ! hs.Ready() {return ""}
|
||||||
return hs.domainname.Get()
|
return hs.domainname.Get()
|
||||||
|
@ -136,33 +126,31 @@ func (hs *hostnameStatus) API() string {
|
||||||
return hs.dnsAPI.Get()
|
return hs.dnsAPI.Get()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func (hs *hostnameStatus) deleteDNSrecord(value string) bool {
|
func (hs *hostnameStatus) deleteDNSrecord(value string) bool {
|
||||||
log.Info("deleteDNSrecord() START for", value)
|
log.Info("deleteDNSrecord() START for", value)
|
||||||
log.Info("deleteDNSrecord() hostname =", me.status.GetHostname())
|
log.Info("deleteDNSrecord() hostname =", me.hostname)
|
||||||
log.Info("deleteDNSrecord() domain =", hs.Domain())
|
log.Info("deleteDNSrecord() domain =", hs.Domain())
|
||||||
log.Info("deleteDNSrecord() DNS API Provider =", hs.API())
|
log.Info("deleteDNSrecord() DNS API Provider =", hs.API())
|
||||||
|
|
||||||
if (hs.API() == "cloudflare") {
|
if (hs.API() == "cloudflare") {
|
||||||
log.Info("deleteDNSrecord() Try to delete via cloudflare")
|
log.Info("deleteDNSrecord() Try to delete via cloudflare")
|
||||||
return cloudflare.Delete(hs.Domain(), me.status.GetHostname(), value)
|
return cloudflare.Delete(hs.Domain(), me.hostname, value)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hs *hostnameStatus) createDNSrecord(value string) bool {
|
func (hs *hostnameStatus) createDNSrecord(value string) bool {
|
||||||
log.Info("createDNSrecord() START for", value)
|
log.Info("createDNSrecord() START for", value)
|
||||||
log.Info("createDNSrecord() hostname =", me.status.GetHostname())
|
log.Info("createDNSrecord() hostname =", me.hostname)
|
||||||
log.Info("createDNSrecord() domain =", hs.Domain())
|
log.Info("createDNSrecord() domain =", hs.Domain())
|
||||||
log.Info("createDNSrecord() DNS API Provider =", hs.API())
|
log.Info("createDNSrecord() DNS API Provider =", hs.API())
|
||||||
|
|
||||||
if (hs.API() == "cloudflare") {
|
if (hs.API() == "cloudflare") {
|
||||||
log.Warn("createDNSrecord() Try to create via cloudflare:", me.status.GetHostname(), value)
|
log.Warn("createDNSrecord() Try to delete via cloudflare:", me.hostname, value)
|
||||||
return cloudflare.Create(hs.Domain(), me.status.GetHostname(), value)
|
return cloudflare.Create(hs.Domain(), me.hostname, value)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
func (hs *hostnameStatus) Update() {
|
func (hs *hostnameStatus) Update() {
|
||||||
log.Info("hostnameStatus() Update() START")
|
log.Info("hostnameStatus() Update() START")
|
||||||
|
@ -241,10 +229,10 @@ func (hs *hostnameStatus) set(a any, s string) {
|
||||||
if reflect.TypeOf(a) == reflect.TypeOf(ol) {
|
if reflect.TypeOf(a) == reflect.TypeOf(ol) {
|
||||||
ol = a.(*gadgets.OneLiner)
|
ol = a.(*gadgets.OneLiner)
|
||||||
if ol == nil {
|
if ol == nil {
|
||||||
// log.Println("ol = nil", reflect.TypeOf(a), "a =", a)
|
log.Println("ol = nil", reflect.TypeOf(a), "a =", a)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// log.Println("SETTING ol:", ol)
|
log.Println("SETTING ol:", ol)
|
||||||
ol.Set(s)
|
ol.Set(s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -252,88 +240,69 @@ func (hs *hostnameStatus) set(a any, s string) {
|
||||||
os.Exit(0)
|
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
|
// figure out if I'm missing any IPv6 address in DNS
|
||||||
func (hs *hostnameStatus) missingAAAA() bool {
|
func (hs *hostnameStatus) missingAAAA() bool {
|
||||||
var aaaa []string
|
var aaaa []string
|
||||||
aaaa = dhcpAAAA()
|
aaaa = dhcpAAAA()
|
||||||
for _, s := range aaaa {
|
for _, s := range aaaa {
|
||||||
log.Log(NET, "my actual AAAA = ",s)
|
log.Log(NET, "my actual AAAA = ",s)
|
||||||
if hs.existsAAAA(s) {
|
hs.dnsValue.SetText(s)
|
||||||
log.Log(NOW, "my actual AAAA already exists in DNS =",s)
|
hs.dnsAction.SetText("CREATE")
|
||||||
} else {
|
return true
|
||||||
log.Log(NOW, "my actual AAAA is missing from DNS",s)
|
|
||||||
hs.dnsValue.SetText(s)
|
|
||||||
hs.dnsAction.SetText("CREATE")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
func (hs *hostnameStatus) updateStatus() {
|
func (hs *hostnameStatus) updateStatus() {
|
||||||
if ! hs.Ready() { return }
|
|
||||||
var s string
|
var s string
|
||||||
var vals []string
|
var vals []string
|
||||||
log.Log(STATUS, "updateStatus() START")
|
log.Info("updateStatus() START")
|
||||||
|
if ! hs.Ready() { return }
|
||||||
|
|
||||||
hs.hostShort.Set(me.statusOS.GetHostShort())
|
hs.hostShort.Set(me.hostshort.S)
|
||||||
hs.domainname.Set(me.statusOS.GetDomainName())
|
hs.domainname.Set(me.domainname.S)
|
||||||
|
|
||||||
if me.statusOS.ValidHostname() {
|
vals = lookupDoH(hs.hostname, "AAAA")
|
||||||
vals = lookupDoH(me.statusOS.GetHostname(), "AAAA")
|
|
||||||
|
|
||||||
log.Log(STATUS, "DNS IPv6 Addresses for ", me.statusOS.GetHostname(), "=", vals)
|
log.Println("DNS IPv6 Addresses for ", hs.hostname, "=", vals)
|
||||||
if len(vals) == 0 {
|
if len(vals) == 0 {
|
||||||
s = "(none)"
|
s = "(none)"
|
||||||
} else {
|
hs.setIPv6("Check for real IPv6 addresses here")
|
||||||
hs.setIPv6("Check for real IPv6 addresses here")
|
if hs.missingAAAA() {
|
||||||
/*
|
hs.setIPv6("Add the missing IPv6 address")
|
||||||
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)
|
} else {
|
||||||
|
for _, addr := range vals {
|
||||||
vals = lookupDoH(me.statusOS.GetHostname(), "A")
|
log.Println(addr)
|
||||||
log.Log(STATUS, "IPv4 Addresses for ", me.statusOS.GetHostname(), "=", vals)
|
s += addr + " (DELETE)"
|
||||||
s = strings.Join(vals, "\n")
|
hs.setIPv6("NEEDS DELETE")
|
||||||
if (s == "") {
|
hs.dnsValue.SetText(addr)
|
||||||
s = "(none)"
|
hs.dnsAction.SetText("DELETE")
|
||||||
hs.setIPv4("NEEDS CNAME")
|
|
||||||
}
|
|
||||||
hs.set(hs.dnsA, s)
|
|
||||||
|
|
||||||
vals = lookupDoH(me.statusOS.GetHostname(), "CNAME")
|
|
||||||
s = strings.Join(vals, "\n")
|
|
||||||
if (s != "") {
|
|
||||||
hs.set(hs.dnsA, "CNAME " + s)
|
|
||||||
hs.setIPv4("GOOD")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hs.set(hs.dnsAAAA, s)
|
||||||
|
|
||||||
// hs.currentIPv4.Set(me.IPv4.S)
|
vals = lookupDoH(hs.hostname, "A")
|
||||||
// hs.currentIPv6.Set(me.IPv6.S)
|
log.Println("IPv4 Addresses for ", hs.hostname, "=", vals)
|
||||||
hs.currentIPv4.Set("get this from linuxStatus")
|
s = strings.Join(vals, "\n")
|
||||||
hs.currentIPv6.Set("get this from linuxStatus")
|
if (s == "") {
|
||||||
|
s = "(none)"
|
||||||
|
hs.setIPv4("NEEDS CNAME")
|
||||||
|
}
|
||||||
|
hs.set(hs.dnsA, s)
|
||||||
|
|
||||||
if hs.IPv4() && hs.IPv6() {
|
vals = lookupDoH(hs.hostname, "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() {
|
||||||
hs.status.Set("GOOD")
|
hs.status.Set("GOOD")
|
||||||
} else {
|
} else {
|
||||||
hs.status.Set("BROKEN")
|
hs.status.Set("BROKEN")
|
||||||
|
@ -343,7 +312,7 @@ func (hs *hostnameStatus) updateStatus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hs *hostnameStatus) Show() {
|
func (hs *hostnameStatus) Show() {
|
||||||
log.Log(STATUS, "hostnameStatus.Show() window")
|
log.Info("hostnameStatus.Show() window")
|
||||||
if hs.hidden {
|
if hs.hidden {
|
||||||
hs.window.Show()
|
hs.window.Show()
|
||||||
}
|
}
|
||||||
|
@ -351,7 +320,7 @@ func (hs *hostnameStatus) Show() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hs *hostnameStatus) Hide() {
|
func (hs *hostnameStatus) Hide() {
|
||||||
log.Log(STATUS, "hostnameStatus.Hide() window")
|
log.Info("hostnameStatus.Hide() window")
|
||||||
if ! hs.hidden {
|
if ! hs.hidden {
|
||||||
hs.window.Hide()
|
hs.window.Hide()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
/*
|
|
||||||
this enables command line options from other packages like 'gui' and 'log'
|
|
||||||
*/
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
var NOW log.LogFlag
|
|
||||||
var INFO log.LogFlag
|
|
||||||
var NET log.LogFlag
|
|
||||||
var DNS log.LogFlag
|
|
||||||
var PROC log.LogFlag
|
|
||||||
var SPEW log.LogFlag
|
|
||||||
var WARN log.LogFlag
|
|
||||||
var CHANGE log.LogFlag
|
|
||||||
var STATUS log.LogFlag
|
|
||||||
|
|
||||||
func myreg(f *log.LogFlag, b bool, name string, desc string) {
|
|
||||||
f.B = b
|
|
||||||
f.Subsystem = "go.wit.com/control-panels/dns/linuxstatus"
|
|
||||||
f.Short = "linux"
|
|
||||||
f.Desc = desc
|
|
||||||
f.Name = name
|
|
||||||
f.Register()
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
myreg(&NOW, true, "NOW", "temp debugging stuff")
|
|
||||||
myreg(&NET, false, "NET", "Network Logging")
|
|
||||||
myreg(&DNS, false, "DNS", "dnsStatus.update()")
|
|
||||||
myreg(&PROC, false, "PROC", "/proc logging")
|
|
||||||
myreg(&SPEW, false, "SPEW", "spew stuff")
|
|
||||||
myreg(&WARN, true, "WARN", "bad things")
|
|
||||||
myreg(&CHANGE, true, "CHANGE", "show droplet state changes")
|
|
||||||
myreg(&STATUS, false, "STATUS", "Update() details")
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
// This creates a simple hello world window
|
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui/gui"
|
|
||||||
)
|
|
||||||
|
|
||||||
// reports externally if something has changed
|
|
||||||
// since the last time it was asked about it
|
|
||||||
func (ls *LinuxStatus) Changed() bool {
|
|
||||||
if ! ls.Ready() {return false}
|
|
||||||
if ls.changed {
|
|
||||||
ls.changed = false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) Make() {
|
|
||||||
if ! ls.Ready() {return}
|
|
||||||
log.Log(CHANGE, "Make() window ready =", ls.ready)
|
|
||||||
ls.window.Make()
|
|
||||||
ls.ready = true
|
|
||||||
}
|
|
||||||
func (ls *LinuxStatus) Draw() {
|
|
||||||
if ! ls.Ready() {return}
|
|
||||||
log.Log(CHANGE, "Draw() window ready =", ls.ready)
|
|
||||||
ls.window.Draw()
|
|
||||||
ls.ready = true
|
|
||||||
}
|
|
||||||
func (ls *LinuxStatus) Draw2() {
|
|
||||||
if ! ls.Ready() {return}
|
|
||||||
log.Log(CHANGE, "draw(ls) ready =", ls.ready)
|
|
||||||
draw(ls)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) Show() {
|
|
||||||
if ! ls.Ready() {return}
|
|
||||||
log.Log(CHANGE, "Show() window ready =", ls.ready)
|
|
||||||
ls.window.Show()
|
|
||||||
ls.hidden = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) Hide() {
|
|
||||||
if ! ls.Ready() {return}
|
|
||||||
log.Log(CHANGE, "Hide() window ready =", ls.ready)
|
|
||||||
ls.window.Hide()
|
|
||||||
ls.hidden = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) Toggle() {
|
|
||||||
if ! ls.Ready() {return}
|
|
||||||
log.Log(CHANGE, "Toggle() window ready =", ls.ready)
|
|
||||||
if ls.hidden {
|
|
||||||
ls.Show()
|
|
||||||
} else {
|
|
||||||
ls.Hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) Ready() bool {
|
|
||||||
log.Log(SPEW, "Ready() maybe not ready? ls =", ls)
|
|
||||||
if me == nil {return false}
|
|
||||||
if ls == nil {return false}
|
|
||||||
if ls.window == nil {return false}
|
|
||||||
return me.ready
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) Initialized() bool {
|
|
||||||
log.Log(CHANGE, "checking Initialized()")
|
|
||||||
if me == nil {return false}
|
|
||||||
if ls == nil {return false}
|
|
||||||
if ls.parent == nil {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) SetParent(p *gui.Node) {
|
|
||||||
log.Log(CHANGE, "Attempting SetParent")
|
|
||||||
if me == nil {return}
|
|
||||||
if ls == nil {return}
|
|
||||||
if ls.parent == nil {
|
|
||||||
log.Log(CHANGE, "SetParent =", p)
|
|
||||||
ls.parent = p
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
log.Log(CHANGE, "SetParent was already set to =", ls.parent)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
// This creates a simple hello world window
|
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/gui/gadgets"
|
|
||||||
)
|
|
||||||
|
|
||||||
// creates the actual widgets.
|
|
||||||
// it's assumed you are always passing in a box
|
|
||||||
func draw(ls *LinuxStatus) {
|
|
||||||
if ! ls.Ready() {return}
|
|
||||||
ls.group = ls.window.Box().NewGroup("What Linux Knows It Is")
|
|
||||||
|
|
||||||
ls.grid = ls.group.NewGrid("gridnuts", 2, 2)
|
|
||||||
|
|
||||||
ls.grid.SetNext(1,1)
|
|
||||||
|
|
||||||
ls.hostnameStatus = gadgets.NewOneLiner(ls.grid, "status")
|
|
||||||
ls.hostname = gadgets.NewOneLiner(ls.grid, "hostname -f")
|
|
||||||
ls.hostshort = gadgets.NewOneLiner(ls.grid, "hostname -s")
|
|
||||||
ls.domainname = gadgets.NewOneLiner(ls.grid, "domain name")
|
|
||||||
ls.resolver = gadgets.NewOneLiner(ls.grid, "nameservers =")
|
|
||||||
ls.resolver.Set("TODO")
|
|
||||||
ls.uid = gadgets.NewOneLiner(ls.grid, "UID =")
|
|
||||||
ls.IPv4 = gadgets.NewOneLiner(ls.grid, "Current IPv4 =")
|
|
||||||
ls.IPv6 = gadgets.NewOneLiner(ls.grid, "Current IPv6 =")
|
|
||||||
ls.workingIPv6 = gadgets.NewOneLiner(ls.grid, "Real IPv6 =")
|
|
||||||
// ls.nics = gadgets.NewOneLiner(ls.grid, "network intefaces =")
|
|
||||||
|
|
||||||
ls.grid.NewLabel("interfaces =")
|
|
||||||
ls.Interfaces = ls.grid.NewCombobox("Interfaces")
|
|
||||||
|
|
||||||
ls.speed = gadgets.NewOneLiner(ls.grid, "refresh speed =")
|
|
||||||
ls.speedActual = gadgets.NewOneLiner(ls.grid, "refresh speed =")
|
|
||||||
|
|
||||||
ls.grid.Margin()
|
|
||||||
ls.grid.Pad()
|
|
||||||
}
|
|
|
@ -1,134 +0,0 @@
|
||||||
// figures out if your hostname is valid
|
|
||||||
// then checks if your DNS is setup correctly
|
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/shell"
|
|
||||||
|
|
||||||
// will try to get this hosts FQDN
|
|
||||||
"github.com/Showmax/go-fqdn"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) GetDomainName() string {
|
|
||||||
if ! me.Ready() {return ""}
|
|
||||||
return me.domainname.Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) setDomainName() {
|
|
||||||
if ! me.Ready() {return}
|
|
||||||
|
|
||||||
dn := run("domainname")
|
|
||||||
if (me.domainname.Get() != dn) {
|
|
||||||
log.Log(CHANGE, "domainname has changed from", me.GetDomainName(), "to", dn)
|
|
||||||
me.domainname.Set(dn)
|
|
||||||
me.changed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) GetHostname() string {
|
|
||||||
if ! me.Ready() {return ""}
|
|
||||||
return me.hostname.Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) ValidHostname() bool {
|
|
||||||
if ! me.Ready() {return false}
|
|
||||||
if me.hostnameStatus.Get() == "VALID" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) setHostname(newname string) {
|
|
||||||
if ! me.Ready() {return}
|
|
||||||
if newname == me.hostname.Get() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Log(CHANGE, "hostname has changed from", me.GetHostname(), "to", newname)
|
|
||||||
me.hostname.Set(newname)
|
|
||||||
me.changed = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) GetHostShort() string {
|
|
||||||
if ! me.Ready() {return ""}
|
|
||||||
return me.hostshort.Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) setHostShort() {
|
|
||||||
if ! me.Ready() {return}
|
|
||||||
hshort := run("hostname -s")
|
|
||||||
if (me.hostshort.Get() != hshort) {
|
|
||||||
log.Log(CHANGE, "hostname -s has changed from", me.hostshort.Get(), "to", hshort)
|
|
||||||
me.hostshort.Set(hshort)
|
|
||||||
me.changed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupHostname() {
|
|
||||||
if ! me.Ready() {return}
|
|
||||||
var err error
|
|
||||||
var hostfqdn string = "broken"
|
|
||||||
hostfqdn, err = fqdn.FqdnHostname()
|
|
||||||
if (err != nil) {
|
|
||||||
log.Error(err, "FQDN hostname error")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Log(NET, "full hostname should be: ", hostfqdn)
|
|
||||||
|
|
||||||
me.setDomainName()
|
|
||||||
me.setHostShort()
|
|
||||||
|
|
||||||
// these are authoritative
|
|
||||||
// if they work wrong, your linux configuration is wrong.
|
|
||||||
// Do not complain.
|
|
||||||
// Fix your distro if your box is otherwise not working this way
|
|
||||||
hshort := me.GetHostShort() // from `hostname -s`
|
|
||||||
dn := me.GetDomainName() // from `domanname`
|
|
||||||
hostname := me.GetHostname() // from `hostname -f`
|
|
||||||
|
|
||||||
if hostfqdn != hostname {
|
|
||||||
log.Log(WARN, "hostname", hostname, "does not equal fqdn.FqdnHostname()", hostfqdn)
|
|
||||||
// TODO: figure out what is wrong
|
|
||||||
}
|
|
||||||
|
|
||||||
var test string
|
|
||||||
test = hshort + "." + dn
|
|
||||||
|
|
||||||
me.setHostname(test)
|
|
||||||
|
|
||||||
if (hostname != test) {
|
|
||||||
log.Log(CHANGE, "hostname", hostname, "does not equal", test)
|
|
||||||
if (me.hostnameStatus.Get() != "BROKEN") {
|
|
||||||
log.Log(CHANGE, "hostname", hostname, "does not equal", test)
|
|
||||||
me.changed = true
|
|
||||||
me.hostnameStatus.Set("BROKEN")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (me.hostnameStatus.Get() != "VALID") {
|
|
||||||
log.Log(CHANGE, "hostname", hostname, "is valid")
|
|
||||||
me.hostnameStatus.Set("VALID")
|
|
||||||
me.changed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns true if the hostname is good
|
|
||||||
// check that all the OS settings are correct here
|
|
||||||
// On Linux, /etc/hosts, /etc/hostname
|
|
||||||
// and domainname and hostname
|
|
||||||
func goodHostname() bool {
|
|
||||||
hostname := shell.Chomp(shell.Cat("/etc/hostname"))
|
|
||||||
log.Log(NOW, "hostname =", hostname)
|
|
||||||
|
|
||||||
hs := run("hostname -s")
|
|
||||||
dn := run("domainname")
|
|
||||||
log.Log(NOW, "hostname short =", hs, "domainname =", dn)
|
|
||||||
|
|
||||||
tmp := hs + "." + dn
|
|
||||||
if (hostname == tmp) {
|
|
||||||
log.Log(NOW, "hostname seems to be good", hostname)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
// GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
|
|
||||||
// Copyright (c) 2023 WIT.COM, Inc.
|
|
||||||
// This is a control panel for DNS
|
|
||||||
|
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"os/user"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func linuxLoop() {
|
|
||||||
me.changed = false
|
|
||||||
duration := timeFunction(lookupHostname)
|
|
||||||
log.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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// get all the real AAAA records from all the network interfaces linux can see
|
|
||||||
tmp := strings.Join(realAAAA(), "\n")
|
|
||||||
tmp = sortLines(tmp)
|
|
||||||
me.workingIPv6.Set(tmp)
|
|
||||||
|
|
||||||
user, _ := user.Current()
|
|
||||||
log.Log(INFO, "os.Getuid =", user.Username, os.Getuid())
|
|
||||||
if (me.uid != nil) {
|
|
||||||
me.uid.Set(user.Username + " (" + strconv.Itoa(os.Getuid()) + ")")
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
}
|
|
|
@ -1,271 +0,0 @@
|
||||||
// This creates a simple hello world window
|
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
import (
|
|
||||||
// "log"
|
|
||||||
"net"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func IsIPv6(address string) bool {
|
|
||||||
return strings.Count(address, ":") >= 2
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *IPtype) IsReal() bool {
|
|
||||||
if (t.ip.IsPrivate() || t.ip.IsLoopback() || t.ip.IsLinkLocalUnicast()) {
|
|
||||||
log.Log(NET, "\t\tIP is Real = false")
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
log.Log(NET, "\t\tIP is Real = true")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsReal(ip *net.IP) bool {
|
|
||||||
if (ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast()) {
|
|
||||||
log.Log(NET, "\t\tIP is Real = false")
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
log.Log(NET, "\t\tIP is Real = true")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func renameInterface(i *net.Interface) {
|
|
||||||
/*
|
|
||||||
/sbin/ip link set eth1 down
|
|
||||||
/sbin/ip link set eth1 name eth123
|
|
||||||
/sbin/ip link set eth123 up
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// Will figure out if an interface was just added
|
|
||||||
func checkInterface(i net.Interface) {
|
|
||||||
val, ok := me.ifmap[i.Index]
|
|
||||||
if ! ok {
|
|
||||||
log.Log(INFO, i.Name, "is a new network interface. The linux kernel index =", i.Index)
|
|
||||||
me.ifmap[i.Index] = new(IFtype)
|
|
||||||
me.ifmap[i.Index].gone = false
|
|
||||||
me.ifmap[i.Index].iface = &i
|
|
||||||
me.changed = true
|
|
||||||
if (me.Interfaces != nil) {
|
|
||||||
me.Interfaces.AddText(i.Name)
|
|
||||||
me.Interfaces.SetText(i.Name)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
me.ifmap[i.Index].gone = false
|
|
||||||
log.Log(NET, "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) {
|
|
||||||
log.Log(INFO, val.iface.Name, "has changed to it's name to", i.Name)
|
|
||||||
me.ifmap[i.Index].iface = &i
|
|
||||||
me.changed = true
|
|
||||||
if (me.Interfaces != nil) {
|
|
||||||
me.Interfaces.AddText(i.Name)
|
|
||||||
me.Interfaces.SetText(i.Name)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
These are the real IP address you have been
|
|
||||||
given from DHCP
|
|
||||||
*/
|
|
||||||
func realAAAA() []string {
|
|
||||||
var aaaa []string
|
|
||||||
|
|
||||||
for s, t := range me.ipmap {
|
|
||||||
if (t.IsReal()) {
|
|
||||||
if (t.ipv6) {
|
|
||||||
aaaa = append(aaaa, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return aaaa
|
|
||||||
}
|
|
||||||
|
|
||||||
func realA() []string {
|
|
||||||
var a []string
|
|
||||||
|
|
||||||
for s, t := range me.ipmap {
|
|
||||||
if (t.IsReal()) {
|
|
||||||
if (t.ipv4) {
|
|
||||||
a = append(a, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkDNS() (map[string]*IPtype, map[string]*IPtype) {
|
|
||||||
var ipv4s map[string]*IPtype
|
|
||||||
var ipv6s map[string]*IPtype
|
|
||||||
|
|
||||||
ipv4s = make(map[string]*IPtype)
|
|
||||||
ipv6s = make(map[string]*IPtype)
|
|
||||||
|
|
||||||
for s, t := range me.ipmap {
|
|
||||||
i := t.iface
|
|
||||||
ipt := "IPv4"
|
|
||||||
if (t.ipv6) {
|
|
||||||
ipt = "IPv6"
|
|
||||||
}
|
|
||||||
if (t.IsReal()) {
|
|
||||||
log.Log(INFO, "\tIP is Real ", ipt, i.Index, i.Name, s)
|
|
||||||
if (t.ipv6) {
|
|
||||||
ipv6s[s] = t
|
|
||||||
} else {
|
|
||||||
ipv4s[s] = t
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Log(INFO, "\tIP is not Real", ipt, i.Index, i.Name, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ipv6s, ipv4s
|
|
||||||
}
|
|
||||||
|
|
||||||
// Will figure out if an IP address is new
|
|
||||||
func checkIP(ip *net.IPNet, i net.Interface) bool {
|
|
||||||
log.Log(NET, "\t\taddr.(type) = *net.IPNet")
|
|
||||||
log.Log(NET, "\t\taddr.(type) =", ip)
|
|
||||||
var realip string
|
|
||||||
realip = ip.IP.String()
|
|
||||||
|
|
||||||
val, ok := me.ipmap[realip]
|
|
||||||
if ok {
|
|
||||||
log.Log(NET, val.ipnet.IP.String(), "is already a defined IP address")
|
|
||||||
me.ipmap[realip].gone = false
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
me.ipmap[realip] = new(IPtype)
|
|
||||||
me.ipmap[realip].gone = false
|
|
||||||
me.ipmap[realip].ipv4 = true
|
|
||||||
me.ipmap[realip].ipnet = ip
|
|
||||||
me.ipmap[realip].ip = ip.IP
|
|
||||||
me.ipmap[realip].iface = &i
|
|
||||||
t := "IPv4"
|
|
||||||
if (IsIPv6(ip.String())) {
|
|
||||||
me.ipmap[realip].ipv6 = true
|
|
||||||
me.ipmap[realip].ipv4 = false
|
|
||||||
t = "IPv6"
|
|
||||||
if (me.IPv6 != nil) {
|
|
||||||
me.IPv6.Set(realip)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
me.ipmap[realip].ipv6 = false
|
|
||||||
me.ipmap[realip].ipv4 = true
|
|
||||||
if (me.IPv4 != nil) {
|
|
||||||
me.IPv4.Set(realip)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (IsReal(&ip.IP)) {
|
|
||||||
log.Log(INFO, "\tIP is Real ", t, i.Index, i.Name, realip)
|
|
||||||
} else {
|
|
||||||
log.Log(INFO, "\tIP is not Real", t, i.Index, i.Name, realip)
|
|
||||||
}
|
|
||||||
log.Log(NET, "\t\tIP is IsPrivate() =", ip.IP.IsPrivate())
|
|
||||||
log.Log(NET, "\t\tIP is IsLoopback() =", ip.IP.IsLoopback())
|
|
||||||
log.Log(NET, "\t\tIP is IsLinkLocalUnicast() =", ip.IP.IsLinkLocalUnicast())
|
|
||||||
// log.Log(INFO, "HERE HERE", "realip =", realip, "me.ip[realip]=", me.ipmap[realip])
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func scanInterfaces() {
|
|
||||||
log.Log(NET, "scanInterfaces() START")
|
|
||||||
ifaces, _ := net.Interfaces()
|
|
||||||
// me.ifnew = ifaces
|
|
||||||
log.Log(NET, SPEW, ifaces)
|
|
||||||
for _, i := range ifaces {
|
|
||||||
addrs, _ := i.Addrs()
|
|
||||||
// log.Log(INFO, "range ifaces = ", i)
|
|
||||||
checkInterface(i)
|
|
||||||
log.Log(NET, "*net.Interface.Name = ", i.Name, i.Index)
|
|
||||||
log.Log(NET, SPEW, i)
|
|
||||||
log.Log(NET, SPEW, addrs)
|
|
||||||
for _, addr := range addrs {
|
|
||||||
log.Log(NET, "\taddr =", addr)
|
|
||||||
log.Log(NET, SPEW, addrs)
|
|
||||||
ips, _ := net.LookupIP(addr.String())
|
|
||||||
log.Log(NET, "\tLookupIP(addr) =", ips)
|
|
||||||
switch v := addr.(type) {
|
|
||||||
case *net.IPNet:
|
|
||||||
if checkIP(v, i) {
|
|
||||||
log.Log(true, "scanInterfaces() IP is new () i =", v.IP.String())
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
log.Log(NET, "\t\taddr.(type) = NO IDEA WHAT TO DO HERE v =", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if deleteChanges() {
|
|
||||||
me.changed = true
|
|
||||||
log.Log(NET, "deleteChanges() detected network changes")
|
|
||||||
}
|
|
||||||
updateRealAAAA()
|
|
||||||
log.Log(NET, "scanInterfaces() END")
|
|
||||||
}
|
|
||||||
|
|
||||||
// displays the IP address found on your network interfaces
|
|
||||||
func updateRealAAAA() {
|
|
||||||
var all4 []string
|
|
||||||
var all6 []string
|
|
||||||
for s, t := range me.ipmap {
|
|
||||||
if (t.ipv4) {
|
|
||||||
all4 = append(all4, s)
|
|
||||||
log.Log(NET, "IPv4 =", s)
|
|
||||||
} else if (t.ipv6) {
|
|
||||||
all6 = append(all6, s)
|
|
||||||
log.Log(NET, "IPv6 =", s)
|
|
||||||
} else {
|
|
||||||
log.Log(NET, "???? =", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort and create text
|
|
||||||
sort.Strings(all4)
|
|
||||||
sort.Strings(all6)
|
|
||||||
s4 := strings.Join(all4, "\n")
|
|
||||||
s6 := strings.Join(all6, "\n")
|
|
||||||
|
|
||||||
if (me.IPv4.Get() != s4) {
|
|
||||||
log.Log(CHANGE, "IPv4 addresses have changed", s4)
|
|
||||||
me.IPv4.Set(s4)
|
|
||||||
me.changed = true
|
|
||||||
}
|
|
||||||
if (me.IPv6.Get() != s6) {
|
|
||||||
log.Log(CHANGE, "IPv6 addresses have changed", s6)
|
|
||||||
me.IPv6.Set(s6)
|
|
||||||
me.changed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete network interfaces and ip addresses from the gui
|
|
||||||
func deleteChanges() bool {
|
|
||||||
var changed bool = false
|
|
||||||
for i, t := range me.ifmap {
|
|
||||||
if (t.gone) {
|
|
||||||
log.Log(CHANGE, "DELETE int =", i, "name =", t.name, t.iface)
|
|
||||||
delete(me.ifmap, i)
|
|
||||||
changed = true
|
|
||||||
}
|
|
||||||
t.gone = true
|
|
||||||
}
|
|
||||||
for s, t := range me.ipmap {
|
|
||||||
if (t.gone) {
|
|
||||||
log.Log(CHANGE, "DELETE name =", s, "IPv4 =", t.ipv4)
|
|
||||||
log.Log(CHANGE, "DELETE name =", s, "IPv6 =", t.ipv6)
|
|
||||||
log.Log(CHANGE, "DELETE name =", s, "iface =", t.iface)
|
|
||||||
log.Log(CHANGE, "DELETE name =", s, "ip =", t.ip)
|
|
||||||
delete(me.ipmap, s)
|
|
||||||
changed = true
|
|
||||||
}
|
|
||||||
t.gone = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
// This creates a simple hello world window
|
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
|
|
||||||
"go.wit.com/gui/gadgets"
|
|
||||||
)
|
|
||||||
|
|
||||||
func New() *LinuxStatus {
|
|
||||||
if me != nil {
|
|
||||||
log.Log(WARN, "You have done New() twice. You can only do this once")
|
|
||||||
return me
|
|
||||||
}
|
|
||||||
me = &LinuxStatus {
|
|
||||||
hidden: true,
|
|
||||||
ready: false,
|
|
||||||
}
|
|
||||||
me.ifmap = make(map[int]*IFtype)
|
|
||||||
me.ipmap = make(map[string]*IPtype)
|
|
||||||
|
|
||||||
return me
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) InitWindow() {
|
|
||||||
if ! ls.Initialized() {
|
|
||||||
log.Log(WARN, "not initalized yet (no parent for the window?)")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ls.window != nil {
|
|
||||||
log.Log(WARN, "You already have a window")
|
|
||||||
ls.ready = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Log(WARN, "Creating the Window")
|
|
||||||
ls.window = gadgets.NewBasicWindow(ls.parent, "Linux OS Details")
|
|
||||||
ls.ready = true
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
figures out if your hostname is valid
|
|
||||||
then checks if your DNS is setup correctly
|
|
||||||
*/
|
|
||||||
|
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"go.wit.com/gui/gui"
|
|
||||||
"go.wit.com/gui/gadgets"
|
|
||||||
)
|
|
||||||
|
|
||||||
var me *LinuxStatus
|
|
||||||
|
|
||||||
type LinuxStatus struct {
|
|
||||||
ready bool
|
|
||||||
hidden bool
|
|
||||||
changed bool
|
|
||||||
|
|
||||||
parent *gui.Node
|
|
||||||
|
|
||||||
ifmap map[int]*IFtype // the current interfaces
|
|
||||||
ipmap map[string]*IPtype // the current ip addresses
|
|
||||||
|
|
||||||
window *gadgets.BasicWindow
|
|
||||||
group *gui.Node
|
|
||||||
grid *gui.Node
|
|
||||||
|
|
||||||
hostnameStatus *gadgets.OneLiner
|
|
||||||
hostname *gadgets.OneLiner
|
|
||||||
hostshort *gadgets.OneLiner
|
|
||||||
domainname *gadgets.OneLiner
|
|
||||||
resolver *gadgets.OneLiner
|
|
||||||
uid *gadgets.OneLiner
|
|
||||||
IPv4 *gadgets.OneLiner
|
|
||||||
IPv6 *gadgets.OneLiner
|
|
||||||
workingIPv6 *gadgets.OneLiner
|
|
||||||
Interfaces *gui.Node
|
|
||||||
speed *gadgets.OneLiner
|
|
||||||
speedActual *gadgets.OneLiner
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type IPtype struct {
|
|
||||||
gone bool // used to track if the ip exists
|
|
||||||
ipv6 bool // the future
|
|
||||||
ipv4 bool // the past
|
|
||||||
LinkLocal bool
|
|
||||||
iface *net.Interface
|
|
||||||
ip net.IP
|
|
||||||
ipnet *net.IPNet
|
|
||||||
}
|
|
||||||
|
|
||||||
type IFtype struct {
|
|
||||||
gone bool // used to track if the interface exists
|
|
||||||
name string // just a shortcut to the name. maybe this is dumb
|
|
||||||
// up bool // could be used to track ifup/ifdown
|
|
||||||
iface *net.Interface
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) SetSpeedActual(s string) {
|
|
||||||
if ! ls.Ready() {return}
|
|
||||||
ls.speedActual.Set(s)
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
// Various Linux/Unix'y things
|
|
||||||
|
|
||||||
// https://wiki.archlinux.org/title/Dynamic_DNS
|
|
||||||
|
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"net"
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/shell"
|
|
||||||
)
|
|
||||||
|
|
||||||
func CheckSuperuser() bool {
|
|
||||||
return os.Getuid() == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func Escalate() {
|
|
||||||
if os.Getuid() != 0 {
|
|
||||||
cmd := exec.Command("sudo", "./control-panel-dns") // TODO: get the actual path
|
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err, "exit in Escalate()")
|
|
||||||
log.Exit(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// You need permission to do a zone transfer. Otherwise:
|
|
||||||
// dig +noall +answer +multiline lab.wit.com any
|
|
||||||
// dig +all +multiline fire.lab.wit.com # gives the zonefile header (ttl vals)
|
|
||||||
func DumpPublicDNSZone(zone string) {
|
|
||||||
entries, err := net.LookupHost(zone)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
for _, entry := range entries {
|
|
||||||
log.Println(entry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dumpIPs(host string) {
|
|
||||||
ips, err := net.LookupIP(host)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err, "dumpIPs() failed")
|
|
||||||
}
|
|
||||||
for _, ip := range ips {
|
|
||||||
log.Println(host, ip)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
check if ddclient is installed, working, and/or configured
|
|
||||||
https://github.com/ddclient/ddclient
|
|
||||||
*/
|
|
||||||
func ddclient() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
check if ddupdate is installed, working, and/or configured
|
|
||||||
*/
|
|
||||||
func ddupdate() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func run(s string) string {
|
|
||||||
cmdArgs := strings.Fields(s)
|
|
||||||
// Define the command you want to run
|
|
||||||
// cmd := exec.Command(cmdArgs)
|
|
||||||
cmd := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...)
|
|
||||||
|
|
||||||
// Create a buffer to capture the output
|
|
||||||
var out bytes.Buffer
|
|
||||||
|
|
||||||
// Set the output of the command to the buffer
|
|
||||||
cmd.Stdout = &out
|
|
||||||
|
|
||||||
// Run the command
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error running command:", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp := shell.Chomp(out.String())
|
|
||||||
// Output the results
|
|
||||||
log.Info("Command Output:", tmp)
|
|
||||||
|
|
||||||
return tmp
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package linuxstatus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) Update() {
|
|
||||||
if ! ls.Ready() {
|
|
||||||
log.Log(WARN, "can't update yet. ready is false")
|
|
||||||
log.Error(errors.New("Update() is not ready yet"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Log(INFO, "Update() START")
|
|
||||||
duration := timeFunction(func () {
|
|
||||||
linuxLoop()
|
|
||||||
})
|
|
||||||
ls.SetSpeed(duration)
|
|
||||||
log.Log(INFO, "Update() END")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LinuxStatus) SetSpeed(duration time.Duration) {
|
|
||||||
s := fmt.Sprint(duration)
|
|
||||||
if ls.speedActual == nil {
|
|
||||||
log.Log(WARN, "can't actually warn")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ls.speedActual.Set(s)
|
|
||||||
|
|
||||||
if (duration > 500 * time.Millisecond ) {
|
|
||||||
ls.speed.Set("SLOW")
|
|
||||||
} else if (duration > 100 * time.Millisecond ) {
|
|
||||||
ls.speed.Set("OK")
|
|
||||||
} else {
|
|
||||||
ls.speed.Set("FAST")
|
|
||||||
}
|
|
||||||
}
|
|
58
main.go
58
main.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
"embed"
|
"embed"
|
||||||
|
@ -16,8 +17,6 @@ import (
|
||||||
"go.wit.com/gui/gui"
|
"go.wit.com/gui/gui"
|
||||||
"go.wit.com/gui/debugger"
|
"go.wit.com/gui/debugger"
|
||||||
|
|
||||||
"go.wit.com/control-panels/dns/linuxstatus"
|
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,11 +44,6 @@ func main() {
|
||||||
log.Sleep(me.artificialSleep)
|
log.Sleep(me.artificialSleep)
|
||||||
setupControlPanelWindow()
|
setupControlPanelWindow()
|
||||||
|
|
||||||
me.digStatus = NewDigStatusWindow(me.myGui)
|
|
||||||
me.status = NewHostnameStatusWindow(me.myGui)
|
|
||||||
|
|
||||||
linuxstatus.New()
|
|
||||||
|
|
||||||
if debugger.ArgDebug() {
|
if debugger.ArgDebug() {
|
||||||
log.Sleep(2)
|
log.Sleep(2)
|
||||||
debugger.DebugWindow(me.myGui)
|
debugger.DebugWindow(me.myGui)
|
||||||
|
@ -100,7 +94,7 @@ func checkNetworkChanges() {
|
||||||
if (runtime.GOOS == "linux") {
|
if (runtime.GOOS == "linux") {
|
||||||
duration := timeFunction(linuxLoop)
|
duration := timeFunction(linuxLoop)
|
||||||
s := fmt.Sprint(duration)
|
s := fmt.Sprint(duration)
|
||||||
me.statusOS.SetSpeedActual(s)
|
me.LocalSpeedActual.SetText(s)
|
||||||
} else {
|
} else {
|
||||||
// TODO: make windows and macos diagnostics
|
// TODO: make windows and macos diagnostics
|
||||||
log.Warn("Windows and MacOS don't work yet")
|
log.Warn("Windows and MacOS don't work yet")
|
||||||
|
@ -127,15 +121,24 @@ func DNSloop() {
|
||||||
log.Info("dnsTTL() execution Time: ", duration)
|
log.Info("dnsTTL() execution Time: ", duration)
|
||||||
var s, newSpeed string
|
var s, newSpeed string
|
||||||
if (duration > 5000 * time.Millisecond ) {
|
if (duration > 5000 * time.Millisecond ) {
|
||||||
newSpeed = "VERY SLOW"
|
newSpeed = "VERY BAD"
|
||||||
|
suggestProcDebugging()
|
||||||
} else if (duration > 2000 * time.Millisecond ) {
|
} else if (duration > 2000 * time.Millisecond ) {
|
||||||
newSpeed = "SLOWER"
|
newSpeed = "BAD"
|
||||||
|
suggestProcDebugging()
|
||||||
} else if (duration > 500 * time.Millisecond ) {
|
} else if (duration > 500 * time.Millisecond ) {
|
||||||
|
suggestProcDebugging()
|
||||||
newSpeed = "SLOW"
|
newSpeed = "SLOW"
|
||||||
} else if (duration > 100 * time.Millisecond ) {
|
} else if (duration > 100 * time.Millisecond ) {
|
||||||
newSpeed = "OK"
|
newSpeed = "OK"
|
||||||
|
if (me.fixProc != nil) {
|
||||||
|
// me.fixProc.Disable()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
newSpeed = "FAST"
|
newSpeed = "FAST"
|
||||||
|
if (me.fixProc != nil) {
|
||||||
|
// me.fixProc.Disable()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (newSpeed != me.DnsSpeedLast) {
|
if (newSpeed != me.DnsSpeedLast) {
|
||||||
log.Log(CHANGE, "dns lookup speed changed =", newSpeed)
|
log.Log(CHANGE, "dns lookup speed changed =", newSpeed)
|
||||||
|
@ -153,16 +156,45 @@ func dnsTTL() {
|
||||||
updateDNS()
|
updateDNS()
|
||||||
}
|
}
|
||||||
|
|
||||||
// run update on the LinuxStatus() window
|
|
||||||
func linuxLoop() {
|
func linuxLoop() {
|
||||||
me.statusOS.Update()
|
me.changed = false
|
||||||
|
log.Log(NET, "FQDN =", me.fqdn.GetText())
|
||||||
|
duration := timeFunction(getHostname)
|
||||||
|
log.Info("getHostname() execution Time: ", duration, "me.changed =", me.changed)
|
||||||
|
|
||||||
if (me.statusOS.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")
|
stamp := time.Now().Format("2006/01/02 15:04:05")
|
||||||
log.Log(CHANGE, "Network things changed on", stamp)
|
log.Log(CHANGE, "Network things changed on", stamp)
|
||||||
duration := timeFunction(updateDNS)
|
duration := timeFunction(updateDNS)
|
||||||
log.Log(CHANGE, "updateDNS() execution Time: ", duration)
|
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
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
201
net.go
201
net.go
|
@ -9,6 +9,35 @@ import (
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// this doesn't work
|
||||||
|
/*
|
||||||
|
func watchNetworkInterfaces() {
|
||||||
|
// Get list of network interfaces
|
||||||
|
interfaces, _ := net.Interfaces()
|
||||||
|
|
||||||
|
// Set up a notification channel
|
||||||
|
notification := make(chan net.Interface)
|
||||||
|
|
||||||
|
log.Log(NET, "watchNet()")
|
||||||
|
// Start goroutine to watch for changes
|
||||||
|
go func() {
|
||||||
|
log.Log(NET, "watchNet() func")
|
||||||
|
for {
|
||||||
|
log.Log(NET, "forever loop start")
|
||||||
|
// Check for changes in each interface
|
||||||
|
for _, i := range interfaces {
|
||||||
|
log.Log(NET, "something on i =", i)
|
||||||
|
if status := i.Flags & net.FlagUp; status != 0 {
|
||||||
|
notification <- i
|
||||||
|
log.Log(NET, "something on i =", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Log(NET, "forever loop end")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func IsIPv6(address string) bool {
|
func IsIPv6(address string) bool {
|
||||||
return strings.Count(address, ":") >= 2
|
return strings.Count(address, ":") >= 2
|
||||||
}
|
}
|
||||||
|
@ -33,6 +62,43 @@ func IsReal(ip *net.IP) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func renameInterface(i *net.Interface) {
|
||||||
|
/*
|
||||||
|
/sbin/ip link set eth1 down
|
||||||
|
/sbin/ip link set eth1 name eth123
|
||||||
|
/sbin/ip link set eth123 up
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will figure out if an interface was just added
|
||||||
|
func checkInterface(i net.Interface) {
|
||||||
|
val, ok := me.ifmap[i.Index]
|
||||||
|
if ! ok {
|
||||||
|
log.Info(i.Name, "is a new network interface. The linux kernel index =", i.Index)
|
||||||
|
me.ifmap[i.Index] = new(IFtype)
|
||||||
|
me.ifmap[i.Index].gone = false
|
||||||
|
me.ifmap[i.Index].iface = &i
|
||||||
|
me.changed = true
|
||||||
|
if (me.Interfaces != nil) {
|
||||||
|
me.Interfaces.AddText(i.Name)
|
||||||
|
me.Interfaces.SetText(i.Name)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
me.ifmap[i.Index].gone = false
|
||||||
|
log.Log(NET, "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) {
|
||||||
|
log.Info(val.iface.Name, "has changed to it's name to", i.Name)
|
||||||
|
me.ifmap[i.Index].iface = &i
|
||||||
|
me.changed = true
|
||||||
|
if (me.Interfaces != nil) {
|
||||||
|
me.Interfaces.AddText(i.Name)
|
||||||
|
me.Interfaces.SetText(i.Name)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These are the real IP address you have been
|
These are the real IP address you have been
|
||||||
given from DHCP
|
given from DHCP
|
||||||
|
@ -89,3 +155,138 @@ func checkDNS() (map[string]*IPtype, map[string]*IPtype) {
|
||||||
}
|
}
|
||||||
return ipv6s, ipv4s
|
return ipv6s, ipv4s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Will figure out if an IP address is new
|
||||||
|
func checkIP(ip *net.IPNet, i net.Interface) bool {
|
||||||
|
log.Log(NET, "\t\taddr.(type) = *net.IPNet")
|
||||||
|
log.Log(NET, "\t\taddr.(type) =", ip)
|
||||||
|
var realip string
|
||||||
|
realip = ip.IP.String()
|
||||||
|
|
||||||
|
val, ok := me.ipmap[realip]
|
||||||
|
if ok {
|
||||||
|
log.Log(NET, val.ipnet.IP.String(), "is already a defined IP address")
|
||||||
|
me.ipmap[realip].gone = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
me.ipmap[realip] = new(IPtype)
|
||||||
|
me.ipmap[realip].gone = false
|
||||||
|
me.ipmap[realip].ipv4 = true
|
||||||
|
me.ipmap[realip].ipnet = ip
|
||||||
|
me.ipmap[realip].ip = ip.IP
|
||||||
|
me.ipmap[realip].iface = &i
|
||||||
|
t := "IPv4"
|
||||||
|
if (IsIPv6(ip.String())) {
|
||||||
|
me.ipmap[realip].ipv6 = true
|
||||||
|
me.ipmap[realip].ipv4 = false
|
||||||
|
t = "IPv6"
|
||||||
|
if (me.IPv6 != nil) {
|
||||||
|
me.IPv6.SetText(realip)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
me.ipmap[realip].ipv6 = false
|
||||||
|
me.ipmap[realip].ipv4 = true
|
||||||
|
if (me.IPv4 != nil) {
|
||||||
|
me.IPv4.SetText(realip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (IsReal(&ip.IP)) {
|
||||||
|
log.Info("\tIP is Real ", t, i.Index, i.Name, realip)
|
||||||
|
} else {
|
||||||
|
log.Info("\tIP is not Real", t, i.Index, i.Name, realip)
|
||||||
|
}
|
||||||
|
log.Log(NET, "\t\tIP is IsPrivate() =", ip.IP.IsPrivate())
|
||||||
|
log.Log(NET, "\t\tIP is IsLoopback() =", ip.IP.IsLoopback())
|
||||||
|
log.Log(NET, "\t\tIP is IsLinkLocalUnicast() =", ip.IP.IsLinkLocalUnicast())
|
||||||
|
// log.Info("HERE HERE", "realip =", realip, "me.ip[realip]=", me.ipmap[realip])
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func scanInterfaces() {
|
||||||
|
log.Log(NET, "scanInterfaces() START")
|
||||||
|
ifaces, _ := net.Interfaces()
|
||||||
|
// me.ifnew = ifaces
|
||||||
|
log.Log(NET, SPEW, ifaces)
|
||||||
|
for _, i := range ifaces {
|
||||||
|
addrs, _ := i.Addrs()
|
||||||
|
// log.Info("range ifaces = ", i)
|
||||||
|
checkInterface(i)
|
||||||
|
log.Log(NET, "*net.Interface.Name = ", i.Name, i.Index)
|
||||||
|
log.Log(NET, SPEW, i)
|
||||||
|
log.Log(NET, SPEW, addrs)
|
||||||
|
for _, addr := range addrs {
|
||||||
|
log.Log(NET, "\taddr =", addr)
|
||||||
|
log.Log(NET, SPEW, addrs)
|
||||||
|
ips, _ := net.LookupIP(addr.String())
|
||||||
|
log.Log(NET, "\tLookupIP(addr) =", ips)
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
if checkIP(v, i) {
|
||||||
|
log.Log(true, "scanInterfaces() IP is new () i =", v.IP.String())
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
log.Log(NET, "\t\taddr.(type) = NO IDEA WHAT TO DO HERE v =", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if deleteChanges() {
|
||||||
|
me.changed = true
|
||||||
|
log.Log(NET, "deleteChanges() detected network changes")
|
||||||
|
}
|
||||||
|
updateRealAAAA()
|
||||||
|
log.Log(NET, "scanInterfaces() END")
|
||||||
|
}
|
||||||
|
|
||||||
|
// displays the IP address found on your network interfaces
|
||||||
|
func updateRealAAAA() {
|
||||||
|
var all4 string
|
||||||
|
var all6 string
|
||||||
|
for s, t := range me.ipmap {
|
||||||
|
if (t.ipv4) {
|
||||||
|
all4 += s + "\n"
|
||||||
|
log.Log(NET, "IPv4 =", s)
|
||||||
|
} else if (t.ipv6) {
|
||||||
|
all6 += s + "\n"
|
||||||
|
log.Log(NET, "IPv6 =", s)
|
||||||
|
} else {
|
||||||
|
log.Log(NET, "???? =", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
all4 = sortLines(all4)
|
||||||
|
all6 = sortLines(all6)
|
||||||
|
if (me.IPv4.S != all4) {
|
||||||
|
log.Log(NET, "IPv4 addresses have changed", all4)
|
||||||
|
me.IPv4.SetText(all4)
|
||||||
|
}
|
||||||
|
if (me.IPv6.S != all6) {
|
||||||
|
log.Log(NET, "IPv6 addresses have changed", all6)
|
||||||
|
me.IPv6.SetText(all6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete network interfaces and ip addresses from the gui
|
||||||
|
func deleteChanges() bool {
|
||||||
|
var changed bool = false
|
||||||
|
for i, t := range me.ifmap {
|
||||||
|
if (t.gone) {
|
||||||
|
log.Log(CHANGE, "DELETE int =", i, "name =", t.name, t.iface)
|
||||||
|
delete(me.ifmap, i)
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
t.gone = true
|
||||||
|
}
|
||||||
|
for s, t := range me.ipmap {
|
||||||
|
if (t.gone) {
|
||||||
|
log.Log(CHANGE, "DELETE name =", s, "IPv4 =", t.ipv4)
|
||||||
|
log.Log(CHANGE, "DELETE name =", s, "IPv6 =", t.ipv6)
|
||||||
|
log.Log(CHANGE, "DELETE name =", s, "iface =", t.iface)
|
||||||
|
log.Log(CHANGE, "DELETE name =", s, "ip =", t.ip)
|
||||||
|
delete(me.ipmap, s)
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
t.gone = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func nsupdate() {
|
||||||
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.statusOS.GetHostname()
|
cmd += " -i wlo1 " + me.hostname
|
||||||
log.Log(NET, "nsupdate() RUN:", cmd)
|
log.Log(NET, "nsupdate() RUN:", cmd)
|
||||||
|
|
||||||
for s, t := range me.ipmap {
|
for s, t := range me.ipmap {
|
||||||
|
|
209
resolverBox.go
209
resolverBox.go
|
@ -1,209 +0,0 @@
|
||||||
/*
|
|
||||||
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
|
|
||||||
}
|
|
43
structs.go
43
structs.go
|
@ -6,8 +6,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"go.wit.com/gui/gui"
|
"go.wit.com/gui/gui"
|
||||||
"go.wit.com/gui/gadgets"
|
"go.wit.com/gui/gadgets"
|
||||||
"go.wit.com/control-panels/dns/linuxstatus"
|
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,12 +13,14 @@ import (
|
||||||
var me Host
|
var me Host
|
||||||
|
|
||||||
type Host struct {
|
type Host struct {
|
||||||
status *hostnameStatus // keeps track of the hostname and it's status
|
hostname string // mirrors
|
||||||
statusOS *linuxstatus.LinuxStatus // what the Linux OS sees
|
domainname *gui.Node // kernel.org
|
||||||
|
hostshort *gui.Node // hostname -s
|
||||||
hostnameStatus *gui.Node // a summary for the user of where things are
|
hostnameStatusOLD *gui.Node // is the hostname configured correctly in the OS?
|
||||||
hostname *gadgets.OneLiner // the hostname grabbed from gadget.linuxStatus
|
// fqdn string // mirrors.kernel.org
|
||||||
|
|
||||||
|
// dnsTTL int `default:"3"` // Recheck DNS is working every TTL (in seconds)
|
||||||
|
// dnsTTLsleep float64 // sleep between loops
|
||||||
artificialSleep float64 `default:"0.7"` // artificial sleep on startup
|
artificialSleep float64 `default:"0.7"` // artificial sleep on startup
|
||||||
artificialS string `default:"abc"` // artificial sleep on startup
|
artificialS string `default:"abc"` // artificial sleep on startup
|
||||||
|
|
||||||
|
@ -42,35 +42,48 @@ type Host struct {
|
||||||
ipv6s map[string]dns.RR
|
ipv6s map[string]dns.RR
|
||||||
|
|
||||||
window *gadgets.BasicWindow // the main window
|
window *gadgets.BasicWindow // the main window
|
||||||
|
details *gadgets.BasicWindow // more details of the DNS state
|
||||||
debug *gadgets.BasicWindow // more attempts to debug the DNS state
|
debug *gadgets.BasicWindow // more attempts to debug the DNS state
|
||||||
|
|
||||||
tab *gui.Node // the main dns tab
|
tab *gui.Node // the main dns tab
|
||||||
notes *gui.Node // using this to put notes here
|
notes *gui.Node // using this to put notes here
|
||||||
|
|
||||||
// local OS settings, network interfaces, etc
|
// local OS settings, network interfaces, etc
|
||||||
// fqdn *gui.Node // display the full hostname
|
uid *gui.Node // user
|
||||||
// Interfaces *gui.Node // Interfaces
|
fqdn *gui.Node // display the full hostname
|
||||||
// LocalSpeedActual *gui.Node // the time it takes to check each network interface
|
IPv4 *gui.Node // show valid IPv4 addresses
|
||||||
|
IPv6 *gui.Node // show valid IPv6 addresses
|
||||||
|
Interfaces *gui.Node // Interfaces
|
||||||
|
LocalSpeedActual *gui.Node // the time it takes to check each network interface
|
||||||
|
|
||||||
// DNS stuff
|
// DNS stuff
|
||||||
|
NSrr *gui.Node // NS resource records for the domain name
|
||||||
DnsAPI *gui.Node // what DNS API to use?
|
DnsAPI *gui.Node // what DNS API to use?
|
||||||
DnsAAAA *gadgets.OneLiner // the actual DNS AAAA results
|
DnsAAAA *gui.Node // 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?)
|
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 // 'FAST', 'OK', 'SLOW', etc
|
DnsSpeed *gui.Node // 'FAST', 'OK', 'SLOW', etc
|
||||||
DnsSpeedActual *gui.Node // the last actual duration
|
DnsSpeedActual *gui.Node // the last actual duration
|
||||||
DnsSpeedLast string // the last state 'FAST', 'OK', etc
|
DnsSpeedLast string // the last state 'FAST', 'OK', etc
|
||||||
|
|
||||||
// fix *gui.Node // button for the user to click
|
fix *gui.Node // button for the user to click
|
||||||
// fixProc *gui.Node // button for the user to click
|
fixProc *gui.Node // button for the user to click
|
||||||
|
|
||||||
// mainStatus *gui.Node // group for the main display of stuff
|
mainStatus *gui.Node // group for the main display of stuff
|
||||||
// cloudflareB *gui.Node // cloudflare button
|
cloudflareB *gui.Node // cloudflare button
|
||||||
|
|
||||||
|
dbOn *gui.Node // button for setting debugging on
|
||||||
|
dbNet *gui.Node // button for setting network debugging on
|
||||||
|
dbProc *gui.Node // button for setting proc debugging on
|
||||||
|
|
||||||
digStatus *digStatus
|
digStatus *digStatus
|
||||||
statusIPv6 *gadgets.OneLiner
|
statusIPv6 *gadgets.OneLiner
|
||||||
digStatusButton *gui.Node
|
digStatusButton *gui.Node
|
||||||
|
|
||||||
|
hostnameStatus *hostnameStatus
|
||||||
|
hostnameStatusButton *gui.Node
|
||||||
|
|
||||||
myDebug *gui.Node
|
myDebug *gui.Node
|
||||||
myGui *gui.Node
|
myGui *gui.Node
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue