[#6617] Re: IPv6 ruby — Jun-ichiro itojun Hagino <itojun@...>

26 messages 1999/04/15
[#6672] Re: IPv6 ruby — matz@... (Yukihiro Matsumoto) 1999/04/28

まつもと ゆきひろです

[#6673] Re: IPv6 ruby — itojun@... 1999/04/28

[#6674] Re: IPv6 ruby — matz@... (Yukihiro Matsumoto) 1999/04/28

まつもと ゆきひろです

[#6675] Re: IPv6 ruby — itojun@... 1999/04/28

[#6676] Re: IPv6 ruby — matz@... (Yukihiro Matsumoto) 1999/04/28

まつもと ゆきひろです

[#6677] Re: IPv6 ruby — itojun@... 1999/04/28

[ruby-dev:6695] Re: cvs repository

From: itojun@...
Date: 1999-04-30 10:23:56 UTC
List: ruby-dev #6695
>|>手順は
>|>  $ cvs -d :pserver:anonymous@cvs.netlab.co.jp:/home/cvs login
>|>  (Logging in to anonymous@cvs.netlab.co.jp)
>|>  CVS password:  guest
>|>  $ cvs -d :pserver:anonymous@cvs.netlab.co.jp:/home/cvs checkout -r ruby_1_3 ruby
>|>です.こっちを書いた方が親切ですねえ.そうしましょうか.
>|	この方がいいですかね。
>そうしました.今日版はIPv6を含んでますから,いとじゅんさんに
>も楽しんで(苦しんで?)いただけるのではないかと思います.

	こんなpatchをあてて、KAME/BSDIで一応コンパイル通りました(socket.cは
	static link)。
	ただし、thread_connect()のどっかに問題があるらしく、添付の
	コードのc.getpeername()が成功しません(ENOTCONNが返る)。
	デバッガで追ってると成功するので、「EAGAINだったらもう一度」の
	あたりでなにかいけないことが起きているように思います。

	#define ss_family __ss_familyは、いちばん最初に必要です。
	IPv6 basic API(RFC2553)の定義のときに、__ss_familyにするかss_familyに
	するかでもめて、両方の実装が存在します。
	(一番安全なのはcc -Dで定義しちゃう)

	SA_LEN、SET_SIN_LENとSIN_LENはそれぞれポインタを期待してますか?
	現物を期待していますか? なんか定義がまちまちに思います。

>write permissionが欲しいですか? > いとじゅんさん
>cryptしたpasswdをくだされば追加します.

	別便でお願いします。

itojun


? config.log
? config.cache
? config.h
? config.status
? Makefile
? y.tab.h
? miniruby
? rbconfig.rb
? ruby
? ext/extinit.c
? ext/extmk.rb
? ext/config.cache
? ext/curses/Makefile
? ext/dbm/Makefile
? ext/etc/Makefile
? ext/fcntl/Makefile
? ext/kconv/Makefile
? ext/mandel/Makefile
? ext/md5/Makefile
? ext/nkf/Makefile
? ext/socket/Makefile
? ext/tk/Makefile
Index: ext/Setup
===================================================================
RCS file: /home/cvs/ruby/ext/Setup,v
retrieving revision 1.1.1.3
diff -c -r1.1.1.3 Setup
*** Setup	1999/01/20 04:59:31	1.1.1.3
--- Setup	1999/04/30 09:58:13
***************
*** 7,13 ****
  #fcntl
  #kconv
  #md5
! #socket
  #tkutil
  #tcltklib
  #gtk
--- 7,13 ----
  #fcntl
  #kconv
  #md5
! socket
  #tkutil
  #tcltklib
  #gtk
Index: ext/socket/extconf.rb
===================================================================
RCS file: /home/cvs/ruby/ext/socket/extconf.rb,v
retrieving revision 1.1.1.3.2.4
diff -c -r1.1.1.3.2.4 extconf.rb
*** extconf.rb	1999/04/30 08:19:59	1.1.1.3.2.4
--- extconf.rb	1999/04/30 09:58:18
***************
*** 100,106 ****
    end
    
    if $ipv6lib
!     if File.directory? $ipv6libdir and File.exist? "#{$ipv6libdir}/#{ipv6lib}.a"
        $LDFLAGS += " -L#$ipv6libdir -l#$ipv6lib"
      else
        print <<EOS
--- 100,106 ----
    end
    
    if $ipv6lib
!     if File.directory? $ipv6libdir and File.exist? "#{$ipv6libdir}/lib#{$ipv6lib}.a"
        $LDFLAGS += " -L#$ipv6libdir -l#$ipv6lib"
      else
        print <<EOS
***************
*** 242,249 ****
--- 242,253 ----
      have_getaddrinfo = true
    end
  end
+ if $ipv6
+   have_getaddrinfo = true
+ end
  
  if have_getaddrinfo
+   $CFLAGS="-DHAVE_GETADDRINFO "+$CFLAGS
    if try_link(<<EOF)
  #include <sys/types.h>
  #include <netdb.h>
***************
*** 256,263 ****
     struct sockaddr_storage storage;
     struct sockaddr_storage *addr = 0;
  
!    addr->_ss_family = &storage.__ss_family;
!    addr->_ss_len = &storage.__ss_len;
     return 0;
  }
  EOF
--- 260,267 ----
     struct sockaddr_storage storage;
     struct sockaddr_storage *addr = 0;
  
!    addr->__ss_family = &storage.__ss_family;
!    addr->__ss_len = &storage.__ss_len;
     return 0;
  }
  EOF
Index: ext/socket/socket.c
===================================================================
RCS file: /home/cvs/ruby/ext/socket/socket.c,v
retrieving revision 1.1.1.3.2.10
diff -c -r1.1.1.3.2.10 socket.c
*** socket.c	1999/04/30 08:20:00	1.1.1.3.2.10
--- socket.c	1999/04/30 09:58:53
***************
*** 8,13 ****
--- 8,20 ----
  
  ************************************************/
  
+ /*
+  * NOTE: this has to be placed before any inclusion of header files,
+  * to cope with version oddity of IPv6 basic API.
+  */
+ #define ss_family	__ss_family
+ #define ss_len		__ss_len
+ 
  #include "ruby.h"
  #include "rubyio.h"
  #include "rubysig.h"
***************
*** 48,58 ****
  # include "addrinfo.h"
  #endif
  
  #ifdef SOCKADDR_STORAGE
- # define ss_family __ss_family
  # define SS_LEN(ss) (ss)->__ss_len
  #else
  # define SOCKADDR_STORAGE sockaddr
  # define ss_family sa_family
  # ifdef SA_LEN
  #  define SS_LEN(ss) SA_LEN(ss)
--- 55,94 ----
  # include "addrinfo.h"
  #endif
  
+ #ifdef HAVE_SA_LEN
+ # ifndef SA_LEN
+ #  define SA_LEN(sa)	(sa)->sa_len
+ # endif
+ # ifndef SIN_LEN
+ #  define SIN_LEN(sin)	(sin).sin_len
+ # endif
+ # ifndef SET_SIN_LEN
+ #  define SET_SIN_LEN(sin, len)		{(sin).sin_len = (len);}
+ # endif
+ #else
+ # ifndef SA_LEN
+ #  ifdef INET6
+ #   define SA_LEN(sa) \
+ 	(((sa)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
+ 				       : sizeof(struct sockaddr))
+ #  else
+ 	/* by tradition, sizeof(struct sockaddr) covers most of the sockaddrs */
+ #   define SA_LEN(sa)	(sizeof(struct sockaddr))
+ #  endif
+ # endif
+ # ifndef SIN_LEN
+ #  define SIN_LEN(sin)	(sizeof(struct sockaddr_in))
+ # endif
+ # ifndef SET_SIN_LEN
+ #  define SET_SIN_LEN(sin, len)		{ /*nothing to do*/ }
+ # endif
+ #endif
+ 
  #ifdef SOCKADDR_STORAGE
  # define SS_LEN(ss) (ss)->__ss_len
  #else
  # define SOCKADDR_STORAGE sockaddr
+ # undef ss_family
  # define ss_family sa_family
  # ifdef SA_LEN
  #  define SS_LEN(ss) SA_LEN(ss)
***************
*** 714,720 ****
  	sin = (struct sockaddr_in *)&addr;
  	memset(sin, 0, sizeof(*sin));
  	sin->sin_family = AF_INET;
! 	SET_SIN_LEN(sin, sizeof(*sin));
  	sin->sin_addr.s_addr = htonl(i);
      }
      else {
--- 750,756 ----
  	sin = (struct sockaddr_in *)&addr;
  	memset(sin, 0, sizeof(*sin));
  	sin->sin_family = AF_INET;
! 	SET_SIN_LEN(*sin, sizeof(*sin));
  	sin->sin_addr.s_addr = htonl(i);
      }
      else {
# simple httpd

# The code demonstrates how a multi-protocol daemon should be written.
# CAVEAT:
# "fork" cannot be replaced with "Thread.start" because TCPserver does not
# support multi-threading in TCPserver.accept (at least in ruby 1.2.5).
# Frankly, fork isn't really necessary.  I hoped to use Thread.start but
# I just couldn't.

#require "socket"
#require "thread"

port = 8888
res = Socket.getaddrinfo(nil, port, nil, Socket::SOCK_STREAM, nil, Socket::AI_PASSIVE)
sockpool = []
names = []

res.each do |i|
  s = TCPserver.new(i[3], i[1])
  n = Socket.getnameinfo(s.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV).join(" port ")
  sockpool.push s
  names.push n
end

(0 .. sockpool.size - 1).each do |i|
  mysock = sockpool[i]
  myname = names[i]
  STDERR.print "socket #{mysock} started, address #{myname}\n"
  fork do		# Thread.start cannot be used here!
    ls = mysock	# copy to dynamic variable
    STDERR.print "socket #{myname} started, pid #{$$}\n"
    while TRUE
      as = ls.accept
      Thread.start do
	STDERR.print "socket #{myname} accepted, thread ", Thread.current, "\n"
	s = as	# copy to dynamic variable
	str = s.gets
	STDERR.print "socket #{myname} got string\n"
	s.write("Content-type: text/plain\n\n")
	s.write("this is test: my name is #{myname}, you sent:\n")
	s.write("---start\n")
	s.write(str)
	s.write("---end\n")
	s.close
	STDERR.print "socket #{myname} processed, thread ", Thread.current, " terminating\n"
      end
    end
    exit 0
  end
end

sleep 1		# just for message sequencing...

STDERR.print "I have #{sockpool.size} children\n"
(0 .. sockpool.size - 1).each do |i|
  STDERR.print Process.wait, " seems to be dead\n"
end
STDERR.print "all children seems to be dead, bye\n"

In This Thread