3333
3434class Gem ::Resolv
3535
36- VERSION = "0.6.0 "
36+ VERSION = "0.6.2 "
3737
3838 ##
3939 # Looks up the first IP address for +name+.
@@ -173,13 +173,16 @@ class ResolvError < StandardError; end
173173
174174 class ResolvTimeout < Gem ::Timeout ::Error ; end
175175
176+ WINDOWS = /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM || ::RbConfig ::CONFIG [ 'host_os' ] =~ /mswin/
177+ private_constant :WINDOWS
178+
176179 ##
177180 # Gem::Resolv::Hosts is a hostname resolver that uses the system hosts file.
178181
179182 class Hosts
180- if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM and
183+ if WINDOWS
181184 begin
182- require 'win32/resolv'
185+ require 'win32/resolv' unless defined? ( Win32 :: Resolv )
183186 DefaultFileName = Win32 ::Resolv . get_hosts_path || IO ::NULL
184187 rescue LoadError
185188 end
@@ -659,8 +662,20 @@ def self.free_request_id(host, port, id) # :nodoc:
659662 }
660663 end
661664
662- def self . bind_random_port ( udpsock , bind_host = "0.0.0.0" ) # :nodoc:
663- begin
665+ case RUBY_PLATFORM
666+ when *[
667+ # https://www.rfc-editor.org/rfc/rfc6056.txt
668+ # Appendix A. Survey of the Algorithms in Use by Some Popular Implementations
669+ /freebsd/ , /linux/ , /netbsd/ , /openbsd/ , /solaris/ ,
670+ /darwin/ , # the same as FreeBSD
671+ ] then
672+ def self . bind_random_port ( udpsock , bind_host = "0.0.0.0" ) # :nodoc:
673+ udpsock . bind ( bind_host , 0 )
674+ end
675+ else
676+ # Sequential port assignment
677+ def self . bind_random_port ( udpsock , bind_host = "0.0.0.0" ) # :nodoc:
678+ # Ephemeral port number range recommended by RFC 6056
664679 port = random ( 1024 ..65535 )
665680 udpsock . bind ( bind_host , port )
666681 rescue Errno ::EADDRINUSE , # POSIX
@@ -983,13 +998,13 @@ def Config.parse_resolv_conf(filename)
983998 next unless keyword
984999 case keyword
9851000 when 'nameserver'
986- nameserver . concat ( args )
1001+ nameserver . concat ( args . each ( & :freeze ) )
9871002 when 'domain'
9881003 next if args . empty?
989- search = [ args [ 0 ] ]
1004+ search = [ args [ 0 ] . freeze ]
9901005 when 'search'
9911006 next if args . empty?
992- search = args
1007+ search = args . each ( & :freeze )
9931008 when 'options'
9941009 args . each { |arg |
9951010 case arg
@@ -1000,22 +1015,22 @@ def Config.parse_resolv_conf(filename)
10001015 end
10011016 }
10021017 }
1003- return { :nameserver => nameserver , :search => search , :ndots => ndots }
1018+ return { :nameserver => nameserver . freeze , :search => search . freeze , :ndots => ndots . freeze } . freeze
10041019 end
10051020
10061021 def Config . default_config_hash ( filename = "/etc/resolv.conf" )
10071022 if File . exist? filename
1008- config_hash = Config . parse_resolv_conf ( filename )
1023+ Config . parse_resolv_conf ( filename )
1024+ elsif WINDOWS
1025+ require 'win32/resolv' unless defined? ( Win32 ::Resolv )
1026+ search , nameserver = Win32 ::Resolv . get_resolv_info
1027+ config_hash = { }
1028+ config_hash [ :nameserver ] = nameserver if nameserver
1029+ config_hash [ :search ] = [ search ] . flatten if search
1030+ config_hash
10091031 else
1010- if /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM
1011- require 'win32/resolv'
1012- search , nameserver = Win32 ::Resolv . get_resolv_info
1013- config_hash = { }
1014- config_hash [ :nameserver ] = nameserver if nameserver
1015- config_hash [ :search ] = [ search ] . flatten if search
1016- end
1032+ { }
10171033 end
1018- config_hash || { }
10191034 end
10201035
10211036 def lazy_initialize
@@ -1664,6 +1679,7 @@ def get_labels
16641679 prev_index = @index
16651680 save_index = nil
16661681 d = [ ]
1682+ size = -1
16671683 while true
16681684 raise DecodeError . new ( "limit exceeded" ) if @limit <= @index
16691685 case @data . getbyte ( @index )
@@ -1684,7 +1700,10 @@ def get_labels
16841700 end
16851701 @index = idx
16861702 else
1687- d << self . get_label
1703+ l = self . get_label
1704+ d << l
1705+ size += 1 + l . string . bytesize
1706+ raise DecodeError . new ( "name label data exceed 255 octets" ) if size > 255
16881707 end
16891708 end
16901709 end
@@ -2110,7 +2129,14 @@ class Resource < Query
21102129
21112130 attr_reader :ttl
21122131
2113- ClassHash = { } # :nodoc:
2132+ ClassHash = Module . new do
2133+ module_function
2134+
2135+ def []=( type_class_value , klass )
2136+ type_value , class_value = type_class_value
2137+ Resource . const_set ( :"Type#{ type_value } _Class#{ class_value } " , klass )
2138+ end
2139+ end
21142140
21152141 def encode_rdata ( msg ) # :nodoc:
21162142 raise NotImplementedError . new
@@ -2148,7 +2174,9 @@ def hash # :nodoc:
21482174 end
21492175
21502176 def self . get_class ( type_value , class_value ) # :nodoc:
2151- return ClassHash [ [ type_value , class_value ] ] ||
2177+ cache = :"Type#{ type_value } _Class#{ class_value } "
2178+
2179+ return ( const_defined? ( cache ) && const_get ( cache ) ) ||
21522180 Generic . create ( type_value , class_value )
21532181 end
21542182
@@ -2577,7 +2605,7 @@ def initialize(flags, tag, value)
25772605 end
25782606
25792607 ##
2580- # Flags for this proprty :
2608+ # Flags for this property :
25812609 # - Bit 0 : 0 = not critical, 1 = critical
25822610
25832611 attr_reader :flags
0 commit comments