forked from nelsonmarcos/dns-check
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
133 lines (116 loc) · 2.9 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
import (
"context"
"flag"
"fmt"
"log"
"net"
"net/http"
"sort"
"strconv"
"strings"
"sync"
)
// Global variables
var wg sync.WaitGroup
var DefaultResolver = net.Resolver{PreferGo: true}
// printProgressBar prints a friendly progress bar so the user can be sure if the program is running or waiting
func printProgressBar(iteration, total int, prefix, suffix string, length int, fill string) {
percent := float64(iteration) / float64(total) * 100
filledLength := int(length * iteration / total)
end := ">"
if iteration == total {
end = "="
}
bar := strings.Repeat(fill, filledLength) + end + strings.Repeat("-", (length-filledLength))
fmt.Printf("\r%s [%s] %.0f%% %s", prefix, bar, percent, suffix)
if iteration == total {
fmt.Println()
}
}
// LookupIP is a replacement for default LookupIP so we can use go as dns resolver instead of the OS
func LookupIP(host string) ([]net.IP, error) {
addrs, err := DefaultResolver.LookupIPAddr(context.Background(), host)
if err != nil {
return nil, err
}
ips := make([]net.IP, len(addrs))
for i, ia := range addrs {
ips[i] = ia.IP
}
return ips, nil
}
func getHealthcheck(url string, ch chan<- string) {
defer wg.Done()
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Connection", "close")
res, err := client.Do(req)
if err != nil {
log.Fatalln(err)
}
defer res.Body.Close()
ch <- strconv.Itoa(res.StatusCode)
}
// dnsResolver resolves a dns add the result to a map and has concurrency control
func dnsResolver(domain string, ch chan<- string) {
defer wg.Done()
iprecords, _ := LookupIP(domain)
for _, ip := range iprecords {
ch <- ip.String()
}
}
func main() {
var (
ch = make(chan string)
result = make(map[string]int)
setWait bool
)
domainPtr := flag.String("domain", "", "`Domain` to be resolved")
repeatPtr := flag.Int("r", 1, "`Number` of run times")
multithread := flag.Bool("d", false, "Enables multithread. Default is false.")
action := flag.String("action", "", "dns or get")
url := flag.String("url", "https://s3.glbimg.com/healthcheck", "GET Url")
flag.Parse()
if *domainPtr != "" {
fmt.Println("Domain: ", *domainPtr)
}
if *action != "dns" {
fmt.Println("Url: ", *url)
}
for rep := 1; rep <= *repeatPtr; rep++ {
printProgressBar(rep, *repeatPtr, "Progress", "Complete", 25, "=")
if *multithread {
setWait = true
wg.Add(1)
if *action == "dns" {
go dnsResolver(*domainPtr, ch)
} else {
go getHealthcheck(*url, ch)
}
} else {
if *action == "dns" {
dnsResolver(*domainPtr, ch)
} else {
getHealthcheck(*url, ch)
}
}
}
go func() {
if setWait == true {
wg.Wait()
}
close(ch)
}()
for res := range ch {
result[res]++
}
allkeys := make([]string, 0, len(result))
for key := range result {
allkeys = append(allkeys, key)
}
sort.Strings(allkeys)
for _, key := range allkeys {
fmt.Println(key, "=", result[key])
}
}