class IPSocket

getaddress getaddress_orig valid? valid_v4? valid_v6? addr peeraddr recvfrom

IPSocket is the super class of TCPSocket and UDPSocket.

Public Class Methods

getaddress(host) → ipaddress click to toggle source

Lookups the IP address of host.

IPSocket.getaddress("localhost")     #=> "127.0.0.1"
IPSocket.getaddress("ip6-localhost") #=> "::1"
static VALUE
ip_s_getaddress(VALUE obj, VALUE host)
{
    struct sockaddr_storage addr;
    struct addrinfo *res = rsock_addrinfo(host, Qnil, SOCK_STREAM, 0);

    /* just take the first one */
    memcpy(&addr, res->ai_addr, res->ai_addrlen);
    freeaddrinfo(res);

    return rsock_make_ipaddr((struct sockaddr*)&addr);
}
Also aliased as: getaddress_orig
getaddress_orig(p1) click to toggle source
Alias for: getaddress
valid?(addr) click to toggle source

Returns true if addr is either a valid IPv4 or IPv6 address.

# File lib/ipaddr.rb, line 50
def valid?(addr)
  valid_v4?(addr) || valid_v6?(addr)
end
valid_v4?(addr) click to toggle source

Returns true if addr is a valid IPv4 address.

# File lib/ipaddr.rb, line 28
def valid_v4?(addr)
  if %r\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr
    return $~.captures.all? {|i| i.to_i < 256}
  end
  return false
end
valid_v6?(addr) click to toggle source

Returns true if addr is a valid IPv6 address.

# File lib/ipaddr.rb, line 36
def valid_v6?(addr)
  # IPv6 (normal)
  return true if %r\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*\Z/ =~ addr
  return true if %r\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 %r\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr
  # IPv6 (IPv4 compat)
  return true if %r\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:/ =~ addr && valid_v4?($')
  return true if %r\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 %r\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($')

  false
end

Public Instance Methods

addr([reverse_lookup]) → [address_family, port, hostname, numeric_address] click to toggle source

Returns the local address as an array which contains address_family, port, hostname and numeric_address.

If reverse_lookup is true or :hostname, hostname is obtained from numeric_address using reverse lookup. Or if it is false, or :numeric, hostname is same as numeric_address. Or if it is nil or ommitted, obeys to ipsocket.do_not_reverse_lookup. See Socket.getaddrinfo also.

TCPSocket.open("www.ruby-lang.org", 80) {|sock|
  p sock.addr #=> ["AF_INET", 49429, "hal", "192.168.0.128"]
  p sock.addr(true)  #=> ["AF_INET", 49429, "hal", "192.168.0.128"]
  p sock.addr(false) #=> ["AF_INET", 49429, "192.168.0.128", "192.168.0.128"]
  p sock.addr(:hostname)  #=> ["AF_INET", 49429, "hal", "192.168.0.128"]
  p sock.addr(:numeric)   #=> ["AF_INET", 49429, "192.168.0.128", "192.168.0.128"]
}
static VALUE
ip_addr(int argc, VALUE *argv, VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_storage addr;
    socklen_t len = (socklen_t)sizeof addr;
    int norevlookup;

    GetOpenFile(sock, fptr);

    if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup))
        norevlookup = fptr->mode & FMODE_NOREVLOOKUP;
    if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
        rb_sys_fail("getsockname(2)");
    return rsock_ipaddr((struct sockaddr*)&addr, norevlookup);
}
peeraddr([reverse_lookup]) → [address_family, port, hostname, numeric_address] click to toggle source

Returns the remote address as an array which contains address_family, port, hostname and numeric_address. It is defined for connection oriented socket such as TCPSocket.

If reverse_lookup is true or :hostname, hostname is obtained from numeric_address using reverse lookup. Or if it is false, or :numeric, hostname is same as numeric_address. Or if it is nil or ommitted, obeys to ipsocket.do_not_reverse_lookup. See Socket.getaddrinfo also.

TCPSocket.open("www.ruby-lang.org", 80) {|sock|
  p sock.peeraddr #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"]
  p sock.peeraddr(true)  #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
  p sock.peeraddr(false) #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
  p sock.peeraddr(:hostname) #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"]
  p sock.peeraddr(:numeric)  #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
}
static VALUE
ip_peeraddr(int argc, VALUE *argv, VALUE sock)
{
    rb_io_t *fptr;
    struct sockaddr_storage addr;
    socklen_t len = (socklen_t)sizeof addr;
    int norevlookup;

    GetOpenFile(sock, fptr);

    if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup))
        norevlookup = fptr->mode & FMODE_NOREVLOOKUP;
    if (getpeername(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
        rb_sys_fail("getpeername(2)");
    return rsock_ipaddr((struct sockaddr*)&addr, norevlookup);
}
recvfrom(maxlen) → [mesg, ipaddr] click to toggle source
recvfrom(maxlen, flags) → [mesg, ipaddr]

Receives a message and return the message as a string and an address which the message come from.

maxlen is the maximum number of bytes to receive.

flags should be a bitwise OR of Socket::MSG_* constants.

ipaddr is same as IPSocket#{peeraddr,addr}.

u1 = UDPSocket.new
u1.bind("127.0.0.1", 4913)
u2 = UDPSocket.new
u2.send "uuuu", 0, "127.0.0.1", 4913
p u1.recvfrom(10) #=> ["uuuu", ["AF_INET", 33230, "localhost", "127.0.0.1"]]
static VALUE
ip_recvfrom(int argc, VALUE *argv, VALUE sock)
{
    return rsock_s_recvfrom(sock, argc, argv, RECV_IP);
}