resolv 0.2.2 → 0.3.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: be8cc01e584a5861d458d566337d00aeafab62860c2170612c1df385df352f0d
4
- data.tar.gz: 4810a106bcf7e982c68c9e8a6a1ff19a5614deacbdabd6859b0d2078fba48c0d
3
+ metadata.gz: d76dc1156c60da694ce1f0a96165e6d5a7e29d662ad7140b443e9aa735082f31
4
+ data.tar.gz: 7b532fc449aff2e5a63cb6a31892a45da5b41b6090d454f94d3c3e5165c94271
5
5
  SHA512:
6
- metadata.gz: 5a8d2b5467bc3af582454742074a91f2d43dbeac233cf33c299541e8c208ff0ef31abe694e7d8b70d6aaf14793df90c7e6fbf976ddc3a989d627f12d59d7c1a7
7
- data.tar.gz: 2898499c18aae2c0f5700084e82cff594c60920e6d5a3782470e18a3001d101d602810b5aa423067be46099d05f144bf508c0d18ce5c7ef566c3f038906e3823
6
+ metadata.gz: 685ce620cc9c83f1d5827de0a374d71f98fbff7629256d2ab7ed65d66eee062a5bc081a869caba31aeb67b4c292ca6dfc53fa4d71180ce15dd82f39d6fb5992b
7
+ data.tar.gz: 9897929fbfc67bc3a8133d3d9b2f99e7c9350802cf86d4cc0d8f061f397393f91308d6d1d6d35e46d497a3beb7fcf6424dc47ae92d5f7f39e572ac04b2677409
@@ -3,15 +3,22 @@ name: test
3
3
  on: [push, pull_request]
4
4
 
5
5
  jobs:
6
+ ruby-versions:
7
+ uses: ruby/actions/.github/workflows/ruby_versions.yml@master
8
+ with:
9
+ engine: cruby
10
+ min_version: 2.5
11
+
6
12
  build:
13
+ needs: ruby-versions
7
14
  name: build (${{ matrix.ruby }} / ${{ matrix.os }})
8
15
  strategy:
9
16
  matrix:
10
- ruby: [ '3.0', 2.7, 2.6, 2.5, head ]
17
+ ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
11
18
  os: [ ubuntu-latest, macos-latest ]
12
19
  runs-on: ${{ matrix.os }}
13
20
  steps:
14
- - uses: actions/checkout@v3
21
+ - uses: actions/checkout@v4
15
22
  - name: Set up Ruby
16
23
  uses: ruby/setup-ruby@v1
17
24
  with:
data/.gitignore CHANGED
@@ -6,3 +6,5 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+
10
+ Gemfile.lock
data/Gemfile CHANGED
@@ -1,4 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
+ gemspec
4
+
3
5
  gem "rake"
4
6
  gem "test-unit"
7
+ gem "test-unit-ruby-core"
data/Rakefile CHANGED
@@ -7,11 +7,4 @@ Rake::TestTask.new(:test) do |t|
7
7
  t.test_files = FileList["test/**/test_*.rb"]
8
8
  end
9
9
 
10
- task :sync_tool do
11
- require 'fileutils'
12
- FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib"
13
- FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib"
14
- FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib"
15
- end
16
-
17
10
  task :default => :test
data/lib/resolv.rb CHANGED
@@ -37,6 +37,8 @@ end
37
37
 
38
38
  class Resolv
39
39
 
40
+ VERSION = "0.3.0"
41
+
40
42
  ##
41
43
  # Looks up the first IP address for +name+.
42
44
 
@@ -82,8 +84,8 @@ class Resolv
82
84
  ##
83
85
  # Creates a new Resolv using +resolvers+.
84
86
 
85
- def initialize(resolvers=[Hosts.new, DNS.new])
86
- @resolvers = resolvers
87
+ def initialize(resolvers=nil, use_ipv6: nil)
88
+ @resolvers = resolvers || [Hosts.new, DNS.new(DNS::Config.default_config_hash.merge(use_ipv6: use_ipv6))]
87
89
  end
