テレビのアニメはどこから来る? / 第23話

第23話:イトは、Wi-FiのACKを「到着」にしなかった|TCP/IPは誰が約束する?

Wi-FiのACKが戻ったのに、遠隔の到着lampは暗い。途中で一つのIP datagramが消える十二秒の実験で、イトはlocal receiptを戻し、endpointのTCPを選ぶ。TCP/IPのlayer分担を物語でつかむ第23話。

TCP/IPのlayer分担IP datagramTCP byte streamend-to-end reliability9分更新

第22話で戻ってきた小さなACKが、イトの手の中で光っていた。

タブレットからaccess pointまで、一つのWi-Fi frameが届いた印だ。

イトはその光を、ルーターの向こうにある遠隔到着slotへ運んだ。

「これを入れれば、届いたことにできる」

slotへ重ねようとした瞬間、奥のnetworkで一つの青い箱が消えた。

遠隔の動画service gateは、暗いままだった。

イト

ACKは戻った。なのに、向こうには届いていない?

ユイ

そのACKは、どこから戻ってきたものでしたか

イト

すぐ近くのaccess point……。遠くのserviceからじゃない

イトは、ACKをslotへ入れる手を止めた。

ラボの壁に、最後の字幕一行が現れる。

その一行を表すbyte streamは、青いbeadの列として可視化されていた。

beadの数や区切りはこの実験の表示で、文字数とbyte数の一般則ではない。

beadは三つのかたまりに分かれ、それぞれ別のIP datagramへ入る。

遠隔側で全beadが順番どおりそろわなければ、字幕gateは開かない。

上には、残り十二秒の輪。

これも、このラボだけの訓練時間だ。

localのreceiptを、遠隔へ貼れる?

最初のIP datagramが、routerを二つ越えた。

二番目は、途中の暗い区間へ入ったまま出てこない。

三番目だけが、先に遠隔hostへ着いた。

受信台には、最初のbead群と最後のbead群が並ぶ。

中央が空いていた。

マコト

近いWi-Fi hopでは受け取れても、その先のIP datagramは別の場所で失われることがある

ピコ

一つのreceiptで、通っていない区間まで確認したことにはできないんだ

イト

じゃあ、どの約束をどこに置けばいい?

TCP/IPという名前は、一枚の万能な保証書ではない。

この実験台には、役割の違う層が重なっている。

下の層で受け取ったことと、上の層の目的が終わったことは、同じではない。

字幕gateの輪は、残り九秒になった。

誰に、覚えてもらう?

操作台に、三枚の設計cardが開いた。

  1. local Wi-Fi ACKを遠隔到着slotへ入れ、全beadが届いたことにする
  2. 通過するすべてのrouterへ、三datagramの順番と再送を最後まで覚えさせる
  3. routerはIP datagramを一つずつforwardし、信頼性が必要な今回の通信では両endpointにTCPの台帳を置く

一番目なら、一秒でgateを開けられる。

けれど、中央の空白は消えない。

二番目なら、途中のrouterが全部を見張ってくれそうだ。

けれど、経路が変わったらどうなるのだろう。すべてのrouterが、この字幕streamの状態を最後まで抱えるのだろうか。

イトは、最初に手の中のACKを見た。

それを遠隔slotではなく、tabletとaccess pointの間にあるlocal hopのhookへ戻した。

次に、routerの上へ置かれた「全streamを記憶する台帳」を外す。

最後に、source hostとdestination hostの二か所だけへ、同じ形のTCP ledgerを置いた。

イト

routerには、次へ運ぶIPの仕事をしてもらう。順番と欠けは、通信の両端で見る

ユイ

途中の道が変わっても、両端なら同じstreamを見続けられます

ピコ

その選択なら、TCPの役割を動かせるよ

ピコは台帳を置かなかった。

local receiptを戻し、routerの余計な台帳を外し、二つのendpointを選んだのはイトだった。

IPは運ぶ。でも、そろうとは約束しない

source側のapplicationが、beadの列をTCPへ渡した。

この学習レーンでは、TCPがbyte streamの位置を記録し、三つのsegmentとして送り出す。

各segmentはIP datagramに入ってnetworkへ進んだ。

IP headerにはsourceとdestinationのaddressがある。

途中のrouterはdestinationを手掛かりに、datagramごとに次のhopを選ぶ。

ただしIPは、三つが全部届くこと、同じ順で着くこと、重複しないことをend-to-endで保証しない。

今回も、一番目と三番目は着き、二番目は着かなかった。

これは「IPが壊れた」のではない。

lossやreorderingが起こりうるnetworkの上で、必要なreliabilityを上の層へ置く設計だ。

IETFのRFC 1122は、IPをend-to-end delivery guaranteeのないconnectionless / datagram serviceとして説明し、必要なreliabilityをhostのtransport layerまたはapplicationへ置くInternet architectureを示している。

