ddig 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d1bcdd660ab21b14d2e5572b27a50f2cc0fe541c64b9c6c8502f85d89a29b28
4
- data.tar.gz: 6462363f2b075b9aad78f88a055e1d53af1901054a22c3a010fcdfb0a28e9fde
3
+ metadata.gz: e1a65973ea90a0410cf7c2bd8846431d1b46f6bfec521cde944deba86c83effc
4
+ data.tar.gz: 4eaf90cdfabfe53095f4a5f4ca5f034b0d79296e0ff64da53a00cd4c71de6d04
5
5
  SHA512:
6
- metadata.gz: 785ef898b4f773668131d56ed8596b11de8bfbe9908cc0de7383a2b0cfbb3aaf613dc813b73284382aaa6bbb3d9e89d6e4a45e0d1205aba45361213d6764cc19
7
- data.tar.gz: c12f638d1899ddb47e6c482b22b315ea8912bce701243fef37a239566653e5e216c8ed01b910105bc06c28843e9d40ef81d653923e1b95a2e386f18c18f2fc72
6
+ metadata.gz: 675a844c854c9bb5d63cac33742cc88e7a712356b41dc1fd61c4a646112ee1080a887218b3f8a6c949c0277c2d7f01851d1f30f3258138c2a57c467f4570c448
7
+ data.tar.gz: bdf9aa4945b93c190716a5809829cc11e2fd58584d0620b48f0793ae5085b3cb5e77b6f0cac2c28303f2dbb3e1c988e3b5f989f80de49049cb6fe5d3420212a8
data/README.md CHANGED
@@ -7,10 +7,13 @@ ddig is DNS lookup utility for Ruby.
7
7
  - DNS Resolvers
8
8
  - UDP (Do53)
9
9
  - DoT (DNS over TLS)
10
- - https://datatracker.ietf.org/doc/html/rfc7858
11
- - ~~DoH (DNS over HTTPS)~~
12
- - Not yet Supported
13
- - https://datatracker.ietf.org/doc/html/rfc8484
10
+ - https://www.rfc-editor.org/rfc/rfc7858.html
11
+ - DoH (DNS over HTTPS)
12
+ - Support only HTTP/1.1
13
+ - https://www.rfc-editor.org/rfc/rfc8484.html
14
+ - ~~DoQ (DNS over QUIC)~~
15
+ - Not Supported
16
+ - https://www.rfc-editor.org/rfc/rfc9250.html
14
17
  - DDR (Discovery of Designated Resolvers)
15
18
  - https://www.rfc-editor.org/rfc/rfc9462.html
16
19
 
@@ -25,6 +28,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
25
28
  $ gem install ddig
26
29
 
27
30
  ## Usage
31
+ ### Ruby
28
32
 
29
33
  ```ruby
30
34
  ddig = Ddig.lookup('dns.google', nameservers: ['8.8.8.8', '2001:4860:4860::8888'])
@@ -83,9 +87,96 @@ ddig[:ddr]
83
87
  ]
84
88
  ```
85
89
 
