QA@IT

CNAME で名前解決されるホストに対する getaddrinfo の動作

5863 PV

CNAME で名前解決されるホストに対する getaddrinfo の動作についてご教授いただければと思います。

ネームサーバのゾーン設定

example.net. のゾーン設定で次の様に設定しています。

aaa     IN  A       192.2.1.10
bbb     IN  CNAME   aaa

getaddrinfo を呼び出すサーバの構成

getaddrinfo を呼び出す側のサーバの構成は次の通りです。

CentOS 6.3
kernel 2.6.32-279.14.1.el6.x86_64
glibc 2.12-1.80.el6_3.6.x86_64

サーバの /etc/resolv.conf は次の通りです(192.2.1.1 は↑のネームサーバです)。

nameserver 192.2.1.1

このサーバ上の dig で aaa.example.net と bbb.example.net を問い合わせるとそれぞれ次のような結果になります。

dig aaa.example.net. a

;; ANSWER SECTION:
aaa.example.net. 60     IN      A       192.2.1.10

dig bbb.example.net. a

;; ANSWER SECTION:
bbb.example.net. 60     IN      CNAME   aaa.example.net.
aaa.example.net. 60     IN      A       192.2.1.10

実行したコード

このサーバ上で aaa.example.net と bbb.example.net に対する getaddrinfo を呼び出して、その時のネームサーバとの通信をキャプチャしたところ次の通り動作になっていました。

  • aaa.example.net の場合は 1 回だけ問い合わせが行われました
  • bbb.example.net の場合は同じ問い合わせが 2 回行われました

実行したコードは次のものです。

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main()
{
    struct addrinfo hints = {0}, *res, *sai;
    //char host[] = "aaa.example.net";
    char host[] = "bbb.example.net";

    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;

    getaddrinfo(host, NULL, &hints, &res);

    sai = res;

    do
    {
        printf("%s\n", inet_ntoa(((struct sockaddr_in *)sai->ai_addr)->sin_addr));
    }
    while ((sai = sai->ai_next) != NULL);

    freeaddrinfo(res);

    return 0;
}

なお、gethostbyname を用いた場合はどちらの場合でも 1 回しか問い合わせは行われませんでした。

確認したいこと

bbb.example.net に対しては同じ問い合わせが 2 回実行されました。が、1 回目の問い合わせで A も返ってきているし、同じ問い合わせを 2 回行う意味も無いように思えます・・・

そこで、下記の点についてご教授いただければと思います。

  1. どのような理由で同じ問い合わせが 2 回行われるのでしょうか?
  2. bbb.example.net に対する場合でも 1 回だけにさせることは出来ないでしょうか?

回答

自己解決しました。

どのような理由で同じ問い合わせが 2 回行われるのでしょうか?

glibc のバグです。

bbb.example.net に対する場合でも 1 回だけにさせることは出来ないでしょうか?

アップデートすれば解決します。

編集 履歴 (0)
bbb.example.net. 60     IN      CNAME   aaa.example.net.

bbb.example.net. に A レコードがないから

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。