現実のnetworkにはstatefulなmiddleboxもある。それでも、この話では「各routerがTCP connection全体のreliabilityを代行する」とは考えない。

TCPは、空白を見逃さなかった

destination側のTCP ledgerには、最初と最後の位置が光っていた。

真ん中だけが空白だ。

三番目のsegmentは着いている。

でも、その中の後ろのbytesを、先にapplicationへ渡して字幕を欠けたまま完成させない。

TCPは、sequence numberを使ってbyte streamの位置を追う。

senderはACKの進み方やtimerなどからlossを検出し、足りないdataをretransmitする。どのACKでどう判断するかは、第25話で詳しく見る。

残り六秒。

source側のTCP ledgerで、中央のsegmentがもう一度光った。

イトは、そのsegmentを再送slotへ入れた。

同じ欠けを埋めるIP datagramが、新しい一歩を走り出す。

途中のrouterは、最初の失敗を覚えて道を保証したわけではない。

目の前のdatagramを、一つずつ次へforwardする。

missing segmentがdestination側へ届いた。

空白へ、中央のbead群が収まる。

stream全体が、先頭から切れ目なく青く光った。

destination側TCPのACKがsource endpointへ戻る。

そのあとで、そろったbyte streamがapplication slotへ渡された。

字幕gateが開き、最後の一行が壁へ映った。

輪は、一つを残して止まった。

イトがWi-Fiのreceiptをlocal hookへ戻し、二つのendpoint TCP ledgerの間で欠けた中央segmentだけを再送してbyte streamをそろえるラボ
local receiptはlocalへ戻す。IP datagramの欠けは両endpointのTCPが見つけ、再送後に順番どおりのbyte streamとしてapplicationへ渡した。

この一件で、成功したのは今回の字幕streamだ。

どんな通信でも十二秒以内にそろう、三segmentに等分される、という意味ではない。

TCPのACKなら、applicationも終わった?

イトはdestination側から戻ったTCP ACKを、今度こそ「全部完了」のslotへ置こうとした。

しかし、remote hostには二つのlampがある。

一つは、TCPがbytesを受け取ったlamp。

もう一つは、applicationがそのbytesを読み、字幕として扱ったlamp。

TCP lampが先に点き、少しあとでapplication lampが点いた。

イト

TCP ACKも、相手のapplicationが意味を理解して保存した証明ではないんだ

マコト

transportの受信と、applicationの処理結果は分けて考える必要があるね

ユイ

必要ならapplication自身のresponseで、その先を確認します

TCPはapplicationへ、reliable, in-order byte-stream serviceを提供する。

IETFの現行TCP標準RFC 9293は、TCPがsequence numberでpacket lossを検出し、retransmissionで補正することを含め、このserviceを定めている。

でもTCPは、字幕の意味や予約の成立、dataの保存完了まで理解しない。

層を分けるとは、責任を曖昧にすることではない。

どのreceiptが、どこまでを見たのかを狭く正確にすることだった。

関連ガイド「TCP/IPとは?」では、application / transport / internet / linkの重なりを、物語から離れて一覧で確認できる。

そろうまで待つ代償

完成した字幕の横で、別の音声streamが流れ始めた。

話し手の声は、もう次の音へ進んでいる。

ところが、途中で遅れた古い一片が、あとから到着した。

字幕では、欠けたbytesを待って順番どおりにすることに価値があった。

live音声では、古い一片を待つ間に「いま」の声が遅れるかもしれない。

TCPには、connection state、ACK、retransmission、順番待ちのcostがある。

それは無駄ではない。

必要なreliabilityを買うためのcostだ。

けれど、すべてのapplicationが同じ買い方をする必要はない。

イト

欠けたら困る字幕では待った。でも、古い声を待つのが正解とは限らない

ピコ

次は、同じdata lossを前にTCPとUDPのどちらを選ぶか比べよう

次回:失った一片を、待つ? 待たない?

左の字幕台では、streamのbeadが順番どおりに光っている。

右のlive音声台では、新しい波の後ろから、遅れた古いbeadが転がってきた。

イトの前に、二つのtransport cardが開く。

一枚は、欠けを補い、順番をそろえる。

もう一枚は、必要最小限のdatagram serviceをapplicationへ渡す。

同じ「速く届けたい」でも、失って困るものは違う。

次回、ピコルート第24話。

TCPとUDPは、どちらが速いかではなく、何を誰が引き受けるかで選ぶ。

この物語を、解説で深める

第23話で生まれた疑問を、解説記事で少し深く見ていきます。物語で感じた不思議さを残したまま、言葉と仕組みを順番に整理しましょう。

TCP/IPとは|データの宛先と届け方を決めるルールを読む