90
+ - Do53
91
+ ```ruby
92
+ do53 = Ddig::Resolver::Do53.new(hostname: 'dns.google', nameservers: '8.8.8.8').lookup
93
+ => #<Ddig::Resolver::Do53:0x0000000121717b78 @a=["8.8.8.8", "8.8.4.4"], @aaaa=["2001:4860:4860::8844", "2001:4860:4860::8888"], @hostname="dns.google", @ip=nil, @nameserver=#<Ddig::Nameserver:0x00000001211fb108 @nameservers="8.8.8.8", @servers=["8.8.8.8"]>, @nameservers=["8.8.8.8"]>
94
+
95
+ do53.a
96
+ => ["8.8.4.4", "8.8.8.8"]
97
+ do53.aaaa
98
+ => ["2001:4860:4860::8844", "2001:4860:4860::8888"]
99
+ ```
100
+
101
+ - DoT
102
+ ```ruby
103
+ dot = Ddig::Resolver::Dot.new(hostname: 'dns.google', server: '8.8.8.8').lookup
104
+ => #<Ddig::Resolver::Dot:0x000000012145da90 @a=["8.8.8.8", "8.8.4.4"], @aaaa=["2001:4860:4860::8844", "2001:4860:4860::8888"], @hostname="dns.google", @open_timeout=3, @port=853, @server="8.8.8.8", @server_name=nil>
105
+
106
+ dot.a
107
+ => ["8.8.4.4", "8.8.8.8"]
108
+ dot.aaaa
109
+ => ["2001:4860:4860::8844", "2001:4860:4860::8888"]
110
+ ```
111
+
112
+ - DoH (HTTP/1.1)
113
+ ```ruby
114
+ doh = Ddig::Resolver::DohH1.new(hostname: 'dns.google', server: 'dns.google', dohpath: '/dns-query{?dns}').lookup
115
+ => #<Ddig::Resolver::DohH1:0x00000001023ed020 @a=["8.8.4.4", "8.8.8.8"], @aaaa=["2001:4860:4860::8888", "2001:4860:4860::8844"], @address=nil, @dohpath="/dns-query{?dns}", @hostname="dns.google", @open_timeout=10, @port=443, @server="dns.google">
116
+
117
+ doh.a
118
+ => ["8.8.4.4", "8.8.8.8"]
119
+ doh.aaaa
120
+ => ["2001:4860:4860::8844", "2001:4860:4860::8888"]
121
+ ```
122
+
86
123
  ### CLI
124
+ - Usage
125
+ ```
126
+ $ ddig --help
127
+ Usage: ddig [options] hostname
128
+ -d, --dns-type={all|do53|dot} resolve type (default: all)
129
+ --udp use resolve type of udp(do53)
130
+ --dot use resolve type of dot
131
+ --doh-h1 use resolve type of doh (http/1.1)
132
+ --doh-path=doh-path doh service path
133
+ -4, --ipv4 use IPv4 query transport only
134
+ -6, --ipv6 use IPv6 query transport only
135
+ -@ipaddress|doh-hostname, nameserver
136
+ --nameserver
137
+ -p, --port=port port
138
+ --format={text|json} output format (default: text)
139
+
140
+ -v, --verbose run verbosely
141
+ -h, --help show this help message.
142
+ --version show version.
143
+ ```
144
+
145
+ - UDP(Do53)
146
+ ```sh
147
+ $ ddig --udp --nameserver 8.8.8.8 dns.google
148
+ dns.google A 8.8.8.8
149
+ dns.google A 8.8.4.4
150
+ dns.google AAAA 2001:4860:4860::8844
151
+ dns.google AAAA 2001:4860:4860::8888
152
+
153
+ # SERVER: 8.8.8.8
154
+ ```
155
+
156
+ - DoT
157
+ ```sh
158
+ $ ddig --dot --nameserver 8.8.8.8 dns.google
159
+ dns.google A 8.8.8.8
160
+ dns.google A 8.8.4.4
161
+ dns.google AAAA 2001:4860:4860::8888
162
+ dns.google AAAA 2001:4860:4860::8844
87
163
 
88
- (TBD)
164
+ # SERVER(Address): 8.8.8.8
165
+ # PORT: 853
166
+ ```
167
+
168
+ - DoH (HTTP/1.1)
169
+ ```sh
170
+ $ ddig --doh-h1 --nameserver dns.google --doh-path /dns-query{?dns} dns.google
171
+ dns.google A 8.8.8.8
172
+ dns.google A 8.8.4.4
173
+ dns.google AAAA 2001:4860:4860::8888
174
+ dns.google AAAA 2001:4860:4860::8844
175
+
176
+ # SERVER(Hostname): dns.google
177
+ # SERVER(Path): /dns-query{?dns}
178
+ # PORT: 443
179
+ ```
89
180
 
90
181
  ## Development
91
182
 
data/lib/ddig/cli.rb CHANGED
@@ -7,6 +7,7 @@ module Ddig
7
7
  def initialize(args)
8
8
  @args = args
9
9
  @options = {
10
+ dns_type: 'all',
10
11
  format: 'text',
11
12
  }
