伝送制御プロトコル(TCP )は、インターネットプロトコルスイートの主要プロトコルの1つであり、 IPネットワークを介して通信するホスト上で動作するアプリケーション間で、オクテット(バイト)のストリームを信頼性が高く、順序付けされ、エラーチェックされた状態で配信します。TCPは、インターネットプロトコル(IP)を補完する形で、初期のネットワーク実装に登場しました。そのため、このスイート全体は一般的にTCP/IPと呼ばれています。
ワールドワイドウェブ、電子メール、リモート管理、ファイル転送、ストリーミングメディアなどの主要なインターネットアプリケーションは、 TCP/IPスイートのトランスポート層の一部であるTCPに依存しています。SSL /TLSは多くの場合TCP上で動作します。今日でもTCPはほとんどのインターネット通信の中核プロトコルであり、多様なネットワーク間で信頼性の高いデータ転送を保証します。[ 1 ]
TCP はコネクション指向であり、送信者と受信者は合意されたパラメータに基づいて最初に接続を確立する必要があります。これは、3 ウェイハンドシェイク手順によって行われます。[ 2 ]サーバーは、接続が確立される前にクライアントからの接続要求を待機(パッシブ オープン)する必要があります。3 ウェイ ハンドシェイク(アクティブ オープン)、再送信、およびエラー検出は信頼性を高めますが、レイテンシを長くします。信頼性の高いデータ ストリームサービスを必要としないアプリケーションは、代わりにユーザー データグラム プロトコル(UDP)を使用できます。UDP は、信頼性よりも時間を優先するコネクションレスデータグラムサービスを提供します。TCP はネットワークの輻輳を回避します。ただし、TCP には、サービス拒否、接続ハイジャック、TCP 拒否、リセット攻撃などの脆弱性があります。
1974 年 5 月、ヴィント・サーフとボブ・カーンは、ネットワーク ノード間でパケット交換を使用してリソースを共有するためのインターネットワーキングプロトコルについて説明しました。 [ 3 ]著者らは、フランスのCYCLADESプロジェクトの概念を新しいネットワークに組み込むために、ジェラール・ル・ランと協力していました。 [ 4 ]その結果作成されたプロトコルの仕様であるRFC 675 (インターネット伝送制御プログラムの仕様)は、ヴィント・サーフ、ヨーゲン・ダラル、カール・サンシャインによって書かれ、1974 年 12 月に公開されました。 [ 5 ]これは、インターネットという用語が、インターネット ワークの略語として初めて使用されたことが確認されています。
伝送制御プログラムは、ホスト間の接続指向リンクとデータグラムサービスの両方を組み込んでいました。バージョン 4 では、モノリシックな伝送制御プログラムは、伝送制御プロトコルとインターネットプロトコルからなるモジュール型アーキテクチャに分割されました。[ 6 ] [ 7 ]これにより、非公式にはTCP/IPとして知られるネットワーク モデルが生まれましたが、正式には、国防総省インターネット アーキテクチャ モデル(略してDoD モデル) またはDARPA モデルなどと呼ばれていました。[ 8 ] [ 9 ] [ 10 ]後に、インターネット プロトコル スイートの一部となり、インターネット プロトコル スイートと同義になりました。TCP は、RFC 9293 (2022) などの RFC で標準化された段階的な更新とベスト プラクティスにより進化を続けています。[ 11 ]
以下のインターネット実験ノート(IEN)文書は、TCPが現代版へと進化する過程を説明しています。[ 12 ]
TCPは1980年1月にRFC 761として標準化された。
2004年、ヴィント・サーフとボブ・カーンはTCP/IPの基礎研究に対してチューリング賞を受賞した。 [ 13 ] [ 14 ]
伝送制御プロトコル(TCP)は、アプリケーションプログラムとインターネットプロトコル(IP)の中間層で通信サービスを提供します。インターネットモデルのトランスポート層において、ホスト間の接続を実現します。アプリケーションは、伝送媒体の最大伝送単位に対応するために必要なIPフラグメンテーションなど、リンクを介して別のホストにデータを送信するための具体的なメカニズムを知る必要はありません。トランスポート層では、TCPがハンドシェイクと伝送の詳細をすべて処理し、通常はネットワークソケットインターフェースを介して、ネットワーク接続の抽象化をアプリケーションに提供します。
プロトコルスタックの下位レベルでは、ネットワークの混雑、トラフィック負荷分散、または予測不可能なネットワーク動作により、IPパケットが失われたり、重複したり、順不同で配信されたりする可能性があります。TCPはこれらの問題を検出し、失われたデータの再送信を要求し、順不同のデータを並べ替え、ネットワークの混雑を最小限に抑えて他の問題の発生を減らすよう支援します。それでもデータが配信されない場合は、送信元にこの障害が通知されます。TCP受信側は、最初に送信されたオクテットのシーケンスを再構成すると、それを受信アプリケーションに渡します。このように、TCPはアプリケーションの通信を基盤となるネットワークの詳細から抽象化します。
TCPは、タイムリーな配信よりも正確な配信に最適化されており、順不同のメッセージの待機や紛失したメッセージの再送信に比較的長い遅延(数秒程度)が発生する可能性があります。そのため、VoIPなどのリアルタイムアプリケーションにはあまり適していません。このようなアプリケーションには、通常、ユーザーデータグラムプロトコル(UDP)上で動作するリアルタイムトランスポートプロトコル(RTP)などのプロトコルが推奨されます。[ 15 ]
TCPは、受信したすべてのバイトが送信したバイトと同一かつ同じ順序であることを保証する信頼性の高いバイトストリーム配信サービスです。多くのネットワークではパケット転送が信頼できないため、TCPは再送付き肯定応答と呼ばれる技術を使用してこれを実現します。これは、受信側がデータを受信すると、確認応答メッセージで応答する必要があることを意味します。送信側は送信した各パケットの記録を保持し、パケットが送信された時点からのタイマーを維持します。確認応答を受信する前にタイマーが期限切れになった場合、送信側はパケットを再送信します。タイマーは、パケットが失われたり破損したりした場合に備えて必要です。[ 15 ]
IPはデータの実際の配信を処理する一方、TCPはセグメント(ネットワークを効率的にルーティングするためにメッセージが分割される個々のデータ伝送単位)を管理します。たとえば、WebサーバーからHTMLファイルが送信されると、そのサーバーのTCPソフトウェア層はファイルをセグメントに分割し、ネットワークスタックのインターネット層に個別に転送します。インターネット層のソフトウェアは、宛先IPアドレスなどのデータを含むヘッダーを追加することで、各TCPセグメントをIPパケットにカプセル化します。宛先コンピュータ上のクライアントプログラムがそれらを受信すると、トランスポート層のTCPソフトウェアはセグメントを再構成し、受信アプリケーションにファイルの内容をストリーミングする際に、セグメントが正しい順序でエラーがないことを確認します。
伝送制御プロトコルはデータストリームからデータを受け取り、それをチャンクに分割し、TCPヘッダーを追加してTCPセグメントを作成します。TCPセグメントはインターネットプロトコル(IP)データグラムにカプセル化され、ピアと交換されます。[ 16 ]
TCPパケットという用語は非公式にも公式にも使われますが、より正確な用語ではセグメントはTCPプロトコルデータユニット(PDU)を指し、データグラム[ 17 ]はIP PDUを指し、フレームはデータリンク層PDUを指します。
プロセスは、TCP を呼び出し、データ バッファを引数として渡すことでデータを送信します。TCP はこれらのバッファからデータをセグメントにパッケージ化し、インターネット モジュール [例えば IP] を呼び出して各セグメントを宛先 TCP に送信します。[ 18 ]
TCPセグメントは、セグメントヘッダーとデータセクションで構成されます。セグメントヘッダーには、10個の必須フィールドと、オプションの拡張フィールド(オプション、表の20~56番目のオクテット)が含まれます。データセクションはヘッダーの後に続き、アプリケーションが運ぶペイロードデータです。[ 19 ]データセクションの長さはセグメントヘッダーでは指定されていません。IPヘッダーで指定されている合計IPデータグラム長から、セグメントヘッダーとIPヘッダーを合わせた長さを差し引くことで計算できます。
Options length (bytes) = (Data Offset − 5) × 4; equivalent bit formula per RFC 9293: (Data Offset − 5) × 32[SYN]。オプションの種類と標準の長さは(オプションの種類、オプションの長さ)として指定されます。
TCPプロトコルの動作は、大きく3つのフェーズに分けられます。接続確立は、データ転送フェーズに入る前に接続を確立する、複数ステップからなるハンドシェイクプロセスです。データ転送が完了すると、接続終了によって接続が閉じられ、割り当てられたすべてのリソースが解放されます。
TCP接続は、通信のローカルエンドポイントを表すリソースであるインターネットソケットを介してオペレーティングシステムによって管理されます。TCP接続の存続期間中、ローカルエンドポイントは一連の状態変化を受けます。[ 34 ]

