Skip to content

Commit

Permalink
Added: "dns and doh"
Browse files Browse the repository at this point in the history
  • Loading branch information
cody0704 committed Mar 26, 2022
1 parent 0ea5e7b commit 0416e56
Show file tree
Hide file tree
Showing 11 changed files with 389 additions and 103 deletions.
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ VERSION ?= $(shell git describe --tags --always || git rev-parse --short HEAD)

compile:
echo "Compiling for every OS and Platform"
GOOS=freebsd GOARCH=amd64 go build -o bin/$(NAME)_$(VERSION)_freebsd-amd64 -ldflags '-X "main.versionID=$(VERSION)"'
GOOS=linux GOARCH=amd64 go build -o bin/$(NAME)_$(VERSION)_linux-amd64 -ldflags '-X "main.versionID=$(VERSION)"'
GOOS=darwin GOARCH=amd64 go build -o bin/$(NAME)_$(VERSION)_darwin-amd64 -ldflags '-X "main.versionID=$(VERSION)"'
GOOS=windows GOARCH=amd64 go build -o bin/$(NAME)_$(VERSION)_windows-amd64 -ldflags '-X "main.versionID=$(VERSION)"'
GOOS=freebsd GOARCH=amd64 go build -o ./bin/$(NAME)_$(VERSION)_freebsd-amd64 -ldflags '-X "main.versionID=$(VERSION)"' ./cmd/dotbomb
GOOS=linux GOARCH=amd64 go build -o ./bin/$(NAME)_$(VERSION)_linux-amd64 -ldflags '-X "main.versionID=$(VERSION)"' ./cmd/dotbomb
GOOS=darwin GOARCH=amd64 go build -o ./bin/$(NAME)_$(VERSION)_darwin-amd64 -ldflags '-X "main.versionID=$(VERSION)"' ./cmd/dotbomb
GOOS=windows GOARCH=amd64 go build -o ./bin/$(NAME)_$(VERSION)_windows-amd64 -ldflags '-X "main.versionID=$(VERSION)"' ./cmd/dotbomb
76 changes: 51 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

This is a DNS over TLS stress test tool

Support DNS and DoH by the way
## Command usage description

```
-v show version
-m mode: dns / dot / doh
-c number of concurrency
-t last Recv Packet Timeout
-n number of query
Expand All @@ -14,45 +16,69 @@ This is a DNS over TLS stress test tool
-f stress domain list
```

## Source Code
## Example

* DoT

```bash
go run main.go -c 20 -n 2000 -r 8.8.8.8 -f ./domains.txt
2022/03/26 14:40:44 DoTBomb start stress...
2022/03/26 14:40:45 DNS Over TLS Server: 8.8.8.8:853
Progress: 4000/4000
$ dotbomb -m dot -c 20 -n 100 -r 8.8.8.8 -f domains.txt
2022/03/26 15:44:10 DoTBomb start stress...
2022/03/26 15:44:10 Mode: dot
2022/03/26 15:44:10 DNS Over TLS Server: 8.8.8.8:853
Progress: 2000/2000

Status: Finish
Finish Time: 3.472923s
Avg Latency: 0.000869s
Finish Time: 2.172188s
Avg Latency: 0.001086s
==========================================
Send: 4000
Recv: 4000
Answer: 3917
NoAnswer: 80
Timeout: 3
Send: 2000
Recv: 2000
Answer: 1980
NoAnswer: 20
Timeout: 0
Other: 0
Timeout: 0
Other: 0
```

* DNS

## Binary executable file
```bash
$ dotbomb -m dns -c 20 -n 50 -r 8.8.8.8 -f domains.txt
2022/03/26 15:44:44 DoTBomb start stress...
2022/03/26 15:44:44 Mode: dns
2022/03/26 15:44:44 DNS Server: 8.8.8.8:53
Progress: 1000/1000

### Linux / MacOS
Status: Finish
Finish Time: 1.569659s
Avg Latency: 0.001571s
==========================================
Send: 1000
Recv: 1000
Answer: 999
NoAnswer: 0
Timeout: 1
Other: 0
```

