ruby-changes:40036
From: nobu <ko1@a...>
Date: Tue, 13 Oct 2015 12:14:35 +0900 (JST)
Subject: [ruby-changes:40036] nobu:r52117 (trunk): rsock_addrinfo: specify address family
nobu 2015-10-13 12:14:13 +0900 (Tue, 13 Oct 2015) New Revision: 52117 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52117 Log: rsock_addrinfo: specify address family * ext/socket/rsock_addrinfo (rsock_addrinfo): specify address family. [Fix GH-1052] * ext/socket/udpsocket.c (udp_connect, udp_bind, udp_send): address family by the receiver. Modified files: trunk/ChangeLog trunk/ext/socket/ipsocket.c trunk/ext/socket/raddrinfo.c trunk/ext/socket/rubysocket.h trunk/ext/socket/socket.c trunk/ext/socket/tcpsocket.c trunk/ext/socket/udpsocket.c Index: ChangeLog =================================================================== --- ChangeLog (revision 52116) +++ ChangeLog (revision 52117) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Oct 13 12:14:10 2015 Craig Davison <craig65535@g...> + + * ext/socket/rsock_addrinfo (rsock_addrinfo): specify address + family. [Fix GH-1052] + + * ext/socket/udpsocket.c (udp_connect, udp_bind, udp_send): + address family by the receiver. + Sun Oct 11 07:09:19 2015 Koichi Sasada <ko1@a...> * vm_insnhelper.c (vm_push_frame): initialize other than sp (and ep) Index: ext/socket/tcpsocket.c =================================================================== --- ext/socket/tcpsocket.c (revision 52116) +++ ext/socket/tcpsocket.c (revision 52117) @@ -50,8 +50,9 @@ tcp_sockaddr(struct sockaddr *addr, sock https://github.com/ruby/ruby/blob/trunk/ext/socket/tcpsocket.c#L50 static VALUE tcp_s_gethostbyname(VALUE obj, VALUE host) { - return rsock_make_hostent(host, rsock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), - tcp_sockaddr); + struct rb_addrinfo *res = + rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME); + return rsock_make_hostent(host, res, tcp_sockaddr); } void Index: ext/socket/rubysocket.h =================================================================== --- ext/socket/rubysocket.h (revision 52116) +++ ext/socket/rubysocket.h (revision 52117) @@ -295,7 +295,8 @@ int rb_getaddrinfo(const char *node, con https://github.com/ruby/ruby/blob/trunk/ext/socket/rubysocket.h#L295 void rb_freeaddrinfo(struct rb_addrinfo *ai); VALUE rsock_freeaddrinfo(VALUE arg); int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); -struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags); +int rsock_fd_family(int fd); +struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags); struct rb_addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack); VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len); VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len); Index: ext/socket/udpsocket.c =================================================================== --- ext/socket/udpsocket.c (revision 52116) +++ ext/socket/udpsocket.c (revision 52117) @@ -87,7 +87,7 @@ udp_connect(VALUE sock, VALUE host, VALU https://github.com/ruby/ruby/blob/trunk/ext/socket/udpsocket.c#L87 VALUE ret; GetOpenFile(sock, arg.fptr); - arg.res = rsock_addrinfo(host, port, SOCK_DGRAM, 0); + arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0); ret = rb_ensure(udp_connect_internal, (VALUE)&arg, rsock_freeaddrinfo, (VALUE)arg.res); if (!ret) rsock_sys_fail_host_port("connect(2)", host, port); @@ -131,7 +131,7 @@ udp_bind(VALUE sock, VALUE host, VALUE p https://github.com/ruby/ruby/blob/trunk/ext/socket/udpsocket.c#L131 VALUE ret; GetOpenFile(sock, arg.fptr); - arg.res = rsock_addrinfo(host, port, SOCK_DGRAM, 0); + arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0); ret = rb_ensure(udp_bind_internal, (VALUE)&arg, rsock_freeaddrinfo, (VALUE)arg.res); if (!ret) rsock_sys_fail_host_port("bind(2)", host, port); @@ -207,7 +207,7 @@ udp_send(int argc, VALUE *argv, VALUE so https://github.com/ruby/ruby/blob/trunk/ext/socket/udpsocket.c#L207 GetOpenFile(sock, arg.fptr); arg.sarg.fd = arg.fptr->fd; arg.sarg.flags = NUM2INT(flags); - arg.res = rsock_addrinfo(host, port, SOCK_DGRAM, 0); + arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0); ret = rb_ensure(udp_send_internal, (VALUE)&arg, rsock_freeaddrinfo, (VALUE)arg.res); if (!ret) rsock_sys_fail_host_port("sendto(2)", host, port); Index: ext/socket/raddrinfo.c =================================================================== --- ext/socket/raddrinfo.c (revision 52116) +++ ext/socket/raddrinfo.c (revision 52117) @@ -518,13 +518,25 @@ rsock_getaddrinfo(VALUE host, VALUE port https://github.com/ruby/ruby/blob/trunk/ext/socket/raddrinfo.c#L518 return res; } +int +rsock_fd_family(int fd) +{ + struct sockaddr sa = { 0 }; + socklen_t sa_len = sizeof(sa); + + if (fd < 0 || getsockname(fd, &sa, &sa_len) != 0) { + return AF_UNSPEC; + } + return sa.sa_family; +} + struct rb_addrinfo* -rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags) +rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags) { struct addrinfo hints; MEMZERO(&hints, struct addrinfo, 1); - hints.ai_family = AF_UNSPEC; + hints.ai_family = family; hints.ai_socktype = socktype; hints.ai_flags = flags; return rsock_getaddrinfo(host, port, &hints, 1); Index: ext/socket/ipsocket.c =================================================================== --- ext/socket/ipsocket.c (revision 52116) +++ ext/socket/ipsocket.c (revision 52117) @@ -45,16 +45,19 @@ init_inetsock_internal(struct inetsock_a https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L45 int type = arg->type; struct addrinfo *res, *lres; int fd, status = 0, local = 0; + int family = AF_UNSPEC; const char *syscall = 0; - arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, SOCK_STREAM, - (type == INET_SERVER) ? AI_PASSIVE : 0); + arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, + family, SOCK_STREAM, + (type == INET_SERVER) ? AI_PASSIVE : 0); /* * Maybe also accept a local address */ if (type != INET_SERVER && (!NIL_P(arg->local.host) || !NIL_P(arg->local.serv))) { - arg->local.res = rsock_addrinfo(arg->local.host, arg->local.serv, SOCK_STREAM, 0); + arg->local.res = rsock_addrinfo(arg->local.host, arg->local.serv, + family, SOCK_STREAM, 0); } arg->fd = fd = -1; @@ -308,7 +311,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L311 ip_s_getaddress(VALUE obj, VALUE host) { union_sockaddr addr; - struct rb_addrinfo *res = rsock_addrinfo(host, Qnil, SOCK_STREAM, 0); + struct rb_addrinfo *res = rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, 0); socklen_t len = res->ai->ai_addrlen; /* just take the first one */ Index: ext/socket/socket.c =================================================================== --- ext/socket/socket.c (revision 52116) +++ ext/socket/socket.c (revision 52117) @@ -1140,7 +1140,9 @@ sock_sockaddr(struct sockaddr *addr, soc https://github.com/ruby/ruby/blob/trunk/ext/socket/socket.c#L1140 static VALUE sock_s_gethostbyname(VALUE obj, VALUE host) { - return rsock_make_hostent(host, rsock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), sock_sockaddr); + struct rb_addrinfo *res = + rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME); + return rsock_make_hostent(host, res, sock_sockaddr); } /* @@ -1518,7 +1520,7 @@ sock_s_getnameinfo(int argc, VALUE *argv https://github.com/ruby/ruby/blob/trunk/ext/socket/socket.c#L1520 static VALUE sock_s_pack_sockaddr_in(VALUE self, VALUE port, VALUE host) { - struct rb_addrinfo *res = rsock_addrinfo(host, port, 0, 0); + struct rb_addrinfo *res = rsock_addrinfo(host, port, AF_UNSPEC, 0, 0); VALUE addr = rb_str_new((char*)res->ai->ai_addr, res->ai->ai_addrlen); rb_freeaddrinfo(res); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/