Detect that a VPN is needed

IPv6() returns true if it's working
    display duration
    a 'DNS Lookup Status' window
    actual dig results
    display status and failure counters
    count lookup failures and successes
    add TCP dns lookup
    logic to test if dns is working at all
    add DNS over HTTPS
    cloudflare new & update kind of working
    holy shit, go.wit.com finally works with git mod tidy
    working, but cloudflare api stuff is broken
    AAAA '(none)' logic detection is better
    cloudflare control panel
    display the working real AAAA addresses

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2023-12-28 09:43:45 -06:00
parent 73b0cee933
commit 6fa6d6dfc9
22 changed files with 857 additions and 152 deletions

2
.gitignore vendored
View File

@ -4,4 +4,4 @@ control-panel-dns
*.swp
/plugins/*
examples/cloudflare/cloudflare
examples/control-panel-cloudflare/control-panel-cloudflare

View File

@ -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)

View File

@ -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 {

View File

@ -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)

View File

@ -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
func doCurl(method string, rr *RRT) string {
var err error
var req *http.Request
var tmp string
tmp = makeJSON(dnsRow)
data := []byte(tmp)
data := []byte(rr.data)
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)
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))

View File

@ -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) {

42
cloudflare/oneLiner.go Normal file
View File

@ -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
}

View File

@ -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()
rr.url = "https://api.cloudflare.com/client/v4/zones/" + rr.ZoneID + "/dns_records"
result := doCurl("POST", rr)
CFdialog.resultNode.SetText(result)
pretty, _ := FormatJSON(result)
log.Println(pretty)
})
group.NewButton("Update RR doCurl(PUT)", func () {
rr := DoChange()
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()
group.Pad()
grid.Pad()
grid.Expand()
}
/*
func CreateCurlRR() (string, string) {
// enable the Save/Create Button
if (CFdialog.saveNode != nil) {
CFdialog.saveNode.Enable()
}
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"
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")
// 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)
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
}
*/

View File

@ -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

62
dns-https.go Normal file
View File

@ -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)
}
}
*/

370
dnsLookupStatus.go Normal file
View File

@ -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
}

View File

@ -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

View File

@ -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()

39
go.mod
View File

@ -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
)

88
go.sum Normal file
View File

@ -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=

116
gui.go
View File

@ -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)
}
broken := displayDNS() // update the GUI based on dig results
me.DnsAAAA.SetText("(none)")
if (cloudflare.CFdialog.TypeNode != nil) {
cloudflare.CFdialog.TypeNode.SetText("AAAA new")
}
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 (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)
*/
}
}
status := displayDNS() // update the GUI based on dig results
me.DnsStatus.SetText(status)
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()) + ")")

View File

@ -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)
}
}
*/

27
main.go
View File

@ -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)

6
net.go
View File

@ -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 {

View File

@ -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 {