名前
getaddrinfo, freeaddrinfo, gai_strerror - ネットワークのアドレスとサービスを変換する
書式
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
void freeaddrinfo(struct addrinfo *res);
const char *gai_strerror(int errcode);
説明
getaddrinfo(3) 関数は、4 つの関数 getipnodebyname(3), getipnodebyaddr(3), getservbyname(3), getservbyport(3) の機能をまとめて一つのインターフェースにしたものである。 getaddrinfo(3) 関数はスレッドセーフで、 ひとつ以上のソケットアドレス構造体を生成する。 この構造体は bind(2) や connect(2) などの関数コールでクライアント用・サーバー用のソケットを生成する際に 用いることができる。
getaddrinfo(3) 関数が作ることのできるのは IPv4 アドレス構造体だけではない。 IPv6 のサポートされているシステムなら IPv6 のソケットアドレス構造体も生成できる。 これらのソケットアドレス構造体は、 クライアントやサーバーでソケットを準備する際に、 bind(2) や connect(2) から直接利用できる。
この関数が用いる addrinfo 構造体には以下のメンバーが含まれている。
struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; };
getaddrinfo(3) は、 メモリを動的に割り当てて addrinfo 構造体のリンクリストを作成し、 そのリンクリストへのポインタを res に設定する。 各構造体は ai_next メンバーでリンクされる。 リンクリストの addrinfo 構造体は複数個になることもあり、その理由はいくつかある。 ネットワークホストがマルチホームの場合、 複数のソケットプロトコルで同じサービスが使える (ひとつが SOCK_STREM アドレスで、もうひとつが SOCK_DGRAM アドレスであるなど) 場合、がある。
ai_family, ai_socktype, ai_protocol メンバーは、それぞれ socket(2) システムコールの対応する引き数と同じ意味を持つ。 getaddrinfo(3) 関数は IPv4 と IPv6 のどちらかのアドレスファミリーのソケットアドレスを返す (ai_family が AF_INET または AF_INET6 のどちらかにセットされる)。
hints パラメータには、希望のソケットのタイプやプロトコル を指定する。 hints を NULL にすることは、どんなネットワークアドレスやプロトコルでもよいことを意味する。 このパラメータが NULL でないときは、 addrinfo 構造体へのポインタとなる。 この構造体の ai_familiy, ai_socktype, ai_protocol メンバーで、希望のソケットタイプなどを指定する。 ai_family に AF_UNSPEC を指定すると、任意のプロトコルファミリーを意味する (例えば IPv4 や IPv6)。 ai_socktype や ai_protocol に 0 を指定すると、 同様に任意のソケットタイプやプロトコルを受付けることを意味する。 ai_flags メンバーには追加オプションを指定する (定義は下のとおり)。 複数のフラグを指定するには、それらの論理 OR をとって指定すればよい。 hints パラメータのその他のメンバーには、 0 (またはヌル・ポインタ) を入れなければならない。
node パラメータと service パラメータのどちらかは NULL にしてよい (両方同時 NULL は不可)。 node には数値形式のネットワークアドレス (IPv4 ならドット区切りの 10 進形式、 IPv6 なら 16 進形式) か、あるいはネットワークホスト名を指定する。 後者の場合は、ネットワークアドレスが検索され、名前解決が行なわれる。 hints.ai_flags に AI_NUMERICHOST フラグが含まれている場合は、 node パラメータは数値的なネットワークアドレスでなければならない。 AI_NUMERICHOST フラグを使うと、 時間の掛かる可能性のあるすべてのネットワークホストアドレスの検索が抑制される。
getaddrinfo(3) 関数は addrinfo 構造体のリンクリストを生成するが、 それぞれのネットワークアドレスは hints パラメータで課されたすべての制限に従っている。 hints.ai_flags に AI_CANONNAME フラグが含まれている場合、これらの addrinfo 構造体の最初の ai_canonname フィールドにはホストの公式な名前を指すように設定される。 ai_family, ai_socktype, ai_protocol 各メンバーにはソケット生成時のパラメータが設定される。 ai_addr メンバーにはソケットアドレスへのポインタが書き込まれ、 ai_addrlen メンバーにはソケットアドレスの長さ (バイト単位) が書き込まれる。
node が NULL の場合、各ソケット構造体のネットワークアドレスは AI_PASSIVE フラグに基づいて初期化される (このフラグは hints.ai_flags に設定される)。 AI_PASSIVE フラグがセットされている場合、 各ソケット構造体のネットワークアドレスは設定されないままとなる (訳注: IPv4 の場合 INADDR_ANY に、IPv6 の場合 IN6ADDR_ANY_INIT に等しい)。 これはすべてのネットワークアドレスでクライアント接続を待ち受けるような サーバーアプリケーションで用いられる。 AI_PASSIVE フラグがセットされていない場合、 ネットワークアドレスは loopback インターフェースアドレスに設定される。 これは同じネットワークホスト上で動作しているサーバーに接続するような クライアントアプリケーションで用いられる。
hints.ai_flags が AI_ADDRCONFIG を含む場合、 result が指すリストには、 ローカルシステムに最低一つの IPv4 アドレスが設定されている場合は IPv4 アドレスが返され、 ローカルシステムに最低一つの IPv6 アドレスが設定されている場合は IPv6 アドレスが返される。
hint.ai_flags に AI_V4MAPPED が指定されていて、 hints.ai_family に AF_INET6 が指定され、 マッチする IPv6 アドレスが見つからなかった場合、 result が指すリストには IPv4-mapped IPv6 アドレスが返される。 hints.ai_family に AI_V4MAPPED と AI_ALL の両方が指定されている場合、 result が指すリストには IPV6 アドレスと IPv4-mapped IPv6 アドレスの 両方が返される。 AI_V4MAPPED が指定されていない場合、 AI_ALL は無視される。
service は、各ソケット構造体のネットワークアドレスのポート番号を設定する。 service が NULL の場合、ポート番号は初期化されない。 hints.ai_flags に AI_NUMERICSERV が指定され、 service が NULL でない場合、 service は数値のポート番号を含む文字列を指し示さなければならない。 このフラグは、名前解決サービスが不要であることが分かっている場合に、 サービスの起動を抑制するために用いられる。
freeaddrinfo(3) 関数は、 リンクリスト res に対して動的に割り当てられたメモリを解放する。
国際化ドメイン名のための getaddrinfo() の拡張
glibc 2.3.4 から、 getaddrinfo() は入出力するホスト名を透過的に国際化ドメイン名 (IDN) 形式 (RFC 3490 の Internationalizing Domain Names in Applications (IDNA) を参照のこと) と変換することを選択的に認めるように拡張されている。 4 つの新しいフラグが定義されている:
AI_IDN | このフラグが指定されると、
node で与えられたノード名は必要があれば IDN 形式に変換される。
ソース符号化形式は現在のロケールのものである。
入力名に非 ASCII 文字が含まれている場合、 IDN 符号化形式が使われる。 非 ASCII 文字が含まれている(ピリオドで区切られる)部分ノード名は、 名前解決機能に渡される前に ASCII 互換符号化形式 (ACE) を使って 符号化される。 |
AI_CANONIDN | |
AI_CANONNAME が指定されている場合、
getaddrinfo() は名前の検索に成功した後、
返された
addrinfo 構造体に対応するノードの正規名を返す。
返り値は名前解決機能から返された値の正確なコピーである。
AI_CANONIDN 名前が ACE で符号化されている場合、一つまたは複数の名前の構成要素の先頭に xn-- を含んでいる。 これらの構成要素を読み込み可能な形に変換するために、 AI_CANONNAME と共に AI_CANONIDN フラグを渡すことも出来る。 返される文字列は現在のロケールの符号化形式で符号化されている。 | |
AI_IDN_ALLOW_UNASSIGNED, AI_IDN_USE_STD3_ASCII_RULES | |
これらのフラグが設定されると、
IDNA ハンドリングを使うときにそれぞれ
IDNA_ALLOW_UNASSIGNED (非割り当て Unicode コードポイントを許可する) と
IDNA_USE_STD3_ASCII_RULES (出力が STD3 準拠ホスト名であることを確認する)
フラグが有効になる。
| |
返り値
getaddrinfo(3) は成功すると 0 を返し、失敗すると以下の非 0 のエラーコードのいずれかを返す。
EAI_ADDRFAMILY | |
指定されたネットワークホストには、 要求されたアドレスファミリーのネットワークアドレスがない。 | |
EAI_AGAIN | |
ネームサーバーから一時的な失敗 (temporary failure) を意味する返事が返された。後でもう一度試してみよ。 | |
EAI_BADFLAGS | |
ai_flags のフラグに不正なフラグが含まれている。 | |
EAI_FAIL | |
ネームサーバーから恒久的な失敗 (permanent failure) を意味する返事が返された。 | |
EAI_FAMILY | |
要求されたアドレスファミリーがサポートされていない。 | |
EAI_MEMORY | |
メモリが足りない。 | |
EAI_NODATA | |
指定されたネットワークホストは存在するが、 ネットワークアドレスがひとつも定義されていない。 | |
EAI_NONAME | |
node と service のどちらかが不明、または node と service の両方が NULL だった場合、または AI_NUMERICSERV が hints.ai_flags に指定されていて、 hints.ai_flags と service が数値のポート番号の文字列でない。 | |
EAI_SERVICE | |
要求されたサービスは、要求されたソケットタイプでは利用できない。 他のソケットタイプでなら利用可能かもしれない。 | |
EAI_SOCKTYPE | |
要求されたソケットタイプがサポートされていない。 | |
EAI_SYSTEM | |
その他のシステムエラー。詳しくは errno を調べること。 | |
準拠
POSIX.1-2001. getaddrinfo() 関数は RFC 2553 に記載されている。
注意
AI_ADDRCONFIG, AI_ALL, AI_V4MAPPED は glibc 2.3.3 以降で利用可能である。 AI_NUMERICSERV は glibc 2.3.4 以降で利用可能である。