12
13
 
@@ -22,7 +23,15 @@ module Ddig
22
23
  @option_parser = OptionParser.new do |opts|
23
24
  opts.banner = "Usage: ddig [options] hostname"
24
25
 
25
- opts.on("--nameserver=ipaddress", "nameserver ip address") { |v| @options[:nameserver] = v }
26
+ opts.on("-d", "--dns-type={all|do53|dot}", "resolve type (default: all)") { |v| @options[:dns_type] = v }
27
+ opts.on("--udp", "use resolve type of udp(do53)") { |v| @options[:dns_type] = 'do53' }
28
+ opts.on("--dot", "use resolve type of dot") { |v| @options[:dns_type] = 'dot' }
29
+ opts.on("--doh-h1", "use resolve type of doh (http/1.1)") { |v| @options[:dns_type] = 'doh_h1' }
30
+ opts.on("--doh-path=doh-path", "doh service path") { |v| @options[:doh_path] = v }
31
+ opts.on("-4", "--ipv4", "use IPv4 query transport only") { |v| @options[:ipv4] = v }
32
+ opts.on("-6", "--ipv6", "use IPv6 query transport only") { |v| @options[:ipv6] = v }
33
+ opts.on("-@", "--nameserver=ipaddress|doh-hostname", "nameserver") { |v| @options[:nameserver] = v }
34
+ opts.on("-p", "--port=port", "port") { |v| @options[:port] = v }
26
35
  opts.on("--format={text|json}", "output format (default: text)") { |v| @options[:format] = v }
27
36
 
28
37
  opts.separator ""
@@ -38,18 +47,95 @@ module Ddig
38
47
  end
39
48
 
40
49
  def exec
41
- @ddig = Ddig.lookup(@hostname, nameservers: [@options[:nameserver]])
50
+ if @options[:ipv4] || @options[:ipv6]
51
+ @use_ipv4 = @options[:ipv4] || false
52
+ @use_ipv6 = @options[:ipv6] || false
53
+ end
54
+
55
+ case @options[:dns_type]
56
+ when "all"
57
+ resolve_all
58
+ when "do53"
59
+ resolve_do53
60
+ when "dot"
61
+ resolve_dot
62
+ when "doh_h1"
63
+ resolve_doh_h1
64
+ end
65
+ end
66
+
67
+ def resolve_all
68
+ @ddig = Ddig.lookup(@hostname, nameservers: @options[:nameserver], use_ipv4: @use_ipv4, use_ipv6: @use_ipv6)
42
69
 
43
70
  if @options[:format] == 'json'
44
71
  # TODO: to_json
45
72
  puts @ddig
46
73
  else
47
- print_result
74
+ puts @ddig
75
+ end
76
+ end
77
+
78
+ def resolve_do53
79
+ ip = Ddig::Ip.new(use_ipv4: @use_ipv4, use_ipv6: @use_ipv6)
80
+ do53 = Ddig::Resolver::Do53.new(hostname: @hostname, nameservers: @options[:nameserver], ip: ip.ip_type).lookup
81
+
82
+ if do53.nil?
83
+ puts "Error: Could not lookup wit nameserver: #{@options[:nameserver]}"
84
+ exit
85
+ end
86
+
87
+ do53.a.each do |address|
88
+ rr_type = 'A'
89
+ puts "#{@hostname}\t#{rr_type}\t#{address}"
90
+ end
91
+ do53.aaaa.each do |address|
92
+ rr_type = 'AAAA'
93
+ puts "#{@hostname}\t#{rr_type}\t#{address}"
48
94
  end
95
+
96
+ puts
97
+ puts "# SERVER: #{do53.nameservers.join(', ')}"
98
+ end
99
+
100
+ def resolve_dot
101
+ dot = Ddig::Resolver::Dot.new(hostname: @hostname, server: @options[:nameserver], port: @options[:port]).lookup
102
+
103
+ dot.a.each do |address|
104
+ rr_type = 'A'
105
+ puts "#{@hostname}\t#{rr_type}\t#{address}"
106
+ end
107
+ dot.aaaa.each do |address|
108
+ rr_type = 'AAAA'
109
+ puts "#{@hostname}\t#{rr_type}\t#{address}"
110
+ end
111
+
112
+ puts
113
+ puts "# SERVER(Address): #{dot.server}"
114
+ #puts "# SERVER(Hostname): #{dot.server_name}"
115
+ puts "# PORT: #{dot.port}"
49
116
  end