88
90
 
89
91
  ##
@@ -196,7 +198,7 @@ class Resolv
196
198
  next unless addr
197
199
  @addr2name[addr] = [] unless @addr2name.include? addr
198
200
  @addr2name[addr] << hostname
199
- @addr2name[addr] += aliases
201
+ @addr2name[addr].concat(aliases)
200
202
  @name2addr[hostname] = [] unless @name2addr.include? hostname
201
203
  @name2addr[hostname] << addr
202
204
  aliases.each {|n|
@@ -310,6 +312,8 @@ class Resolv
310
312
  # String:: Path to a file using /etc/resolv.conf's format.
311
313
  # Hash:: Must contain :nameserver, :search and :ndots keys.
312
314
  # :nameserver_port can be used to specify port number of nameserver address.
315
+ # :raise_timeout_errors can be used to raise timeout errors
316
+ # as exceptions instead of treating the same as an NXDOMAIN response.
313
317
  #
314
318
  # The value of :nameserver should be an address string or
315
319
  # an array of address strings.
@@ -406,6 +410,11 @@ class Resolv
406
410
  end
407
411
 
408
412
  def use_ipv6? # :nodoc:
413
+ use_ipv6 = @config.use_ipv6?
414
+ unless use_ipv6.nil?
415
+ return use_ipv6
416
+ end
417
+
409
418
  begin
410
419
  list = Socket.ip_address_list
411
420
  rescue NotImplementedError
@@ -748,7 +757,7 @@ class Resolv
748
757
  next if @socks_hash[bind_host]
749
758
  begin
750
759
  sock = UDPSocket.new(af)
751
- rescue Errno::EAFNOSUPPORT
760
+ rescue Errno::EAFNOSUPPORT, Errno::EPROTONOSUPPORT
752
761
  next # The kernel doesn't support the address family.
753
762
  end
754
763
  @socks << sock
@@ -965,7 +974,7 @@ class Resolv
965
974
  next unless keyword
966
975
  case keyword
967
976
  when 'nameserver'
968
- nameserver += args
977
+ nameserver.concat(args)
969
978
  when 'domain'
970
979
  next if args.empty?
971
980
  search = [args[0]]
@@ -1004,6 +1013,7 @@ class Resolv
1004
1013
  @mutex.synchronize {
1005
1014
  unless @initialized
1006
1015
  @nameserver_port = []
1016
+ @use_ipv6 = nil
1007
1017
  @search = nil
1008
1018
  @ndots = 1
1009
1019
  case @config_info
@@ -1028,8 +1038,12 @@ class Resolv
1028
1038
  if config_hash.include? :nameserver_port
1029
1039
  @nameserver_port = config_hash[:nameserver_port].map {|ns, port| [ns, (port || Port)] }
1030
1040
  end
1041
+ if config_hash.include? :use_ipv6
1042
+ @use_ipv6 = config_hash[:use_ipv6]
1043
+ end
1031
1044
  @search = config_hash[:search] if config_hash.include? :search
1032
1045
  @ndots = config_hash[:ndots] if config_hash.include? :ndots
1046
+ @raise_timeout_errors = config_hash[:raise_timeout_errors]
1033
1047
 
1034
1048
  if @nameserver_port.empty?
1035
1049
  @nameserver_port << ['0.0.0.0', Port]
@@ -1083,6 +1097,10 @@ class Resolv
1083
1097
  @nameserver_port
1084
1098
  end
1085
1099
 
1100
+ def use_ipv6?
1101
+ @use_ipv6
1102
+ end
1103
+
1086
1104
  def generate_candidates(name)
1087
1105
  candidates = nil
1088
1106
  name = Name.create(name)
@@ -1116,6 +1134,7 @@ class Resolv
1116
1134
  def resolv(name)
1117
1135
  candidates = generate_candidates(name)
1118
1136
  timeouts = @timeouts || generate_timeouts
1137
+ timeout_error = false
1119
1138
  begin
1120
1139
  candidates.each {|candidate|
1121
1140
  begin
@@ -1127,11 +1146,13 @@ class Resolv
1127
1146
  end
1128
1147
  }
1129
1148
  }
1149
+ timeout_error = true
1130
1150
  raise ResolvError.new("DNS resolv timeout: #{name}")
1131
1151
  rescue NXDomain
1132
1152
  end
1133
1153
  }
