From: Jun-ichiro itojun Hagino Date: 1999-05-20T13:25:36+09:00 Subject: [ruby-dev:6921] Re: ext/socket/getaddrinfo.c tiny fix > ext/socket/getaddrinfo.cに以下のpatchをおねがいします。 > IPv4 only kernelの上でgetaddrinfo(NULL, "ftp", &hints, &res) > (hints.ai_flags = AI_PASSIVE)としたときにAF_INET6のアドレスが > 返るのをふせぎます。 そいから、各所の struct sockaddr ss; は struct sockaddr_storage ss; でないといけません。struct sockaddrの現物を定義するとIPv6 support できなくなります。 sizeof(struct sockaddr) < sizeof(struct sockaddr_in6)なので。 extconf.rbでなにかsockaddr_storage=trueという記述がありますが、 ソースになにも気配がないのでどう対処すべきかいまいちわかりませんでした。 とりあえず#ifdef INET6でいってますが、これは嘘かも。 すいません、IPv4 only hostで試していません。 itojun --- Index: socket.c =================================================================== RCS file: /home/cvs/ruby/ext/socket/socket.c,v retrieving revision 1.1.1.3.2.15 diff -c -r1.1.1.3.2.15 socket.c *** socket.c 1999/05/11 01:34:33 1.1.1.3.2.15 --- socket.c 1999/05/20 04:01:45 *************** *** 72,77 **** --- 72,83 ---- #define INET_SERVER 1 #define INET_SOCKS 2 + #ifndef INET6 + # define sockaddr_storage sockaddr + # define ss_family sa_family + # define ss_len sa_len + #endif + #ifdef NT static void sock_finalize(fptr) *************** *** 692,698 **** tcp_s_gethostbyname(obj, host) VALUE obj, host; { ! struct sockaddr addr; struct hostent *h; char **pch; VALUE ary, names; --- 698,704 ---- tcp_s_gethostbyname(obj, host) VALUE obj, host; { ! struct sockaddr_storage addr; struct hostent *h; char **pch; VALUE ary, names; *************** *** 709,715 **** else { setipaddr(STR2CSTR(host), (struct sockaddr *)&addr); } ! switch (addr.sa_family) { case AF_INET: { struct sockaddr_in *sin; --- 715,721 ---- else { setipaddr(STR2CSTR(host), (struct sockaddr *)&addr); } ! switch (addr.ss_family) { case AF_INET: { struct sockaddr_in *sin; *************** *** 752,758 **** rb_ary_push(ary, INT2NUM(h->h_addrtype)); #ifdef h_addr for (pch = h->h_addr_list; *pch; pch++) { ! switch (addr.sa_family) { case AF_INET: { struct sockaddr_in sin; --- 758,764 ---- rb_ary_push(ary, INT2NUM(h->h_addrtype)); #ifdef h_addr for (pch = h->h_addr_list; *pch; pch++) { ! switch (addr.ss_family) { case AF_INET: { struct sockaddr_in sin; *************** *** 787,793 **** } #else memcpy((char *)&addr.sin_addr, h->h_addr, h->h_length); ! rb_ary_push(ary, mkipaddr(addr.sin_addr.s_addr)); #endif return ary; --- 793,799 ---- } #else memcpy((char *)&addr.sin_addr, h->h_addr, h->h_length); ! rb_ary_push(ary, mkipaddr((struct sockaddr *)&addr)); #endif return ary; *************** *** 844,850 **** VALUE sock; { OpenFile *fptr; ! struct sockaddr from; int fromlen; GetOpenFile(sock, fptr); --- 850,856 ---- VALUE sock; { OpenFile *fptr; ! struct sockaddr_storage from; int fromlen; GetOpenFile(sock, fptr); *************** *** 910,916 **** VALUE sock; { OpenFile *fptr; ! struct sockaddr addr; int len = sizeof addr; GetOpenFile(sock, fptr); --- 916,922 ---- VALUE sock; { OpenFile *fptr; ! struct sockaddr_storage addr; int len = sizeof addr; GetOpenFile(sock, fptr); *************** *** 925,931 **** VALUE sock; { OpenFile *fptr; ! struct sockaddr addr; int len = sizeof addr; GetOpenFile(sock, fptr); --- 931,937 ---- VALUE sock; { OpenFile *fptr; ! struct sockaddr_storage addr; int len = sizeof addr; GetOpenFile(sock, fptr); *************** *** 939,945 **** ip_s_getaddress(obj, host) VALUE obj, host; { ! struct sockaddr addr; if (rb_obj_is_kind_of(host, rb_cInteger)) { long i = NUM2LONG(host); --- 945,951 ---- ip_s_getaddress(obj, host) VALUE obj, host; { ! struct sockaddr_storage addr; if (rb_obj_is_kind_of(host, rb_cInteger)) { long i = NUM2LONG(host); *************** *** 1049,1055 **** udp_bind(sock, host, port) VALUE sock, host, port; { - struct sockaddr addr; OpenFile *fptr; struct addrinfo *res0, *res; --- 1055,1060 ---- *************** *** 1514,1520 **** sock_s_gethostbyname(obj, host) VALUE obj, host; { ! struct sockaddr addr; struct hostent *h; if (rb_obj_is_kind_of(host, rb_cInteger)) { --- 1519,1525 ---- sock_s_gethostbyname(obj, host) VALUE obj, host; { ! struct sockaddr_storage addr; struct hostent *h; if (rb_obj_is_kind_of(host, rb_cInteger)) { *************** *** 1529,1535 **** else { setipaddr(STR2CSTR(host), (struct sockaddr *)&addr); } ! switch (addr.sa_family) { case AF_INET: { struct sockaddr_in *sin; --- 1534,1540 ---- else { setipaddr(STR2CSTR(host), (struct sockaddr *)&addr); } ! switch (addr.ss_family) { case AF_INET: { struct sockaddr_in *sin; *************** *** 1685,1691 **** int fl; struct addrinfo hints, *res = NULL; int error; ! struct sockaddr ss; struct sockaddr *sap; sa = flags = Qnil; --- 1690,1696 ---- int fl; struct addrinfo hints, *res = NULL; int error; ! struct sockaddr_storage ss; struct sockaddr *sap; sa = flags = Qnil; *************** *** 1696,1702 **** rb_raise(rb_eTypeError, "sockaddr length too big"); } memcpy(&ss, RSTRING(sa)->ptr, RSTRING(sa)->len); ! if (RSTRING(sa)->len != SA_LEN(&ss)) { rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); } sap = (struct sockaddr *)&ss; --- 1701,1707 ---- rb_raise(rb_eTypeError, "sockaddr length too big"); } memcpy(&ss, RSTRING(sa)->ptr, RSTRING(sa)->len); ! if (RSTRING(sa)->len != SA_LEN((struct sockaddr *)&ss)) { rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); } sap = (struct sockaddr *)&ss;