クライアントがサーバーに接続を試みる前に、サーバーはまずポートにバインドして接続を受け付けられるようにする必要があります。これをパッシブオープンと呼びます。パッシブオープンが確立されると、クライアントは3ウェイ(または3ステップ)ハンドシェイクを使用してアクティブオープンを開始することで接続を確立できます。
ステップ1とステップ2では、一方向(クライアントからサーバー)のシーケンス番号を確立し、確認応答を行います。ステップ2とステップ3では、もう一方の方向(サーバーからクライアント)のシーケンス番号を確立し、確認応答を行います。これらのステップが完了すると、クライアントとサーバーの両方が確認応答を受信し、全二重通信が確立されます。


接続終了フェーズでは、4 ウェイ ハンドシェイクが使用され、接続の両側が独立して終了します。エンドポイントが接続の自分の側を停止したい場合、FIN パケットを送信し、もう一方のエンドポイントは ACK でそれを確認応答します。したがって、一般的な切断には、各 TCP エンドポイントからの FIN セグメントと ACK セグメントのペアが必要です。最初の FIN を送信した側が最後の ACK で応答した後、最終的に接続を閉じる前にタイムアウトを待ちます。この間、ローカル ポートは新しい接続に使用できません。この状態により、TCP クライアントは、ACK が転送中に失われた場合にサーバーに最後の確認応答を再送信できます。タイムアウト時間は実装に依存しますが、一般的な値としては 30 秒、1 分、2 分などがあります。タイムアウト後、クライアントは CLOSED 状態になり、ローカル ポートは新しい接続に使用できるようになります。[ 35 ]
ホスト A が FIN を送信し、ホスト B が FIN と ACK で応答し (2 つのステップを 1 つにまとめる)、ホスト A が ACK で応答する場合、3 ウェイ ハンドシェイクによって接続を終了することも可能である。[ 36 ]
Linux [ 37 ]などの一部のオペレーティングシステムは、半二重クローズシーケンスを実装しています。ホストが未読の受信データがまだ利用可能な状態で接続をアクティブに閉じる場合、ホストは FIN の代わりに RST シグナルを送信します (受信データはすべて失われます)。これにより、TCP アプリケーションはデータ損失が発生したことを認識できます。[ 38 ]
接続は半開状態になることがあります。この場合、一方の側が接続を終了しましたが、もう一方の側は終了していません。接続を終了した側は接続にデータを送信できなくなりますが、もう一方の側は送信できます。接続を終了した側は、もう一方の側も接続を終了するまでデータの読み取りを続ける必要があります。[ 39 ] [ 40 ]
ほとんどの実装では、セッションを実行中のオペレーティングシステムプロセスにマッピングするエントリをテーブルに割り当てます。TCPパケットにはセッション識別子が含まれていないため、両方のエンドポイントはクライアントのアドレスとポートを使用してセッションを識別します。パケットを受信するたびに、TCP実装はこのテーブルを参照して宛先プロセスを見つける必要があります。テーブル内の各エントリは、伝送制御ブロック(TCB)と呼ばれます。TCBには、エンドポイント(IPアドレスとポート番号)、接続の状態、交換中のパケットに関する実行中のデータ、およびデータの送受信用のバッファに関する情報が含まれています。
サーバー側のセッション数はメモリ容量によってのみ制限され、新しい接続が到着するにつれて増加しますが、クライアントはサーバーに最初のSYNを送信する前に一時的なポートを割り当てる必要があります。このポートは通信全体を通して割り当てられたままになり、クライアントの各IPアドレスからの発信接続数を実質的に制限します。アプリケーションが不要な接続を適切に閉じられない場合、クライアントはリソース不足に陥り、他のアプリケーションからであっても新しいTCP接続を確立できなくなる可能性があります。
両方のエンドポイントは、未確認パケットと受信済み(ただし未読)データのための領域も確保する必要がある。
伝送制御プロトコルは、ユーザーデータグラムプロトコルと比較して、いくつかの重要な点で異なっている。
TCPは、各データバイトを識別するためにシーケンス番号を使用します。シーケンス番号は、各コンピュータから送信されるバイトの順序を識別するため、データの配信順序が前後した場合でも、データを正しい順序で復元できます。最初のバイトのシーケンス番号は、SYNフラグが付けられた最初のパケットの送信側によって選択されます。この番号は任意であり、TCPシーケンス予測攻撃を防ぐために、実際には予測不可能であるべきです。
確認応答(ACK)は、データの受信側がシーケンス番号とともに送信側に送信し、指定されたバイトまでデータが受信されたことを送信側に通知します。ACKはデータがアプリケーションに配信されたことを意味するものではなく、単に受信側がデータを配信する責任を負ったことを示すものです。
信頼性は、送信側がデータの損失を検出し、それを再送信することによって実現されます。TCPは、損失を検出するために主に2つの手法を使用します。再送信タイムアウト(RTO)と重複累積確認応答(DupAcks)です。
TCPセグメントが再送信されると、元の配信試行と同じシーケンス番号が保持されます。配信と論理的なデータ順序が混同されるため、再送信後に確認応答を受信した場合、送信側は元の送信と再送信のどちらが確認応答されているのかを判別できません。これが、いわゆる再送信の曖昧さです。[ 41 ] TCPは再送信の曖昧さのために複雑化します。[ 42 ]
ストリーム内の単一のセグメント (たとえばセグメント番号 100) が失われた場合、受信側は累積 ACK を使用するため、そのセグメント番号 (100) より上のパケットを承認できません。したがって、受信側は別のデータ パケットを受信すると、パケット 99 を再度承認します。この重複した承認は、パケット損失のシグナルとして使用されます。つまり、送信側が 3 つの重複した承認を受信すると、最後に確認されていないパケットを再送信します。3 というしきい値が使用されるのは、ネットワークがセグメントの順序を変更して重複した承認を引き起こす可能性があるためです。このしきい値は、順序変更による誤った再送信を回避することが実証されています。[ 43 ]一部の TCP 実装では、受信したセグメントに関する明示的なフィードバックを提供するために選択的承認(SACK) を使用します。これにより、TCP が正しいセグメントを再送信する能力が大幅に向上します。
再送の曖昧さは、重複確認のしきい値を超える再順序付けがある場合、誤った高速再送や輻輳回避を引き起こす可能性があります。[ 44 ]過去20年間、インターネット上でパケットの再順序付けがより多く観測されており[ 45 ]、LinuxカーネルなどのTCP実装では、重複確認のしきい値をスケーリングするためにヒューリスティックな方法を採用しています。[ 46 ]最近では、重複ACKベースの高速再送を完全に段階的に廃止し、タイマーベースのものに置き換える取り組みが行われています。[ 47 ] (以下で説明する従来のRTOと混同しないでください)。Recent Acknowledgment (RACK) [ 48 ]と呼ばれる時間ベースの損失検出アルゴリズムは、LinuxとWindowsのデフォルトアルゴリズムとして採用されています。[ 49 ]
送信者がセグメントを送信すると、確認応答の到着時間の保守的な推定値でタイマーを初期化します。タイマーが期限切れになるとセグメントが再送信され、新しいタイムアウトしきい値は以前の値の 2 倍になり、指数バックオフ動作になります。通常、初期タイマー値は平滑化された RTT + max( G、 4 × RTT 変動)で、Gはクロックの粒度です。[ 50 ]これにより、中間者攻撃によるサービス拒否攻撃者など、欠陥のあるまたは悪意のあるアクターによる過剰な送信トラフィックから保護されます。
正確な RTT 推定は損失回復にとって重要です。なぜなら、送信者は十分な時間が経過した後 (つまり、RTO 時間を決定した後)、未確認パケットが失われたと想定できるからです。[ 51 ]再送の曖昧さにより、送信者の RTT 推定が不正確になる可能性があります。[ 51 ] RTT が変動する環境では、誤ったタイムアウトが発生する可能性があります。[ 52 ] RTT が過小評価されている場合、RTO が発火し、不要な再送とスロースタートがトリガーされます。誤った再送の後、元の送信の確認応答が到着すると、送信者はそれらが再送の確認応答であると信じ、元の送信と再送信の間に送信されたセグメントが失われたと誤って結論付け、リンクが実際に混雑するほど、さらに不要な再送が発生します。[ 53 ] [ 54 ]選択的確認応答はこの影響を軽減できます。[ 55 ] RFC 6298では、RTT を推定する際に再送信セグメントを使用してはならないと規定されています。[ 56 ] Karn のアルゴリズムは、 RTO を調整する前に明確な確認応答があるまで待つことで、最終的には良好な RTT 推定値が得られることを保証します。 [ 57 ]しかし、誤った再送信の後では、そのような明確な確認応答が到着するまでにかなりの時間がかかる場合があり、その間パフォーマンスが低下します。[ 58 ] TCP タイムスタンプも RTO の設定における再送信の曖昧さの問題を解決しますが、[ 56 ]必ずしも RTT 推定値を改善するわけではありません。[ 59 ]
シーケンス番号により、受信側は重複パケットを破棄し、順序が乱れたパケットを正しく処理することができます。確認応答により、送信側は紛失したパケットを再送信するタイミングを判断できます。
正確性を保証するためにチェックサム フィールドが含まれています。詳細については、§ チェックサムの計算を参照してください。TCP チェックサムは現代の基準では弱いチェックであり、通常はPPPやイーサネットフレームで使用されるような、TCP と IP の両方の下位レイヤー 2でのCRC整合性チェックと組み合わせて使用されます。ただし、CRC で保護されたホップ間のパケットにエラーが混入することはよくあり、16 ビットの TCP チェックサムはこれらのほとんどを検出します。[ 60 ]
TCPはエンドツーエンドのフロー制御プロトコルを使用して、送信側がTCP受信側が確実に受信および処理できる速度よりも速くデータを送信することを回避します。フロー制御のメカニズムを持つことは、ネットワーク速度が異なるマシンが通信する環境では不可欠です。たとえば、PCがスマートフォンにデータを送信し、スマートフォンが受信データの処理に時間がかかる場合、スマートフォンはデータフローを制御できなければ、データに圧倒されてしまいます。[ 15 ]
TCPはスライディングウィンドウ方式のフロー制御プロトコルを使用します。各TCPセグメントにおいて、受信側は受信ウィンドウフィールドに、接続のためにバッファリングできる追加受信データ量(バイト単位)を指定します。送信側ホストは、受信側ホストからの確認応答と受信ウィンドウの更新を待つ前に、指定されたデータ量までしか送信できません。

