Project

General

Profile

Actions

Feature #3711

closed

IPAddr must not make DNS lookups via IPSocket.getaddress

Added by pk (Philipp Kempgen) over 14 years ago. Updated about 7 years ago.

Status:
Closed
Target version:
[ruby-core:31756]

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

Actions #1

Updated by nobu (Nobuyoshi Nakada) over 14 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}
    
  •    return $~.captures.all? {|i| i.to_i < 256} || nil
     end
     return false
    
    end
  • 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?($')
    
  •  return s if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && (s = valid_v4?($')) != false
    
     false
    
    end
  • 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)
    
  •  (s = valid_v4?(addr)) == false ? valid_v6?(addr) : s
    
    end
  • 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
  •  raise ArgumentError, "invalid address"
    
    end
    end
    end

--
Nobu Nakada

=end

Actions #2

Updated by shyouhei (Shyouhei Urabe) over 14 years ago

  • Status changed from Open to Feedback

=begin

=end

Updated by nahi (Hiroshi Nakamura) almost 13 years ago

  • Description updated (diff)
  • Assignee set to knu (Akinori MUSHA)

Updated by mame (Yusuke Endoh) about 12 years ago

  • Target version set to 2.6

Updated by knu (Akinori MUSHA) about 7 years ago

A few years later IPAddr was fixed so it does not call IPSocket.getaddress.

Actions #6

Updated by knu (Akinori MUSHA) about 7 years ago

  • Status changed from Feedback to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0