getaddrinfoのヘルプ・マニュアル
日本語 英語
getaddrinfo --help
man getaddrinfo
GETADDRINFO(3) Linux Programmer’s Manual GETADDRINFO(3)
名前
getaddrinfo, freeaddrinfo, gai_strerror - ネットワークのアドレスとサー
ビスを変換する
書式
#include
#include
#include
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);
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
getaddrinfo(), freeaddrinfo(), gai_strerror(): _POSIX_C_SOURCE >= 1 ||
_XOPEN_SOURCE || _POSIX_SOURCE
説明
getaddrinfo() は、(インターネットのホストとサービスを識別する) node と
service を渡すと、一つ以上の addrinfo 構造体を返す。それぞれの addrinfo
構造体には、 bind(2) や connect(2) を呼び出す際に指定できるインターネッ
トアドレスが格納されている。 getaddrinfo() 関数は、 getservbyname(3) と
getservbyport(3) の機能をまとめて一つのインターフェースにしたものである
が、これらの関数と違い、 getaddrinfo() はリエントラントであり、 getad-
drinfo() を使うことでプログラムは IPv4 と IPv6 の違いに関する依存関係を
なくすことができる。
getaddrinfo() が用いる 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;
};
hints 引き数は addrinfo 構造体を指し示し、この構造体を用いて res が指す
リ ストに入れて返すソケットアドレス構造体を選択するための基準を指定する
。 hints が NULL でない場合、 hints は addrinfo 構造体を指し示し、そ の
構造体のフィールド ai_family, ai_socktype, ai_protocol で getaddrinfo()
が返すソケットアドレス集合に対する基準を指定する。
ai_family このフィールドは返されるアドレスの希望のアドレスファミリ ー
を 指 定 す る 。このフィールドに指定できる有効な値としては
AF_INET と AF_INET6 がある。また、値 AF_UNSPEC を指定すると
、 getaddrinfo() は node と service で使用できるいずれかの
アドレスファミリー (例えば IPv4 か IPv6) のソケットアドレス
を返すことを求められる。
ai_socktype こ の フ ィールドは推奨のソケット型 (例えば SOCK_STREAM や
SOCK_DGRAM) を指定する。このフィールドに 0 を指定すると、任
意のソケット型のソケットアドレスを getaddrinfo() が返してよ
いことを意味する。
ai_protocol このフィールドは返されるソケットアドレスのプロトコルを指 定
する。このフィールドに 0 を指定すると、任意のプロトコルのの
ソケットアドレスを getaddrinfo() が返してよいことを意味する
。
ai_flags このフィールドは、追加のオプション (下記) を指定する。複数
のフラグを指定する際には、それらの論理 OR をとって指定す る
。
hints が指し示す構造体の他のすべてのフィールドには 0 か NULL ポインタを
適切に入れなければならない。 hints に NULL を指定するのは、 ai_socktype
と ai_protocol に 0 を 、 ai_family に AF_UNSPEC を、 ai_flags に
(AI_V4MAPPED | AI_ADDRCONFIG) を設定するのと等価である。
node には、数値形式のネットワークアドレス (IPv4 の場合 は inet_aton(3)
で サ ポ ー ト さ れ ているドット区切りの数字による表記、 IPv6 の場合は
inet_pton(3) でサポートされている 16 進数の文字列形式) もしくはネットワ
ー クホスト名を指定する。ネットワークホスト名を指定した場合には、そのネ
ットワークアドレスが検索され、名前解決が行なわれる。 hints.ai_flags に
AI_NUMERICHOST フラグが含まれている場合は、 node は数値形式のネットワー
クアドレスでなければならない。 AI_NUMERICHOST フラグを使うと、時間の 掛
かる可能性のあるネットワークホストアドレスの検索はすべて抑制される。
hints.ai_flags に AI_PASSIVE フラグが指定され、かつ node が NULL の場合
、返されるソケットアドレスはコネクションを accept(2) するためのソケット
を bind(2) するのに適したものとなる。返されるソケットアドレスには「ワイ
ルドカード・アドレス」 (IPv4 アドレスの場合は INADDR_ANY、 IPv6 アド レ
スの場合は IN6ADDR_ANY_INIT) が入る。ワイルドカード・アドレスは、任意の
ホストのネットワークアドレスで接続を受け付けようとするアプリケーショ ン
(通常はサーバー) で用いられる。 node が NULL でない場合、 AI_PASSIVE フ
ラグは無視される。
hints.ai_flags に AI_PASSIVE フラグがセットされていない場合、返されるソ
ケットアドレスは connect(2), sendto(2), sendmsg(2) での使用に適したもの
となる。 node が NULL の場合、ネットワークアドレスにはループバック・ イ
ンターフェイスのアドレス (IPv4 アドレスの場合は INADDR_LOOPBACK IPv6 ア
ドレスの場合は IN6ADDR_LOOPBACK_INIT)が設定される。これは同じホスト上で
動作している接続相手と通信するようなアプリケーションで用いられる。
service により、返される各アドレス構造体のポート番号が決まる。この引き
数がサービス名 (services(5) 参照) の場合、対応するポート番号に翻訳さ れ
る 。この引き数には 10 進数も指定することができ、この場合にはバイナリへ
の変換だけが行われる。 service が NULL の場合、返されるソケットアドレス
の ポート番号は初期化されないままとなる。 hints.ai_flags に AI_NUMERIC-
SERV が指定され、かつ service が NULL でない場合、 service は数値のポー
ト 番号を含む文字列を指し示さなければならない。このフラグは、名前解決サ
ービスが不要であることが分かっている場合に、サービスの起動を抑制する た
めに用いられる。
node と service のどちらかは NULL にしてよいが、両方同時に NULL にして
はならない。
getaddrinfo() 関数は、 addrinfo 構造体のメモリ確保を行い、 addrinfo 構
造体のリンクリストを初期化し、 res にリストの先頭へのポインタを入れて返
す。このとき、各構造体のネットワークアドレスは node と service に一致し
、 hints で課されたすべての制限を満たすものとなる。リンクリストの要素は
ai_next フィールドにより連結される。
リンクリストの addrinfo 構造体は複数個になることもあり、その理由はい く
つ かある。ネットワークホストがマルチホームである、複数のプロトコルでア
クセスできる (例えば AF_INET と AF_INET6 の両方) 、複数のソケット種別で
同 じサービスが利用できる (例えば、ひとつが SOCK_STREM アドレスで、もう
ひとつが SOCK_DGRAM アドレスである)、がある。通常は、アプリケーションは
返された順序でアドレスを試すべきである。 getaddrinfo() の中で使用される
並べ替え関数は RFC 3484 で定義されている。特 殊 な シ ス テ ム で は 、
/etc/gai.conf を 編 集 す る ことで、この順序を微調整することができる
(/etc/gai.conf は glibc 2.5 以降で利用できる)。
hints.ai_flags に AI_CANONNAME フラグが含まれている場合、返されるリスト
の 最初の addrinfo 構造体の ai_canonname フィールドはホストの公式な名前
を指すように設定される。
返される各々の addrinfo 構造体の残りのフィールドは以下のように初期化 さ
れる。
* ai_family, ai_socktype, ai_protocol フィールドはソケット生成パラメー
タを返す (これらのフィールドの意味は socket(2) の同じ名前の引き数と同
じ で あ る) 。 例 え ば 、 ai_family は AF_INET や AF_INET6 を返し、
ai_socktype は SOCK_DGRAM や SOCK_STREAM を返し、 ai_protocol はそ の
ソケットのプロトコルを返す。
* ai_addr フ ィ ー ルドにはソケットアドレスへのポインタが書き込まれ、
ai_addrlen フィールドにはソケットアドレスの長さがバイト単位で書き込ま
れる。
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 は無視される。
freeaddrinfo() 関数は、リンクリスト 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() は成功すると 0 を返し、失敗すると以下の非 0 のエラーコ ー
ドのいずれかを返す。
EAI_ADDRFAMILY
指定されたネットワークホストには、要求されたアドレスファミリーの
ネットワークアドレスがない。
EAI_AGAIN
ネームサーバーから一時的な失敗 (temporary failure) を意味する 返
事が返された。後でもう一度試してみよ。
EAI_BADFLAGS
hints.ai_flags の フラグに不正なフラグが含まれている。または、
hints.ai_flags に AI_CANONNAME が含まれていて、かつ name が NULL
であった。
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
要求されたサービスは、要求されたソケットタイプでは利用できない。
他のソケットタイプでなら利用可能かもしれない。このエラーが発生す
る例としては、 service が "shell" (ストリーム・ソケットでのみ 利
用できるサービス) で、 hints.ai_protocol に IPPROTO_UDP が指定さ
れたり、 hints.ai_socktype に SOCK_DGRAM が指定されたりした場 合
が あ る 。 また、 service が NULL 以外で、 hints.ai_socktype に
SOCK_RAW (サービスの考え方をサポートしていないソケット種別) が指
定された場合にも、このエラーが発生する。
EAI_SOCKTYPE
要求されたソケットタイプがサポートされていない。このエラーが発生
する例としては、 hints.ai_socktype と hints.ai_protocol が矛盾し
て い る 場 合 ( 例 え ば hints.ai_socktype が SOCK_DGRAM で
hints.ai_protocol が IPPROTO_TCP) がある。
EAI_SYSTEM
その他のシステムエラー。詳しくは errno を調べること。
gai_strerror() 関数を用いると、これらのエラーコードを人間に可読な文字列
に変換できるので、エラー報告に適するだろう。
ファイル
/etc/gai.conf
準拠
POSIX.1-2001. getaddrinfo() 関数は RFC 2553 に記載されている。
注意
getaddrinfo() は、IPv6 scope-ID を指定するために address%scope-id 記法
をサポートしている。
AI_ADDRCONFIG, AI_ALL, AI_V4MAPPED は glibc 2.3.3 以降で利用可能であ る
。 AI_NUMERICSERV は glibc 2.3.4 以降で利用可能である。
例
以 下 の プ ログラムは、 getaddrinfo(), gai_strerror(), freeaddrinfo(),
getnameinfo(3) の使い方を示したものである。プログラムは UDP データグ ラ
ムの echo サーバとクライアントである。
サーバのプログラム
#include
#include
#include
#include
#include
#include
#include
#define BUF_SIZE 500
int
main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s;
struct sockaddr_storage peer_addr;
socklen_t peer_addr_len;
ssize_t nread;
char buf[BUF_SIZE];
if (argc != 2) {
fprintf(stderr, "Usage: %s port\n", argv[0]);
exit(EXIT_FAILURE);
}
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
s = getaddrinfo(NULL, argv[1], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
/* getaddrinfo() returns a list of address structures.
Try each address until we successfully bind(2).
If socket(2) (or bind(2)) fails, we (close the socket
and) try the next address. */
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not bind\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* No longer needed */
/* Read datagrams and echo them back to sender */
for (;;) {
peer_addr_len = sizeof(struct sockaddr_storage);
nread = recvfrom(sfd, buf, BUF_SIZE, 0,
(struct sockaddr *) &peer_addr, &peer_addr_len);
if (nread == -1)
continue; /* Ignore failed request */
char host[NI_MAXHOST], service[NI_MAXSERV];
s = getnameinfo((struct sockaddr *) &peer_addr,
peer_addr_len, host, NI_MAXHOST,
service, NI_MAXSERV, NI_NUMERICSERV);
if (s == 0)
printf("Received %ld bytes from %s:%s\n",
(long) nread, host, service);
else
fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
if (sendto(sfd, buf, nread, 0,
(struct sockaddr *) &peer_addr,
peer_addr_len) != nread)
fprintf(stderr, "Error sending response\n");
}
}
クライアントのプログラム
#include
#include
#include
#include
#include
#include
#include
#define BUF_SIZE 500
int
main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s, j;
size_t len;
ssize_t nread;
char buf[BUF_SIZE];
if (argc < 3) {
fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Obtain address(es) matching host/port */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = 0;
hints.ai_protocol = 0; /* Any protocol */
s = getaddrinfo(argv[1], argv[2], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
/* getaddrinfo() returns a list of address structures.
Try each address until we successfully connect(2).
If socket(2) (or connect(2)) fails, we (close the socket
and) try the next address. */
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not connect\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* No longer needed */
/* Send remaining command-line arguments as separate
datagrams, and read responses from server */
for (j = 3; j < argc; j++) {
len = strlen(argv[j]) + 1;
/* +1 for terminating null byte */
if (len + 1 > BUF_SIZE) {
fprintf(stderr,
"Ignoring long message in argument %d\n", j);
continue;
}
if (write(sfd, argv[j], len) != len) {
fprintf(stderr, "partial/failed write\n");
exit(EXIT_FAILURE);
}
nread = read(sfd, buf, BUF_SIZE);
if (nread == -1) {
perror("read");
exit(EXIT_FAILURE);
}
printf("Received %ld bytes: %s\n", (long) nread, buf);
}
exit(EXIT_SUCCESS);
}
関連項目
gethostbyname(3), getnameinfo(3), inet(3), hostname(7), ip(7)
GNU 2008-12-04 GETADDRINFO(3)
GETADDRINFO(3) Linux Programmer’s Manual GETADDRINFO(3)
NAME
getaddrinfo, freeaddrinfo, gai_strerror - network address and service
translation
SYNOPSIS
#include
#include
#include
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);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
getaddrinfo(), freeaddrinfo(), gai_strerror(): _POSIX_C_SOURCE >= 1 ||
_XOPEN_SOURCE || _POSIX_SOURCE
DESCRIPTION
Given node and service, which identify an Internet host and a service,
getaddrinfo() returns one or more addrinfo structures, each of which
contains an Internet address that can be specified in a call to bind(2)
or connect(2). The getaddrinfo() function combines the functionality
provided by the getservbyname(3) and getservbyport(3) functions into a
single interface, but unlike the latter functions, getaddrinfo() is
reentrant and allows programs to eliminate IPv4-versus-IPv6 dependen-
cies.
The addrinfo structure used by getaddrinfo() contains the following
fields:
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;
};
The hints argument points to an addrinfo structure that specifies cri-
teria for selecting the socket address structures returned in the list
pointed to by res. If hints is not NULL it points to an addrinfo
structure whose ai_family, ai_socktype, and ai_protocol specify crite-
ria that limit the set of socket addresses returned by getaddrinfo(),
as follows:
ai_family This field specifies the desired address family for the
returned addresses. Valid values for this field include
AF_INET and AF_INET6. The value AF_UNSPEC indicates that
getaddrinfo() should return socket addresses for any
address family (either IPv4 or IPv6, for example) that can
be used with node and service.
ai_socktype This field specifies the preferred socket type, for example
SOCK_STREAM or SOCK_DGRAM. Specifying 0 in this field
indicates that socket addresses of any type can be returned
by getaddrinfo().
ai_protocol This field specifies the protocol for the returned socket
addresses. Specifying 0 in this field indicates that
socket addresses with any protocol can be returned by
getaddrinfo().
ai_flags This field specifies additional options, described below.
Multiple flags are specified by logically OR-ing them
together.
All the other fields in the structure pointed to by hints must contain
either 0 or a null pointer, as appropriate. Specifying hints as NULL
is equivalent to setting ai_socktype and ai_protocol to 0; ai_family to
AF_UNSPEC; and ai_flags to (AI_V4MAPPED | AI_ADDRCONFIG).
node specifies either a numerical network address (for IPv4, numbers-
and-dots notation as supported by inet_aton(3); for IPv6, hexadecimal
string format as supported by inet_pton(3)), or a network hostname,
whose network addresses are looked up and resolved. If hints.ai_flags
contains the AI_NUMERICHOST flag then node must be a numerical network
address. The AI_NUMERICHOST flag suppresses any potentially lengthy
network host address lookups.
If the AI_PASSIVE flag is specified in hints.ai_flags, and node is
NULL, then the returned socket addresses will be suitable for
bind(2)ing a socket that will accept(2) connections. The returned
socket address will contain the "wildcard address" (INADDR_ANY for IPv4
addresses, IN6ADDR_ANY_INIT for IPv6 address). The wildcard address is
used by applications (typically servers) that intend to accept connec-
tions on any of the hosts’s network addresses. If node is not NULL,
then the AI_PASSIVE flag is ignored.
If the AI_PASSIVE flag is not set in hints.ai_flags, then the returned
socket addresses will be suitable for use with connect(2), sendto(2),
or sendmsg(2). If node is NULL, then the network address will be set
to the loopback interface address (INADDR_LOOPBACK for IPv4 addresses,
IN6ADDR_LOOPBACK_INIT for IPv6 address); this is used by applications
that intend to communicate with peers running on the same host.
service sets the port in each returned address structure. If this
argument is a service name (see services(5)), it is translated to the
corresponding port number. This argument can also be specified as a
decimal number, which is simply converted to binary. If service is
NULL, then the port number of the returned socket addresses will be
left uninitialized. If AI_NUMERICSERV is specified in hints.ai_flags
and service is not NULL, then service must point to a string containing
a numeric port number. This flag is used to inhibit the invocation of
a name resolution service in cases where it is known not to be
required.
Either node or service, but not both, may be NULL.
The getaddrinfo() function allocates and initializes a linked list of
addrinfo structures, one for each network address that matches node and
service, subject to any restrictions imposed by hints, and returns a
pointer to the start of the list in res. The items in the linked list
are linked by the ai_next field.
There are several reasons why the linked list may have more than one
addrinfo structure, including: the network host is multi-homed, acces-
sible over multiple protocols (e.g. both AF_INET and AF_INET6); or the
same service is available from multiple socket types (one SOCK_STREAM
address and another SOCK_DGRAM address, for example). Normally, the
application should try using the addresses in the order in which they
are returned. The sorting function used within getaddrinfo() is
defined in RFC 3484; the order can be tweaked for a particular system
by editing /etc/gai.conf (available since glibc 2.5).
If hints.ai_flags includes the AI_CANONNAME flag, then the ai_canonname
field of the first of the addrinfo structures in the returned list is
set to point to the official name of the host.
The remaining fields of each returned addrinfo structure are initial-
ized as follows:
* The ai_family, ai_socktype, and ai_protocol fields return the socket
creation parameters (i.e., these fields have the same meaning as the
corresponding arguments of socket(2)). For example, ai_family might
return AF_INET or AF_INET6; ai_socktype might return SOCK_DGRAM or
SOCK_STREAM; and ai_protocol returns the protocol for the socket.
* A pointer to the socket address is placed in the ai_addr field, and
the length of the socket address, in bytes, is placed in the
ai_addrlen field.
If hints.ai_flags includes the AI_ADDRCONFIG flag, then IPv4 addresses
are returned in the list pointed to by result only if the local system
has at least one IPv4 address configured, and IPv6 addresses are only
returned if the local system has at least one IPv6 address configured.
If hint.ai_flags specifies the AI_V4MAPPED flag, and hints.ai_family
was specified as AF_INET6, and no matching IPv6 addresses could be
found, then return IPv4-mapped IPv6 addresses in the list pointed to by
result. If both AI_V4MAPPED and AI_ALL are specified in hints.ai_fam-
ily, then return both IPv6 and IPv4-mapped IPv6 addresses in the list
pointed to by result. AI_ALL is ignored if AI_V4MAPPED is not also
specified.
The freeaddrinfo() function frees the memory that was allocated for the
dynamically allocated linked list res.
Extensions to getaddrinfo() for Internationalized Domain Names
Starting with glibc 2.3.4, getaddrinfo() has been extended to selec-
tively allow the incoming and outgoing hostnames to be transparently
converted to and from the Internationalized Domain Name (IDN) format
(see RFC 3490, Internationalizing Domain Names in Applications (IDNA)).
Four new flags are defined:
AI_IDN If this flag is specified, then the node name given in node is
converted to IDN format if necessary. The source encoding is
that of the current locale.
If the input name contains non-ASCII characters, then the IDN
encoding is used. Those parts of the node name (delimited by
dots) that contain non-ASCII characters are encoded using ASCII
Compatible Encoding (ACE) before being passed to the name reso-
lution functions.
AI_CANONIDN
After a successful name lookup, and if the AI_CANONNAME flag was
specified, getaddrinfo() will return the canonical name of the
node corresponding to the addrinfo structure value passed back.
The return value is an exact copy of the value returned by the
name resolution function.
If the name is encoded using ACE, then it will contain the xn--
prefix for one or more components of the name. To convert these
components into a readable form the AI_CANONIDN flag can be
passed in addition to AI_CANONNAME. The resulting string is
encoded using the current locale’s encoding.
AI_IDN_ALLOW_UNASSIGNED, AI_IDN_USE_STD3_ASCII_RULES
Setting these flags will enable the IDNA_ALLOW_UNASSIGNED (allow
unassigned Unicode code points) and IDNA_USE_STD3_ASCII_RULES
(check output to make sure it is a STD3 conforming hostname)
flags respectively to be used in the IDNA handling.
RETURN VALUE
getaddrinfo() returns 0 if it succeeds, or one of the following non-
zero error codes:
EAI_ADDRFAMILY
The specified network host does not have any network addresses
in the requested address family.
EAI_AGAIN
The name server returned a temporary failure indication. Try
again later.
EAI_BADFLAGS
hints.ai_flags contains invalid flags; or, hints.ai_flags
included AI_CANONNAME and name was NULL.
EAI_FAIL
The name server returned a permanent failure indication.
EAI_FAMILY
The requested address family is not supported.
EAI_MEMORY
Out of memory.
EAI_NODATA
The specified network host exists, but does not have any network
addresses defined.
EAI_NONAME
The node or service is not known; or both node and service are
NULL; or AI_NUMERICSERV was specified in hints.ai_flags and ser-
vice was not a numeric port-number string.
EAI_SERVICE
The requested service is not available for the requested socket
type. It may be available through another socket type. For
example, this error could occur if service was "shell" (a ser-
vice only available on stream sockets), and either hints.ai_pro-
tocol was IPPROTO_UDP, or hints.ai_socktype was SOCK_DGRAM; or
the error could occur if service was not NULL, and
hints.ai_socktype was SOCK_RAW (a socket type that does not sup-
port the concept of services).
EAI_SOCKTYPE
The requested socket type is not supported. This could occur,
for example, if hints.ai_socktype and hints.ai_protocol are
inconsistent (e.g., SOCK_DGRAM and IPPROTO_TCP, repectively).
EAI_SYSTEM
Other system error, check errno for details.
The gai_strerror() function translates these error codes to a human
readable string, suitable for error reporting.
FILES
/etc/gai.conf
CONFORMING TO
POSIX.1-2001. The getaddrinfo() function is documented in RFC 2553.
NOTES
getaddrinfo() supports the address%scope-id notation for specifying the
IPv6 scope-ID.
AI_ADDRCONFIG, AI_ALL, and AI_V4MAPPED are available since glibc 2.3.3.
AI_NUMERICSERV is available since glibc 2.3.4.
EXAMPLE
The following programs demonstrate the use of getaddrinfo(), gai_str-
error(), freeaddrinfo(), and getnameinfo(3). The programs are an echo
server and client for UDP datagrams.
Server program
#include
#include
#include
#include
#include
#include
#include
#define BUF_SIZE 500
int
main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s;
struct sockaddr_storage peer_addr;
socklen_t peer_addr_len;
ssize_t nread;
char buf[BUF_SIZE];
if (argc != 2) {
fprintf(stderr, "Usage: %s port\n", argv[0]);
exit(EXIT_FAILURE);
}
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
s = getaddrinfo(NULL, argv[1], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
/* getaddrinfo() returns a list of address structures.
Try each address until we successfully bind(2).
If socket(2) (or bind(2)) fails, we (close the socket
and) try the next address. */
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not bind\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* No longer needed */
/* Read datagrams and echo them back to sender */
for (;;) {
peer_addr_len = sizeof(struct sockaddr_storage);
nread = recvfrom(sfd, buf, BUF_SIZE, 0,
(struct sockaddr *) &peer_addr, &peer_addr_len);
if (nread == -1)
continue; /* Ignore failed request */
char host[NI_MAXHOST], service[NI_MAXSERV];
s = getnameinfo((struct sockaddr *) &peer_addr,
peer_addr_len, host, NI_MAXHOST,
service, NI_MAXSERV, NI_NUMERICSERV);
if (s == 0)
printf("Received %ld bytes from %s:%s\n",
(long) nread, host, service);
else
fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
if (sendto(sfd, buf, nread, 0,
(struct sockaddr *) &peer_addr,
peer_addr_len) != nread)
fprintf(stderr, "Error sending response\n");
}
}
Client program
#include
#include
#include
#include
#include
#include
#include
#define BUF_SIZE 500
int
main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s, j;
size_t len;
ssize_t nread;
char buf[BUF_SIZE];
if (argc < 3) {
fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Obtain address(es) matching host/port */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = 0;
hints.ai_protocol = 0; /* Any protocol */
s = getaddrinfo(argv[1], argv[2], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
/* getaddrinfo() returns a list of address structures.
Try each address until we successfully connect(2).
If socket(2) (or connect(2)) fails, we (close the socket
and) try the next address. */
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not connect\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* No longer needed */
/* Send remaining command-line arguments as separate
datagrams, and read responses from server */
for (j = 3; j < argc; j++) {
len = strlen(argv[j]) + 1;
/* +1 for terminating null byte */
if (len + 1 > BUF_SIZE) {
fprintf(stderr,
"Ignoring long message in argument %d\n", j);
continue;
}
if (write(sfd, argv[j], len) != len) {
fprintf(stderr, "partial/failed write\n");
exit(EXIT_FAILURE);
}
nread = read(sfd, buf, BUF_SIZE);
if (nread == -1) {
perror("read");
exit(EXIT_FAILURE);
}
printf("Received %ld bytes: %s\n", (long) nread, buf);
}
exit(EXIT_SUCCESS);
}
SEE ALSO
gethostbyname(3), getnameinfo(3), inet(3), hostname(7), ip(7)
COLOPHON
This page is part of release 3.22 of the Linux man-pages project. A
description of the project, and information about reporting bugs, can
be found at http://www.kernel.org/doc/man-pages/.
GNU 2008-12-04 GETADDRINFO(3)