受信側がウィンドウサイズ0を通知すると、送信側はデータの送信を停止し、パーシスタイマーを開始します。パーシスタイマーは、受信側からの後続のウィンドウサイズ更新が失われた場合に発生する可能性のあるデッドロック状態からTCPを保護するために使用されます。受信側から新しいウィンドウサイズ更新を受信するまで、送信側はそれ以上データを送信できません。パーシスタイマーが期限切れになると、TCP送信側は小さなパケットを送信して回復を試み、受信側は新しいウィンドウサイズを含む別の確認応答を送信して応答します。
受信側が受信データを小さな単位で処理する場合、小さな受信ウィンドウを繰り返し通知することがあります。これは、TCPヘッダーのオーバーヘッドが比較的大きいことを考えると、TCPセグメントで数バイトのデータしか送信しないのは非効率的であるため、 「無駄なウィンドウ症候群」と呼ばれています。
TCPの最後の主要な側面は輻輳制御です。TCPは、高いパフォーマンスを実現し、ネットワークのパフォーマンスが著しく低下する混雑状態である輻輳崩壊を回避するために、いくつかのメカニズムを使用します。これらのメカニズムは、ネットワークに流入するデータの速度を制御し、データフローが輻輳崩壊を引き起こす速度を下回るようにします。また、フロー間でほぼ最大最小の公平な割り当てを実現します。
送信されたデータに対する確認応答、あるいは確認応答の欠如は、送信側がTCP送信側と受信側の間のネットワーク状態を推測するために使用されます。タイマーと組み合わせることで、TCP送信側と受信側はデータフローの動作を変更できます。これは一般的に輻輳制御または輻輳回避と呼ばれます。
TCPの最新の実装には、スロースタート、輻輳回避、高速再送信、高速回復という4つの相互に関連するアルゴリズムが含まれています。[ 61 ]
さらに、送信者は、送信者と受信者間の推定往復時間(RTT) と、この往復時間のばらつきに基づいて再送タイムアウト(RTO) を採用します。 [ 62 ] RTT の推定には微妙な点があります。たとえば、送信者は再送パケットの RTT サンプルを計算する際に注意する必要があります。通常、送信者はKarn のアルゴリズムまたは TCP タイムスタンプを使用します。[ 29 ]これらの個々の RTT サンプルは、 Jacobson のアルゴリズムを使用して、時間にわたって平均化され、平滑化された往復時間 (SRTT) が作成されます。この SRTT 値が往復時間の推定値として使用されます。
TCPを強化し、パケット損失を確実に処理し、エラーを最小限に抑え、輻輳を管理し、超高速環境でも高速に動作するようにすることは、継続的な研究および標準化開発の分野です。その結果、TCPの輻輳回避アルゴリズムには数多くのバリエーションが存在します。
最大セグメントサイズ(MSS)は、TCPが1つのセグメントで受信できる最大データ量(バイト単位)です。最高のパフォーマンスを得るには、パケット損失や過剰な再送信につながるIPフラグメンテーションを回避するために、MSSを十分に小さく設定する必要があります。これを実現するために、通常、TCP接続が確立される際に、各側がMSSオプションを使用してMSSを通知します。このオプションの値は、送信側と受信側が直接接続されているネットワークのデータリンク層の最大伝送単位(MTU)サイズから算出されます。TCP送信側は、パスMTU検出を使用して、送信側と受信側の間のネットワークパスに沿った最小MTUを推測し、これを利用してMSSを動的に調整し、ネットワーク内でのIPフラグメンテーションを回避できます。
MSS アナウンスはMSS ネゴシエーションとも呼ばれますが、厳密に言えば MSS はネゴシエーションされません。TCP 接続では、データの双方向に対して 2 つの完全に独立した MSS 値が許可されているため、[ 63 ] [ 18 ]双方向接続の共通の MSS 構成に合意する必要はありません。
オリジナルのTCPで採用されている累積確認応答方式だけに頼ると、パケットが失われた場合に非効率になる可能性があります。たとえば、シーケンス番号1,000から10,999までのバイトが、同じサイズの10個の異なるTCPセグメントで送信され、2番目のセグメント(シーケンス番号2,000から2,999)が送信中に失われたとします。純粋な累積確認応答プロトコルでは、受信側は累積ACK値2,000(受信データの最後のシーケンス番号の直後のシーケンス番号)しか送信できず、3,000から10,999までのバイトを正常に受信したとは言えません。そのため、送信側はシーケンス番号2,000から始まるすべてのデータを再送信する必要が生じる可能性があります。
この問題を解決するために、TCP は1996 年にRFC 2018で定義された選択的確認応答 (SACK)オプションを使用します。このオプションを使用すると、受信側は、基本的な TCP 確認応答と同様に、連続して受信した最後のバイトの最後のシーケンス番号の直後のシーケンス番号に加えて、正しく受信した不連続なパケットブロックを確認応答できます。確認応答には複数のSACK ブロックを含めることができ、各 SACK ブロックはブロックの左端(ブロックの最初のシーケンス番号) とブロックの右端(ブロックの最後のシーケンス番号の直後のシーケンス番号) によって伝達されます。ブロックとは、受信側が正しく受信した連続した範囲のことです。上記の例では、受信側は累積 ACK 値が 2,000 の ACK セグメントと、シーケンス番号 3,000 と 11,000 の SACK オプション ヘッダーを送信します。したがって、送信者はシーケンス番号が2,000から2,999までの2番目のセグメントのみを再送信する。
TCP送信側は、順序が乱れたセグメント配信をセグメントの損失と解釈する場合があります。その場合、TCP送信側は順序が乱れたパケットの前のセグメントを再送信し、その接続におけるデータ配信速度を低下させます。この問題は、2000年5月にRFC 2883で定義されたSACKオプションの拡張機能であるduplicate-SACKオプションによって解決されます。TCP受信側は、2つ目の重複パケットを検出すると、セグメントの損失がなかったことを示すD-ACKを送信し、TCP送信側がより高い送信速度を回復できるようにします。
SACKオプションは必須ではなく、両方の当事者がサポートしている場合にのみ有効になります。これは接続確立時にネゴシエートされます。SACKはTCPヘッダーオプションを使用します(詳細は「TCPセグメント構造」の項を参照)。SACKの使用は広く普及しており、主要なTCPスタックはすべてSACKをサポートしています。選択的確認応答は、 ストリーム制御伝送プロトコル(SCTP)でも使用されています。
選択的確認応答は「取り消し」される可能性があり、受信側が選択的に確認されたデータを一方的に破棄します。RFC 2018 ではこのような動作は推奨されませんでしたが、受信側がバッファ領域が不足した場合などに取り消しのオプションを許可するために禁止はされませんでした。[ 64 ]取り消しの可能性は、送信側と受信側の両方で実装の複雑さを招き、送信側にメモリコストも課します。[ 65 ]
高帯域幅ネットワークをより効率的に利用するために、より大きなTCPウィンドウサイズを使用する場合があります。16ビットのTCPウィンドウサイズフィールドはデータの流れを制御し、その値は65,535バイトに制限されています。サイズフィールドはこの制限を超えて拡張できないため、スケーリング係数が使用されます。RFC 1323で定義されているTCPウィンドウスケールオプションは、最大ウィンドウサイズを1ギガバイトに増やすために使用されるオプションです。これらのより大きなウィンドウサイズへのスケーリングは、TCPチューニングに必要です。
ウィンドウ スケール オプションは、TCP 3 ウェイ ハンドシェイク中にのみ使用されます。ウィンドウ スケールの値は、16 ビットのウィンドウ サイズ フィールドを解釈する際に左シフトするビット数を表します。ウィンドウ スケールの値は、各方向で個別に 0 (シフトなし) から 14 まで設定できます。ウィンドウ スケーリングを有効にするには、両方の側が SYN セグメントでこのオプションを送信する必要があります。
一部のルーターやパケットファイアウォールは、送信中にウィンドウのスケーリング係数を書き換えます。これにより、送信側と受信側で異なるTCPウィンドウサイズが想定されるようになります。その結果、不安定なトラフィックが発生し、非常に遅くなる場合があります。この問題は、欠陥のあるルーターの背後にある一部のサイトで顕著に現れます。[ 66 ]
1992年にRFC 1323で定義されたTCPタイムスタンプは、TCPがパケットの送信順序を判断するのに役立ちます。TCPタイムスタンプは通常、システムクロックに同期しておらず、ランダムな値から始まります。多くのオペレーティングシステムは、経過したミリ秒ごとにタイムスタンプをインクリメントしますが、RFCでは、そのインクリメントが比例的であるべきであるとだけ規定しています。
タイムスタンプフィールドは2つあります。
TCPタイムスタンプは、シーケンス番号のラップアラウンド防止( PAWS)と呼ばれるアルゴリズムで使用されます。PAWSは、受信ウィンドウがシーケンス番号のラップアラウンド境界を越える場合に使用されます。パケットが再送信された可能性がある場合、「このシーケンス番号は最初の4GBに含まれるのか 、それとも2番目の4GBに含まれるのか?」という疑問に答えます。そして、タイムスタンプを使用して、その判断を確定します。
また、Eifel検出アルゴリズムはTCPタイムスタンプを使用して、再送信がパケットの損失によるものか、単に順序が乱れているためかを判断します。[ 67 ]
TCPタイムスタンプはLinuxではデフォルトで有効になっており[ 68 ] 、 Windows Server 2008、2012、2016ではデフォルトで無効になっています[ 69 ]。
最近の統計によると、Windows Server 2008以降、Windows Serverがサポートを終了したため、TCPタイムスタンプの採用率は約40%で停滞している。[ 70 ]
ストリームの終了を待つ代わりに、キューに入れられたストリームを中断または中止することが可能です。これは、データを緊急として指定することによって行われます。これにより、送信が帯域外データ(OOB) としてマークされ、受信プログラムにそれをすぐに処理するように指示されます。処理が完了すると、TCP はアプリケーションに通知し、ストリームキューを再開します。例として、TCP がリモートログインセッションで使用される場合、ユーザーはキーボードシーケンスを送信して、プログラムが現在の転送を完了するのを待たずに、リモートで実行されているプログラムを中断または中止することができます。[ 15 ]
緊急ポインタはリモートホストでの処理のみを変更し、ネットワーク自体での処理を早めることはありません。この機能はシステムによって実装方法が異なるか、不十分な場合があり、サポートされていない場合もあります。利用可能な場合は、OOB データの 1 バイトのみが確実に処理されると想定するのが賢明です。[ 71 ] [ 72 ]この機能は頻繁に使用されないため、一部のプラットフォームでは十分にテストされておらず、たとえばWinNukeなどの脆弱性に関連付けられています。
通常、TCPはデータパケット全体を送信するまで200ミリ秒待機します( Nagleアルゴリズムは小さなメッセージを1つのパケットにまとめようとします)。この待機は、ファイル転送中に繰り返し発生すると、わずかではあるものの深刻な遅延を引き起こす可能性があります。たとえば、一般的な送信ブロックは4KB 、一般的なMSSは1460なので、10Mbit /sイーサネットでは2つのパケットがそれぞれ約1.2 ミリ秒で送信され、その後、TCPがバッファがいっぱいになるのを待っているため197ミリ秒の一時停止の後、残りの1176を運ぶ3つ目のパケットが 送信されます。Telnetの場合、ユーザーがキーを打つたびに、サーバーがそれをエコーバックしてから、ユーザーが画面で確認できるようになります。この遅延は非常に煩わしいものになります。
ソケットオプションを設定すると、TCP_NODELAYデフォルトの200 ミリ秒の送信遅延が上書きされます。アプリケーションプログラムは、このソケットオプションを使用して、文字または行を書き込んだ後に出力を強制的に送信します。
RFC 793 ではPSH、プッシュ ビットを「受信側の TCP スタックに、このデータを受信側のアプリケーションに直ちに送信するように指示するメッセージ」と定義しています。 [ 15 ] Berkeley ソケットを使用してユーザー空間でプッシュ ビットを指定または制御する方法はありません。プッシュ ビットはプロトコル スタックによってのみ制御されます。[ 73 ]
TCPはさまざまな方法で攻撃される可能性があります。TCPの徹底的なセキュリティ評価の結果と、特定された問題に対する可能な緩和策は2009年に公開され[ 74 ] 、 IETF内で2012年まで追求されました[ 75 ]。注目すべき脆弱性には、サービス拒否、接続ハイジャック、TCP拒否、TCPリセット攻撃などがあります。
偽装された IP アドレスを使用し、意図的に組み立てられたSYN パケットを繰り返し送信し、その後多数の ACK パケットを送信することで、攻撃者はサーバーに偽の接続を追跡するための大量のリソースを消費させることができます。これはSYN フラッド攻撃として知られています。この問題に対する提案された解決策には、SYN クッキーや暗号パズルなどがありますが、SYN クッキーには独自の脆弱性があります。[ 76 ] Sockstressは同様の攻撃であり、システム リソース管理で軽減できる可能性があります。[ 77 ] TCP のパーシスト タイマーを悪用する高度な DoS 攻撃はPhrack No. 66で分析されました。[ 78 ] PUSH および ACK フラッドは他の亜種です。[ 79 ]
TCPセッションを傍受してパケットをリダイレクトできる攻撃者は、TCP接続をハイジャックすることができます。そのためには、攻撃者は進行中の通信からシーケンス番号を学習し、ストリーム内の次のセグメントのように見える偽のセグメントを偽造します。単純なハイジャックでは、一方の端で1つのパケットが誤って受け入れられる可能性があります。受信ホストが偽のセグメントを確認すると、同期が失われます。[ 80 ]ハイジャックは、 ARPスプーフィングやその他のルーティング攻撃と組み合わされ、攻撃者がTCP接続を恒久的に制御できるようになります。
RFC 1948以前は、初期シーケンス番号が容易に推測できたため、別のIPアドレスになりすますことは難しくありませんでした。以前の実装では、攻撃者はARPやルーティング攻撃による通信傍受を行うことなく、受信者が別のIPアドレスから送信されたと信じる一連のパケットを盲目的に送信することができました。なりすまそうとするIPアドレスの正当なホストがダウンしていることを確認するか、サービス拒否攻撃を使用してダウン状態にするだけで十分でした。これが、初期シーケンス番号がランダムに選択されるようになった理由です。
傍受して次に送信されるパケットのサイズを予測できる攻撃者は、既存の接続を中断することなく、受信側に悪意のあるペイロードを受け入れさせることができます。攻撃者は、次に予想されるパケットのシーケンス番号とペイロードサイズを持つ悪意のあるパケットを挿入します。最終的に正当なパケットが受信されると、既に受信済みのパケットと同じシーケンス番号と長さであることが判明し、通常の重複パケットとして静かに破棄されます。正当なパケットは悪意のあるパケットによって拒否されます。接続ハイジャックとは異なり、接続は決して同期が解除されず、悪意のあるペイロードが受け入れられた後も通信は通常どおり継続されます。TCP veto は攻撃者に通信に対する制御を少なくしますが、攻撃の検出に対する耐性を特に高めます。受信側にとって何かがおかしいという唯一の証拠は、IP ネットワークでは通常のことである単一の重複パケットです。拒否されたパケットの送信者は、攻撃の証拠を一切見ることができません。[ 81 ]
TCP接続は、送信元アドレス、送信元ポート、宛先アドレス、宛先ポートの4つ組で識別されます。 [ d ] [ 82 ] [ 83 ]ポート番号は、異なるサービスを識別し、ホスト間で複数の接続を可能にするために使用されます。[ 16 ] TCPは16ビットのポート番号を使用し、送信元ポートと宛先ポートそれぞれに65,536個の可能な値を提供します。[ 19 ]接続の識別がアドレスに依存しているため、TCP接続は単一のネットワークパスにバインドされます。TCPは、マルチホームホストが利用できる他のルートを使用することはできず、エンドポイントのアドレスが変更されると接続が切断されます。[ 84 ]
ポート番号は、よく知られているポート、登録済みポート、動的ポートまたはプライベートポートの 3 つの基本カテゴリに分類されます。よく知られているポートは、インターネット割り当て番号機関(IANA) によって割り当てられ、通常はシステムレベルのプロセスで使用されます。サーバーとして実行され、接続をパッシブに待機しているよく知られているアプリケーションは、通常これらのポートを使用します。例としては、FTP (20 と 21)、SSH (22)、TELNET (23)、SMTP (25)、SSL/TLS 上の HTTP (443)、HTTP (80) などがあります。[ e ]登録済みポート (1024 ~ 49151) は、サードパーティの開発者によって特定のサービスに割り当てられる場合がありますが、一部のオペレーティングシステムでは、この範囲から一時的なクライアントポートも割り当てられます。動的ポートまたはプライベートポート (49152 ~ 65535) は、登録済みサービスに関連付けられておらず、通常は一時的なクライアント接続用の一時ポートとしてのみ使用されます。
ネットワークアドレス変換(NAT)は、通常、パブリック側で動的なポート番号を使用して、パブリックネットワークとプライベートサブネットワーク間を通過するトラフィックの流れを明確にし、それによってサブネット上の多数のIPアドレス(およびそのポート)を単一のパブリックアドレスで処理できるようにします。
TCPは複雑なプロトコルです。しかし、長年にわたって大幅な機能強化が行われ、提案されてきましたが、その最も基本的な動作は、1974年の最初の仕様RFC 675と、 1981年9月に公開されたv4仕様RFC 793以来、大きく変わっていません。1989年10月に公開されたRFC 1122は、TCPプロトコルの実装要件のいくつかを明確にしました。8つの必須仕様と20を超える強く推奨される機能強化のリストは、RFC 7414で入手できます。このリストの中には、近年のTCP関連のRFCの中で最も重要なものの1つであるRFC 2581「TCP輻輳制御」があり、不必要な輻輳を回避する更新されたアルゴリズムについて説明しています。2001年には、輻輳回避シグナリングメカニズムである明示的輻輳通知(ECN)を説明するRFC 3168が作成されました。
元々のTCP輻輳回避アルゴリズムはTCP Tahoeとして知られていましたが、その後、TCP Reno、TCP Vegas、FAST TCP、TCP New Reno、TCP Hyblaなど、多くの代替アルゴリズムが提案されています。
マルチパス TCP (MPTCP) [ 85 ] [ 86 ]は、IETF 内で進行中の取り組みであり、TCP 接続が複数のパスを使用してリソースの使用を最大化し、冗長性を高めることを目的としています。無線ネットワークのコンテキストでマルチパス TCP が提供する冗長性により、異なるネットワークを同時に使用することが可能になり、スループットの向上とハンドオーバー機能の改善が実現します。マルチパス TCP は、データセンター環境でもパフォーマンス上の利点をもたらします。[ 87 ]マルチパス TCP のリファレンス実装[ 88 ]は、Linux カーネルで開発されました。[ 89 ]マルチパス TCP は、iPhone、iPad、Mac の Siri 音声認識アプリケーションをサポートするために使用されています。[ 90 ]
tcpcrypt は、 TCP 自体に直接トランスポート層暗号化を提供する目的で 2010 年 7 月に提案された拡張機能です。透過的に動作し、設定を必要としないように設計されています。TLS (SSL) とは異なり、 tcpcrypt 自体は認証を提供しませんが、アプリケーションが認証を行うためのシンプルなプリミティブを提供します。tcpcrypt RFC は、IETF によって 2019 年 5 月に公開されました。[ 91 ]
TCP Fast Open は、2 つのエンドポイント間で連続する TCP 接続の確立を高速化するための拡張機能です。暗号化されたCookieを使用して 3 ウェイ ハンドシェイクをスキップすることで機能します。これは、セキュリティ上の問題により広く採用されなかったT/TCPと呼ばれる以前の提案に似ています。 [ 92 ] TCP Fast Open は2014 年にRFC 7413として公開されました。[ 93 ]
2013年5月に提案された比例レート削減(PRR)は、Googleのエンジニアによって開発されたTCP拡張機能です。PRRは、回復後のTCPウィンドウサイズがスロースタートのしきい値にできるだけ近くなるようにします。[ 94 ]このアルゴリズムは回復速度を向上させるように設計されており、Linux 3.2以降のカーネルのデフォルトの輻輳制御アルゴリズムです。[ 95 ]
TCP Cookie Transactions (TCPCT) は、サービス拒否攻撃からサーバーを保護するために2009 年 12 月に提案された拡張機能です[ 96 ] 。SYN Cookie とは異なり、TCPCT はウィンドウ スケーリングなどの他の TCP 拡張機能と競合しません。TCPCT は、サーバーが多数の短命な TCP 接続を処理する必要があるDNSSECの必要性から設計されました。2016 年に、TCPCT は TCP Fast Open に置き換えられ、非推奨となりました。元の RFC のステータスは、historicalに変更されました。[ 97 ]
TCPの処理能力要件を克服する一つの方法は、TCPオフロードエンジン(TOE)として広く知られるハードウェア実装を構築することである。TOEの主な問題点は、コンピュータやデバイスのオペレーティングシステムに大幅な変更が必要となるため、コンピュータシステムへの統合が難しいことである。
TCP低電力(TCPlp)は、UDPベースのCoAPが好まれるようなリソース制約のある環境で動作することが実証されている。[ 98 ] [ 99 ]
TCP のワイヤデータは、プロトコル メタデータが平文で送信されるため、経路上の観測者に重要な情報収集と変更の機会を提供します。[ 100 ] [ 101 ]この透明性はネットワーク オペレーター[ 102 ]や研究者[ 103 ]にとって有用ですが、プロトコル メタデータから収集された情報はエンド ユーザーのプライバシーを低下させる可能性があります。[ 104 ]このメタデータの可視性と柔軟性により、TCP は拡張が困難になっています。これはプロトコルの硬直化の一例です。中間ノード (「ミドルボックス」) は、そのメタデータに基づいて決定を下したり、変更したりすることができ、[ 105 ] [ 106 ]エンド ツー エンドの原則を破ることになります。[ 107 ]ある測定では、インターネット上の経路の 3 分の 1 が、TCP メタデータを変更する少なくとも 1 つの中間ノードに遭遇し、経路の 6.5% が中間ノードからの有害な硬直化効果に遭遇していることがわかりました。[ 108 ]中間者による拡張性の危険を回避することは、 MPTCPの設計に大きな制約を課し、[ 109 ] [ 110 ]中間者によって引き起こされる困難は、 Web ブラウザでの TCP Fast Open の展開を妨げてきました。[ 111 ]もう 1 つの硬直化の原因は、エンドポイントでの TCP 機能の変更の難しさであり、通常はオペレーティングシステムのカーネル[ 112 ]またはTCP オフロード エンジンを備えたハードウェア[ 113 ]で行われます。
TCP はアプリケーションに信頼性の高いバイト ストリームの抽象化を提供するので、先頭ブロッキングの影響を受ける可能性があります。パケットが再順序付けされたり、失われたりして再送信が必要になった場合 (したがって再順序付けされた場合)、ストリームの順序的に後の部分のデータが、順序的に前の部分のデータよりも先に受信される可能性があります。ただし、通常は前のデータが受信されるまで後のデータは使用できず、ネットワーク遅延が発生します。複数の独立した上位レベルのメッセージがカプセル化され、単一の TCP 接続に多重化されている場合、先頭ブロッキングにより、後から送信された完全に受信されたメッセージの処理が、先に送信されたメッセージの配信を待つことになる可能性があります。[ 114 ] Web ブラウザーは、複数の並列接続を開くことで先頭ブロッキングを軽減しようとします。これにより、接続確立のコストが繰り返し発生し、エンドポイントでこれらの接続を追跡するために必要なリソースも増加します。[ 115 ]並列接続では、輻輳制御が互いに独立して動作するため、情報をプールして観測されたネットワークの状態に迅速に対応することはできません。[ 116 ] TCPの積極的な初期送信パターンは、複数の並列接続が開かれた場合に輻輳を引き起こす可能性があり、接続ごとの公平性モデルは、このアプローチを採用するアプリケーションによるリソースの独占につながる。[ 117 ]
接続確立は、Web ユーザーが経験する遅延の主な原因です。[ 118 ] [ 119 ] TCP の 3 ウェイ ハンドシェイクでは、データ送信前に接続確立中に 1 RTT の遅延が発生します。[ 119 ]短いフローの場合、これらの遅延は非常に大きくなります。[ 120 ]トランスポート層セキュリティ(TLS) では、接続確立時に鍵交換のために独自のハンドシェイクが必要です。階層設計のため、TCP ハンドシェイクと TLS ハンドシェイクは直列に実行されます。TLS ハンドシェイクは、TCP ハンドシェイクが終了するまで開始できません。[ 121 ] TCP 上のTLS 1.2で接続を確立するには 2 RTT が必要です。[ 122 ] TLS 1.3では、状況によっては 0 RTT 接続再開が可能ですが、TCP 上に階層化されている場合、TCP ハンドシェイクには 1 RTT が必要であり、これは初期接続には役立ちません。ゼロ RTT ハンドシェイクは、効率的でリプレイセーフかつ前方安全 な非対話型鍵交換が未解決の研究テーマであるため、暗号化上の課題も提示します。[ 123 ] TCP Fast Open は、最初の (SYN および SYN-ACK) パケットでデータを送信することを可能にし、接続確立中の 1 RTT の遅延を削減します。[ 124 ]しかし、TCP Fast Open はプロトコルの硬直化により展開が困難でした。2020年現在デフォルトではどのウェブブラウザも使用していなかった。 [ 111 ]
TCP スループットはパケットの順序変更の影響を受けます。順序変更されたパケットは重複した確認応答の送信を引き起こし、それがしきい値を超えると、誤った再送信と輻輳制御がトリガーされます。また、送信動作はバースト的になる可能性があり、範囲の先頭で順序変更されたパケットが受信されると、広範囲が一度に確認応答されます (ヘッド オブ ライン ブロッキングがアプリケーションに与える影響と同様の方法)。[ 125 ] BlantonとAllman (2002)は、スループットは順序変更の量に反比例し、すべての順序変更が誤った再送信をトリガーするしきい値までであることを発見しました。[ 126 ]順序変更の緩和は、送信者が誤った再送信を送信したことを判断できるかどうか、つまり再送信の曖昧さを解消できるかどうかに依存します。[ 127 ]順序変更によって誘発される誤った再送信を減らすと、実際の損失からの回復が遅くなる可能性があります。[ 128 ]
選択的確認応答はスループットに大きなメリットをもたらす可能性があります。Bruyeron 、Hemon 、 Zhang (1998)は最大 45% のゲインを測定しました。[ 129 ]改善の重要な要因は、選択的確認応答により損失後にスロースタートを回避できることが多くなり、利用可能な帯域幅をより有効に活用できることです。[ 130 ]ただし、TCP では最大 3 ブロックのシーケンス番号しか選択的に確認応答できません。これにより、再送レートが制限され、損失回復が妨げられたり、特に損失の多い環境では不要な再送が発生したりする可能性があります。[ 131 ] [ 132 ]
TCPは元々、パケット損失がネットワークの輻輳の結果であると考えられ、予防措置として輻輳ウィンドウサイズが大幅に縮小される有線ネットワーク向けに設計されました。しかし、無線リンクでは、フェージング、シャドウイング、ハンドオフ、干渉、その他の無線効果により、厳密には輻輳ではないものの、散発的で通常は一時的な損失が発生することが知られています。無線パケット損失による輻輳ウィンドウサイズの(誤った)バックオフの後、ウィンドウサイズを保守的に縮小する輻輳回避フェーズが発生する可能性があります。これにより、無線リンクが十分に活用されなくなります。これらの有害な影響に対処するための広範な研究が行われてきました。提案されたソリューションは、クライアントまたはサーバーでの変更を必要とするエンドツーエンドソリューション[ 133 ] 、セルラーネットワークの無線リンクプロトコルなどのリンクレイヤーソリューション、またはエンドノードを変更せずにネットワークに何らかの変更を必要とするプロキシベースのソリューションに分類できます。[ 133 ] [ 134 ]無線問題を解決するために、 Vegas、Westwood、Veno、Santa Cruzなどの代替輻輳制御アルゴリズムがいくつか提案されている。
TCPアクセラレータの考え方は、ネットワークプロセッサ内でTCP接続を終了し、データをエンドシステムへの2番目の接続に中継することです。送信元から発信されたデータパケットはアクセラレータノードでバッファリングされ、パケット損失が発生した場合にローカルでの再送信を実行します。したがって、損失が発生した場合、送信元と受信側の間のフィードバックループはアクセラレーションノードと受信側の間のループに短縮され、受信側へのデータのより高速な配信が保証されます。[ 135 ]
TCPはレート適応型プロトコルであるため、TCP送信側がネットワークにパケットを注入するレートは、ネットワーク内の負荷状況と受信側の処理能力に直接比例します。ネットワーク内の負荷状況は、送信側が受信した確認応答に基づいて判断されます。アクセラレーションノードは、送信側と受信側の間のフィードバックループを分割することで、パケットあたりの往復時間(RTT)を短縮します。RTTが短いほど、ネットワークの変化に対する応答時間が短縮され、送信側がこれらの変化に迅速に対応できるようになるため、有益です。
この方法の欠点としては、TCPセッションをアクセラレータ経由でルーティングする必要がある点が挙げられます。つまり、ルーティングが変更されてアクセラレータが経路から外れると、接続が切断されてしまいます。また、TCP ACKメカニズムのエンドツーエンド特性も損なわれます。送信側がACKを受信した時点で、パケットはアクセラレータに保存されているだけで、受信側には配信されていないためです。
ネットワークリンク上のTCPトラフィックを傍受するパケットスニファは、ネットワーク、ネットワークスタック、およびTCPを使用するアプリケーションのデバッグに役立ちます。パケットスニファは、リンクを通過するパケットをエンジニアに表示します。一部のネットワークスタックはSO_DEBUGソケットオプションをサポートしており、setsockoptを使用してソケットで有効にできます。このオプションは、そのソケット上のすべてのパケット、TCP状態、およびイベントをダンプするため、デバッグに役立ちます。Netstatもデバッグに使用できるユーティリティです。
多くのアプリケーションにとって、TCPは適切ではありません。アプリケーションは通常、失われたパケットの再送信コピーを受信するまで、失われたパケットの後に続くパケットにアクセスできません。これは、ストリーミングメディア、リアルタイムマルチプレイヤーゲーム、 VoIP( Voice over IP)などのリアルタイムアプリケーションにとって問題となります。これらのアプリケーションでは、すべてのデータを順番通りに取得するよりも、ほとんどのデータをタイムリーに取得する方が一般的に有用だからです。
歴史的背景とパフォーマンス上の理由から、ほとんどのストレージエリアネットワーク(SAN)はファイバーチャネル接続上でファイバーチャネルプロトコル(FCP)を使用しています。組み込みシステム、ネットワークブート、および多数のクライアントからの単純なリクエストを処理するサーバー(DNSサーバーなど)では、TCPの複雑さが問題となる場合があります。NATの背後にある2つのホスト間でデータを送信する(STUNなどのシステムを使用する)といった手法は、TCPのような比較的複雑なプロトコルを介さずに済むため、はるかに簡単になります。
一般的に、TCPが不適切な場合は、ユーザーデータグラムプロトコル(UDP)が使用されます。UDPはTCPと同様にアプリケーションの多重化とチェックサムを提供しますが、ストリームや再送信は処理しません。そのため、アプリケーション開発者は状況に応じて適切な方法でコードを記述したり、前方誤り訂正や誤り隠蔽などの他の方法で置き換えたりすることができます。
ストリーム制御伝送プロトコル(SCTP)は、TCPと同様に信頼性の高いストリーム指向サービスを提供するプロトコルです。TCPよりも新しく、かなり複雑なため、まだ広く普及していません。しかし、信頼性とほぼリアルタイム性が重要な状況での使用を想定して設計されています。
ベンチュリ伝送プロトコル(VTP)は、無線データ伝送における非効率性を克服するために、TCPを透過的に置き換えるように設計された特許取得済みの独自プロトコルです。特にモバイル通信や無線ネットワークでは、高遅延や信号干渉によりデータ伝送が不安定になることがあります。
TCPの輻輳回避アルゴリズムは、データ送信者が事前に不明なアドホック環境では非常に効果的です。環境が予測可能な場合は、非同期転送モード(ATM)などのタイミングベースのプロトコルを使用することで、TCPの再送信オーバーヘッドを回避できます。
UDPベースのデータ転送プロトコル(UDT)は、特にファイルやメディアのストリーミングなどの大規模なデータ転送など、高帯域幅、高遅延のネットワーク環境向けに設計されています。帯域 幅遅延積が高いネットワークでは、[ 136 ] UDTはTCPよりも優れた効率性と公平性を提供します。
多目的トランザクションプロトコル(MTP/IP)は、特許取得済みの独自ソフトウェアであり、特にTCPが非効率的とみなされるような、さまざまなネットワーク環境において、高いスループットとトランザクション性能を適応的に実現するように設計されています。
TCPがIPv4上で実行される場合、チェックサムを計算するために使用される方法は次のように定義されます。[ 18 ]
チェックサムフィールドは、ヘッダーとテキスト内のすべての 16 ビットワードの 1 の補数和の 16 ビット 1 の補数です。チェックサムの計算では、合計するデータの 16 ビットアライメントを確保する必要があります。セグメントに奇数個のヘッダーとテキストのオクテットが含まれている場合、チェックサム用に 16 ビットワードを形成するために、最後のオクテットの右側にゼロをパディングすることでアライメントを実現できます。パディングはセグメントの一部として送信されません。チェックサムを計算する際、チェックサムフィールド自体はゼロに置き換えられます。
つまり、適切なパディングの後、すべての16ビットワードが1の補数演算を使用して加算されます。その後、合計がビットごとに補数化され、チェックサムフィールドとして挿入されます。チェックサム計算で使用されるIPv4パケットヘッダーを模倣した擬似ヘッダーは次のとおりです。
チェックサムは以下のフィールドに基づいて計算されます。
TCPがIPv6上で実行される場合、チェックサムを計算するために使用される方法が変更されます。[ 137 ]
チェックサム計算にIPヘッダーのアドレスを含めるトランスポート層またはその他の上位層プロトコルは、IPv6で使用する場合、32ビットのIPv4アドレスの代わりに128ビットのIPv6アドレスを含めるように変更する必要があります。
チェックサムの計算に使用するIPv6ヘッダーを模倣した擬似ヘッダーを以下に示します。
チェックサムは以下のフィールドに基づいて計算されます。
Zeroes == 0多くのTCP/IPソフトウェアスタックの実装では、ネットワークアダプタ内でハードウェア支援を利用して、ネットワークへの送信前またはネットワークからの受信時にチェックサムを自動的に計算し、検証を行うオプションが提供されています。これにより、チェックサムの計算に伴うCPU負荷が軽減され、ネットワーク全体のパフォーマンスが向上する可能性があります。
この機能により、チェックサム オフロードの使用を認識していない、または確信が持てないパケット アナライザーが、ネットワーク アダプタにまだ到達していない送信パケットのチェックサムが無効であると報告する可能性があります。 [ 138 ]これは、ネットワーク アダプタによって送信される前に傍受されたパケットに対してのみ発生します。ネットワーク アダプタによってワイヤ上を送信されるすべてのパケットには有効なチェックサムがあります。[ 139 ]この問題は、同じホスト上の仮想マシン間で送信されるパケットを監視する場合にも発生する可能性があります。この場合、仮想デバイス ドライバは、チェックサムが後で VM ホスト カーネルまたはその物理ハードウェアによって計算されることを知っているため、(最適化として)チェックサムの計算を省略する可能性があります。
インターネット プロトコルの設計において、階層化の原則に違反することで、私たちは失敗しています。具体的には、TCP を 2 つの目的で使用しようとしています。ホスト レベルのエンド ツー エンド プロトコルとして機能させること、およびインターネットのパッケージングとルーティング プロトコルとして機能させることです。これら 2 つの機能は、階層化されモジュール化された方法で提供されるべきです。
{{cite book}}: CS1メンテナンス: 場所の発行元が見つかりません (リンク)は、パケットがネットワークアダプタに送信される前にキャプチャします。チェックサムはまだ計算されていないため、正しいチェックサムは表示されません。さらに悪いことに、ほとんどのOSはこのデータを初期化しないため、表示されるべきではない小さなメモリのチャンクが表示される可能性があります。Wireshark 1.2以降の新規インストールでは、IP、TCP、およびUDPのチェックサム検証がデフォルトで無効になっています。必要に応じて、これらのディセクタのそれぞれでチェックサム検証を手動で無効にすることができます。
チェックサムのオフロードは、送信されるネットワークパケットが実際にチェックサムが計算される前にWiresharkに渡されるため、混乱を招くことがよくあります。Wiresharkはこれらの「空の」チェックサムを受け取り、パケットが後でネットワークハードウェアから出るときに有効なチェックサムを含むにもかかわらず、それらを無効として表示します。