* DoH

```bash
./dotbomb_v1.1.1_darwin-amd64 -c 20 -n 100 -r 8.8.8.8 -f domains.txt
2022/03/26 14:39:49 DoTBomb start stress...
2022/03/26 14:39:49 DNS Over TLS Server: 8.8.8.8:853
Progress: 2000/2000
$ dotbomb -m doh -c 20 -n 300 -r 8.8.8.8 -f domains.txt
2022/03/26 15:45:10 DoTBomb start stress...
2022/03/26 15:45:10 Mode: doh
2022/03/26 15:45:10 DNS Over HTTPS Server: https://8.8.8.8:443/dns-query
Progress: 6000/6000

Status: Finish
Finish Time: 1.084065s
Avg Latency: 0.000542s
Finish Time: 18.190158s
Avg Latency: 0.003032s
==========================================
Send: 2000
Recv: 2000
Answer: 1980
NoAnswer: 20
Send: 6000
Recv: 6000
Answer: 5820
NoAnswer: 180
Timeout: 0
Other: 0
```
```
69 changes: 69 additions & 0 deletions cmd/dotbomb/flag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package main

import (
"flag"
"fmt"
"os"
)

var (
versionID string = "%VERSION%"
version bool
mode string
timeout int
concurrency int
totalRequest int
requestIP string
requestPort string
domainFile string
)

func init() {
flag.BoolVar(&version, "v", false, "number of concurrency")
flag.StringVar(&mode, "m", "dot", "dot / doh / dns")
flag.IntVar(&timeout, "t", 3, "Last Recv Packet Timeout")
flag.IntVar(&concurrency, "c", 1, "number of concurrency")
flag.IntVar(&totalRequest, "n", 1, "number of request")
flag.StringVar(&requestIP, "r", "", "request ip address")
flag.StringVar(&requestPort, "p", "", "request port")
flag.StringVar(&domainFile, "f", "", "domain list file")

flag.Parse()

if version {
fmt.Println(versionID)
os.Exit(0)
}

if concurrency == 0 || totalRequest == 0 || requestIP == "" || mode == "" {
fmt.Println("Example: dotbomb -m dot -c 10 -n 100 -r 8.8.8.8 -p 853 -f domains.txt")
fmt.Println("-v [Version]")
fmt.Println("-m [Mode] Default: dot, Option: dot / doh / dns")
fmt.Println("-c [Concurrency] <Number>")
fmt.Println("-t [Timeout] <Second>")
fmt.Println("-n [request] <Number>")
fmt.Println("-r <Server IP>")
fmt.Println("-p <Port: DoT 853 / DoH 443 / DNS 53>")
fmt.Println("-f <DomainList File Path>")

os.Exit(0)
}

switch mode {
case "dns", "dot", "doh":
default:
fmt.Println("-m [Mode] Default: dot, Option: dot / doh / dns")
os.Exit(0)
}

if requestPort == "" {
switch mode {
case "dns":
requestPort = "53"
case "dot":
requestPort = "853"
case "doh":
requestPort = "443"
}
}
}
59 changes: 13 additions & 46 deletions main.go → cmd/dotbomb/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"bufio"
"flag"
"fmt"
"log"
"math"
Expand All @@ -14,51 +13,11 @@ import (
"github.com/cody0704/dotbomb/server"
)

var (
versionID string = "%VERSION%"
version bool
timeout int
concurrency int
totalRequest int
requestIP string
requestPort string
domainFile string
)

func init() {
flag.BoolVar(&version, "v", false, "number of concurrency")
flag.IntVar(&timeout, "t", 3, "RecvTimeout")
flag.IntVar(&concurrency, "c", 1, "number of concurrency")
flag.IntVar(&totalRequest, "n", 1, "number of request")
flag.StringVar(&requestIP, "r", "", "request ip address")
flag.StringVar(&requestPort, "p", "853", "request port")
flag.StringVar(&domainFile, "f", "", "domain list file")

flag.Parse()

if version {
fmt.Println(versionID)
os.Exit(0)
}

if concurrency == 0 || totalRequest == 0 || requestIP == "" {
fmt.Println("Example: ./dotbomb -c 10 -n 100 -r 8.8.8.8 -f domains.txt")
fmt.Println("Example: ./dotbomb -c 10 -n 100 -r 8.8.8.8 -p 853 -f domains.txt")
fmt.Println("-c [Concurrency] <Number>")
fmt.Println("-n [request] <Number>")
fmt.Println("-r <DNS Over TLS Server IP>")
fmt.Println("-p <Default Port 853>")

flag.Usage()
os.Exit(0)
}
}

func main() {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)

var dotbomb = server.DoTBomb{
var bomb = server.Bomb{
Concurrency: concurrency,
TotalRequest: totalRequest,
RequestIP: requestIP,
Expand All @@ -77,10 +36,10 @@ func main() {
if domain == "" {
continue
}
dotbomb.DomainArray = append(dotbomb.DomainArray, domain)
bomb.DomainArray = append(bomb.DomainArray, domain)
}

if len(dotbomb.DomainArray) == 0 {
if len(bomb.DomainArray) == 0 {
log.Fatal(domainFile, " does not have any domains")
}

Expand All @@ -90,8 +49,16 @@ func main() {
file.Close()

log.Println("DoTBomb start stress...")

go dotbomb.Start()
log.Println("Mode:", mode)

switch mode {
case "dns":
go bomb.DNS()
case "dot":
go bomb.DoT()
case "doh":
go bomb.DoH()
}

select {
case <-sigChan:
Expand Down
80 changes: 80 additions & 0 deletions server/dns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package server

import (
"fmt"
"log"
"os"
"strconv"
"strings"
"sync/atomic"
"time"

"github.com/cody0704/dotbomb/server/verify"

rdns "github.com/folbricht/routedns"
"github.com/miekg/dns"
)

func (b Bomb) DNS() {
server := b.RequestIP + ":" + b.RequestPort
if !verify.DNSServer(server) {
log.Println("Cannot connect to DNS Server:", server)
os.Exit(0)
return
}
log.Println("DNS Server:", server)

t1 := time.Now()

wg.Add(b.Concurrency)
var domainCount = len(b.DomainArray)
finish := b.TotalRequest * b.Concurrency
for count := 1; count <= b.Concurrency; count++ {
go func(count, finish int) {
// Build a query
q := new(dns.Msg)

// Resolve the query
dnsClient, err := rdns.NewDNSClient("stress-dns-"+strconv.Itoa(count), server, "udp", rdns.DNSClientOptions{})
if err != nil {
log.Println(err)
wg.Done()
return
}

for i := 0; i < b.TotalRequest; i++ {
domain := b.DomainArray[i%domainCount] + "."

q.SetQuestion(domain, dns.TypeA)
atomic.AddUint64(&Result.SendCount, 1)
fmt.Printf("Progress:\t%d/%d\r", Result.SendCount, finish)
resp, err := dnsClient.Resolve(q, rdns.ClientInfo{})
if err != nil {
if strings.Contains(err.Error(), "timed out") {
atomic.AddUint64(&Result.TimeoutCount, 1)
} else {
atomic.AddUint64(&Result.OtherCount, 1)
}
continue
}
Result.LastTime = time.Since(t1)

answers := resp.Answer
if len(answers) > 0 {
switch len(strings.Split(answers[0].String(), "\t")) {
case 5:
atomic.AddUint64(&Result.RecvAnsCount, 1)
default:
atomic.AddUint64(&Result.RecvNoAnsCount, 1)
}
} else {
atomic.AddUint64(&Result.RecvNoAnsCount, 1)
}

}
wg.Done()
}(count, finish)
}
wg.Wait()
StatusChan <- 0
}
Loading

0 comments on commit 0416e56

Please sign in to comment.