50
117
 
51
- def print_result
52
- puts @ddig
118
+ def resolve_doh_h1
119
+ if @options[:nameserver].nil? || @options[:doh_path].nil?
120
+ puts 'ddig: doh needs option of --doh-path=doh-path'
121
+ exit
122
+ end
123
+
124
+ doh = Ddig::Resolver::DohH1.new(hostname: @hostname, server: @options[:nameserver], dohpath: @options[:doh_path], port: @options[:port]).lookup
125
+
126
+ doh.a.each do |address|
127
+ rr_type = 'A'
128
+ puts "#{@hostname}\t#{rr_type}\t#{address}"
129
+ end
130
+ doh.aaaa.each do |address|
131
+ rr_type = 'AAAA'
132
+ puts "#{@hostname}\t#{rr_type}\t#{address}"
133
+ end
134
+
135
+ puts
136
+ puts "# SERVER(Hostname): #{doh.server}"
137
+ puts "# SERVER(Path): #{doh.dohpath}"
138
+ puts "# PORT: #{doh.port}"
53
139
  end
54
140
  end
55
141
  end
data/lib/ddig/ddr.rb CHANGED
@@ -68,35 +68,39 @@ module Ddig
68
68
  do53_v6 = ::Ddig::Resolver::Do53.new(hostname: target, nameservers: [unencrypted_resolver], ip: :ipv6).lookup
69
69
 
70
70
  # ipv4
71
- unless do53_v4.nil? || do53_v4.a.nil?
72
- do53_v4.a.each do |address|
73
- designated_resolver = ::Ddig::Ddr::DesignatedResolver.new(unencrypted_resolver: unencrypted_resolver, target: target, protocol: protocol, port: port, dohpath: dohpath, address: address.to_s, ip: :ipv4)
74
- @designated_resolvers << designated_resolver
71
+ unless @ip == :ipv6
72
+ unless do53_v4.nil? || do53_v4.a.nil?
73
+ do53_v4.a.each do |address|
74
+ designated_resolver = ::Ddig::Ddr::DesignatedResolver.new(unencrypted_resolver: unencrypted_resolver, target: target, protocol: protocol, port: port, dohpath: dohpath, address: address.to_s, ip: :ipv4)
75
+ @designated_resolvers << designated_resolver
76
+ end
75
77
  end
76
- end
77
- unless do53_v6.nil? || do53_v6.a.nil?
78
- do53_v6.a.each do |address|
79
- designated_resolver = ::Ddig::Ddr::DesignatedResolver.new(unencrypted_resolver: unencrypted_resolver, target: target, protocol: protocol, port: port, dohpath: dohpath, address: address.to_s, ip: :ipv4)
80
- @designated_resolvers << designated_resolver
78
+ unless do53_v6.nil? || do53_v6.a.nil?
79
+ do53_v6.a.each do |address|
80
+ designated_resolver = ::Ddig::Ddr::DesignatedResolver.new(unencrypted_resolver: unencrypted_resolver, target: target, protocol: protocol, port: port, dohpath: dohpath, address: address.to_s, ip: :ipv4)
81
+ @designated_resolvers << designated_resolver
82
+ end
81
83
  end
82
84
  end
83
85
 
84
86
  # ipv6
85
- unless do53_v4.nil? || do53_v4.aaaa.nil?
86
- do53_v4.aaaa.each do |address|
87
- designated_resolver = ::Ddig::Ddr::DesignatedResolver.new(unencrypted_resolver: unencrypted_resolver, target: target, protocol: protocol, port: port, dohpath: dohpath, address: address.to_s, ip: :ipv6)
88
- @designated_resolvers << designated_resolver
87
+ unless @ip == :ipv4
88
+ unless do53_v4.nil? || do53_v4.aaaa.nil?
89
+ do53_v4.aaaa.each do |address|
90
+ designated_resolver = ::Ddig::Ddr::DesignatedResolver.new(unencrypted_resolver: unencrypted_resolver, target: target, protocol: protocol, port: port, dohpath: dohpath, address: address.to_s, ip: :ipv6)
91
+ @designated_resolvers << designated_resolver
92
+ end
89
93
  end
