resolv 0.2.3 → 0.3.1

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: de34c7e32535d585b82bea070ca7b56a4b5d0bd27a9d50dbb871ab06c2421204
4
- data.tar.gz: e8122bbdfdc8462968355fe776aacd774928462017adfe73a92303640dff0acc
3
+ metadata.gz: 69d284d2efb6b6833a61ba3737c584fc67b18550e2e0f50b18f9125c259e6464
4
+ data.tar.gz: 8081d3d7396a29a6d359df59b6c52d25063074e1d5af285b333bc22dc59432ef
5
5
  SHA512:
6
- metadata.gz: 1446b793dbef8b7b8d3031780f5cab36e6bce49513d5f9cb8d5776d1ef6f7171bf460294355a34a0a19dc7dc24b3a93d29b7e1789939436f678b522dc48321be
7
- data.tar.gz: 043b12fa55d170a85b8c7e4a564effcae5983368359b0f403808f4c5818a20dcd21689892196e465b23a8682918bc1e032aa6ab7e12343283940bd3f84aac917
6
+ metadata.gz: 3b0fe1a7fa99005ce6771c792219b567e968b3ba3a40c63ae70eeabbc5766479e0577edfd6b4f8316f06c3d73a910423eebb29c32062addff564bcc1b905b501
7
+ data.tar.gz: 87b7cadc26a2f2bb95e78af53b3556de81ebd0b8890827b1c4b31de1780389a8b3f8d8780fdb991f79700977edd728e08d4ef65b32f7d130b903194dee209577
@@ -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.1"
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
@@ -1680,6 +1711,378 @@ class Resolv
1680
1711
  end
1681
1712
  end
1682
1713
 
