TCP技術入門を読んだので、 気になったところを雑多な感じだがメモしておく。まず前半部分。 ネットワークまわりの話は聞いたことはあるが、使わずに忘れてしまっていることが多い。

1章 TCP入門

  • 伝送効率
    • Ethernetフレーム 1500 バイト、TCPヘッダが 60 バイト、IPヘッダが20バイトとする
    • アプリケーションが使えるのは 1420 バイト
    • Ethernetヘッダ 14 バイト、FCS(Frame Check Sequence)4バイトを考慮すると、伝送効率は$1420/(1500+18) \times 100=93.5 %$
  • UDP
    • 実際にUDPがやっていることは、転送先へデータを送ることと、チェックサムの確認だけ
    • TCPはユニキャストだが、UDPはユニキャストに加えて、マルチキャストとブロードキャストにも対応
    • シーケンス番号とタイムスタンプを追加したRTP(Real-time Transport Protocol)や、それに加えて再送機能も追加したRUDP(Reliable user Datagram Protocol)もある
    • QUIC はUDPベースで、それを使ったHTTP/3(HTTP-over-QUIC)。コネクション確立とTLS確立を同時に実施。
  • TCP
    • ACKのシーケンス番号は、次に受信したい番号。当該セグメントが届くまで、同じシーケンス番号を返送し続ける。
    • フロー制御:受信側のバッファ溢れを防ぐために、送信データ量を調整すること。TCPでは一度に送信可能なサイズをウィンドウと呼ぶ。特に、送信側がもつパラメータを swnd (send window)と表記する。対して、受信側はrwnd(recieve wndoe)。
  • TCP輻輳制御
    • Loss-based:データの消失から輻輳を判断
    • Delay-based:RTTから輻輳を判断
  • 特定の用途向けプロトコル
    • RUDP(Reliable User Datagram Protocol):UDPベースで、シーケンス番号、ACK、再送、フロー制御を加えたもの
    • DCCP(Datagram Congestion Control Protocol):UDPにおける輻輳緩和が目的

2章 TCP/IPの変遷

  • ARPNETなどではネットワークが信頼性を担保していたが、TCP/IPは各ノードがその役割を担う
  • Nagleアルゴリズム:TCP/IPの送出パケット数削減の方法。輻輳制御アルゴリズムのはしり
  • Windows95(OSR2以降)にTCP/IPが搭載されたことが普及のきっかけになった
  • IEEE 802.11ではMACレイヤーでCSMA/CAを採用

3章 TCPとデータ転送

  • MTUは、イーサネットは1500バイト、PPPoEでは1492バイト、ATMは9180バイト。ただ最近は任意に設定できる
  • MSS(Maximum Segment Size):TCPが区切る最大パケット長さ
  • MTU(1500バイト)= IPヘッダ(20バイト)+ TCPヘッダ(20~60バイト)+ アプリケーションデータ(MSS以下)
    • MSSは、TCPのペイロードのみ
    • MTUは、TCPのペイロードからTCPヘッダやIPヘッダまで。Ethernetヘッダは含まない
  • ACK(Acknoledgement Number):確認応答番号。次に送ってほしいシーケンス番号
  • コントロールフラグ
    • RST(Reset the connection):コネクションを強制切断。使われていないポート番号に送るなど、異常があれば有効になる
    • CWR(Congestion Window Reduced):輻輳ウィンドウの減少を通知する。ECNとセットで使われる
    • ECE(ECN echo):輻輳が発生したら通知
  • ウィンドウ制御:一度に送信可能なウィンドウサイズ $swnd$ を調整 $swnd = min(rwnd, cwnd)$
    • フロー制御:受信側から送信側に送信量を通知して、調整する。受信側は、送信側へ受信可能なバッファ量$rnwd$を通知
    • 輻輳制御:輻輳ウィンドウ $cwnd$ を調整
  • スロースタート
    • 通信開始時点で、ACKを受け取るたびに $cwnd$ を1セグメントずつ増やしていく $cwnd = cwnd + mss$
    • 指数的に $cwnd$ が拡大
  • 輻輳回避
    • スロースタートを行うと、再び再送が起きやすい
    • 再送が起きた時の $cwnd$ の半分 $cwnd/2$を閾値として、それを越えた時は更新を緩やかにする $cwnd = cwnd + mss/cwnd$
    • RTTごとに線形に増える
  • 高速リカバリー
    • 輻輳のたびに、スロースタート→輻輳回避という挙動をするのは効率が悪い
    • 重複ACKを契機とする
    • Recoで採用
  • セグメントの消失
    • 再送タイマーがタイムアウトした場合
    • 重複ACKが一定数届いた場合