summaryrefslogtreecommitdiff
path: root/ext/socket/ipsocket.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-02-06 02:35:11 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-02-06 02:35:11 +0000
commitaf2f1bf4f9fa58aee5a1333c8701eff80071d267 (patch)
tree9fa572aedbd1532bd5faad3e0e56bacdca1f14b3 /ext/socket/ipsocket.c
parente5757042f94830dd3f5c019ab5ec2838ea794cd8 (diff)
* ext/socket/ipsocket.c (ip_addr, ip_peeraddr),
ext/socket/socket.c (sock_s_getaddrinfo): added optional reverse_lookup flag. [ruby-core:28007] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26590 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/ipsocket.c')
-rw-r--r--ext/socket/ipsocket.c67
1 files changed, 58 insertions, 9 deletions
diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c
index e87f9edc00..ee455998f0 100644
--- a/ext/socket/ipsocket.c
+++ b/ext/socket/ipsocket.c
@@ -129,61 +129,108 @@ rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv,
inetsock_cleanup, (VALUE)&arg);
}
+static ID id_numeric, id_hostname;
+
+int
+rsock_revlookup_flag(VALUE revlookup, int *norevlookup)
+{
+#define return_norevlookup(x) {*norevlookup = x; return 1;}
+ ID id;
+
+ switch (revlookup) {
+ case Qtrue: return_norevlookup(0);
+ case Qfalse: return_norevlookup(1);
+ case Qnil: break;
+ default:
+ Check_Type(revlookup, T_SYMBOL);
+ id = SYM2ID(revlookup);
+ if (id == id_numeric) return_norevlookup(1);
+ if (id == id_hostname) return_norevlookup(0);
+ rb_raise(rb_eArgError, "invalid reverse_lookup flag: :%s", rb_id2name(id));
+ }
+ return 0;
+#undef return_norevlookup
+}
+
/*
* call-seq:
- * ipsocket.addr => [address_family, port, hostname, numeric_address]
+ * ipsocket.addr([reverse_lookup]) => [address_family, port, hostname, numeric_address]
*
* 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.
- * If ipsocket.do_not_reverse_lookup is true,
+ * 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(VALUE sock)
+ip_addr(int argc, VALUE *argv, VALUE sock)
{
rb_io_t *fptr;
struct sockaddr_storage addr;
socklen_t len = 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, fptr->mode & FMODE_NOREVLOOKUP);
+ return rsock_ipaddr((struct sockaddr*)&addr, norevlookup);
}
/*
* call-seq:
- * ipsocket.peeraddr => [address_family, port, hostname, numeric_address]
+ * ipsocket.peeraddr([reverse_lookup]) => [address_family, port, hostname, numeric_address]
*
* 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(VALUE sock)
+ip_peeraddr(int argc, VALUE *argv, VALUE sock)
{
rb_io_t *fptr;
struct sockaddr_storage addr;
socklen_t len = 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, fptr->mode & FMODE_NOREVLOOKUP);
+ return rsock_ipaddr((struct sockaddr*)&addr, norevlookup);
}
/*
@@ -243,10 +290,12 @@ void
Init_ipsocket(void)
{
rb_cIPSocket = rb_define_class("IPSocket", rb_cBasicSocket);
- rb_define_method(rb_cIPSocket, "addr", ip_addr, 0);
- rb_define_method(rb_cIPSocket, "peeraddr", ip_peeraddr, 0);
+ rb_define_method(rb_cIPSocket, "addr", ip_addr, -1);
+ rb_define_method(rb_cIPSocket, "peeraddr", ip_peeraddr, -1);
rb_define_method(rb_cIPSocket, "recvfrom", ip_recvfrom, -1);
rb_define_singleton_method(rb_cIPSocket, "getaddress", ip_s_getaddress, 1);
rb_undef_method(rb_cIPSocket, "getpeereid");
+ id_numeric = rb_intern_const("numeric");
+ id_hostname = rb_intern_const("hostname");
}