web-dev-qa-db-ja.com

`SO_REUSEPORT`を設定せずに` nc`をポートでリッスンさせる方法

ncコマンドにTCPポートでリッスンさせたいので、次のようにしました。

nc -lv 8888

次に、別のコンソールで、同じポートでリッスンしようとしている別のプログラムでAddress already in useタイプのエラーが発生するかどうかを確認したので、同じコマンドを再度発行しました。

nc -lv 8888

驚いたことに、2番目のコマンドも成功しました。 2つのプログラムが同じTCPポートでリッスンする方法を調査したところ、リスニングソケットをオプションSO_REUSEPORTで開くと可能であることがわかったので、私はimagine = ncが使用しています。

ncに他のプログラムが同じポートを使用できないようにするにはどうすればよいですか?ポート8888でリッスンし、それがそのポートでリッスンする唯一のプログラムであることを確認したいと思います。

これまでのところ、次のようにsocatに沿ってncを導入することで、やりたいことができました。

socat TCP-LISTEN:8888,fork TCP:localhost:4444
nc -lv 4444

socatは、他のプログラムが同じポートでリッスンすることを禁止しているためです。

しかし、ncだけでこれを達成することは可能ですか?

2
MondKin

メソッドlocal_listenでnetcatソースコードの1つ netcat.c を探しています:

        ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
        if (ret == -1)
            err(1, NULL);

# if defined(SO_REUSEPORT)
        ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
        if (ret == -1)
            err(1, NULL);
# endif

次に、動作を変更するには、コードを変更する必要があります。

ただし、UbuntuXenialの一部であるnetcat-openbsd1.105-7を使用してテストを行ったところ、SO_REUSEPORTを定義せずにビルドされたようです。 SO_REUSEADDRを設定しますがSO_REUSEPORTは設定しないため(カーネル> 3.9の場合)、同じポートで2番目のインスタンスの実行を拒否することを期待するように機能します。

3
mpromonet