summaryrefslogtreecommitdiff
path: root/method/combined.go
blob: f2647104d71a348cdc44aeecad2b7d84ff958d91 (plain)
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
package method

import (
	"edns_svcb/utils"
	"fmt"
	"log"
	"sync"

	"github.com/miekg/dns"
)

type CombinedResult struct {
	Alive        bool
	EDNSSupport  bool
	SVCBSupport  bool
	HTTPSSupport bool
	Err          error
}

func CombinedMeasurement(ip_pool chan string, result_pool chan CombinedResult, routine_num int, wg *sync.WaitGroup, logger *log.Logger) {
	for i := 0; i < routine_num; i++ {
		wg.Add(1)
		go CombinedTestRoutine(ip_pool, result_pool, wg, logger)
	}
}

func CombinedTestRoutine(ip_pool chan string, result_pool chan CombinedResult, wg *sync.WaitGroup, logger *log.Logger) {
	for {
		if ip, ok := <-ip_pool; ok {
			addr := ip + ":53"
			res := CombinedTest(addr)
			result_pool <- res
			if res.Err != nil {
				logger.Printf("%v : failed ( %v )", ip, res.Err)
			} else {
				logger.Printf("%v : alive %v edns %v svcb %v https %v", ip, res.Alive, res.EDNSSupport, res.SVCBSupport, res.HTTPSSupport)
			}
		} else {
			break
		}
	}
	wg.Done()
}

func CombinedTest(addr string) CombinedResult {
	result := CombinedResult{}
	_, err := utils.DNSQuery(addr, utils.DNSOptions{Domain: "www.example.com", RD: true})
	if err != nil {
		return CombinedResult{Err: err}
	}
	result.Alive = true

	//edns support
	res, err := utils.DNSQuery(addr, utils.DNSOptions{Domain: "www.example.com", EDNS: true, RD: true})
	if err == nil {
		if len(res.Extra) > 0 {
			if _, ok := res.Extra[0].(*dns.OPT); ok {
				result.EDNSSupport = true
			}
		}
	} else {
		result.Err = err
		return result
	}

	// svcb support
	res, err = utils.DNSQuery(addr, utils.DNSOptions{Domain: "_dns.resolver.arpa", Qtype: dns.TypeSVCB, RD: true})
	if err == nil {
		if len(res.Answer) > 0 {
			if _, ok := res.Answer[0].(*dns.SVCB); ok {
				result.SVCBSupport = true
			}
		}
	} else {
		result.Err = err
		return result
	}

	// https support
	res, err = utils.DNSQuery(addr, utils.DNSOptions{Domain: "blog.cloudflare.com", Qtype: dns.TypeHTTPS, RD: true})
	if err == nil {
		if len(res.Answer) > 0 {
			if _, ok := res.Answer[0].(*dns.HTTPS); ok {
				result.HTTPSSupport = true
			}
		}
	} else {
		result.Err = err
		return result
	}

	return result
}

func CombinedResultProcess(result_pool chan CombinedResult, wg *sync.WaitGroup) {
	alive_cnt := 0
	edns_cnt := 0
	svcb_cnt := 0
	https_cnt := 0
	for {
		if res, ok := <-result_pool; ok {
			if res.Err != nil {
				continue
			}
			if res.Alive {
				alive_cnt++
			}
			if res.EDNSSupport {
				edns_cnt++
			}
			if res.SVCBSupport {
				svcb_cnt++
			}
			if res.HTTPSSupport {
				https_cnt++
			}
		} else {
			break
		}
	}
	fmt.Printf("EDNS support Test: alive %v edns %v svcb %v https %v\n", alive_cnt, edns_cnt, svcb_cnt, https_cnt)
	wg.Done()
}