inetd 経由で起動されても peeraddr は取得可能

UNIXデーモンを作ろう

TCP/IPとアプリ層を組み合わせたアクセス制御が出来ない
例:http の名前バーチャルでIPアクセス制限

の意味がよくわからない。HTTP/1.1 のバーチャルホストって、

GET /index.html HTTP/1.1
Host: example.com

の Host: example.com をみて挙動を切り換えるだけなので TCP/IP 関係ないですよね。というか inetd 経由で起動されたプログラムも peeraddr わかりますよね。
元の資料は環境が UNIX としか書いていませんが、以下は全て

% uname -srm
FreeBSD 6.2-RELEASE-p2 i386

上でやりました。
/etc/inetd.conf を編集

test_inetd  stream  tcp nowait  root    /path/to/in.inetd_test  test_inetd

/etc/services を編集

test_inetd  12345/tcp  # TEST

/etc/rc.conf を編集

inetd_enable="YES"

inetd 起動

# /etc/rc.d/inetd start

port 12345 が listen になっていることを確認する

% sockstat | grep 12345
root     inetd      5087  5  tcp4   *:12345               *:*

% netstat -anf inet | grep 12345
tcp4       0      0  *.12345                *.*                    LISTEN

in.inetd_test を作る

#!/usr/bin/perl

use strict;
use warnings;
use IO::Socket;

# get peeraddr
my $peername = getpeername(STDIN);
if ($peername) {
    my( $peerport, $peeraddr ) = sockaddr_in($peername);
    my $ip_address = inet_ntoa($peeraddr);

    printf "Hello %s %s\n", $ip_address, $peerport;
}
else {
    print "no peername\n";
}

このスクリプトを普通に起動すると peername は取得できませんが、

% perl in.inetd_test
no peername

inetd 経由で接続すると

% telnet localhost 12345
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello 127.0.0.1 51445
Connection closed by foreign host.

と、接続元はわかる。念のため他のホスト(Linux)から接続してみたけど、

% telnet 192.168.1.xxx 12345
Trying 192.168.1.xxx...
Connected to xxx.
Escape character is '^]'.
Hello 192.168.1.6 53199
Connection closed by foreign host.

接続元はわかる。ウノウの人が「inetd 経由だと接続元IPアドレスがわからない」と言っているのだとしたら、そんなことはないんじゃないかと。元資料が大雑把にしか書いてないので僕の指摘が的外れかもしれませんけどね。そうだったらすみません。
ところで Perl で inetd 起動のスクリプト書くと STDIN から入力を読み取って, STDOUT に出力すれば良いだけなんだけど、実は STDERR も inetd を通してネットワークストリームに出力されるので use warnings; する人は注意が必要です。