1714
+ ##
1715
+ # SvcParams for service binding RRs. [RFC9460]
1716
+
1717
+ class SvcParams
1718
+ include Enumerable
1719
+
1720
+ ##
1721
+ # Create a list of SvcParams with the given initial content.
1722
+ #
1723
+ # +params+ has to be an enumerable of +SvcParam+s.
1724
+ # If its content has +SvcParam+s with the duplicate key,
1725
+ # the one appears last takes precedence.
1726
+
1727
+ def initialize(params = [])
1728
+ @params = {}
1729
+
1730
+ params.each do |param|
1731
+ add param
1732
+ end
1733
+ end
1734
+
1735
+ ##
1736
+ # Get SvcParam for the given +key+ in this list.
1737
+
1738
+ def [](key)
1739
+ @params[canonical_key(key)]
1740
+ end
1741
+
1742
+ ##
1743
+ # Get the number of SvcParams in this list.
1744
+
1745
+ def count
1746
+ @params.count
1747
+ end
1748
+
1749
+ ##
1750
+ # Get whether this list is empty.
1751
+
1752
+ def empty?
1753
+ @params.empty?
1754
+ end
1755
+
1756
+ ##
1757
+ # Add the SvcParam +param+ to this list, overwriting the existing one with the same key.
1758
+
1759
+ def add(param)
1760
+ @params[param.class.key_number] = param
1761
+ end
1762
+
1763
+ ##
1764
+ # Remove the +SvcParam+ with the given +key+ and return it.
1765
+
1766
+ def delete(key)
1767
+ @params.delete(canonical_key(key))
1768
+ end
1769
+
1770
+ ##
1771
+ # Enumerate the +SvcParam+s in this list.
1772
+
1773
+ def each(&block)
1774
+ return enum_for(:each) unless block
1775
+ @params.each_value(&block)
1776
+ end
1777
+
1778
+ def encode(msg) # :nodoc:
1779
+ @params.keys.sort.each do |key|
1780
+ msg.put_pack('n', key)
1781
+ msg.put_length16 do
1782
+ @params.fetch(key).encode(msg)
1783
+ end
1784
+ end
1785
+ end
1786
+
1787
+ def self.decode(msg) # :nodoc:
1788
+ params = msg.get_list do
1789
+ key, = msg.get_unpack('n')
1790
+ msg.get_length16 do
1791
+ SvcParam::ClassHash[key].decode(msg)
1792
+ end
1793
+ end
1794
+
1795
+ return self.new(params)
1796
+ end
1797
+
1798
+ private
1799
+
1800
+ def canonical_key(key) # :nodoc:
1801
+ case key
1802
+ when Integer
1803
+ key
1804
+ when /\Akey(\d+)\z/
1805
+ Integer($1)
1806
+ when Symbol
1807
+ SvcParam::ClassHash[key].key_number
1808
+ else
1809
+ raise TypeError, 'key must be either String or Symbol'
1810
+ end
1811
+ end
1812
+ end
1813
+
1814
+
1815
+ ##
1816
+ # Base class for SvcParam. [RFC9460]
1817
+
1818
+ class SvcParam
1819
+
1820
+ ##
1821
+ # Get the presentation name of the SvcParamKey.
1822
+
1823
+ def self.key_name
1824
+ const_get(:KeyName)
1825
+ end
1826
+
1827
+ ##
1828
+ # Get the registered number of the SvcParamKey.
1829
+
1830
+ def self.key_number
1831
+ const_get(:KeyNumber)
1832
+ end
1833
+
1834
+ ClassHash = Hash.new do |h, key| # :nodoc:
1835
+ case key
1836
+ when Integer
1837
+ Generic.create(key)
1838
+ when /\Akey(?<key>\d+)\z/
1839
+ Generic.create(key.to_int)
1840
+ when Symbol
1841
+ raise KeyError, "unknown key #{key}"
1842
+ else
1843
+ raise TypeError, 'key must be either String or Symbol'
1844
+ end
1845
+ end
1846
+
1847
+ ##
1848
+ # Generic SvcParam abstract class.
1849
+
1850
+ class Generic < SvcParam
1851
+
1852
+ ##
1853
+ # SvcParamValue in wire-format byte string.
1854
+
1855
+ attr_reader :value
1856
+
1857
+ ##
1858
+ # Create generic SvcParam
1859
+
1860
+ def initialize(value)
1861
+ @value = value
1862
+ end
1863
+
1864
+ def encode(msg) # :nodoc:
1865
+ msg.put_bytes(@value)
1866
+ end
1867
+
1868
+ def self.decode(msg) # :nodoc:
1869
+ return self.new(msg.get_bytes)
1870
+ end
1871
+
1872
+ def self.create(key_number)
1873
+ c = Class.new(Generic)
1874
+ key_name = :"key#{key_number}"
1875
+ c.const_set(:KeyName, key_name)
1876
+ c.const_set(:KeyNumber, key_number)
1877
+ self.const_set(:"Key#{key_number}", c)
1878
+ ClassHash[key_name] = ClassHash[key_number] = c
1879
+ return c
1880
+ end
1881
+ end
1882
+
1883
+ ##
1884
+ # "mandatory" SvcParam -- Mandatory keys in service binding RR
1885
+
1886
+ class Mandatory < SvcParam
1887
+ KeyName = :mandatory
1888
+ KeyNumber = 0
1889
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
1890
+
1891
+ ##
1892
+ # Mandatory keys.
1893
+
1894
+ attr_reader :keys
1895
+
1896
+ ##
1897
+ # Initialize "mandatory" ScvParam.
1898
+
1899
+ def initialize(keys)
1900
+ @keys = keys.map(&:to_int)
1901
+ end
1902
+
1903
+ def encode(msg) # :nodoc:
1904
+ @keys.sort.each do |key|
1905
+ msg.put_pack('n', key)
1906
+ end
1907
+ end
1908
+
1909
+ def self.decode(msg) # :nodoc:
1910
+ keys = msg.get_list { msg.get_unpack('n')[0] }
1911
+ return self.new(keys)
1912
+ end
1913
+ end
1914
+
1915
+ ##
1916
+ # "alpn" SvcParam -- Additional supported protocols
1917
+
1918
+ class ALPN < SvcParam
1919
+ KeyName = :alpn
1920
+ KeyNumber = 1
1921
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
1922
+
1923
+ ##
1924
+ # Supported protocol IDs.
1925
+
1926
+ attr_reader :protocol_ids
1927
+
1928
+ ##
1929
+ # Initialize "alpn" ScvParam.
1930
+
1931
+ def initialize(protocol_ids)
1932
+ @protocol_ids = protocol_ids.map(&:to_str)
1933
+ end
1934
+
1935
+ def encode(msg) # :nodoc:
1936
+ msg.put_string_list(@protocol_ids)
1937
+ end
1938
+
1939
+ def self.decode(msg) # :nodoc:
1940
+ return self.new(msg.get_string_list)
1941
+ end
1942
+ end
1943
+
1944
+ ##
1945
+ # "no-default-alpn" SvcParam -- No support for default protocol
1946
+
1947
+ class NoDefaultALPN < SvcParam
1948
+ KeyName = :'no-default-alpn'
1949
+ KeyNumber = 2
1950
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
1951
+
1952
+ def encode(msg) # :nodoc:
1953
+ # no payload
1954
+ end
1955
+
1956
+ def self.decode(msg) # :nodoc:
1957
+ return self.new
1958
+ end
1959
+ end
1960
+
1961
+ ##
1962
+ # "port" SvcParam -- Port for alternative endpoint
1963
+
1964
+ class Port < SvcParam
1965
+ KeyName = :port
1966
+ KeyNumber = 3
1967
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
1968
+
1969
+ ##
1970
+ # Port number.
1971
+
1972
+ attr_reader :port
1973
+
1974
+ ##
1975
+ # Initialize "port" ScvParam.
1976
+
1977
+ def initialize(port)
1978
+ @port = port.to_int
1979
+ end
1980
+
1981
+ def encode(msg) # :nodoc:
1982
+ msg.put_pack('n', @port)
1983
+ end
1984
+
1985
+ def self.decode(msg) # :nodoc:
1986
+ port, = msg.get_unpack('n')
1987
+ return self.new(port)
1988
+ end
1989
+ end
1990
+
1991
+ ##
1992
+ # "ipv4hint" SvcParam -- IPv4 address hints
1993
+
1994
+ class IPv4Hint < SvcParam
1995
+ KeyName = :ipv4hint
1996
+ KeyNumber = 4
1997
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
1998
+
1999
+ ##
2000
+ # Set of IPv4 addresses.
2001
+
2002
+ attr_reader :addresses
2003
+
2004
+ ##
2005
+ # Initialize "ipv4hint" ScvParam.
2006
+
2007
+ def initialize(addresses)
2008
+ @addresses = addresses.map {|address| IPv4.create(address) }
2009
+ end
2010
+
2011
+ def encode(msg) # :nodoc:
2012
+ @addresses.each do |address|
2013
+ msg.put_bytes(address.address)
2014
+ end
2015
+ end
2016
+
2017
+ def self.decode(msg) # :nodoc:
2018
+ addresses = msg.get_list { IPv4.new(msg.get_bytes(4)) }
2019
+ return self.new(addresses)
2020
+ end
2021
+ end
2022
+
2023
+ ##
2024
+ # "ipv6hint" SvcParam -- IPv6 address hints
2025
+
2026
+ class IPv6Hint < SvcParam
2027
+ KeyName = :ipv6hint
2028
+ KeyNumber = 6
2029
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
2030
+
2031
+ ##
2032
+ # Set of IPv6 addresses.
2033
+
2034
+ attr_reader :addresses
2035
+
2036
+ ##
2037
+ # Initialize "ipv6hint" ScvParam.
2038
+
2039
+ def initialize(addresses)
2040
+ @addresses = addresses.map {|address| IPv6.create(address) }
2041
+ end
2042
+
2043
+ def encode(msg) # :nodoc:
2044
+ @addresses.each do |address|
2045
+ msg.put_bytes(address.address)
2046
+ end
2047
+ end
2048
+
2049
+ def self.decode(msg) # :nodoc:
2050
+ addresses = msg.get_list { IPv6.new(msg.get_bytes(16)) }
2051
+ return self.new(addresses)
2052
+ end
2053
+ end
2054
+
2055
+ ##
2056
+ # "dohpath" SvcParam -- DNS over HTTPS path template [RFC9461]
2057
+
2058
+ class DoHPath < SvcParam
2059
+ KeyName = :dohpath
2060
+ KeyNumber = 7
2061
+ ClassHash[KeyName] = ClassHash[KeyNumber] = self # :nodoc:
2062
+
2063
+ ##
2064
+ # URI template for DoH queries.
2065
+
2066
+ attr_reader :template
2067
+
2068
+ ##
2069
+ # Initialize "dohpath" ScvParam.
2070
+
2071
+ def initialize(template)
2072
+ @template = template.encode('utf-8')
2073
+ end
2074
+
2075
+ def encode(msg) # :nodoc:
2076
+ msg.put_bytes(@template)
2077
+ end
2078
+
2079
+ def self.decode(msg) # :nodoc:
2080
+ template = msg.get_bytes.force_encoding('utf-8')
2081
+ return self.new(template)
2082
+ end
2083
+ end
2084
+ end
2085
+
1683
2086
  ##
