Java DatagramSocket と SOCKS5 による UDP リレー
TCP 接続がすでに SOCKS を使っていても、Java の UDP ソケットに SOCKS5 UDP の実装が必要な理由を理解します。
Java の HTTP リクエストは SOCKS 経由で動作しますが、UDP の機能は依然として直接トラフィックを送信したり失敗したりします。JVM の SOCKS プロパティを設定しても、DatagramSocket に SOCKS5 UDP の実装は与えられません。
DatagramSocket API は、ネットワークのエンドポイント宛てのデータグラムを送受信します。その connect() メソッドは、そのソケットのピアを選びます。ピアとの SOCKS ネゴシエーションは行いません。
SOCKS5 の UDP 経路には追加の作業が必要
SOCKS5 は、TCP 制御接続の上に確立される UDP アソシエーションを定義します。その後クライアントは、プロキシが示すリレーアドレスとの間でカプセル化されたデータグラムを交換します。カプセル化された各メッセージは宛先を識別します。クライアントの実装は、そのフレーミングと制御接続の寿命を扱う必要があります。
通常の UDP ソケットをプロキシの TCP 待受ポートに向けても、これらの手順は省略されます。アプリケーションの生のデータグラムをそのアドレスに送ることは、アソシエーションの代わりにはなりません。
SOCKS5 UDP リレーを明示的にサポートするライブラリまたはアプリケーション機能を選び、サーバーもそれをサポートしていることを確認してください。SOCKS サポートをうたうライブラリが実装しているのは TCP CONNECT だけかもしれません。プロトコル仕様はこれらのコマンドを区別しています。
UDP リレーには使える経路も必要
プロキシへの TCP 接続の成功は、制御経路を確立するだけです。ファイアウォールや NAT の挙動は、リレーに送られるデータグラムに依然として干渉する可能性があります。アプリケーションの宛先がオフラインだと結論づける前に、返されたリレーのエンドポイントとリレーのエラーを収集してください。
最後に、SOCKS のトランスポート対応は UDP に配信保証を加えません。経路が変わった後も、アプリケーション自身のタイムアウト、損失処理、メッセージサイズの制約は引き続き適用されます。