システムプログラム(第6週): ライブラリ関数 getaddrinfo()


電子・情報工学系/システム情報工学研究科CS専攻
新城 靖
<yas@is.tsukuba.ac.jp>

このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~syspro/2007/No6_files/getaddrinfo.html
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~syspro/2007/
http://www.coins.tsukuba.ac.jp/~yas/

ライブラリ関数getaddrinfo()

GETADDRINFO(3)           BSD Library Functions Manual           GETADDRINFO(3)

     int
     getaddrinfo(const char *hostname, const char *servname,
         const struct addrinfo *hints, struct addrinfo **res);

     struct addrinfo {
             int ai_flags;           /* input flags */
             int ai_family;          /* protocol family for socket */
             int ai_socktype;        /* socket type */
             int ai_protocol;        /* protocol for socket */
             socklen_t ai_addrlen;   /* length of socket-address */
             struct sockaddr *ai_addr; /* socket-address for socket */
             char *ai_canonname;     /* canonical name for service location */
             struct addrinfo *ai_next; /* pointer to next in list */
     };
ライブラリ関数 getaddrinfo() は、第一引数として、ホスト名、第2引数とし てポート番号に関連した(/etc/services に含まれている)、第3引数として、 調べたいアドレスの制約に関するヒントを与える。重要なヒントとしては、以 下のものがある。
ai_family
IPv4 専用にするには、AF_INET と指定するが、IPv4/IPv6 の両方に対応させる ためには、0 を指定する(memset() でクリアしていれば何も指定しない)。
ai_socktype
TCP の場合、SOCK_STREAM, UDP の場合、SOCK_DGRAM と指定す ることがよいとgetaddrinfo() の設計者は考えている。

ライブラリ関数 getaddrinfo() は、与えられた引数から、IP アドレス(やポー ト番号)を調べ、結果を構造体 struct addrinfo に格納して返す。その構造体 は、ヒープ(malloc() されたメモリ)に置かれている。関数 getaddrinfo() は、構造体へのポインタを第4引数で示された番地に保存する(第4引数は、 ポインタを保存するための番地)。 この構造体の中の ai_addr に目的の IP アドレスを含んだ struct sockaddr が含まれている。

1つのホストに複数の IP アドレスが割り当てられている場合もある。その場 合は、ai_next を手繰ればわかる。

getaddrinfo() の設計者は、こうして得られたstruct sockaddr をそのまま利 用して、socket() システム・コールやconnect() システム・コールを呼ぶこと を想定している。

     s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
     connect(s, res->ai_addr, res->ai_addrlen);
便利といえば便利だが、想定外の利用方法で利用するときに使いにくい。たと えば、TCP か UDP を後で決めたい時や、複数のアドレスのうちどれを使う化を 後で決めたい時などである。

ライブラリ関数 getaddrinfo() の内部的では、/etc/hosts というファイル や, NIS の hosts マップ, DNSの名前サーバなどが調べられる。どれがどの順 番で調べられるかは、システムに依存する。


Last updated: 2007/05/22 13:10:47
Yasushi Shinjo / <yas@is.tsukuba.ac.jp>