1require 'socket'
2require 'resolv'
3
4class << IPSocket
5  # :stopdoc:
6  alias original_resolv_getaddress getaddress
7  # :startdoc:
8  def getaddress(host)
9    begin
10      return Resolv.getaddress(host).to_s
11    rescue Resolv::ResolvError
12      raise SocketError, "Hostname not known: #{host}"
13    end
14  end
15end
16
17class TCPSocket < IPSocket
18  # :stopdoc:
19  alias original_resolv_initialize initialize
20  # :startdoc:
21  def initialize(host, serv, *rest)
22    rest[0] = IPSocket.getaddress(rest[0]) if rest[0]
23    original_resolv_initialize(IPSocket.getaddress(host), serv, *rest)
24  end
25end
26
27class UDPSocket < IPSocket
28  # :stopdoc:
29  alias original_resolv_bind bind
30  # :startdoc:
31  def bind(host, port)
32    host = IPSocket.getaddress(host) if host != ""
33    original_resolv_bind(host, port)
34  end
35
36  # :stopdoc:
37  alias original_resolv_connect connect
38  # :startdoc:
39  def connect(host, port)
40    original_resolv_connect(IPSocket.getaddress(host), port)
41  end
42
43  # :stopdoc:
44  alias original_resolv_send send
45  # :startdoc:
46  def send(mesg, flags, *rest)
47    if rest.length == 2
48      host, port = rest
49      begin
50        addrs = Resolv.getaddresses(host)
51      rescue Resolv::ResolvError
52        raise SocketError, "Hostname not known: #{host}"
53      end
54      addrs[0...-1].each {|addr|
55        begin
56          return original_resolv_send(mesg, flags, addr, port)
57        rescue SystemCallError
58        end
59      }
60      original_resolv_send(mesg, flags, addrs[-1], port)
61    else
62      original_resolv_send(mesg, flags, *rest)
63    end
64  end
65end
66
67class SOCKSSocket < TCPSocket
68  # :stopdoc:
69  alias original_resolv_initialize initialize
70  # :startdoc:
71  def initialize(host, serv)
72    original_resolv_initialize(IPSocket.getaddress(host), port)
73  end
74end if defined? SOCKSSocket
75