3

質問の背景:

私たちのマシンには、異なるネットワークにつながる複数のネットワークインターフェイスがあります。IP アドレスが重複している可能性があります (たとえば、2 つの異なるネットワーク内の同じ IP アドレスを持つ 2 つの異なるマシン)。したがって、特定のピアに接続する場合は、その IP アドレスだけでなく、適切なネットワークにつながるネットワーク インターフェイスも指定する必要があります。TCP 経由で特定のピアに接続できる C/C++ でアプリケーションを作成したいと考えています。

質問:

SO_BINDTODEVICE が設定されたソケットを使用して TCP 接続を確立しようとしています。簡略化されたスニペットを次に示します。

sockfd = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, interface_name,
    strlen(interface_name));
connect(sockfd, (sockaddr *) &serv_addr, sizeof(serv_addr));

(私は struct ifreq について知っていますが、その中の最初のフィールド (ifr_name フィールドが使用されている) だけのようです。したがって、インターフェイスの名前のみを渡すことができます。)

  • 強制されたインターフェイスがルーティング テーブルによるインターフェイスと同じである場合、すべてが正しく機能します。
  • 強制されたインターフェイスが異なる場合、(Wireshark でテスト済み):
    1. SYN は、強制されたインターフェイスから目的のピアに送信されます。
    2. 目的のピアからの SYN,ACK が強制インターフェイスで受信されます。
    3. 強制インタフェースから ACK が送信されず、接続が確立されません。(そして、ステップ 2 に進みます。)

SYN、ACK、または ACK がシステムによって拒否された場所を確認する方法は? また、特定のインターフェイスを使用して(ルーティングテーブルに対して)TCPソケットに接続を強制する方法は?

目的のインターフェイスで TCP 接続を作成するための、より便利な方法が他にもあるのではないでしょうか?

ありがとう!

4

3 に答える 3

0

SO_BINDTODEVICE を使用しないでください。すべてのプラットフォームでサポートされているわけではなく、もっと簡単な方法があります。

代わりに、リモート側への接続に使用する正しいネットワーク上のローカル IP アドレスにソケットをバインドします。

すなわち、

sockfd = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = 0; //Auto-determine port.
sin.sin_addr.s_addr = inet_addr("192.168.1.123"); //Your IP address on same network as peer you want to connect to

bind(sockfd, (sockaddr*)&sin, sizeof(sin));

次に、接続を呼び出します。

サーバー側では、0 の代わりにポートを指定し、connect の代わりに listen を呼び出す以外は同じことを行います。

于 2012-10-01T19:50:18.780 に答える