Linux

TCPのURGフラグの謎

普段からネットワークを扱う人にとってはお馴染みのTCPという技術。

ネットワークを学ぼうとするビギナーが最初に教わるであろう基礎的で重要なプロトコルですが、ずっとTCPヘッダにあるURGフラグ(緊急フラグ)とUrgenポインタ(緊急ポインタ)の使いどころが疑問でした。

参考書やネットで調べて出てくる記事にはURGフラグとUrgentポインタの意味は書いてあるのですが、具体的にどんなシーンで使うのかは書いてない事が多いので良く分かっていませんでした。

今回は疑問を解消するべくURGフラグについて少し調べてみました。

URGフラグ(緊急フラグ)とは

URGフラッグとは図で言うところの赤で囲ったところにある1bit幅のフィールドです。

大抵は”0″になっていますが、これに”1″が立っているとUrgentポインタ(緊急ポインタ)のフィールドにデータの在り処が設定されます。…みたいな説明をよく見かけます。

TCPヘッダ フォーマット
f:id:segmentation-fault:20171014113429p:plain

出典:RFC 793 – Transmission Control Protocol

URGフラグを使う一般的なプログラム

実際にURGフラグを使ってるプログラムは無いだろうかと探したところ、Telnetで使われているらしいです。というかTelnet以外見つけられなかった。

説明を見ると端末から実行したコマンドを<Ctrl-C>でキャンセルすれば発生するみたい。

参考
TCP Flags: PSH and URG – PacketLife.net
3 Minutes Networking No.54

実際にキャプチャして確認

コマンドを<Ctrl-C>でキャンセル
f:id:segmentation-fault:20171014120524p:plain

キャプチャ
f:id:segmentation-fault:20171014120715p:plain

確かにフラグが立っている!

プログラムを作って確認

実際にURGフラグが立ったデータを受信するとアプリケーションからはどう見えるのでしょうか。
簡単なプログラムを作って確認してみます。

Windowsをクライアント、LinuxをサーバとしてクライアントからURGフラグ無し、有りのデータを送信します。

URGフラグを付けるには送受信時(recv, send)実行時のフラグに”MSG_OOB”を設定すればよく、受信側にはOSからアプリに対しシグナル SIGURG が発行されるぽい。

クライアント

サーバ

シグナルハンドラ内で、やってはイケない事をしてますが、サンプルなので許してください。

実行結果

実際にプログラムを実行して、送受信データをキャプチャしてみます。

f:id:segmentation-fault:20171014121546p:plain
f:id:segmentation-fault:20171014121600p:plain

確かにクライアントからはデータがURGフラグ付きで送信されていて、サーバ側ではSIGURGを受信しました。

ただ、SIGURG受信時にMSG_OOBフラグ付きでrecvしたらデータを先読み出来ると思ったのですが、違うみたいです。(実装が間違ってるだけかもですが)

まとめ

またまだ謎は多いのですが、実際にURGフラグを使っている例があると分かっただけで良い収穫でした。

telnetのソースコードを読んでもう少し理解を深めたいと思います。