90
- end
91
- unless do53_v6.nil? || do53_v6.aaaa.nil?
92
- do53_v6.aaaa.each do |address|
93
- designated_resolver = ::Ddig::Ddr::DesignatedResolver.new(unencrypted_resolver: unencrypted_resolver, target: target, protocol: protocol, port: port, dohpath: dohpath, address: address.to_s, ip: :ipv6)
94
- @designated_resolvers << designated_resolver
94
+ unless do53_v6.nil? || do53_v6.aaaa.nil?
95
+ do53_v6.aaaa.each do |address|
96
+ designated_resolver = ::Ddig::Ddr::DesignatedResolver.new(unencrypted_resolver: unencrypted_resolver, target: target, protocol: protocol, port: port, dohpath: dohpath, address: address.to_s, ip: :ipv6)
97
+ @designated_resolvers << designated_resolver
98
+ end
95
99
  end
96
100
  end
97
101
 
98
102
  # ipv4hint
99
- unless ipv4hint.nil?
103
+ unless ipv4hint.nil? || @ip == :ipv6
100
104
  ipv4hint.each do |address|
101
105
  ip = :ipv4
102
106
  designated_resolver = ::Ddig::Ddr::DesignatedResolver.new(unencrypted_resolver: unencrypted_resolver, target: target, protocol: protocol, port: port, dohpath: dohpath, address: address.to_s, ip: ip)
@@ -105,7 +109,7 @@ module Ddig
105
109
  end
106
110
 
107
111
  # ipv6hint
108
- unless ipv6hint.nil?
112
+ unless ipv6hint.nil? || @ip == :ipv4
109
113
  ipv6hint.each do |address|
110
114
  ip = :ipv6
111
115
  designated_resolver = ::Ddig::Ddr::DesignatedResolver.new(unencrypted_resolver: unencrypted_resolver, target: target, protocol: protocol, port: port, dohpath: dohpath, address: address.to_s, ip: ip)
