gitlab-net-dns 0.12.0 → 0.15.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: 626fddeccebd199f0753f59a1f0da00bf17c923ab59863f6dcf4f1712e565aa9
4
- data.tar.gz: 266c1c5e8b273c3b09305cca8a96127b4d46bfe9396ceb103ef3278edef54101
3
+ metadata.gz: 74ee6c4e55aca3a4b262ef65ed15aa7eb4faefba46e236581313e600f488d4fb
4
+ data.tar.gz: c0737bd705ee060cb3e0cabd8f16985e24cbc9c32435ab7287435075a70c4532
5
5
  SHA512:
6
- metadata.gz: f17432960ab586b0e2d74dc9d3d8cdad69a477c050f20139038155825b4dcd116d41fa8b423203310fd88cd8510f49086db89d2fee372219eb72fe5d39a56cf1
7
- data.tar.gz: b357ac43e0927bccd981530f026f4af77f3a1da4d2263966621a9744a62781bf44f7438f383b404d3194f5a9f1f0f16ea490ac8116ad1299683aa5a408405af9
6
+ metadata.gz: 88cc517f05b54349d8cc62a597415e395888398e9d4557b1f9c8176b7dc1b98ab6b4683a82ca50909c37054c1e9bee076648eb637242db69d2ab94899577ea71
7
+ data.tar.gz: 9e4bfdd6c46a3e1e48449aa384561cd158c4e7580e01593d24f860900ffc708d789fbdfbc5f6b39ba35fdeccc2d5d3971e4f482e158792e16d56509d2d5b200d
data/.rubocop_todo.yml CHANGED
@@ -11,7 +11,7 @@
11
11
  # Include: **/*.gemspec
12
12
  Gemspec/RequiredRubyVersion:
13
13
  Exclude:
14
- - 'net-dns.gemspec'
14
+ - 'gitlab-net-dns.gemspec'
15
15
 
16
16
 
17
17
  # Offense count: 2
data/README.md CHANGED
@@ -17,16 +17,16 @@ Ruby >= 2.1
17
17
 
18
18
  ## Installation
19
19
 
