summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--README.md1
-rw-r--r--cloudflare/api.go26
-rw-r--r--cloudflare/durationSlider.go2
-rw-r--r--cloudflare/http.go49
-rw-r--r--cloudflare/mainWindow.go3
-rw-r--r--cloudflare/oneLiner.go42
-rw-r--r--cloudflare/rr.go (renamed from cloudflare/cloudflare.go)83
-rw-r--r--cloudflare/structs.go2
-rw-r--r--dns-https.go62
-rw-r--r--dnsLookupStatus.go370
-rw-r--r--examples/control-panel-cloudflare/Makefile (renamed from examples/cloudflare/Makefile)8
-rw-r--r--examples/control-panel-cloudflare/argv.go (renamed from examples/cloudflare/argv.go)0
-rw-r--r--examples/control-panel-cloudflare/config.go (renamed from examples/cloudflare/config.go)0
-rw-r--r--examples/control-panel-cloudflare/main.go (renamed from examples/cloudflare/main.go)16
-rw-r--r--go.mod39
-rw-r--r--go.sum88
-rw-r--r--gui.go114
-rw-r--r--hostname.go57
-rw-r--r--main.go27
-rw-r--r--net.go6
-rw-r--r--structs.go4
22 files changed, 853 insertions, 148 deletions
diff --git a/.gitignore b/.gitignore
index 148dce4..cd8a456 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,4 @@ control-panel-dns
*.swp
/plugins/*
-examples/cloudflare/cloudflare
+examples/control-panel-cloudflare/control-panel-cloudflare
diff --git a/README.md b/README.md
index e98c2b1..74f747f 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@ to update the DNS server.
Useful links and other
external things which might be useful
+* [DNS Resource Record Types](https://en.wikipedia.org/wiki/List_of_DNS_record_types)
* [WIT GO projects](http://go.wit.com/)
* [GOLANG GUI](https://go.wit.com/gui)
* [GO Style Guide](https://google.github.io/styleguide/go/index)
diff --git a/cloudflare/api.go b/cloudflare/api.go
index 1769f6b..036adc7 100644
--- a/cloudflare/api.go
+++ b/cloudflare/api.go
@@ -10,11 +10,20 @@ import (
"github.com/davecgh/go-spew/spew"
)
+/*
+ This function should run each time
+ the user chanegs anything in the GUi
+ or each time something in general changes
+
+ It returns a RR record which then can be
+ turned into JSON and sent via http
+ to cloudflare's API
+*/
func DoChange() *RRT {
var dnsRow *RRT
dnsRow = new(RRT)
- log.Println("Look for changes in row", dnsRow.ID)
+ log.Println("DoChange() START")
if (CFdialog.proxyNode.S == "On") {
dnsRow.Proxied = true
} else {
@@ -88,21 +97,6 @@ func SetRow(dnsRow *RRT) {
log.Println("http PUT curl =", pretty)
CFdialog.curlNode.SetText(pretty)
}
-
- return
- log.Println("UPDATE VALUE", CFdialog.NameNode.Name, CFdialog.TypeNode.Name, "to", CFdialog.ValueNode.S)
- stuff, result := httpPut(dnsRow)
- if (CFdialog.curlNode != nil) {
- pretty, _ := FormatJSON(stuff)
- log.Println("http PUT curl =", pretty)
- CFdialog.curlNode.SetText(pretty)
- }
- if (CFdialog.resultNode != nil) {
- pretty, _ := FormatJSON(result)
- log.Println("http PUT result =", pretty)
- CFdialog.resultNode.SetText(pretty)
- }
- // CFdialog.saveNode.Disable()
}
func GetZonefile(c *ConfigT) *DNSRecords {
diff --git a/cloudflare/durationSlider.go b/cloudflare/durationSlider.go
index 0d9559b..1ab0e50 100644
--- a/cloudflare/durationSlider.go
+++ b/cloudflare/durationSlider.go
@@ -9,6 +9,8 @@ import (
"go.wit.com/gui"
)
+// TODO: use: https://github.com/robfig/cron/
+
// ttl := cloudflare.DurationSlider(g2, "control panel TTL (in tenths of seconds)", 10 * time.Millisecond, 5 * time.Second)
// ttl.Set(200 * time.Millisecond)
diff --git a/cloudflare/http.go b/cloudflare/http.go
index f258f61..1917c8b 100644
--- a/cloudflare/http.go
+++ b/cloudflare/http.go
@@ -3,7 +3,6 @@ package cloudflare
import (
"log"
- "fmt"
"io/ioutil"
"net/http"
"bytes"
@@ -27,45 +26,43 @@ curl --request POST \
}'
*/
-func httpPut(dnsRow *RRT) (string, string) {
- var url string = cloudflareURL + dnsRow.ZoneID + "/dns_records/" + dnsRow.ID
- var authKey string = dnsRow.Auth
- var email string = dnsRow.Email
-
- var tmp string
- tmp = makeJSON(dnsRow)
- data := []byte(tmp)
+func doCurl(method string, rr *RRT) string {
+ var err error
+ var req *http.Request
- log.Println("http PUT url =", url)
- // log.Println("http PUT data =", data)
- // spew.Dump(data)
- pretty, _ := FormatJSON(string(data))
- log.Println("http PUT data =", pretty)
+ data := []byte(rr.data)
- req, err := http.NewRequest(http.MethodPut, url, bytes.NewBuffer(data))
+ if (method == "PUT") {
+ req, err = http.NewRequest(http.MethodPut, rr.url, bytes.NewBuffer(data))
+ } else {
+ req, err = http.NewRequest(http.MethodPost, rr.url, bytes.NewBuffer(data))
+ }
// Set headers
req.Header.Set("Content-Type", "application/json")
- req.Header.Set("X-Auth-Key", authKey)
- req.Header.Set("X-Auth-Email", email)
+ req.Header.Set("X-Auth-Key", rr.Auth)
+ req.Header.Set("X-Auth-Email", rr.Email)
+
+ log.Println("http PUT url =", rr.url)
+ log.Println("http PUT Auth =", rr.Auth)
+ log.Println("http PUT Email =", rr.Email)
+ log.Println("http PUT data =", rr.data)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Println(err)
- return tmp, fmt.Sprintf("blah err =", err)
+ return ""
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println(err)
- return tmp, fmt.Sprintf("blah err =", err)
+ return ""
}
- // log.Println("http PUT body =", body)
- // spew.Dump(body)
- return tmp, string(body)
+ return string(body)
}
func curlPost(dnsRow *RRT) string {
@@ -75,10 +72,10 @@ func curlPost(dnsRow *RRT) string {
url := dnsRow.url
tmp := dnsRow.data
- log.Println("curl() START")
- log.Println("curl() authkey = ", authKey)
- log.Println("curl() email = ", email)
- log.Println("curl() url = ", url)
+ log.Println("curlPost() START")
+ log.Println("curlPost() authkey = ", authKey)
+ log.Println("curlPost() email = ", email)
+ log.Println("curlPost() url = ", url)
data := []byte(tmp)
req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data))
diff --git a/cloudflare/mainWindow.go b/cloudflare/mainWindow.go
index dddb0b7..af5b221 100644
--- a/cloudflare/mainWindow.go
+++ b/cloudflare/mainWindow.go
@@ -9,7 +9,7 @@ import (
)
// This creates a window
-func MakeCloudflareWindow(n *gui.Node) {
+func MakeCloudflareWindow(n *gui.Node) *gui.Node {
CFdialog.rootGui = n
var t *gui.Node
@@ -54,6 +54,7 @@ func MakeCloudflareWindow(n *gui.Node) {
showCloudflareCredentials(more)
makeDebugWindow(CFdialog.mainWindow)
+ return CFdialog.mainWindow
}
func makeConfigWindow(n *gui.Node) {
diff --git a/cloudflare/oneLiner.go b/cloudflare/oneLiner.go
new file mode 100644
index 0000000..5fc7a51
--- /dev/null
+++ b/cloudflare/oneLiner.go
@@ -0,0 +1,42 @@
+// This is a simple example
+package cloudflare
+
+import (
+ "log"
+
+ "go.wit.com/gui"
+)
+
+type OneLiner struct {
+ p *gui.Node // parent widget
+ l *gui.Node // label widget
+ v *gui.Node // value widget
+
+ value string
+ label string
+
+ Custom func()
+}
+
+func (n *OneLiner) Set(value string) {
+ log.Println("OneLiner.Set() =", value)
+ n.v.Set(value)
+ n.value = value
+}
+
+func NewOneLiner(n *gui.Node, name string) *OneLiner {
+ d := OneLiner {
+ p: n,
+ value: "",
+ }
+
+ // various timeout settings
+ d.l = n.NewLabel(name)
+ d.v = n.NewLabel("")
+ d.v.Custom = func() {
+ d.value = d.v.S
+ log.Println("OneLiner.Custom() user changed value to =", d.value)
+ }
+
+ return &d
+}
diff --git a/cloudflare/cloudflare.go b/cloudflare/rr.go
index db98c92..05065b2 100644
--- a/cloudflare/cloudflare.go
+++ b/cloudflare/rr.go
@@ -1,4 +1,9 @@
-// This is a simple example
+/*
+ This will let you edit a single Resource Record within
+ a DNS zone file. For example:
+ google-dns.wit.com. 1 IN A 8.8.8.8
+*/
+
package cloudflare
import (
@@ -110,7 +115,7 @@ func CreateRR(myGui *gui.Node, zone string, zoneID string) {
CFdialog.resultNode = group.NewTextbox("result")
CFdialog.resultNode.SetText("API response will show here")
- CFdialog.saveNode = group.NewButton("Save", func () {
+ CFdialog.SaveNode = group.NewButton("Save curlPost()", func () {
dnsRow := DoChange()
result := curlPost(dnsRow)
CFdialog.resultNode.SetText(result)
@@ -120,63 +125,33 @@ func CreateRR(myGui *gui.Node, zone string, zoneID string) {
// CFdialog.resultNode.SetText(result)
})
// CFdialog.saveNode.Disable()
+ group.NewButton("New RR doCurl(PUT)", func () {
+ rr := DoChange()
- group.Pad()
- grid.Pad()
- grid.Expand()
-}
+ rr.url = "https://api.cloudflare.com/client/v4/zones/" + rr.ZoneID + "/dns_records"
-/*
-func CreateCurlRR() (string, string) {
- // enable the Save/Create Button
- if (CFdialog.saveNode != nil) {
- CFdialog.saveNode.Enable()
- }
+ result := doCurl("POST", rr)
+ CFdialog.resultNode.SetText(result)
- if (CFdialog.TypeNode != nil) {
- CFdialog.Type = CFdialog.TypeNode.S
- }
- if (CFdialog.NameNode != nil) {
- CFdialog.Name = CFdialog.NameNode.S
- }
- if (CFdialog.proxyNode != nil) {
- if (CFdialog.proxyNode.S == "On") {
- CFdialog.ProxyS = "true"
- } else {
- CFdialog.ProxyS = "false"
- }
- }
- if (CFdialog.ValueNode != nil) {
- CFdialog.Content = CFdialog.ValueNode.S
- }
- CFdialog.Ttl = "3600"
+ pretty, _ := FormatJSON(result)
+ log.Println(pretty)
+ })
- var url string = "https://api.cloudflare.com/client/v4/zones/" + CFdialog.ID + "/dns_records"
- // https://api.cloudflare.com/client/v4/zones/zone_identifier/dns_records \
- // var authKey string = os.Getenv("CF_API_KEY")
- // var email string = os.Getenv("CF_API_EMAIL")
+ group.NewButton("Update RR doCurl(PUT)", func () {
+ rr := DoChange()
- // make a json record to send on port 80 to cloudflare
- var tmp string
- tmp = `{"content": "` + CFdialog.Content + `", `
- tmp += `"name": "` + CFdialog.Name + `", `
- tmp += `"type": "` + CFdialog.Type + `", `
- tmp += `"ttl": ` + CFdialog.Ttl + `, `
- tmp += `"proxied": ` + CFdialog.ProxyS + `, `
- tmp += `"comment": "WIT DNS Control Panel"`
- tmp += `}`
- data := []byte(tmp)
+ rr.url = "https://api.cloudflare.com/client/v4/zones/" + rr.ZoneID + "/dns_records/" + rr.ID
+
+ result := doCurl("PUT", rr)
+ CFdialog.resultNode.SetText(result)
+
+ pretty, _ := FormatJSON(result)
+ log.Println(pretty)
+ })
+ // CFdialog.saveNode.Disable()
- log.Println("http PUT url =", url)
- // log.Println("http PUT data =", data)
- // spew.Dump(data)
- pretty, _ := FormatJSON(string(data))
- log.Println("http URL =", url)
- log.Println("http PUT data =", pretty)
- if (CFdialog.curlNode != nil) {
- CFdialog.curlNode.SetText("URL: " + url + "\n" + pretty)
- }
- return url, tmp
+ group.Pad()
+ grid.Pad()
+ grid.Expand()
}
-*/
diff --git a/cloudflare/structs.go b/cloudflare/structs.go
index f0a23d8..9efef62 100644
--- a/cloudflare/structs.go
+++ b/cloudflare/structs.go
@@ -50,7 +50,7 @@ type dialogT struct {
ttlNode *gui.Node // just set to 1 which means automatic to cloudflare
curlNode *gui.Node // shows you what you could run via curl
resultNode *gui.Node // what the cloudflare API returned
- saveNode *gui.Node // button to send it to cloudflare
+ SaveNode *gui.Node // button to send it to cloudflare
zoneNode *gui.Node // "wit.com"
zoneIdNode *gui.Node // cloudflare zone ID
diff --git a/dns-https.go b/dns-https.go
new file mode 100644
index 0000000..00eec82
--- /dev/null
+++ b/dns-https.go
@@ -0,0 +1,62 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+)
+
+// dnsLookupDoH performs a DNS lookup for AAAA records over HTTPS.
+func dnsLookupDoH(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)
+
+ // 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
+}
+
+/*
+func main() {
+ domain := "google.com"
+ ipv6Addresses, err := dnsLookupDoH(domain)
+ if err != nil {
+ fmt.Println("Error:", err)
+ return
+ }
+
+ fmt.Printf("IPv6 Addresses for %s:\n", domain)
+ for _, addr := range ipv6Addresses {
+ fmt.Println(addr)
+ }
+}
+*/
diff --git a/dnsLookupStatus.go b/dnsLookupStatus.go
new file mode 100644
index 0000000..e623cae
--- /dev/null
+++ b/dnsLookupStatus.go
@@ -0,0 +1,370 @@
+/*
+ '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 (
+ "log"
+ "fmt"
+ "time"
+ "strconv"
+
+ "github.com/miekg/dns"
+ "go.wit.com/gui"
+ "go.wit.com/control-panel-dns/cloudflare"
+ "go.wit.com/shell"
+)
+
+type digStatus struct {
+ ready bool
+ statusIPv4 string
+ statusIPv6 string
+
+ parent *gui.Node
+ window *gui.Node
+ group *gui.Node
+ grid *gui.Node
+ box *gui.Node
+
+ summary *gui.Node
+ status *cloudflare.OneLiner
+ statusAAAA *cloudflare.OneLiner
+ speed *cloudflare.OneLiner
+ speedActual *cloudflare.OneLiner
+
+ details *gui.Node
+ dsLocalhost *dnsStatus
+ dsLocalNetwork *dnsStatus
+ dsCloudflare *dnsStatus
+ dsGoogle *dnsStatus
+ DnsDigUDP *gui.Node
+ DnsDigTCP *gui.Node
+}
+
+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.window = p.NewWindow("DNS Lookup Status")
+ ds.box = ds.window.NewBox("hBox", true)
+
+ // summary of the current state of things
+ ds.summary = ds.box.NewGroup("Summary")
+
+ b := ds.summary.NewBox("hBox", true)
+ ds.status = cloudflare.NewOneLiner(b, "status")
+ ds.status.Set("unknown")
+
+ b = ds.summary.NewBox("hBox", true)
+ ds.statusAAAA = cloudflare.NewOneLiner(b, "IPv6 status")
+ ds.statusAAAA.Set("unknown")
+
+ b = ds.summary.NewBox("hBox", true)
+ ds.speed = cloudflare.NewOneLiner(b, "speed")
+ ds.speed.Set("unknown")
+
+ b = ds.summary.NewBox("hBox", true)
+ ds.speedActual = cloudflare.NewOneLiner(b, "actual")
+ ds.speedActual.Set("unknown")
+
+ // make the area to store the raw details
+ ds.details = ds.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()
+
+ return ds
+}
+
+func (ds *digStatus) Update() {
+ duration := timeFunction(func () { ds.updateDnsStatus() })
+ s := fmt.Sprint(duration)
+ ds.speedActual.Set(s)
+
+ if (duration > 500 * time.Millisecond ) {
+ ds.speed.Set("SLOW")
+ } else if (duration > 100 * time.Millisecond ) {
+ ds.speed.Set("OK")
+ } else {
+ ds.speed.Set("FAST")
+ }
+}
+
+// Returns true if the status is valid
+func (ds *digStatus) Ready() bool {
+ return ds.ready
+}
+
+// Returns true if IPv4 is working
+func (ds *digStatus) IPv4() bool {
+ 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.statusIPv6 == "GOOD") {
+ return true
+ }
+ return false
+}
+
+func (ds *digStatus) setIPv4(s string) {
+ ds.status.Set(s)
+ ds.statusIPv4 = s
+}
+
+func (ds *digStatus) setIPv6(s string) {
+ ds.statusAAAA.Set(s)
+ ds.statusIPv6 = s
+}
+
+func (ds *digStatus) updateDnsStatus() {
+ var cmd, out string
+ var ipv4, ipv6 bool
+
+ ipv4, ipv6 = ds.dsLocalhost.Update()
+ ipv4, ipv6 = ds.dsLocalNetwork.Update()
+ ipv4, ipv6 = ds.dsCloudflare.Update()
+ ipv4, ipv6 = ds.dsGoogle.Update()
+
+ 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)
+ ds.DnsDigUDP.SetText(out)
+
+ cmd = "dig +noall +answer www.wit.com AAAA"
+ out = shell.Run(cmd)
+ log.Println("makeDnsStatusGrid() dig", out)
+ ds.DnsDigTCP.SetText(out)
+
+ ds.ready = true
+}
+
+// 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) {
+ ds.udpA.SetText("BROKEN")
+ ds.aFailc += 1
+ } else {
+ ds.udpA.SetText("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) {
+ ds.tcpA.SetText("BROKEN")
+ ds.aFailc += 1
+ } else {
+ ds.tcpA.SetText("WORKING")
+ ds.aSuccessc += 1
+ a = true
+ }
+
+ ds.aFail.SetText(strconv.Itoa(ds.aFailc))
+ ds.aSuccess.SetText(strconv.Itoa(ds.aSuccessc))
+
+ results, _ = dnsUdpLookup(ds.server, ds.hostname, dns.TypeAAAA)
+ log.Println("dnsStatus.Update() UDP type AAAA =", results)
+
+ if (len(results) == 0) {
+ ds.udpAAAA.SetText("BROKEN")
+ ds.aaaaFailc += 1
+ ds.aaaaFail.SetText(strconv.Itoa(ds.aaaaFailc))
+ } else {
+ ds.udpAAAA.SetText("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) {
+ ds.tcpAAAA.SetText("BROKEN")
+ ds.aaaaFailc += 1
+ ds.aaaaFail.SetText(strconv.Itoa(ds.aaaaFailc))
+ } else {
+ ds.tcpAAAA.SetText("WORKING")
+ ds.aaaaSuccessc += 1
+ aaaa = true
+ }
+
+ ds.aaaaFail.SetText(strconv.Itoa(ds.aaaaFailc))
+ ds.aaaaSuccess.SetText(strconv.Itoa(ds.aaaaSuccessc))
+
+ return a, aaaa
+}
+
+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)
+ ds.DnsDigUDP.SetText(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)
+ ds.DnsDigTCP.SetText(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
+}
diff --git a/examples/cloudflare/Makefile b/examples/control-panel-cloudflare/Makefile
index 32f3f55..07d8f77 100644
--- a/examples/cloudflare/Makefile
+++ b/examples/control-panel-cloudflare/Makefile
@@ -1,10 +1,10 @@
run: build
- ./cloudflare
+ ./control-panel-cloudflare
build-release:
go get -v -u -x .
go build
- ./cloudflare
+ ./control-panel-cloudflare
build:
GO111MODULE="off" go get -v -x .
@@ -18,7 +18,7 @@ log:
tail -f /tmp/witgui.* /tmp/guilogfile
gocui: build
- ./cloudflare -gui gocui >/tmp/witgui.log.stderr 2>&1
+ ./control-panel-cloudflare -gui gocui >/tmp/witgui.log.stderr 2>&1
quiet:
- ./cloudflare >/tmp/witgui.log.stderr 2>&1
+ ./control-panel-cloudflare >/tmp/witgui.log.stderr 2>&1
diff --git a/examples/cloudflare/argv.go b/examples/control-panel-cloudflare/argv.go
index 49167cd..49167cd 100644
--- a/examples/cloudflare/argv.go
+++ b/examples/control-panel-cloudflare/argv.go
diff --git a/examples/cloudflare/config.go b/examples/control-panel-cloudflare/config.go
index a65ad25..a65ad25 100644
--- a/examples/cloudflare/config.go
+++ b/examples/control-panel-cloudflare/config.go
diff --git a/examples/cloudflare/main.go b/examples/control-panel-cloudflare/main.go
index 2308478..0661a93 100644
--- a/examples/cloudflare/main.go
+++ b/examples/control-panel-cloudflare/main.go
@@ -20,19 +20,6 @@ var myGui *gui.Node
// var cloudflareURL string = "https://api.cloudflare.com/client/v4/zones/"
-/*
-var zonedrop *gui.Node
-var domainWidget *gui.Node
-var masterSave *gui.Node
-
-var zoneWidget *gui.Node
-var authWidget *gui.Node
-var emailWidget *gui.Node
-
-var loadButton *gui.Node
-var saveButton *gui.Node
-*/
-
func main() {
// parse the config file
readConfig()
@@ -41,7 +28,8 @@ func main() {
myGui = gui.New().Default()
// draw the cloudflare control panel window
- cloudflare.MakeCloudflareWindow(myGui)
+ win := cloudflare.MakeCloudflareWindow(myGui)
+ win.SetText(title)
// This is just a optional goroutine to watch that things are alive
gui.Watchdog()
diff --git a/go.mod b/go.mod
index f21c131..cde5d25 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,42 @@
module go.wit.com/control-panel-dns
go 1.21.4
+
+require (
+ github.com/Showmax/go-fqdn v1.0.0
+ github.com/alexflint/go-arg v1.4.3
+ github.com/creack/pty v1.1.21
+ github.com/davecgh/go-spew v1.1.1
+ github.com/fsnotify/fsnotify v1.7.0
+ github.com/golang/protobuf v1.5.3
+ github.com/jsimonetti/rtnetlink v1.4.0
+ github.com/miekg/dns v1.1.57
+ github.com/rs/dnstrace v1.4.1
+ go.wit.com/gui v0.9.2
+ go.wit.com/shell v0.0.0-20231220210920-25715e30ee82
+ golang.org/x/term v0.15.0
+)
+
+require (
+ github.com/alexflint/go-scalar v1.1.0 // indirect
+ github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
+ github.com/google/go-cmp v0.6.0 // indirect
+ github.com/josharian/native v1.1.0 // indirect
+ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
+ github.com/mdlayher/netlink v1.7.2 // indirect
+ github.com/mdlayher/socket v0.4.1 // indirect
+ github.com/sirupsen/logrus v1.9.3 // indirect
+ github.com/sourcegraph/conc v0.3.0 // indirect
+ github.com/svent/go-nbreader v0.0.0-20150201200112-7cef48da76dc // indirect
+ github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef // indirect
+ github.com/wercker/journalhook v0.0.0-20230927020745-64542ffa4117 // indirect
+ go.uber.org/atomic v1.7.0 // indirect
+ go.uber.org/multierr v1.9.0 // indirect
+ golang.org/x/crypto v0.17.0 // indirect
+ golang.org/x/mod v0.12.0 // indirect
+ golang.org/x/net v0.17.0 // indirect
+ golang.org/x/sync v0.4.0 // indirect
+ golang.org/x/sys v0.15.0 // indirect
+ golang.org/x/tools v0.13.0 // indirect
+ google.golang.org/protobuf v1.26.0 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..1162892
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,88 @@
+github.com/Showmax/go-fqdn v1.0.0 h1:0rG5IbmVliNT5O19Mfuvna9LL7zlHyRfsSvBPZmF9tM=
+github.com/Showmax/go-fqdn v1.0.0/go.mod h1:SfrFBzmDCtCGrnHhoDjuvFnKsWjEQX/Q9ARZvOrJAko=
+github.com/alexflint/go-arg v1.4.3 h1:9rwwEBpMXfKQKceuZfYcwuc/7YY7tWJbFsgG5cAU/uo=
+github.com/alexflint/go-arg v1.4.3/go.mod h1:3PZ/wp/8HuqRZMUUgu7I+e1qcpUbvmS258mRXkFH4IA=
+github.com/alexflint/go-scalar v1.1.0 h1:aaAouLLzI9TChcPXotr6gUhq+Scr8rl0P9P4PnltbhM=
+github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
+github.com/cilium/ebpf v0.12.3 h1:8ht6F9MquybnY97at+VDZb3eQQr8ev79RueWeVaEcG4=
+github.com/cilium/ebpf v0.12.3/go.mod h1:TctK1ivibvI3znr66ljgi4hqOT8EYQjz1KWBfb1UVgM=
+github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
+github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
+github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
+github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
+github.com/jsimonetti/rtnetlink v1.4.0 h1:Z1BF0fRgcETPEa0Kt0MRk3yV5+kF1FWTni6KUFKrq2I=
+github.com/jsimonetti/rtnetlink v1.4.0/go.mod h1:5W1jDvWdnthFJ7fxYX1GMK07BUpI4oskfOqvPteYS6E=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
+github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
+github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
+github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
+github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
+github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
+github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rs/dnstrace v1.4.1 h1:o6W+8hO9kGcdq9FZAVudpCyw6WXeD9XXamXyYiei/Hs=
+github.com/rs/dnstrace v1.4.1/go.mod h1:pFQiHK1kt94r2csi+qAxUsJ58r74QbN2q4JCDuFYTeY=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
+github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/svent/go-nbreader v0.0.0-20150201200112-7cef48da76dc h1:usYkrH2/es/TT7ETdC/qLAagcJPW3EEYFKqvibSnFbA=
+github.com/svent/go-nbreader v0.0.0-20150201200112-7cef48da76dc/go.mod h1:pPzZl0vMkUhyoxUF8PAGG5bDRGo7PY80oO/PMmpLkkc=
+github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef h1:7D6Nm4D6f0ci9yttWaKjM1TMAXrH5Su72dojqYGntFY=
+github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef/go.mod h1:WLFStEdnJXpjK8kd4qKLwQKX/1vrDzp5BcDyiZJBHJM=
+github.com/wercker/journalhook v0.0.0-20230927020745-64542ffa4117 h1:67A5tweHp3C7osHjrYsy6pQZ00bYkTTttZ7kiOwwHeA=
+github.com/wercker/journalhook v0.0.0-20230927020745-64542ffa4117/go.mod h1:XCsSkdKK4gwBMNrOCZWww0pX6AOt+2gYc5Z6jBRrNVg=
+go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
+go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
+go.wit.com/gui v0.9.2 h1:QHMYdwpV6MzKwmFUMGevKUDn2a6GAqHN2Ltx8V3HufI=
+go.wit.com/gui v0.9.2/go.mod h1:asRXEYKmdjhtg1yiBi5A8YEY2YG4lWPS0gvNz4NXGDE=
+go.wit.com/shell v0.0.0-20231220210920-25715e30ee82 h1:5YVB3Y2PHtH+oE8Y1SzWHIKnJ1SPQa09xNHEw9yxmAI=
+go.wit.com/shell v0.0.0-20231220210920-25715e30ee82/go.mod h1:57dOTStlN5aao4EOCZFC+D47rF7In6qDZCjQoobJWcA=
+golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
+golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI=
+golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
+golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
+golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
+golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
+golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/gui.go b/gui.go
index 1688a9c..df00cf2 100644
--- a/gui.go
+++ b/gui.go
@@ -14,8 +14,6 @@ import (
"go.wit.com/gui"
"go.wit.com/shell"
"go.wit.com/control-panel-dns/cloudflare"
-
- "github.com/davecgh/go-spew/spew"
)
// This setups up the dns control panel window
@@ -25,9 +23,13 @@ func setupControlPanelWindow() {
debug("artificial sleep of:", me.artificialSleep)
sleep(me.artificialSleep)
+
+ // setup the main tab
dnsTab("DNS")
detailsTab("Details")
debugTab("Debug")
+
+ me.digStatus = NewDigStatusWindow(me.window)
}
func detailsTab(title string) {
@@ -59,6 +61,9 @@ func detailsTab(title string) {
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")
@@ -122,7 +127,6 @@ func debugTab(title string) {
g2.NewButton("os.User()", func () {
user, _ := user.Current()
- spew.Dump(user)
log.Println("os.Getuid =", user.Username, os.Getuid())
if (me.uid != nil) {
me.uid.SetText(user.Username + " (" + strconv.Itoa(os.Getuid()) + ")")
@@ -132,7 +136,6 @@ func debugTab(title string) {
g2.NewButton("dig +trace", func () {
o := shell.Run("dig +trace +noadditional DS " + me.hostname + " @8.8.8.8")
log.Println(o)
- // log.Println(o)
})
g2.NewButton("Example_listLink()", func () {
@@ -186,30 +189,54 @@ func debugTab(title string) {
g2.Pad()
}
+// will return a AAAA value that needs to be deleted
+func deleteAAA() string {
+ var aaaa []string
+ aaaa = dhcpAAAA() // your AAAA IP addresses right now
+ for _, s := range aaaa {
+ debug(LogNow, "DNS AAAA =", s)
+ if ( me.ipmap[s] == nil) {
+ return s
+ }
+ }
+ return ""
+}
+
+// will return a AAAA value that needs to be added
+func missingAAAA() string {
+ var aaaa []string
+ aaaa = dhcpAAAA() // your AAAA IP addresses right now
+ for _, s := range aaaa {
+ debug(LogNow, "missing AAAA =", s)
+ return s
+ }
+ return ""
+}
+
// doesn't actually do any network traffic
// it just updates the GUI
-func displayDNS() int {
+func displayDNS() string {
var aaaa []string
- aaaa = realAAAA() // your AAAA records right now
+ aaaa = dhcpAAAA() // your AAAA records right now
h := me.hostname
var all string
- var broken int = 0
+ var broken string = "unknown"
for _, s := range aaaa {
debug(LogNow, "host", h, "DNS AAAA =", s, "ipmap[s] =", me.ipmap[s])
all += s + "\n"
if ( me.ipmap[s] == nil) {
debug(LogError, "THIS IS THE WRONG AAAA DNS ENTRY: host", h, "DNS AAAA =", s)
- broken = 2
+ broken = "wrong AAAA entry"
} else {
- if (broken == 0) {
- broken = 1
+ if (broken == "unknown") {
+ broken = "needs update"
}
}
}
all = sortLines(all)
- if (me.DnsAAAA.S != all) {
- debug(LogError, "DnsAAAA.SetText() to:", all)
- me.DnsAAAA.SetText(all)
+ if (me.workingIPv6.S != all) {
+ debug(LogError, "workingIPv6.SetText() to:", all)
+ me.workingIPv6.SetText(all)
}
var a []string
@@ -296,6 +323,9 @@ func statusGrid(n *gui.Node) {
gridP.NewLabel("DNS Status =")
me.DnsStatus = gridP.NewLabel("unknown")
+ me.statusIPv6 = cloudflare.NewOneLiner(gridP, "IPv6 working")
+ me.statusIPv6.Set("known")
+
gridP.NewLabel("hostname =")
me.hostnameStatus = gridP.NewLabel("invalid")
@@ -315,9 +345,6 @@ func statusGrid(n *gui.Node) {
ng := n.NewGroup("TODO:")
gridP = ng.NewGrid("nut2", 2, 2)
- gridP.NewLabel("IPv6 working =")
- gridP.NewLabel("unknown")
-
gridP.NewLabel("ping.wit.com =")
gridP.NewLabel("unknown")
@@ -337,26 +364,63 @@ func updateDNS() {
if (h == "") {
h = "test.wit.com"
}
+
+ me.digStatus.Update()
+
// log.Println("digAAAA()")
aaaa = digAAAA(h)
debug(LogNow, "digAAAA() =", aaaa)
+
// log.Println(SPEW, me)
if (aaaa == nil) {
debug(LogError, "There are no DNS AAAA records for hostname: ", h)
+ me.DnsAAAA.SetText("(none)")
+ if (cloudflare.CFdialog.TypeNode != nil) {
+ cloudflare.CFdialog.TypeNode.SetText("AAAA new")
+ }
+
+ if (cloudflare.CFdialog.NameNode != nil) {
+ cloudflare.CFdialog.NameNode.SetText(me.hostname)
+ }
+
+ d := deleteAAA()
+ if (d != "") {
+ if (cloudflare.CFdialog.ValueNode != nil) {
+ cloudflare.CFdialog.ValueNode.SetText(d)
+ }
+ }
+ m := missingAAAA()
+ if (m != "") {
+ if (cloudflare.CFdialog.ValueNode != nil) {
+ cloudflare.CFdialog.ValueNode.SetText(m)
+ }
+ /*
+ rr := &cloudflare.RRT{
+ Type: "AAAA",
+ Name: me.hostname,
+ Ttl: "Auto",
+ Proxied: false,
+ Content: m,
+ }
+ cloudflare.Update(rr)
+ */
+ }
}
- broken := displayDNS() // update the GUI based on dig results
+ status := displayDNS() // update the GUI based on dig results
+ me.DnsStatus.SetText(status)
- if (broken == 1) {
- me.DnsStatus.SetText("PARTLY WORKING")
- } else if (broken == 2) {
- me.DnsStatus.SetText("WORKING")
- } else {
- me.DnsStatus.SetText("BROKEN")
- me.fix.Enable()
+ if me.digStatus.Ready() {
+ if me.digStatus.IPv6() {
+ me.statusIPv6.Set("IPv6 WORKING")
+ } else {
+ me.statusIPv6.Set("Need VPN")
+ }
}
+
+ // me.fix.Enable()
+
user, _ := user.Current()
- spew.Dump(user)
log.Println("os.Getuid =", user.Username, os.Getuid())
if (me.uid != nil) {
me.uid.SetText(user.Username + " (" + strconv.Itoa(os.Getuid()) + ")")
diff --git a/hostname.go b/hostname.go
index a0da280..7b7132a 100644
--- a/hostname.go
+++ b/hostname.go
@@ -6,17 +6,22 @@
package main
import (
+ "log"
+// "net"
+ "strings"
+
"go.wit.com/shell"
"go.wit.com/control-panel-dns/cloudflare"
- "go.wit.com/control-panel-dns/dnssecsocket"
+
+ "github.com/miekg/dns"
)
// will try to get this hosts FQDN
import "github.com/Showmax/go-fqdn"
// this is the king of dns libraries
-import "github.com/miekg/dns"
+// import "github.com/miekg/dns"
func getHostname() {
@@ -98,6 +103,7 @@ func goodHostname(h string) bool {
return false
}
+/*
func digAAAA(s string) []string {
var aaaa []string
// lookup the IP address from DNS
@@ -114,5 +120,52 @@ func digAAAA(s string) []string {
me.ipv6s[ipaddr] = rr
}
debug(true, 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 dnsLookupDoH(domain)")
+ ipv6Addresses, _ = dnsLookupDoH(hostname)
+ log.Println("digAAAA() has ipv6Addresses =", strings.Join(ipv6Addresses, " "))
+ log.Printf("digAAAA() IPv6 Addresses for %s:\n", hostname)
+ 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 {
+ fmt.Println("Error:", err)
+ return
+ }
+
+ fmt.Printf("IPv6 Addresses for %s:\n", domain)
+ for _, addr := range ipv6Addresses {
+ fmt.Println(addr)
+ }
+}
+*/
diff --git a/main.go b/main.go
index 36be8cd..ec859d1 100644
--- a/main.go
+++ b/main.go
@@ -59,6 +59,27 @@ func main() {
/*
Poll for changes to the networking settings
*/
+
+/* https://github.com/robfig/cron/blob/master/cron.go
+
+// Run the cron scheduler, or no-op if already running.
+func (c *Cron) Run() {
+ c.runningMu.Lock()
+ if c.running {
+ c.runningMu.Unlock()
+ return
+ }
+ c.running = true
+ c.runningMu.Unlock()
+ c.run()
+}
+
+// run the scheduler.. this is private just due to the need to synchronize
+// access to the 'running' state variable.
+func (c *Cron) run() {
+ c.logger.Info("start")
+*/
+
func checkNetworkChanges() {
var lastLocal time.Time = time.Now()
var lastDNS time.Time = time.Now()
@@ -119,12 +140,12 @@ func DNSloop() {
} else if (duration > 100 * time.Millisecond ) {
newSpeed = "OK"
if (me.fixProc != nil) {
- me.fixProc.Disable()
+ // me.fixProc.Disable()
}
} else {
newSpeed = "FAST"
if (me.fixProc != nil) {
- me.fixProc.Disable()
+ // me.fixProc.Disable()
}
}
if (newSpeed != me.DnsSpeedLast) {
@@ -156,7 +177,7 @@ func linuxLoop() {
}
var aaaa []string
- aaaa = realAAAA()
+ aaaa = dhcpAAAA()
var all string
for _, s := range aaaa {
debug(LogNet, "my actual AAAA = ",s)
diff --git a/net.go b/net.go
index 487486e..10b909a 100644
--- a/net.go
+++ b/net.go
@@ -97,7 +97,11 @@ func checkInterface(i net.Interface) {
}
}
-func realAAAA() []string {
+/*
+ These are the real IP address you have been
+ given from DHCP
+*/
+func dhcpAAAA() []string {
var aaaa []string
for s, t := range me.ipmap {
diff --git a/structs.go b/structs.go
index 3d1ba4a..36d84c3 100644
--- a/structs.go
+++ b/structs.go
@@ -57,6 +57,7 @@ type Host struct {
NSrr *gui.Node // NS resource records for the domain name
DnsAPI *gui.Node // what DNS API to use?
DnsAAAA *gui.Node // the actual DNS AAAA results
+ workingIPv6 *gui.Node // currently working AAAA
DnsA *gui.Node // the actual DNS A results (ignore for status since mostly never happens?)
DnsStatus *gui.Node // the current state of DNS
DnsSpeed *gui.Node // 'FAST', 'OK', 'SLOW', etc
@@ -72,6 +73,9 @@ type Host struct {
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
+ statusIPv6 *cloudflare.OneLiner
}
type IPtype struct {