1

複数のインターフェイスを備えた Linux サーバーがあります。各インターフェースには IP とネットワークがあります。また、ルーティング テーブルにはデフォルト ルートとその他のルートがあり、特定のネットワークへの接続がいずれかのインターフェイスを経由するようになっています。もちろん、サーバーのインターフェイスの 1 つと同じネットワーク内の IP に向かうプログラムによって開始された接続は、そのインターフェイスを経由します。

そのサーバー上のプログラムが接続しようとしているターゲット IP が与えられた場合: 使用されるローカル インターフェイスの IP アドレスを取得する API はありますか?

または、別の方法として、特定の IP への接続が開始された直後に、サーバーの最も適切なローカル IP アドレスを正確に取得するにはどうすればよいでしょうか? それは利用できますか?

ルーティング ロジックを再度記述したくありません。

例: eth0: 192.168.1.10/24 eth1: 10.1.1.20/24 デフォルト gw: 192.168.1.1 追加の静的ルート: 10.1.1.1 経由で 10.2.0.0/16 へ

プログラムが 1.2.3.4 への UDP 接続を開始すると、eth0 が使用され、照会する適切な IP は 192.168.10 になります。プログラムが 10.2.55.66 への UDP 接続を開始すると、eth1 が使用され、照会する適切な IP は 10.1.1.20 になります。プログラムが 10.1.1.9 への UDP 接続を開始すると、eth1 が使用され、照会する適切な IP は 10.1.1.20 になります。

この質問の理由は、snmp-trap 送信プログラムを変更して、agentField に正しいアドレスを入れたいからです。

4

2 に答える 2

2

mountパラメータを介してローカル IP アドレスが指定されていない場合、NFSv4は非常によく似た処理を行いclientaddrます。ローカル マシンに複数のインターフェイスがある場合でも、リモート NFS サーバーが接続できるローカル IP アドレスを取得する必要があります。

これは、UDP データグラム ソケットを作成し、ローカル アドレスにバインドしconnect()てリモート マシンに接続し、getsockname(). UDP はコネクションレス プロトコルであるため、ネットワーク経由でデータが送信されることはありません。これは、ローカル ルーティング テーブルのみを使用して、ソケットにバインドされたローカル IP アドレスを決定します。

実装については、 Linux-NFS git リポジトリのutils/mount/network.c:nfs_callback_address()を参照してください。utils/mount/network.c:nfs_ca_sockname()を使用してアドレスを取得し、utils/mount/network.c:nfs_ca_gai()を使用してアドレス ファミリがローカル マシンでサポートされているかどうかを確認します (返されないようにするため)。ローカル マシンではサポートされていない IPv6 などのアドレス ファミリを使用するローカル アドレス (NFS 用語ではコールバック アドレス)。

はい、上記の作業を行った後にマシン内部のルーティングが変更された場合、これは失敗します。つまり、ルーティング テーブルを手動で変更して、その宛先 IP アドレスに別のインターフェイスを使用する場合です。間違ったローカル IP アドレスにバインドされており、カーネルがプロセスの下からそれを切り替えることができないため、既存のすべての接続が切断される (タイムアウトになるまでハングする) ため、これは実際には問題ではありません。つまり、それを行う場合、いずれにせよ接続の切断を予期する必要があります。

ローカル マシン外のルーティングの変更は影響を受けません。理由は明らかです。元の UDP 接続テストはマシンの外部に到達せず、ローカル ルーティング テーブルにのみ到達しました。マシン自体の外側のルーティング (ローカル ルーティング テーブル内のネクスト ホップ、またはマシンの外部のゲートウェイ アドレスを含む) は、破損を引き起こさず、上記の手順を使用して得られた結果を変更しません。

これが役に立つことを願っています。

于 2013-04-09T10:15:04.840 に答える