Thursday 16 January 2014

Perl5 IPv4/IPv6 Dual Stack

Perl5 IPv4/IPv6 Dual Stack昔は、Socket6 ってのがあったりしたんですが、Perl5 の最近の書き方はどうやるんだ ろうと思って調べて見ました。Socket6 は default では入ってないらしい。
IPv6 はdual stackで書くのが普通。つまり、getaddrinfo で、接続可能なすべてのアド レスを取ってきて、それを全部待つ。そして、どれかに接続できるまで全部試す。
perldoc perlipc は、あまり update されてなくて、dual stack な書き方は皆無。あら らら。
Socket ではなくて、OOな IO::Socketを使えと。なるほど。でも、全然動きません。
    IO::Socket->new(PeerAddress=>$addr);


とかすると、generic socket は作れないとか文句を言う。そこで、
    IO::Socket::INET
    IO::Socket::INET6


ってのがあるのがわかって、それは、もちろん、IPv4 only / IPv6 only 。これで dual stack を書くのは無理だ。
で、 IO::Socket::IP ってのを作った人がいるらしいというのはわかりましたが、
* defalut では入ってないから、cpan で入れろ
そうなのか。そこで、メゲそうになったんですが、
    my ($err,@res) = getaddrinfo($host0, $port0, {socktype=>SOCK_STREAM});
    for my $res (@res) {
        my ($err1, $host, $port) = getnameinfo($res->{addr},NI_NUMERICHOST | NI_NUMERICSERV);
        print STDERR "Trying to connect to $host : $port...\n";


my $sock = new IO::Socket; $sock->socket($res->{family}, $res->{socktype}, $res->{protocol}) || next; if ($sock->connect($res->{addr})) { print STDERR "connected to $host port $port\n"; return $sock; } $sock->close; }
とすれば良いということがわかりました。OOな皮だけ作って、中のsocketを自分で law evel で作ってやれば良いわけね。おそらく、Perl5のdual stack なsocketの作り方は 、これが一番ましでしょう。
    http://www.ie.u-ryukyu.ac.jp/~kono/os/ex/etc/client-io.pl
    http://www.ie.u-ryukyu.ac.jp/~kono/os/ex/etc/server-io.pl


です。
Cでやるとさらに面倒くさい。Java は楽。Ruby/Python は Perl とおんなじようなもの らしいです。





No comments: