2.5. TCPヘッダ

TCP ヘッダには、前述の役目を全て達成できる素養が求められる。幾つかのヘッダについては、それがいつ、どのように利用されるか既に説明したが、まだ明らかにしていない領域が他にも沢山ある。下に、 TCP ヘッダを全て網羅した図を示した。見ての通り、1 段を 32 ビットワードとした形になっている。

送信元ポート (Source port) - ビット 0-15。パケットの送信元ポート。元来は、送信元ポートはそれを送信したシステム上のプロセスを直接指し示すものだった。今日では、双方の IP アドレスから求めたハッシュ値と、宛先ポートおよび送信元ポートを併用して、各々のアプリケーション (プログラム) との一意性を確保している。

宛先ポート (Destination port) - ビット 16-31。 TCP パケットの宛先ポート。送信元ポートと同様に、元来は受信側システム上のプロセスを直接指し示していた。今日では、より多くのコネクションを同時に張れるよう、ハッシュ値が用いられる。パケットを受信したら、送信元への返答では宛先ポートと送信元ポートを逆さにする。つまり、元の宛先ポートが送信元ポート、送信元ポートが宛先ポートになるようにするわけだ。

シーケンスナンバー (Sequence Number) - ビット 32-63。シーケンスナンバーフィールドは各 TCP パケットに付け、 TCP ストリームが歯抜けにならないようにする (例えば、パケットが正しい順番で並ぶこと)。同じシーケンスナンバーは、パケットが問題なく届いたことを知らせるために、回答の際 ACK フィールドに載せて返される。

確認応答ナンバー (Acknowledge Number) - ビット 64-95。ホストの受け取った特定のパケットに対して承認を行う際に使用される。具体的に言えば、或るシーケンスナンバーを持ったパケットを受け取った時、パケットに特に問題がなかったら ACK パケットで承認の返事をするわけだが、その際、受け取ったパケットのシーケンスナンバーと同じ値をその確認応答ナンバーフィールドへセットして返答するのだ。

データオフセット (Data Offset) - ビット 96-99。このフィールドは、 TCP ヘッダの長さと、パケットのデータ部がどこから始まっているのかを示す。これは 4 ビットで表され、 TCP ヘッダを 32 ビットのワード単位で数えた値となる。ヘッダは、どんなオプションが使われていようとも常に 32ビット境界で終わっていなければならない。それを可能にしているのは、 TCP ヘッダの末端にあるパディングフィールド だ。

予約域 (Reserved) - ビット 100-103。これらのビットは将来の用途のために確保されている。 RFC 793 では、 CWR ビットと ECE ビットの位置もこの予約域こ規定されていた。 RFC 793 によれば 100-105 (つまり、ここと CWR および ECE フィールド) はゼロになっていなければ、規格に完全に整合しているとはいえないのだ。後になって ECN が提唱されると、多くのインターネットアプリケーション (例えばファイヤーウォールやルータ) がこの部分のビットの立ったパケットを破棄してしまうという障害を多発させる結果となった。こうして書いている今現在でも、この問題は継続している。

CWR - ビット 104。このビットは RFC 3268 で追加され、 ECN に利用されている。 CWRCongestion Window Reduced を表し、データを送った側が受け取り側へ、輻輳制御ウィンドウ (congestion window) が縮小されたことを知らせるために利用される。輻輳制御ウィンドウ が縮小したら、我々は時間当たりの送信データ量を減らすことによってネットワーク負荷の総量の折り合いを付けることができる。

ECE - ビット 105。このビットも RFC 3268 で追加され、 ECN に利用されている。 ECEECN Echo を表す。 ECE は受信側の TCP/IP スタックによって使用され、 CE パケットを受け取った旨を送信側ホストに知らせる役目をする。ここでも CWR ビットと同じことが言え、ここがかつて予約済みフィールドだったことから、ゼロ以外の値を持つパケットは、ネットワーク機器によっては破棄されてしまう恐れがある。残念なことだが、実際、そうしたアプライアンスはまだまだ存在する。

URG - ビット 106。このフィールドは、緊急ポインタ (Urgent Pointer) フィールドを使用するべきか否かを伝える。 0 ならば緊急ポインタは使うな、 1 ならば緊急ポインタを使うべし、となる。

ACK - ビット 107。パケットにこのビットを立てるのは、そのパケットが他のパケットに対する返答であり、先ほどのパケットがデータをきちんと運んできたという旨を知らせる時だ。パケットを正しく受け取り、パケットに何のエラーもなかった場合には、そのことを伝えるために必ず確認応答 (Acknowledgement) パケットを送ることになっている。このビットが立っているのを見たら、先ほどデータを送った送り主は、確認応答ナンバー (Acknowledgment Number) を見て承認の対象がどのパケットかを確認した後、バッファに保持していたそのデータを破棄する。

PSH - ビット 108。プッシュ (PUSH) フラグは、経路途中のあらゆるホスト上の TCP プロトコルに対して、データをすぐに最終ユーザへ送れと告げるのが役目。 "ホスト上のTCP" には、データを受け取ることになるホストが実装する TCP 機構も含まれる。この指示が行われると、 TCPウィンドウ上に残留しているデータの量にかかわらず、全データが強制送出 (push) される。

RST - ビット 109。リセット (RESET) フラグをセットするのは、相手方へ TCP コネクションの切断を要求したい時だ。切断の行わる場面は幾つか考えられるが、代表的なのが、既にコネクションが存在しなくなっていたりパケットが不正なものだったりした時の強制断絶だ。

SYN - ビット 110。 SYN (Synchronize sequence numbers = 同期シーケンスナンバー) は、コネクションの初めの接続確立行程で使用される。 SYN はふたつの場面で使われる。ひとつはコネクションの皮切りのパケット、そしてもうひとつが返答の SYN/ACK パケットだ。 SYN フラグをこれ以外の場面で使用することは許されていない。

FIN - ビット 111。 FIN ビットは、FIN ビットを送ったホストはもう送るべきデータがない、ということを示す。 FIN ビットを受け取った相手は FIN/ACK で応える。このやりとりが行われると、先に FIN ビットを出したホストはもうデータを送ることができない。ただしもう一方は、送信しかけていたデータを最後まで送りきることはできる。送りきった後、ホスト [: 後者] は FIN パケットを返し、締めの FIN/ACK を待つ。この手順を経ることによって、コネクションは CLOSED ステートへと落ちる。

ウィンドウ (Window) - ビット 112-127。ウィンドウフィールドは、パケットを受け取る側が、その時点で受け取り可能なデータの量を送信側へ知らせるのが役目。これは ACK パケットによって行われるのだが、その ACK パケットには、先ほど受け取ったパケットの承認を示すシーケンスナンバー とともに、次の ACK パケットまでに送信側の指定可能なシーケンスナンバーの最大値がウィンドウフィールドとして記載される。次の ACK パケットにはまた新しいウィンドウが反映される。

チェックサム (Checksum) - ビット 128-143。このフィールドは TCP ヘッダ全体としてのチェックサムを格納している。チェックサムは、ヘッダ 16 ビット毎の相補 (one's complement = 1の補数) の和 (sum) を求め、それの相補を求めた値。もしもヘッダが 16 ビット境界で終わっていなければ、それ以降のビットはゼロで埋められる。チェックサムを計算している最中は、チェックサム 自体はゼロにしておく。チェックサム はまた、96 ビットの疑似ヘッダを内包し、この疑似ヘッダには、宛先アドレス、送信元アドレス、プロトコル、TCP パケット長が含まれる。チェックサムTCP の信頼性を一段と高めるためにある。

緊急ポインタ (Urgent Pointer) - ビット 144-159。これは、緊急性の求められるデータの終端位置を指すポインタだ。受け取り側にいち早く処理してもらわなくてはならない重要なデータがコネクションに含まれている場合、送信側は、 URG フラグ を立てた上で、緊急ポインタ に緊急データの終端位置を示す。

オプション (Options) - ビット 160-**。オプションフィールド は可変長で、必須のもの以外に使いたいヘッダがあればここに入っている。このフィールドは必ず、大別すると 3つのサブフィールドから成っており、最初のフィールドはオプションフィールド の長さ、2番目は、どのオプションを使用しているか、そして最後にオプションそのものが来る。 TCPオプション の全種類は付録 TCPオプション で見られる。

パディング (Padding) - ビット **。 TCP ヘッダが 32 ビット境界で終わるように終端に詰め物 (padding) をするのがパディングフィールド の役割。これがあるおかげで、パケットのデータ部は 32 ビット境界から開始することができ、パケット内のデータを隈無く読んでもらえるのだ。詰め物は常に全部ゼロ。