1134
1154
  rescue ResolvError
1155
+ raise if @raise_timeout_errors && timeout_error
1135
1156
  end
1136
1157
  end
1137
1158
 
@@ -1487,14 +1508,14 @@ class Resolv
1487
1508
  }
1488
1509
  end
1489
1510
 
1490
- def put_name(d)
1491
- put_labels(d.to_a)
1511
+ def put_name(d, compress: true)
1512
+ put_labels(d.to_a, compress: compress)
1492
1513
  end
1493
1514
 
1494
- def put_labels(d)
1515
+ def put_labels(d, compress: true)
1495
1516
  d.each_index {|i|
1496
1517
  domain = d[i..-1]
1497
- if idx = @names[domain]
1518
+ if compress && idx = @names[domain]
1498
1519
  self.put_pack("n", 0xc000 | idx)
1499
1520
  return
1500
1521
  else
@@ -1518,13 +1539,15 @@ class Resolv
1518
1539
  id, flag, qdcount, ancount, nscount, arcount =
1519
1540
  msg.get_unpack('nnnnnn')
1520
1541
  o.id = id
1542
+ o.tc = (flag >> 9) & 1
1543
+ o.rcode = flag & 15
1544
+ return o unless o.tc.zero?
1545
+
1521
1546
  o.qr = (flag >> 15) & 1
1522
1547
  o.opcode = (flag >> 11) & 15
1523
1548
  o.aa = (flag >> 10) & 1
1524
- o.tc = (flag >> 9) & 1
1525
1549
  o.rd = (flag >> 8) & 1
1526
1550
  o.ra = (flag >> 7) & 1
1527
- o.rcode = flag & 15
1528
1551
  (1..qdcount).each {
1529
1552
  name, typeclass = msg.get_question
1530
1553
  o.add_question(name, typeclass)
@@ -1616,6 +1639,14 @@ class Resolv
1616
1639
  strings
1617
1640
  end
1618
1641
 
1642
+ def get_list
1643
+ [].tap do |values|
1644
+ while @index < @limit
1645
+ values << yield
1646
+ end
1647
+ end
1648
+ end
1649
+
1619
1650
  def get_name
1620
1651
  return Name.new(self.get_labels)
1621
1652
  end
@@ -1676,6 +1707,378 @@ class Resolv
1676
1707
  end
1677
1708
  end
1678
1709
 
1710
+ ##
1711
+ # SvcParams for service binding RRs. [RFC9460]
1712
+
1713
+ class SvcParams
1714
+ include Enumerable
1715
+
1716
+ ##
1717
+ # Create a list of SvcParams with the given initial content.
1718
+ #
1719
+ # +params+ has to be an enumerable of +SvcParam+s.
1720
+ # If its content has +SvcParam+s with the duplicate key,
1721
+ # the one appears last takes precedence.
1722
+
1723
+ def initialize(params = [])
1724
+ @params = {}
1725
+
1726
+ params.each do |param|
1727
+ add param
1728
+ end
1729
+ end
1730
+
1731
+ ##
1732
+ # Get SvcParam for the given +key+ in this list.
1733
+
1734
+ def [](key)
1735
+ @params[canonical_key(key)]
1736
+ end
1737
+
1738
+ ##
1739
+ # Get the number of SvcParams in this list.
1740
+
1741
+ def count
1742
+ @params.count
1743
+ end
1744
+
1745
+ ##
1746
+ # Get whether this list is empty.
1747
+
1748
+ def empty?
1749
+ @params.empty?
1750
+ end
1751
+
1752
+ ##
1753
+ # Add the SvcParam +param+ to this list, overwriting the existing one with the same key.
1754
+
1755
+ def add(param)
1756
+ @params[param.class.key_number] = param
1757
+ end
1758
+
1759
+ ##
1760
+ # Remove the +SvcParam+ with the given +key+ and return it.
1761
+
1762
+ def delete(key)
1763
+ @params.delete(canonical_key(key))
1764
+ end
1765
+
1766
+ ##
1767
+ # Enumerate the +SvcParam+s in this list.
1768
+
1769
+ def each(&block)
1770
+ return enum_for(:each) unless block
1771
+ @params.each_value(&block)
1772
+ end
1773
+
1774
+ def encode(msg) # :nodoc:
1775
+ @params.keys.sort.each do |key|
1776
+ msg.put_pack('n', key)
1777
+ msg.put_length16 do
1778
+ @params.fetch(key).encode(msg)
1779
+ end
1780
+ end
1781
+ end
1782
+
1783
+ def self.decode(msg) # :nodoc:
1784
+ params = msg.get_list do
1785
+ key, = msg.get_unpack('n')
1786
+ msg.get_length16 do
1787
+ SvcParam::ClassHash[key].decode(msg)
1788
+ end
1789
+ end
1790
+
1791
+ return self.new(params)
1792
+ end
1793
+
1794
+ private
1795
+
1796
+ def canonical_key(key) # :nodoc:
1797
+ case key
1798
+ when Integer
1799
+ key
1800
+ when /\Akey(\d+)\z/
1801
+ Integer($1)
1802
+ when Symbol
1803
+ SvcParam::ClassHash[key].key_number
1804
+ else
1805
+ raise TypeError, 'key must be either String or Symbol'
1806
+ end
1807
+ end
1808
+ end
1809
+
1810
+
1811
+ ##
1812
+ # Base class for SvcParam. [RFC9460]
1813
+
1814
+ class SvcParam
1815
+
1816
+ ##
1817
+ # Get the presentation name of the SvcParamKey.
1818
+
1819
+ def self.key_name
1820
+ const_get(:KeyName)
1821
+ end
1822
+
1823
+ ##
1824
+ # Get the registered number of the SvcParamKey.
1825
+
1826
+ def self.key_number
1827
+ const_get(:KeyNumber)
1828
+ end
1829
+
1830
+ ClassHash = Hash.new do |h, key| # :nodoc:
1831
+ case key
1832
+ when Integer
1833
+ Generic.create(key)
1834
+ when /\Akey(?<key>\d+)\z/
1835
+ Generic.create(key.to_int)
1836
+ when Symbol
1837
+ raise KeyError, "unknown key #{key}"
1838
+ else
1839
+ raise TypeError, 'key must be either String or Symbol'
1840
+ end
1841
+ end
1842
+
1843
+ ##
1844
+ # Generic SvcParam abstract class.
1845
+
1846
+ class Generic < SvcParam
1847
+
1848
+ ##
1849
+ # SvcParamValue in wire-format byte string.
1850
+
1851
+ attr_reader :value
1852
+
1853
+ ##
1854
+ # Create generic SvcParam
1855
+
1856
+ def initialize(value)
1857
+ @value = value
1858
+ end
1859
+
1860
+ def encode(msg) # :nodoc:
1861
+ msg.put_bytes(@value)
1862
+ end
1863
+
1864
+ def self.decode(msg) # :nodoc:
1865
+ return self.new(msg.get_bytes)
1866
+ end
1867
+
1868
+ def self.create(key_number)
1869
+ c = Class.new(Generic)
1870
+ key_name = :"key#{key_number}"
1871
+ c.const_set(:KeyName, key_name)
1872
+ c.const_set(:KeyNumber, key_number)
1873
+ self.const_set(:"Key#{key_number}", c)
1874
+ ClassHash[key_name] = ClassHash[key_number] = c
1875
+ return c
1876
+ end
1877
+ end
1878
+
1879
+ ##
1880
+ # "mandatory" SvcParam -- Mandatory keys in service binding RR
1881
+
1882
+ class Mandatory < SvcParam
1883
+ KeyName = :mandatory
1884
+ KeyNumber = 0
1885
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
1886
+
1887
+ ##
1888
+ # Mandatory keys.
1889
+
1890
+ attr_reader :keys
1891
+
1892
+ ##
1893
+ # Initialize "mandatory" ScvParam.
1894
+
1895
+ def initialize(keys)
1896
+ @keys = keys.map(&:to_int)
1897
+ end
1898
+
1899
+ def encode(msg) # :nodoc:
1900
+ @keys.sort.each do |key|
1901
+ msg.put_pack('n', key)
1902
+ end
1903
+ end
1904
+
1905
+ def self.decode(msg) # :nodoc:
1906
+ keys = msg.get_list { msg.get_unpack('n')[0] }
1907
+ return self.new(keys)
1908
+ end
1909
+ end
1910
+
1911
+ ##
1912
+ # "alpn" SvcParam -- Additional supported protocols
1913
+
1914
+ class ALPN < SvcParam
1915
+ KeyName = :alpn
1916
+ KeyNumber = 1
1917
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
1918
+
1919
+ ##
1920
+ # Supported protocol IDs.
1921
+
1922
+ attr_reader :protocol_ids
1923
+
1924
+ ##
1925
+ # Initialize "alpn" ScvParam.
1926
+
1927
+ def initialize(protocol_ids)
1928
+ @protocol_ids = protocol_ids.map(&:to_str)
1929
+ end
1930
+
1931
+ def encode(msg) # :nodoc:
1932
+ msg.put_string_list(@protocol_ids)
1933
+ end
1934
+
1935
+ def self.decode(msg) # :nodoc:
1936
+ return self.new(msg.get_string_list)
1937
+ end
1938
+ end
1939
+
1940
+ ##
1941
+ # "no-default-alpn" SvcParam -- No support for default protocol
1942
+
1943
+ class NoDefaultALPN < SvcParam
1944
+ KeyName = :'no-default-alpn'
1945
+ KeyNumber = 2
1946
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
1947
+
1948
+ def encode(msg) # :nodoc:
1949
+ # no payload
1950
+ end
1951
+
1952
+ def self.decode(msg) # :nodoc:
1953
+ return self.new
1954
+ end
1955
+ end
1956
+
1957
+ ##
1958
+ # "port" SvcParam -- Port for alternative endpoint
1959
+
1960
+ class Port < SvcParam
1961
+ KeyName = :port
1962
+ KeyNumber = 3
1963
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
1964
+
1965
+ ##
1966
+ # Port number.
1967
+
1968
+ attr_reader :port
1969
+
1970
+ ##
1971
+ # Initialize "port" ScvParam.
1972
+
1973
+ def initialize(port)
1974
+ @port = port.to_int
1975
+ end
1976
+
1977
+ def encode(msg) # :nodoc:
1978
+ msg.put_pack('n', @port)
1979
+ end
1980
+
1981
+ def self.decode(msg) # :nodoc:
1982
+ port, = msg.get_unpack('n')
1983
+ return self.new(port)
1984
+ end
1985
+ end
1986
+
1987
+ ##
1988
+ # "ipv4hint" SvcParam -- IPv4 address hints
1989
+
1990
+ class IPv4Hint < SvcParam
1991
+ KeyName = :ipv4hint
1992
+ KeyNumber = 4
1993
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
1994
+
1995
+ ##
1996
+ # Set of IPv4 addresses.
1997
+
1998
+ attr_reader :addresses
1999
+
2000
+ ##
2001
+ # Initialize "ipv4hint" ScvParam.
2002
+
2003
+ def initialize(addresses)
2004
+ @addresses = addresses.map {|address| IPv4.create(address) }
2005
+ end
2006
+
2007
+ def encode(msg) # :nodoc:
2008
+ @addresses.each do |address|
2009
+ msg.put_bytes(address.address)
2010
+ end
2011
+ end
2012
+
2013
+ def self.decode(msg) # :nodoc:
2014
+ addresses = msg.get_list { IPv4.new(msg.get_bytes(4)) }
2015
+ return self.new(addresses)
2016
+ end
2017
+ end
2018
+
2019
+ ##
2020
+ # "ipv6hint" SvcParam -- IPv6 address hints
2021
+
2022
+ class IPv6Hint < SvcParam
2023
+ KeyName = :ipv6hint
2024
+ KeyNumber = 6
2025
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
2026
+
2027
+ ##
2028
+ # Set of IPv6 addresses.
2029
+
2030
+ attr_reader :addresses
2031
+
2032
+ ##
2033
+ # Initialize "ipv6hint" ScvParam.
2034
+
2035
+ def initialize(addresses)
2036
+ @addresses = addresses.map {|address| IPv6.create(address) }
2037
+ end
2038
+
2039
+ def encode(msg) # :nodoc:
2040
+ @addresses.each do |address|
2041
+ msg.put_bytes(address.address)
2042
+ end
2043
+ end
2044
+
2045
+ def self.decode(msg) # :nodoc:
2046
+ addresses = msg.get_list { IPv6.new(msg.get_bytes(16)) }
2047
+ return self.new(addresses)
2048
+ end
2049
+ end
2050
+
2051
+ ##
2052
+ # "dohpath" SvcParam -- DNS over HTTPS path template [RFC9461]
2053
+
2054
+ class DoHPath < SvcParam
2055
+ KeyName = :dohpath
2056
+ KeyNumber = 7
2057
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
2058
+
2059
+ ##
2060
+ # URI template for DoH queries.
2061
+
2062
+ attr_reader :template
2063
+
2064
+ ##
2065
+ # Initialize "dohpath" ScvParam.
2066
+
2067
+ def initialize(template)
2068
+ @template = template.encode('utf-8')
2069
+ end
2070
+
2071
+ def encode(msg) # :nodoc:
2072
+ msg.put_bytes(@template)
2073
+ end
2074
+
2075
+ def self.decode(msg) # :nodoc:
2076
+ template = msg.get_bytes.force_encoding('utf-8')
2077
+ return self.new(template)
2078
+ end
2079
+ end
2080
+ end
2081
+
1679
2082
  ##
1680
2083
  # A DNS query abstract class.
1681
2084
 
@@ -2328,7 +2731,7 @@ class Resolv
2328
2731
  msg.put_pack("n", @priority)
2329
2732
  msg.put_pack("n", @weight)
2330
2733
  msg.put_pack("n", @port)
2331
- msg.put_name(@target)
2734
+ msg.put_name(@target, compress: false)
2332
2735
  end
2333
2736
 
2334
2737
  def self.decode_rdata(msg) # :nodoc:
@@ -2339,6 +2742,84 @@ class Resolv
2339
2742
  return self.new(priority, weight, port, target)
2340
2743
  end
2341
2744
  end
2745
+
2746
+ ##
2747
+ # Common implementation for SVCB-compatible resource records.
2748
+
2749
+ class ServiceBinding
2750
+
2751
+ ##
2752
+ # Create a service binding resource record.
2753
+
2754
+ def initialize(priority, target, params = [])
2755
+ @priority = priority.to_int
2756
+ @target = Name.create(target)
2757
+ @params = SvcParams.new(params)
2758
+ end
2759
+
2760
+ ##
2761
+ # The priority of this target host.
2762
+ #
2763
+ # The range is 0-65535.
2764
+ # If set to 0, this RR is in AliasMode. Otherwise, it is in ServiceMode.
2765
+
2766
+ attr_reader :priority
2767
+
2768
+ ##
2769
+ # The domain name of the target host.
2770
+
2771
+ attr_reader :target
2772
+
2773
+ ##
2774
+ # The service paramters for the target host.
2775
+
2776
+ attr_reader :params
2777
+
2778
+ ##
2779
+ # Whether this RR is in AliasMode.
2780
+
2781
+ def alias_mode?
2782
+ self.priority == 0
2783
+ end
2784
+
2785
+ ##
2786
+ # Whether this RR is in ServiceMode.
2787
+
2788
+ def service_mode?
2789
+ !alias_mode?
2790
+ end
2791
+
2792
+ def encode_rdata(msg) # :nodoc:
2793
+ msg.put_pack("n", @priority)
2794
+ msg.put_name(@target, compress: false)
2795
+ @params.encode(msg)
2796
+ end
2797
+
2798
+ def self.decode_rdata(msg) # :nodoc:
2799
+ priority, = msg.get_unpack("n")
2800
+ target = msg.get_name
2801
+ params = SvcParams.decode(msg)
2802
+ return self.new(priority, target, params)
2803
+ end
2804
+ end
2805
+
2806
+ ##
2807
+ # SVCB resource record [RFC9460]
2808
+
2809
+ class SVCB < ServiceBinding
2810
+ TypeValue = 64
2811
+ ClassValue = IN::ClassValue
2812
+ ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
2813
+ end
2814
+
2815
+ ##
2816
+ # HTTPS resource record [RFC9460]
2817
+
2818
+ class HTTPS < ServiceBinding
2819
+ TypeValue = 65
2820
+ ClassValue = IN::ClassValue
2821
+ ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
2822
+ end
2342
2823
  end
2343
2824
  end
2344
2825
  end
@@ -2558,11 +3039,7 @@ class Resolv
2558
3039
  attr_reader :address
2559
3040
 
2560
3041
  def to_s # :nodoc:
2561
- address = sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *@address.unpack("nnnnnnnn"))
2562
- unless address.sub!(/(^|:)0(:0)+(:|$)/, '::')
2563
- address.sub!(/(^|:)0(:|$)/, '::')
2564
- end
2565
- return address
3042
+ sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *@address.unpack("nnnnnnnn")).sub(/(^|:)0(:0)+(:|$)/, '::')
2566
3043
  end
2567
3044
 
2568
3045
  def inspect # :nodoc:
data/resolv.gemspec CHANGED
@@ -1,6 +1,13 @@
1
+ name = File.basename(__FILE__, ".gemspec")
2
+ version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
3
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
4
+ /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
5
+ end rescue nil
6
+ end
7
+
1
8
  Gem::Specification.new do |spec|
2
- spec.name = "resolv"
3
- spec.version = "0.2.2"
9
+ spec.name = name
10
+ spec.version = version
4
11
  spec.authors = ["Tanaka Akira"]
5
12
  spec.email = ["akr@fsij.org"]
6
13
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resolv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanaka Akira
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-12-05 00:00:00.000000000 Z
11
+ date: 2023-12-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Thread-aware DNS resolver library in Ruby.
14
14
  email:
@@ -50,7 +50,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
50
50
  - !ruby/object:Gem::Version
51
51
  version: '0'
52
52
  requirements: []
53
- rubygems_version: 3.4.0.dev
53
+ rubygems_version: 3.5.0.dev
54
54
  signing_key:
55
55
  specification_version: 4
56
56
  summary: Thread-aware DNS resolver library in Ruby.