diff options
author | Eric Wong <e@yhbt.net> | 2011-02-02 21:33:28 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2011-02-02 13:42:33 -0800 |
commit | 17abe6ce8f01810022b948c71de0026b4ac89597 (patch) | |
tree | ca4cee3b39ecba1fcf0a51336f2399717c96750b /ext/kgio/accept.c | |
parent | 879f2f0ee9133f34ec3e24141bdb4936e3408d3a (diff) | |
download | kgio-17abe6ce8f01810022b948c71de0026b4ac89597.tar.gz |
No extra #ifdefs, we just won't support old systems without getaddrinfo() and friends anymore. I doubt anybody still has them...
Diffstat (limited to 'ext/kgio/accept.c')
-rw-r--r-- | ext/kgio/accept.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/ext/kgio/accept.c b/ext/kgio/accept.c index afb44a2..f61e820 100644 --- a/ext/kgio/accept.c +++ b/ext/kgio/accept.c @@ -187,16 +187,29 @@ retry: return client_io; } -static void in_addr_set(VALUE io, struct sockaddr_in *addr) +static void in_addr_set(VALUE io, struct sockaddr_storage *addr, socklen_t len) { - VALUE host = rb_str_new(0, INET_ADDRSTRLEN); - socklen_t addrlen = (socklen_t)INET_ADDRSTRLEN; - const char *name; - - name = inet_ntop(AF_INET, &addr->sin_addr, RSTRING_PTR(host), addrlen); - if (name == NULL) - rb_sys_fail("inet_ntop"); - rb_str_set_len(host, strlen(name)); + VALUE host; + int host_len, rc; + char *host_ptr; + + switch (addr->ss_family) { + case AF_INET: + host_len = (long)INET_ADDRSTRLEN; + break; + case AF_INET6: + host_len = (long)INET6_ADDRSTRLEN; + break; + default: + rb_raise(rb_eRuntimeError, "unsupported address family"); + } + host = rb_str_new(NULL, host_len); + host_ptr = RSTRING_PTR(host); + rc = getnameinfo((struct sockaddr *)addr, len, + host_ptr, host_len, NULL, 0, NI_NUMERICHOST); + if (rc != 0) + rb_raise(rb_eRuntimeError, "getnameinfo: %s", gai_strerror(rc)); + rb_str_set_len(host, strlen(host_ptr)); rb_ivar_set(io, iv_kgio_addr, host); } @@ -219,13 +232,13 @@ static void in_addr_set(VALUE io, struct sockaddr_in *addr) */ static VALUE tcp_tryaccept(int argc, VALUE *argv, VALUE io) { - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); + struct sockaddr_storage addr; + socklen_t addrlen = sizeof(struct sockaddr_storage); VALUE klass = acceptor(argc, argv); VALUE rv = my_accept(io, klass, (struct sockaddr *)&addr, &addrlen, 1); if (!NIL_P(rv)) - in_addr_set(rv, &addr); + in_addr_set(rv, &addr, addrlen); return rv; } @@ -249,12 +262,12 @@ static VALUE tcp_tryaccept(int argc, VALUE *argv, VALUE io) */ static VALUE tcp_accept(int argc, VALUE *argv, VALUE io) { - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); + struct sockaddr_storage addr; + socklen_t addrlen = sizeof(struct sockaddr_storage); VALUE klass = acceptor(argc, argv); VALUE rv = my_accept(io, klass, (struct sockaddr *)&addr, &addrlen, 0); - in_addr_set(rv, &addr); + in_addr_set(rv, &addr, addrlen); return rv; } |