ddig 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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