20
- The best way to install this library is via [RubyGems](https://rubygems.org/).
20
+ The best way to install this library is via [RubyGems](https://rubygems.org/gems/gitlab-net-dns/).
21
21
 
22
22
  ```
23
- gem install net-dns
23
+ gem install gitlab-net-dns
24
24
  ```
25
25
 
26
26
 
27
27
  ## API Documentation
28
28
 
29
- Visit the page http://rdoc.info/gems/net-dns
29
+ Visit the page http://rdoc.info/gems/gitlab-net-dns
30
30
 
31
31
 
32
32
  ## Trivial resolver
@@ -92,7 +92,10 @@ module Net
92
92
  class NoResponseError < Error
93
93
  end
94
94
 
95
- # An hash with the defaults values of almost all the
95
+ class ResolverPermissionError < Error
96
+ end
97
+
98
+ # A hash with the default values of almost all the
96
99
  # configuration parameters of a resolver object. See
97
100
  # the description for each parameter to have an
98
101
  # explanation of its usage.
@@ -315,7 +318,16 @@ module Net
315
318
  # #=> ["192.168.0.1","192.168.0.2"]
316
319
  #
317
320
  def nameservers
318
- @config[:nameservers].map(&:to_s)
321
+ @config[:nameservers].map do |entry|
322
+ case entry
323
+ in IPAddr
324
+ entry.to_s
325
+ in [IPAddr]
326
+ [entry[0].to_s]
327
+ in [IPAddr, Integer]
328
+ [entry[0].to_s, entry[1]]
329
+ end
330
+ end
319
331
  end
320
332
 
321
333
  alias nameserver nameservers
@@ -326,48 +338,38 @@ module Net
326
338
  # res.nameservers = "192.168.0.1"
327
339
  # res.nameservers = ["192.168.0.1","192.168.0.2"]
328
340
  #
329
- # If you want you can specify the addresses as IPAddr instances.
341
+ # If you want, you can specify the addresses as IPAddr instances.
330
342
  #
331
- # ip = IPAddr.new("192.168.0.3")
332
- # res.nameservers << ip
333
- # #=> ["192.168.0.1","192.168.0.2","192.168.0.3"]
343
+ # res.nameservers = IPAddr.new("192.168.0.3")
334
344
  #
335
345
  # The default is 127.0.0.1 (localhost)
336
346
  #
337
347
  def nameservers=(arg)
338
- case arg
339
- when String
340
- begin
341
- @config[:nameservers] = [IPAddr.new(arg)]
342
- @logger.info "Nameservers list changed to value #{@config[:nameservers].inspect}"
343
- rescue ArgumentError # arg is in the name form, not IP
344
- nameservers_from_name(arg)
345
- end
346
- when IPAddr
347
- @config[:nameservers] = [arg]
348
- @logger.info "Nameservers list changed to value #{@config[:nameservers].inspect}"
349
- when Array
350
- @config[:nameservers] = []
351
- arg.each do |x|
352
- val = case x
353
- when String
354
- begin
355
- IPAddr.new(x)
356
- rescue ArgumentError
357
- nameservers_from_name(arg)
358
- return
359
- end
360
- when IPAddr
361
- x
362
- else
363
- raise ArgumentError, "Wrong argument format"
348
+ @config[:nameservers] = Array(arg).flat_map do |entry|
349
+ case entry
350
+ in String
351
+ begin
352
+ IPAddr.new(entry)
353
+ rescue ArgumentError
354
+ nameservers_from_name(entry)
364
355
  end
365
- @config[:nameservers] << val
356
+ in IPAddr
357
+ entry
358
+ in [String]
359
+ [[IPAddr.new(entry[0])]]
360
+ in [IPAddr]
361
+ [[entry[0]]]
362
+ in [String, Integer]
363
+ validate_port!(entry[1])
364
+ [[IPAddr.new(entry[0]), entry[1]]]
365
+ in [IPAddr, Integer]
366
+ validate_port!(entry[1])
367
+ [[entry[0], entry[1]]]
368
+ else
369
+ raise ArgumentError, "Wrong argument format, neither String, Array nor IPAddr"
366
370
  end
367
- @logger.info "Nameservers list changed to value #{@config[:nameservers].inspect}"
368
- else
369
- raise ArgumentError, "Wrong argument format, neither String, Array nor IPAddr"
370
371
  end
372
+ @logger.info "Nameservers list changed to value #{@config[:nameservers].inspect}"
371
373
  end
372
374
  alias_method("nameserver=", "nameservers=")
373
375
 
@@ -402,8 +404,7 @@ module Net
402
404
  # The default is port 53.
403
405
  #
404
406
  def port=(num)
405
- (0..65_535).cover?(num) or
406
- raise(ArgumentError, "Wrong port number #{num}")
407
+ validate_port!(num)
407
408
 
408
409
  @config[:port] = num
409
410
  @logger.info "Port number changed to #{num}"
@@ -422,7 +423,7 @@ module Net
422
423
  #
423
424
  # res.source_port = 40000
424
425
  #
425
- # Note that if you want to set a port you need root priviledges, as
426
+ # Note that if you want to set a port, you need root privileges, as
426
427
  # raw sockets will be used to generate packets. The class will then
427
428
  # generate the exception ResolverPermissionError if you're not root.
428
429
  #
@@ -430,10 +431,8 @@ module Net
430
431
  # underlaying layers.
431
432
  #
432
433
  def source_port=(num)
433
- root? or
434
- raise(ResolverPermissionError, "Are you root?")
435
- (0..65_535).cover?(num) or
436
- raise(ArgumentError, "Wrong port number #{num}")
434
+ raise(ResolverPermissionError, "Are you root?") unless root?
435
+ validate_port!(num)
437
436
 
438
437
  @config[:source_port] = num
439
438
  end
@@ -871,43 +870,6 @@ module Net
871
870
  query(name + ".", type, cls)
872
871
  end
873
872
 
874
- # Performs a DNS query for the given name; the search list
875
- # is not applied. If the name doesn't contain any dots and
876
- # +defname+ is true then the default domain will be appended.
877
- #
878
- # The record type and class can be omitted; they default to +A+
879
- # and +IN+. If the name looks like an IP address (IPv4 or IPv6),
880
- # then an appropriate PTR query will be performed.
881
- #
882
- # packet = res.query('mailhost')
883
- # packet = res.query('mailhost.example.com')
884
- # packet = res.query('example.com', Net::DNS::MX)
885
- # packet = res.query('user.passwd.example.com', Net::DNS::TXT, Net::DNS::HS)
886
- #
887
- # If the name is an IP address (Ipv4 or IPv6), in the form of a string
888
- # or a +IPAddr+ object, then an appropriate PTR query will be performed:
889
- #
890
- # ip = IPAddr.new("172.16.100.2")
891
- # packet = res.query(ip)
892
- # packet = res.query("192.168.10.254")
893
- #
894
- # Returns a Net::DNS::Packet object. If you need to examine the response
895
- # packet whether it contains any answers or not, use the Resolver#query
896
- # method instead.
897
- #
898
- def query(name, type = Net::DNS::A, cls = Net::DNS::IN)
899
- return send(name, type, cls) if name.class == IPAddr
900
-
901
- # If the name doesn't contain any dots then append the default domain.
902
- if name !~ /\./ && name !~ /:/ && @config[:defname]
903
- name += "." + @config[:domain]
904
- end
905
-
906
- @logger.debug "Query(#{name},#{Net::DNS::RR::Types.new(type)},#{Net::DNS::RR::Classes.new(cls)})"
907
-
908
- send(name, type, cls)
909
- end
910
-
911
873
  # Performs a DNS query for the given name. Neither the
912
874
  # searchlist nor the default domain will be appended.
913
875
  #
@@ -1293,11 +1255,9 @@ module Net
1293
1255
  # res.nameservers = "192.168.0.1"
1294
1256
  # res.nameservers = ["192.168.0.1","192.168.0.2"]
1295
1257
  #
1296
- # If you want you can specify the addresses as IPAddr instances.
1258
+ # If you want, you can specify the addresses as IPAddr instances.
1297
1259
  #
1298
- # ip = IPAddr.new("192.168.0.3")
1299
- # res.nameservers << ip
1300
- # #=> ["192.168.0.1","192.168.0.2","192.168.0.3"]
1260
+ # res.nameservers = IPAddr.new("192.168.0.3")
1301
1261
  #
1302
1262
  # The default is 127.0.0.1 (localhost)
1303
1263
  #
@@ -1639,7 +1599,7 @@ module Net
1639
1599
  arr << ip
1640
1600
  end
1641
1601
  end
1642
- @config[:nameservers] << arr
1602
+ arr
1643
1603
  end
1644
1604
 
1645
1605
  def make_query_packet(string, type, cls)
@@ -1675,20 +1635,21 @@ module Net
1675
1635
  ans = nil
1676
1636
  length = [packet_data.size].pack("n")
1677
1637
 
1678
- @config[:nameservers].each do |ns|
1638
+ nameserver_port_pairs.each do |(ns, ns_port)|
1679
1639
  begin
1680
1640
  buffer = ""
1681
1641
  socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
1682
1642
  socket.bind(Socket.pack_sockaddr_in(@config[:source_port], @config[:source_address].to_s))
1683
1643
 
1684
- sockaddr = Socket.pack_sockaddr_in(@config[:port], ns.to_s)
1644
+ sockaddr = Socket.pack_sockaddr_in(ns_port, ns.to_s)
1645
+ success = false
1685
1646
 
1686
1647
  @config[:tcp_timeout].timeout do
1687
1648
  socket.connect(sockaddr)
1688
- @logger.info "Contacting nameserver #{ns} port #{@config[:port]}"
1649
+ @logger.info "Contacting nameserver #{ns} port #{ns_port}"
1689
1650
  socket.write(length + packet_data)
1690
1651
  ans = socket.recv(Net::DNS::INT16SZ)
1691
- len = ans.unpack("n")[0]
1652
+ len = ans.unpack("n")[0].to_i
1692
1653
 
1693
1654
  @logger.info "Receiving #{len} bytes..."
1694
1655
 
@@ -1707,8 +1668,16 @@ module Net
1707
1668
  @logger.warn "Malformed packet from nameserver #{ns}, trying next."
1708
1669
  next
1709
1670
  end
1671
+
1672
+ success = true
1710
1673
  end
1711
- return [buffer, ["", @config[:port], ns.to_s, ns.to_s]]
1674
+
1675
+ # Return buffer and the socket "from" data:
1676
+ # from[0] - Address family as a string (e.g., "AF_INET" or "AF_INET6")
1677
+ # from[1] - Port number as an integer
1678
+ # from[2] - IP address as a string (e.g., "192.168.1.1" or "::1")
1679
+ # from[3] - IP address as a string (same as from[2])
1680
+ return [buffer, ["", ns_port, ns.to_s, ns.to_s]] if success
1712
1681
  rescue Timeout::Error
1713
1682
  @logger.warn "Nameserver #{ns} not responding within TCP timeout, trying next one"
1714
1683
  next
@@ -1716,7 +1685,8 @@ module Net
1716
1685
  socket.close
1717
1686
  end
1718
1687
  end
1719
- ans
1688
+
1689
+ nil
1720
1690
  end
1721
1691
 
1722
1692
  def query_udp(packet, packet_data)
@@ -1727,15 +1697,15 @@ module Net
1727
1697
 
1728
1698
  ans = nil
1729
1699
  response = ""
1730
- @config[:nameservers].each do |ns|
1700
+ nameserver_port_pairs.each do |(ns, ns_port)|
1731
1701
  begin
1732
1702
  @config[:udp_timeout].timeout do
1733
- @logger.info "Contacting nameserver #{ns} port #{@config[:port]}"
1703
+ @logger.info "Contacting nameserver #{ns} port #{ns_port}"
1734
1704
  ans = if ns.ipv6?
1735
- socket6.send(packet_data, 0, ns.to_s, @config[:port])
1705
+ socket6.send(packet_data, 0, ns.to_s, ns_port)
1736
1706
  socket6.recvfrom(@config[:packet_size])
1737
1707
  else
1738
- socket4.send(packet_data, 0, ns.to_s, @config[:port])
1708
+ socket4.send(packet_data, 0, ns.to_s, ns_port)
1739
1709
  socket4.recvfrom(@config[:packet_size])
1740
1710
  end
1741
1711
  end
@@ -1748,6 +1718,22 @@ module Net
1748
1718
  ans
1749
1719
  end
1750
1720
 
1721
+ def nameserver_port_pairs
1722
+ @config[:nameservers].map { |entry| Array(entry) }.map { |ns, ns_port| [ns, ns_port || port] }
1723
+ end
1724
+
1725
+ def validate_port!(port)
1726
+ raise(ArgumentError, "Wrong port number #{port}") unless valid_port?(port)
1727
+ end
1728
+
1729
+ def valid_port?(port)
1730
+ (0..65_535).cover?(port)
1731
+ end
1732
+
1733
+ def root?
1734
+ Process.euid == 0
1735
+ end
1736
+
1751
1737
  # FIXME: a ? method should never raise.
1752
1738
  def valid?(name)
1753
1739
  name !~ /[^-\w\.]/ or
@@ -3,6 +3,6 @@
3
3
  module Net
4
4
  module DNS
5
5
  # The current library version.
6
- VERSION = "0.12.0"
6
+ VERSION = "0.15.0"
7
7
  end
8
8
  end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require 'net/dns/resolver/timeouts'
3
+
4
+ describe Net::DNS::Resolver do
5
+ it 'executes UDP query' do
6
+ ipv4_sock = instance_double(UDPSocket, bind: 0, send: 0)
7
+ ipv6_sock = instance_double(UDPSocket, bind: 0)
8
+
9
+ google_com_a_record_response = [
10
+ "A\x06\x81\x80\x00\x01\x00\x01\x00\x00\x00\x00\x06google\x03com\x00\x00\x01\x00\x01\xC0\f\x00\x01\x00\x01\x00\x00\x00I\x00\x04\x8E\xFA\xBA\xCE",
11
+ ['AF_INET', 53, '8.8.8.8', '8.8.8.8']
12
+ ]
13
+ allow(ipv4_sock).to receive(:recvfrom).and_return(google_com_a_record_response)
14
+
15
+ allow(UDPSocket).to receive(:new).and_return(ipv4_sock)
16
+ allow(UDPSocket).to receive(:new).with(Socket::AF_INET6).and_return(ipv6_sock)
17
+
18
+ resolver = Net::DNS::Resolver.new(nameservers: %w[8.8.8.8])
19
+ response = resolver.query('google.com')
20
+
21
+ expect(response.answer[0].address.to_s).to eq('142.250.186.206')
22
+ expect(ipv4_sock).to have_received(:bind).with(instance_of(String), instance_of(Integer))
23
+ expect(ipv4_sock).to have_received(:send).with(instance_of(String), 0, '8.8.8.8', 53)
24
+ expect(ipv4_sock).to have_received(:recvfrom).with(instance_of(Integer))
25
+ end
26
+
27
+ it 'executes TCP query' do
28
+ sock = instance_double(Socket, bind: 0, connect: 0, write: 0, close: nil)
29
+
30
+ allow(sock).to receive(:recv).and_return("\x00,")
31
+ google_com_a_record_response = "%\xF9\x81\x80\x00\x01\x00\x01\x00\x00\x00\x00\x06google\x03com\x00\x00\x01\x00\x01\xC0\f\x00\x01\x00\x01\x00\x00\x00\xB3\x00\x04\x8E\xFA\xBA\xCE"
32
+ allow(sock).to receive(:recvfrom).and_return(google_com_a_record_response)
33
+
34
+ allow(Socket).to receive(:new).and_return(sock)
35
+
36
+ resolver = Net::DNS::Resolver.new(nameservers: %w[8.8.8.8], use_tcp: true)
37
+ response = resolver.query('google.com')
38
+
39
+ expect(response.answer[0].address.to_s).to eq('142.250.186.206')
40
+ expect(sock).to have_received(:bind).with(instance_of(String))
41
+ expect(sock).to have_received(:connect).with(Socket.pack_sockaddr_in(53, '8.8.8.8'))
42
+ expect(sock).to have_received(:write).with(instance_of(String))
43
+ expect(sock).to have_received(:recv)
44
+ expect(sock).to have_received(:recvfrom).with(instance_of(Integer))
45
+ expect(sock).to have_received(:close)
46
+ end
47
+ end
@@ -0,0 +1,80 @@
1
+ require 'test_helper'
2
+ require 'net/dns/resolver'
3
+
4
+ class TestDNSResolver < Minitest::Test
5
+ def setup
6
+ @resolver = Net::DNS::Resolver.new(
7
+ nameservers: ['8.8.8.8'],
8
+ port: 53,
9
+ source_address: IPAddr.new('0.0.0.0'),
10
+ tcp_timeout: 5,
11
+ udp_timeout: 5
12
+ )
13
+
14
+ # Sample DNS packet data
15
+ @packet_data = "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x06google\x03com\x00\x00\x01\x00\x01"
16
+ end
17
+
18
+ # Tests for query_tcp
19
+ def test_query_tcp_successful_response
20
+ mock_socket = Minitest::Mock.new
21
+
22
+ Socket.stub(:new, mock_socket) do
23
+ mock_socket.expect(:bind, nil, [String])
24
+ mock_socket.expect(:connect, nil, [String])
25
+ mock_socket.expect(:write, @packet_data.size + 2, [String])
26
+ mock_socket.expect(:recv, "\x00\x20", [2]) # Length = 32 bytes
27
+ mock_socket.expect(:recvfrom, ["A" * 32, nil], [32])
28
+ mock_socket.expect(:close, nil)
29
+
30
+ Socket.stub(:pack_sockaddr_in, "mock_sockaddr") do
31
+ result = @resolver.send(:query_tcp, @packet, @packet_data)
32
+
33
+ refute_nil result
34
+ assert_equal 2, result.size
35
+ assert_equal "A" * 32, result[0] # Response data
36
+ assert_equal ["", 53, "8.8.8.8", "8.8.8.8"], result[1] # From info
37
+ end
38
+ end
39
+
40
+ mock_socket.verify
41
+ end
42
+
43
+ def test_query_tcp_zero_length_response
44
+ mock_socket = Minitest::Mock.new
45
+
46
+ Socket.stub(:new, mock_socket) do
47
+ mock_socket.expect(:bind, nil, [String])
48
+ mock_socket.expect(:connect, nil, [String])
49
+ mock_socket.expect(:write, @packet_data.size + 2, [String])
50
+ mock_socket.expect(:recv, "\x00\x00", [2]) # Length = 0 bytes
51
+ mock_socket.expect(:close, nil)
52
+
53
+ Socket.stub(:pack_sockaddr_in, "mock_sockaddr") do
54
+ result = @resolver.send(:query_tcp, @packet, @packet_data)
55
+ assert_nil result # Should return nil for zero-length response
56
+ end
57
+ end
58
+
59
+ mock_socket.verify
60
+ end
61
+
62
+ def test_query_tcp_bogus_response
63
+ mock_socket = Minitest::Mock.new
64
+
65
+ Socket.stub(:new, mock_socket) do
66
+ mock_socket.expect(:bind, nil, [String])
67
+ mock_socket.expect(:connect, nil, [String])
68
+ mock_socket.expect(:write, @packet_data.size + 2, [String])
69
+ mock_socket.expect(:recv, "0", [2]) # Length = 0 bytes
70
+ mock_socket.expect(:close, nil)
71
+
72
+ Socket.stub(:pack_sockaddr_in, "mock_sockaddr") do
73
+ result = @resolver.send(:query_tcp, @packet, @packet_data)
74
+ assert_nil result # Should return nil for zero-length response
75
+ end
76
+ end
77
+
78
+ mock_socket.verify
79
+ end
80
+ end
@@ -25,6 +25,69 @@ class ResolverTest < Minitest::Test
25
25
  assert_raises(ArgumentError) { Net::DNS::Resolver.new(:foo) }
26
26
  end
27
27
 
28
+ def test_set_port
29
+ resolver = Net::DNS::Resolver.new
30
+ assert_equal 53, resolver.port
31
+
32
+ assert_raises(ArgumentError) { resolver.port = 100_000 }
33
+ assert_equal 53, resolver.port
34
+
35
+ resolver.port = 10_053
36
+ assert_equal 10_053, resolver.port
37
+ end
38
+
39
+ def test_set_source_port
40
+ resolver = Net::DNS::Resolver.new
41
+ assert_equal 0, resolver.source_port
42
+
43
+ resolver.stub :root?, false do
44
+ assert_raises(Net::DNS::Resolver::ResolverPermissionError) { resolver.source_port = 1 }
45
+ assert_equal 0, resolver.source_port
46
+ end
47
+
48
+ resolver.stub :root?, true do
49
+ assert_raises(ArgumentError) { resolver.source_port = 100_000 }
50
+ assert_equal 0, resolver.source_port
51
+
52
+ resolver.source_port = 1
53
+ assert_equal 1, resolver.source_port
54
+ end
55
+ end
56
+
57
+ def test_set_nameservers
58
+ resolver = Net::DNS::Resolver.new nameservers: '127.0.0.1'
59
+ assert_equal ['127.0.0.1'], resolver.nameservers
60
+
61
+ assert_raises(ArgumentError) { resolver.nameservers = 1 }
62
+ assert_equal ['127.0.0.1'], resolver.nameservers
63
+
64
+ assert_raises(ArgumentError) { resolver.nameservers = ['192.168.1.1', 1] }
65
+ assert_equal ['127.0.0.1'], resolver.nameservers
66
+
67
+ resolver.stub :nameservers_from_name, [IPAddr.new('192.168.1.1')] do
68
+ assert_raises(ArgumentError) { resolver.nameservers = ['test.com', 1] }
69
+ assert_equal ['127.0.0.1'], resolver.nameservers
70
+
71
+ resolver.nameservers = 'test.com'
72
+ assert_equal ['192.168.1.1'], resolver.nameservers
73
+
74
+ resolver.nameservers = ['test.com']
75
+ assert_equal ['192.168.1.1'], resolver.nameservers
76
+
77
+ resolver.nameservers = ['192.168.1.2', 'test.com', IPAddr.new('192.168.1.3')]
78
+ assert_equal ['192.168.1.2', '192.168.1.1', '192.168.1.3'], resolver.nameservers
79
+ end
80
+
81
+ resolver.nameservers = [['192.168.1.1', 30053], ['192.168.1.2'], '192.168.1.3']
82
+ assert_equal [['192.168.1.1', 30053], ['192.168.1.2'], '192.168.1.3'], resolver.nameservers
83
+
84
+ resolver.nameservers = [[IPAddr.new('192.168.1.1'), 30053], [IPAddr.new('192.168.1.2')], IPAddr.new('192.168.1.3')]
85
+ assert_equal [['192.168.1.1', 30053], ['192.168.1.2'], '192.168.1.3'], resolver.nameservers
86
+
87
+ assert_raises(ArgumentError) { resolver.nameservers = [['192.168.1.1', 100_000]] }
88
+ assert_raises(ArgumentError) { resolver.nameservers = [[IPAddr.new('192.168.1.2'), 100_000]] }
89
+ end
90
+
28
91
  def test_query_with_no_nameservers_should_raise_resolvererror
29
92
  assert_raises(Net::DNS::Resolver::Error) { Net::DNS::Resolver.new(nameservers: []).query("example.com") }
30
93
  end
@@ -75,6 +138,13 @@ class ResolverTest < Minitest::Test
75
138
  assert_equal Net::DNS::IN.to_i, packet.question.first.qClass.to_i
76
139
  end
77
140
 
141
+ def test_nameserver_port_pairs
142
+ resolver = Net::DNS::Resolver.new(nameservers: [['172.16.1.1', 30_053], ['172.16.1.2'], '172.16.1.3'])
143
+ nameserver_port_pairs = resolver.send(:nameserver_port_pairs)
144
+ assert_equal ['172.16.1.1', '172.16.1.2', '172.16.1.3'], nameserver_port_pairs.map(&:first).map(&:to_s)
145
+ assert_equal [30_053, 53, 53], nameserver_port_pairs.map(&:last)
146
+ end
147
+
78
148
  def test_should_return_state_without_exception
79
149
  res = Net::DNS::Resolver.new
80
150
  assert_nothing_raised { res.state }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-net-dns
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Ceresa
8
8
  - Simone Carletti
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-03 00:00:00.000000000 Z
11
+ date: 2025-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -122,7 +122,9 @@ files:
122
122
  - spec/unit/resolver/dns_timeout_spec.rb
123
123
  - spec/unit/resolver/tcp_timeout_spec.rb
124
124
  - spec/unit/resolver/udp_timeout_spec.rb
125
+ - spec/unit/resolver_spec.rb
125
126
  - test/test_helper.rb
127
+ - test/unit/dns_resolver_test.rb
126
128
  - test/unit/header_test.rb
127
129
  - test/unit/names_test.rb
128
130
  - test/unit/packet_test.rb
@@ -165,7 +167,9 @@ test_files:
165
167
  - spec/unit/resolver/dns_timeout_spec.rb
166
168
  - spec/unit/resolver/tcp_timeout_spec.rb
167
169
  - spec/unit/resolver/udp_timeout_spec.rb
170
+ - spec/unit/resolver_spec.rb
168
171
  - test/test_helper.rb
172
+ - test/unit/dns_resolver_test.rb
169
173
  - test/unit/header_test.rb
170
174
  - test/unit/names_test.rb
171
175
  - test/unit/packet_test.rb