通信するプログラムでホスト名を省略すると、どのアドレスが使われるのでしょうか。getaddrinfoでは、ホストを示すnodeにNULLを渡した場合、AI_PASSIVEというフラグの有無が返されるアドレスの意味を変えます。空文字列を渡す場合とは区別して考える必要があります。
簡単にまとめると?
- nodeがNULLでAI_PASSIVEを指定すると、ワイルドカードのアドレスが得られます。同じ条件でフラグを外すと、ループバックのアドレスになります。
- getaddrinfoが返すのは、通信に使うアドレスなどの候補です。これだけでソケットを開いたり、接続を受け付けたりするわけではありません。
- IPv4とIPv6、ホストの指定、フラグ、ポートを分けて記録すると、ローカル用の設定と待受け候補の設定を比較できます。
アドレスを求める処理と、使う処理
getaddrinfoは、ホストとサービスの指定から、プログラムがbindやconnectなどへ渡せるアドレス情報を求める関数です。返り値は一つとは限りません。アドレスの種類、ソケットの種類、プロトコルをhintsで指定すると、候補を絞れます。[1]
ここで大切なのは、候補を得る段階と、それを実際に使う段階を分けることです。たとえば、住所を調べて紙に書き出せても、その住所で受付を開いたことにはなりません。ソケットにローカルのアドレスを割り当てるbindは別の操作で、使われているアドレスや存在しないインターフェースなどによって失敗することもあります。[2]
NULLとAI_PASSIVEの組合せ
Linuxの公開マニュアルでは、nodeがNULLでAI_PASSIVEを指定した場合、IPv4ではINADDR_ANY、IPv6ではIN6ADDR_ANY_INITに対応するワイルドカードのアドレスが得られると説明されています。これは、ホストのいずれのネットワークアドレスでも接続を受け付けたいサーバーなどが使う指定です。[1]
同じくnodeをNULLにして、AI_PASSIVEを付けなければ、返されるのはループバックのアドレスです。同じホストで動いている相手との通信に使う方向になります。一方、nodeへ具体的なホストを指定した場合、AI_PASSIVEは無視されます。[1] フラグだけを見て「受信用」と決めるのではなく、nodeも合わせて読む理由がここにあります。
ワイルドカードは、特定の外部サーバーの宛先を表すものとして読むべきではありません。また、その値を得ただけで外部から接続できるとも判断できません。アドレスの割当て、待受け、経路、周辺のアクセス制御など、実際に通信が成立する条件を別に確かめる必要があります。
四つの返り値を、接続せずに比較する
今回はローカル環境のPythonから、getaddrinfoの返り値だけを調べました。hostにはNoneを渡し、サービスは文字列の8080、ソケットの種類はSOCK_STREAM、プロトコルはIPPROTO_TCPに固定しました。IPv4とIPv6は別々に指定し、数値のサービス名を使うAI_NUMERICSERVに、AI_PASSIVEを加える場合と加えない場合を比べています。[3]

観測結果は、AI_PASSIVEありでIPv4が0.0.0.0、IPv6が::でした。フラグなしでは、それぞれ127.0.0.1と::1でした。四つともポートは8080です。プログラムでは、アドレス文字列を集合として比較し、ポートも確認しました。候補の並び順に依存した判定にはしていません。
この実行はmacOS上のPythonによる観測です。PythonのsocketはOSのソケットAPIを利用するため、仕様を読む資料と実行した環境を区別して記録しました。[3] Linuxカーネルでの通信試験を行ったという意味ではありません。また、socketの生成、bind、listen、connectは実行していないため、この試験で8080番を待受け状態にはしていません。
設定の比較で見落としたくない点
開発用の小さなサービスを考えると、「同じコンピューターだけで使う」と「別の機器からも使う」では、望む待受けの範囲が変わります。ただし、getaddrinfoの入力を変えて候補を得ることだけで、その要望を実現したとは言えません。返ったアドレスをどの操作へ渡したか、その操作が成功したかまで追います。
不具合を調べる記録には、まずnodeがNULLなのか、具体的な文字列なのかを残します。次に、アドレスファミリー、ソケット型、プロトコル、フラグ、サービスを記録します。返り値についてはアドレスとポートを残し、その後のbindやconnectの成否と別の欄にします。こうすると「候補が意図と違う」のか、「候補は得たが利用時に失敗した」のかを混同しにくくなります。
IPv4の結果だけを見てIPv6も同じ表記だと考えたり、最初の候補だけを全環境に通用する答えだと考えたりしないことも重要です。本稿の四行は入力を限定した比較で、一般のホスト名の名前解決、DNSキャッシュ、複数候補の接続順序を網羅した試験ではありません。入力条件と、確認できた処理の範囲をそろえることが、再現できる比較の出発点になります。
出典
- Linux man-pages 6.19、getaddrinfo(3)、DESCRIPTION。node、AI_PASSIVE、hints、serviceの条件。
- 同、bind(2)、DESCRIPTION・ERRORS。ソケットへのアドレス割当て。
- Python socket文書、getaddrinfoとプラットフォーム依存性。2026年10月23日取得の文書と、実行環境の版は記録上区別。図と観測スクリプトは独自作成。
