>	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;