SIPスタックを作成していますが、メッセージにIPアドレスを挿入する必要があります。このアドレスは、メッセージの送信に使用されるアドレスである必要があります。宛先IPを知っているので、メッセージの送信に使用されるNIC(そのアドレス)を決定する必要があります。
4 に答える
Remy Lebeauのコメントを少し拡張するには、Windows XP以降を使用している場合は、GetBestInterfaceEx()が最善の策です。これは、IPv4アドレスとIPv6アドレスの両方で機能します。
GetBestInterface / GetBestInterfaceExは、あるアドレスへの連絡に使用するのに最も適切なインターフェースのインデックス(IDXと呼びます)を返します。
次に、デュアルスタッキング(IPv6とIPv4の両方をサポート)の場合は、GetIpAddrTableまたはGetAdaptersAddressesを使用してインターフェイス<-> IPアドレスマッピングを取得することにより、そのインデックスをローカルIPアドレスにマッピングできます。
そのテーブルを繰り返し処理し、IDXと一致するdwIndex(またはGetAdaptersAddressesの場合はIfIndex)を持つインターフェースを見つけます。
通常、SIPスタックが動作するIPアドレスを調整可能な構成オプションとして設定できるようにするのが最善です。これは、ユーザーが構成オプションを設定する必要があることを意味しますが、少なくともスタックはそれが動作しているIPアドレスを知っています。
それが不可能な場合、使用できるアプローチは、0.0.0.0などのViaヘッダーのダミー値を使用してすべてのIPアドレスでSIP要求を送信し、応答を受け取るインターフェイスをデフォルトのインターフェイスとして設定することです。このアプローチは、SIP応答が要求の受信元のパブリックIPアドレスを通知するという利点もあります。これは、SIPスタックがNATの背後にある場合に役立ちます。
TCPを介して、connect()の後でソケットのローカル側のアドレスを取得できると思います。同じことがUDPにも当てはまるかどうかはわかりませんが(おそらくそうではないと思います)、試してみる価値があるかもしれません。
ソケットを使用すると、connect(UDPとTCPの両方)を呼び出す前にローカルエンドポイントにバインドできます。
ポートを知っていれば、それで問題ありません。ただし、ポートを一時的なものにしたい場合(たとえば、ランダムなポート番号)、それを行うための独自のアルゴリズムと、ポートが別のアプリケーションによって排他的に使用される場合を処理するための堅牢なコードを考え出す必要があります。