1684
2087
  # A DNS query abstract class.
1685
2088
 
@@ -2332,7 +2735,7 @@ class Resolv
2332
2735
  msg.put_pack("n", @priority)
2333
2736
  msg.put_pack("n", @weight)
2334
2737
  msg.put_pack("n", @port)
2335
- msg.put_name(@target)
2738
+ msg.put_name(@target, compress: false)
2336
2739
  end
2337
2740
 
2338
2741
  def self.decode_rdata(msg) # :nodoc:
@@ -2343,6 +2746,84 @@ class Resolv
2343
2746
  return self.new(priority, weight, port, target)
2344
2747
  end
2345
2748
  end
2749
+
2750
+ ##
2751
+ # Common implementation for SVCB-compatible resource records.
2752
+
2753
+ class ServiceBinding
2754
+
2755
+ ##
2756
+ # Create a service binding resource record.
2757
+
2758
+ def initialize(priority, target, params = [])
2759
+ @priority = priority.to_int
2760
+ @target = Name.create(target)
2761
+ @params = SvcParams.new(params)
2762
+ end
2763
+
2764
+ ##
2765
+ # The priority of this target host.
2766
+ #
2767
+ # The range is 0-65535.
2768
+ # If set to 0, this RR is in AliasMode. Otherwise, it is in ServiceMode.
2769
+
2770
+ attr_reader :priority
2771
+
2772
+ ##
2773
+ # The domain name of the target host.
2774
+
2775
+ attr_reader :target
2776
+
2777
+ ##
2778
+ # The service paramters for the target host.
2779
+
2780
+ attr_reader :params
2781
+
2782
+ ##
2783
+ # Whether this RR is in AliasMode.
2784
+
2785
+ def alias_mode?
2786
+ self.priority == 0
2787
+ end
2788
+
2789
+ ##
2790
+ # Whether this RR is in ServiceMode.
2791
+
2792
+ def service_mode?
2793
+ !alias_mode?
2794
+ end
2795
+
2796
+ def encode_rdata(msg) # :nodoc:
2797
+ msg.put_pack("n", @priority)
2798
+ msg.put_name(@target, compress: false)
2799
+ @params.encode(msg)
2800
+ end
2801
+
2802
+ def self.decode_rdata(msg) # :nodoc:
2803
+ priority, = msg.get_unpack("n")
2804
+ target = msg.get_name
2805
+ params = SvcParams.decode(msg)
2806
+ return self.new(priority, target, params)
2807
+ end
2808
+ end
2809
+
2810
+ ##
2811
+ # SVCB resource record [RFC9460]
2812
+
2813
+ class SVCB < ServiceBinding
2814
+ TypeValue = 64
2815
+ ClassValue = IN::ClassValue
2816
+ ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
2817
+ end
2818
+
2819
+ ##
2820
+ # HTTPS resource record [RFC9460]
2821
+
2822
+ class HTTPS < ServiceBinding
2823
+ TypeValue = 65
2824
+ ClassValue = IN::ClassValue
2825
+ ClassHash[[TypeValue, ClassValue]] = self # :nodoc:
2826
+ end
2346
2827
  end
2347
2828
  end
2348
2829
  end
@@ -2562,11 +3043,7 @@ class Resolv
2562
3043
  attr_reader :address
2563
3044
 
2564
3045
  def to_s # :nodoc:
2565
- address = sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *@address.unpack("nnnnnnnn"))
2566
- unless address.sub!(/(^|:)0(:0)+(:|$)/, '::')
2567
- address.sub!(/(^|:)0(:|$)/, '::')
2568
- end
2569
- return address
3046
+ sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *@address.unpack("nnnnnnnn")).sub(/(^|:)0(:0)+(:|$)/, '::')
2570
3047
  end
2571
3048
 
2572
3049
  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.3"
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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resolv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanaka Akira