Feature #3711
closedIPAddr must not make DNS lookups via IPSocket.getaddress
Description
=begin
class MustNotCallError < NotImplementedError ; end
class IpAddrNoResolvTestCase < Test::Unit::TestCase
def setup()
class << IPSocket
alias original_getaddress getaddress
def getaddress( host )
# DNS lookups are slow and totally unnecessary for IP addresses
raise MustNotCallError.new( 'IPAddr.new() must not call IPSocket.getaddress()!' )
end
end
end
def test_ipaddr_must_not_resolve_valid_ipv4_address
assert_nothing_raised { IPAddr.new( '1.2.3.4', Socket::AF_INET ) }
end
def test_ipaddr_must_not_resolve_invalid_ipv4_style_address
assert_raise( ArgumentError ) { IPAddr.new( '1.2.3.400', Socket::AF_INET ) }
end
def test_ipaddr_must_not_resolve_valid_ipv6_address
assert_nothing_raised { IPAddr.new( '::', Socket::AF_INET6 ) }
end
def test_ipaddr_must_not_resolve_invalid_ipv6_style_address
assert_raise( ArgumentError ) { IPAddr.new( '::1::', Socket::AF_INET6 ) }
end
end
=end
        
          
          Updated by nobu (Nobuyoshi Nakada) about 15 years ago
          
          
        
        
      
      =begin
Hi,
At Wed, 18 Aug 2010 22:07:42 +0900,
Philipp Kempgen wrote in [ruby-core:31756]:
DNS lookups are slow and totally unnecessary for IP addresses¶
raise MustNotCallError.new( 'IPAddr.new() must not call IPSocket.getaddress()!' )
IPAddr.new already does not call getaddress for valid IPv4
addresses if IPv6 is not available.  Seems it should be enabled
even if IPv6 is available, since there is valid_v6? method
already.
diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb
index 226a996..8d3ee00 100644
--- a/lib/ipaddr.rb
+++ b/lib/ipaddr.rb
@@ -17,45 +17,71 @@
require 'socket'
-unless Socket.const_defined? "AF_INET6"
+have_inet4 = Socket.const_defined? "AF_INET"
+have_inet6 = Socket.const_defined? "AF_INET6"
+
+unless have_inet6
class Socket < BasicSocket
AF_INET6 = Object.new
end
+end
+if have_inet4
class << IPSocket
def valid_v4?(addr)
if /\A(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})\Z/ =~ addr
- 
return $~.captures.all? {|i| i.to_i < 256} 
- 
endreturn $~.captures.all? {|i| i.to_i < 256} || nil end return false - end
+end 
+if have_inet6
- class << IPSocket
def valid_v6?(addr) - 
s = nil # IPv6 (normal) return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*\Z/ =~ addr return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr # IPv6 (IPv4 compat) 
- 
return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:/ =~ addr && valid_v4?($') 
- 
return s if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:/ =~ addr && (s = valid_v4?($')) != false return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($') 
- 
return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($') 
- 
endreturn s if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && (s = valid_v4?($')) != false false - end
+else - class << IPSocket
 - def valid_v6?(addr)
 - 
false - end
 - end
+end 
+if have_inet6
- class << IPSocket
def valid?(addr) 
- 
valid_v4?(addr) || valid_v6?(addr) 
- 
end(s = valid_v4?(addr)) == false ? valid_v6?(addr) : s - end
+else - class << IPSocket
 - alias valid? valid_v4?
 - end
+end 
- alias getaddress_orig getaddress
 - def getaddress(s)
 - 
if valid?(s) - 
s - 
elsif /\A[-A-Za-z\d.]+\Z/ =~ s - 
getaddress_orig(s) - 
else - 
raise ArgumentError, "invalid address" - 
end 
+class << IPSocket
- alias getaddress_orig getaddress
 - def getaddress(s)
 - if v = valid?(s)
 - 
s - elsif v == false && /\A[-A-Za-z\d.]+\Z/ =~ s
 - 
getaddress_orig(s) - else
 - 
endraise ArgumentError, "invalid address"
end
end
 
--
Nobu Nakada
=end
        
          
          Updated by shyouhei (Shyouhei Urabe) about 15 years ago
          
          
        
        
      
      - Status changed from Open to Feedback
 
=begin
=end
        
          
          Updated by nahi (Hiroshi Nakamura) over 13 years ago
          
          
        
        
      
      - Description updated (diff)
 - Assignee set to knu (Akinori MUSHA)
 
        
          
          Updated by mame (Yusuke Endoh) almost 13 years ago
          
          
        
        
      
      - Target version set to 2.6
 
        
          
          Updated by knu (Akinori MUSHA) about 8 years ago
          
          
        
        
      
      A few years later IPAddr was fixed so it does not call IPSocket.getaddress.
        
          
          Updated by knu (Akinori MUSHA) about 8 years ago
          
          
        
        
      
      - Status changed from Feedback to Closed