data/lib/ddig/ip.rb ADDED
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ddig
4
+ class Ip
5
+ attr_reader :ip_type
6
+
7
+ def initialize(use_ipv4: nil, use_ipv6: nil)
8
+ @use_ipv4 = use_ipv4
9
+ @use_ipv6 = use_ipv6
10
+
11
+ set_ip_type
12
+ end
13
+
14
+ def set_ip_type
15
+ if @use_ipv4.nil? && self.class.enable_ipv4?
16
+ @use_ipv4 = true
17
+ end
18
+
19
+ if @use_ipv6.nil? && self.class.enable_ipv6?
20
+ @use_ipv6 = true
21
+ end
22
+
23
+ if @use_ipv4 && @use_ipv6
24
+ @ip_type = :all
25
+ elsif @use_ipv4
26
+ @ip_type = :ipv4
27
+ elsif @use_ipv6
28
+ @ip_type = :ipv6
29
+ end
30
+ end
31
+
32
+ def self.enable_ipv4?
33
+ ip_list.any? { |addr| addr.ipv4? }
34
+ end
35
+
36
+ def self.enable_ipv6?
37
+ ip_list.any? { |addr| addr.ipv6? }
38
+ end
39
+
40
+ private
41
+
42
+ def self.ip_list
43
+ Socket.ip_address_list.map do |addrinfo|
44
+ if RUBY_VERSION < '3.1'
45
+ # for ipaddr gem <= v1.2.2, Not support zone identifiers in IPv6 addresses
46
+ addr = IPAddr.new(addrinfo.ip_address.split('%').first)
47
+ else
48
+ addr = IPAddr.new(addrinfo.ip_address)
49
+ end
50
+
51
+ if !addr.loopback? && !addr.link_local?
52
+ addr
53
+ end
54
+ end.compact
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,40 @@
1
+ require 'resolv'
2
+
3
+ module Ddig
4
+ module Resolver
5
+ class DnsMessage
6
+ def self.encode(hostname, typeclass)
7
+ if hostname.nil?
8
+ return nil
9
+ end
10
+ if typeclass.nil?
11
+ return nil
12
+ end
13
+
14
+ message = Resolv::DNS::Message.new
15
+ message.rd = 1 # recursive query
16
+ message.add_question(hostname, typeclass)
17
+
18
+ message.encode
19
+ end
20
+
21
+ def self.decode(payload)
22
+ if payload.nil?
23
+ return nil
24
+ end
25
+
26
+ Resolv::DNS::Message.decode(payload)
27
+ end
28
+
29
+ def self.getresources(payload)
30
+ if payload.nil?
31
+ return []
32
+ end
33
+
34
+ response = self.decode(payload)
35
+
36
+ return response.answer.map { |name, ttl, resource| resource }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ require 'net/http'
2
+ require 'resolv'
3
+ require 'base64'
4
+
5
+ require_relative 'dns_message'
6
+
7
+ module Ddig
8
+ module Resolver
9
+ # DNS over HTTPS (HTTP/1.1)
10
+ class DohH1
11
+ attr_reader :hostname, :server, :address, :dohpath, :port
12
+ attr_reader :a, :aaaa
13
+
14
+ def initialize(hostname:, server:, address: nil, dohpath:, port: 443)
15
+ @hostname = hostname
16
+ @server = server
17
+ @address = address
18
+ @dohpath = dohpath
19
+ @port = port || 443
20
+
21
+ @open_timeout = 10
22
+ end
23
+
24
+ def lookup
25
+ if @server.nil?
26
+ return nil
27
+ end
28
+
29
+ @a = get_resources(@hostname, Resolv::DNS::Resource::IN::A).map { |resource| resource.address.to_s if resource.is_a?(Resolv::DNS::Resource::IN::A) }.compact
30
+
31
+ @aaaa = get_resources(@hostname, Resolv::DNS::Resource::IN::AAAA).map { |resource| resource.address.to_s if resource.is_a?(Resolv::DNS::Resource::IN::AAAA) }.compact
32
+
33
+ self
34
+ end
35
+
36
+ def get_resources(hostname, typeclass)
37
+ # send query
38
+ payload = DnsMessage.encode(hostname, typeclass)
39
+
40
+ path_with_query = @dohpath.gsub('{?dns}', '?dns=' + Base64.urlsafe_encode64(payload, padding: false))
41
+
42
+ http_response = Net::HTTP.start(@server, @port, use_ssl: true, ipaddr: @address) do |http|
43
+ header = {}
44
+ header['Accept'] = 'application/dns-message'
45
+ #http.open_timeout = @open_timeout
46
+
47
+ http.get(path_with_query, header)
48
+ end
49
+
50
+ case http_response
51
+ when Net::HTTPSuccess
52
+ # recive answer
53
+ return DnsMessage.getresources(http_response.body)
54
+ else
55
+ http_response.value
56
+ return []
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,6 +1,8 @@
1
1
  require 'openssl'
2
2
  require 'resolv'
3
3
 
4
+ require_relative 'dns_message'
5
+
4
6
  module Ddig
5
7
  module Resolver
6
8
  # DNS over TLS/TCP
@@ -12,7 +14,7 @@ module Ddig
12
14
  @hostname = hostname
13
15
  @server = server
14
16
  @server_name = server_name
15
- @port = port
17
+ @port = port || 853
16
18
 
17
19
  @open_timeout = 3
18
20
  end
@@ -33,16 +35,14 @@ module Ddig
33
35
  ssl_socket = get_socket
34
36
 
35
37
  # send query
36
- message = dns_message(hostname, typeclass)
38
+ payload = DnsMessage.encode(hostname, typeclass)
39
+ request = [payload.length].pack('n') + payload
37
40
 
38
- request = [message.encode.length].pack('n') + message.encode
39
41
  ssl_socket.write(request)
40
42
 
41
43
  # recive answer
42
44
  len = ssl_socket.read(2).unpack1('n')
43
- response = Resolv::DNS::Message.decode(ssl_socket.read(len))
44
-
45
- resources = response.answer.map { |name, ttl, resource| resource }
45
+ resources = DnsMessage.getresources(ssl_socket.read(len))
46
46
 
47
47
  resources
48
48
  end
@@ -74,21 +74,6 @@ module Ddig
74
74
  ssl_socket
75
75
  end
76
76
  end
77
-
78
- def dns_message(hostname, typeclass)
79
- if hostname.nil?
80
- return nil
81
- end
82
- if typeclass.nil?
83
- return nil
84
- end
85
-
86
- message = Resolv::DNS::Message.new
87
- message.rd = 1 # recursive query
88
- message.add_question(hostname, typeclass)
89
-
90
- message
91
- end
92
77
  end
93
78
  end
94
79
  end
data/lib/ddig/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ddig
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/ddig.rb CHANGED
@@ -2,23 +2,28 @@
2
2
 
3
3
  require_relative "ddig/version"
4
4
  require_relative "ddig/nameserver"
5
+ require_relative "ddig/ip"
5
6
  require_relative "ddig/resolver/do53"
6
7
  require_relative "ddig/resolver/dot"
8
+ require_relative "ddig/resolver/doh_h1"
7
9
  require_relative "ddig/ddr"
8
10
 
9
11
  module Ddig
10
12
  class Error < StandardError; end
11
13
 
12
- def self.lookup(hostname, nameservers: nil)
14
+ def self.lookup(hostname, nameservers: nil, use_ipv4: nil, use_ipv6: nil)
13
15
  @hostname = hostname
14
16
  @nameservers = nameservers
17
+ @use_ipv4 = use_ipv4
18
+ @use_ipv6 = use_ipv6
15
19
 
16
20
  @nameserver = Ddig::Nameserver.new(nameservers: @nameservers)
21
+ @ip = Ddig::Ip.new(use_ipv4: @use_ipv4, use_ipv6: @use_ipv6)
17
22
 
18
- @do53_ipv4 = Ddig::Resolver::Do53.new(hostname: @hostname, nameservers: @nameserver.servers, ip: :ipv4).lookup
19
- @do53_ipv6 = Ddig::Resolver::Do53.new(hostname: @hostname, nameservers: @nameserver.servers, ip: :ipv6).lookup
23
+ @do53_ipv4 = Ddig::Resolver::Do53.new(hostname: @hostname, nameservers: @nameserver.servers, ip: :ipv4).lookup unless @ip.ip_type == :ipv6
24
+ @do53_ipv6 = Ddig::Resolver::Do53.new(hostname: @hostname, nameservers: @nameserver.servers, ip: :ipv6).lookup unless @ip.ip_type == :ipv4
20
25
 
21
- @ddr = Ddig::Ddr.new(nameservers: @nameservers)
26
+ @ddr = Ddig::Ddr.new(nameservers: @nameservers, ip: @ip.ip_type)
22
27
 
23
28
  {
24
29
  do53: {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taketo Takashima
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-16 00:00:00.000000000 Z
11
+ date: 2024-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: resolv
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.3.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: base64
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description: DNS lookup utility for Ruby
28
42
  email:
29
43
  - t.taketo1113@gmail.com
@@ -42,8 +56,11 @@ files:
42
56
  - lib/ddig/ddr.rb
43
57
  - lib/ddig/ddr/designated_resolver.rb
44
58
  - lib/ddig/ddr/verify_cert.rb
59
+ - lib/ddig/ip.rb
45
60
  - lib/ddig/nameserver.rb
61
+ - lib/ddig/resolver/dns_message.rb
46
62
  - lib/ddig/resolver/do53.rb
63
+ - lib/ddig/resolver/doh_h1.rb
47
64
  - lib/ddig/resolver/dot.rb
48
65
  - lib/ddig/version.rb
49
66
  - sig/ddig.rbs