class: title, smokescreen, shelf, no-footer # <small>情報技術応用特論 第02回<br>TCP/IP(2) トランスポート層</small> <div class=footnote> <small><small> Copyright (C) Ken'ichi Fukamachi <fukachan@fml.org>, 2021-2025. CC BY-NC-SA 4.0 </small></small> </div> --- class: title, smokescreen, shelf, no-footer # TCP<br>(Transmission Control Protocol) <div class=footnote> <small><small> </small></small> </div> --- class: img-right,compact # TCP: 信頼性のあるデータストリーム通信を提供します <div class=footnote> <small><small> (脚注1) 地球の反対側まで20,000kmあろうとも(速度はともかく)通信できます (脚注2) char buf[NBUF] (C言語)、 []byte (Go言語) </small></small> </div>     <small> - <b>END-TO-END</b>で<b>信頼性のあるデータ転送の仕組み</b>を提供することがTCPの役割 - 入力された**データストリーム**はTCPによりパケット群に分割され、転送、 到着後に再構成される - データストリームとは? ... <br> <b>特定の構造を仮定しないデータ(バイト列)</b> <small> **ところてん**もしくは**流しそうめん**のように、 入れたものがバイト単位で反対側から次々と出てくるイメージです (注意: TCPでは同じ通信路で返事も返ってくるため、 一方通行に聞こえる**流しそうめん**は少しよくない例えですが、 ストリーム(流れ)のイメージとしては良いでしょう) </small> </small> --- class: img-right,compact # TCP: 信頼性 <div class=footnote> <small><small> (脚注) 本当にいろいろな品質のネットワークがあるので、 複雑なリカバリができないと障害時や僻地との通信は難しい。 どんな品質でも接続し続けられることが本来の主目標と考えられます (ただ、これは現実とずれてきているような... -> HTTP/3節を参照) </small></small> </div>  <small> - **コネクション指向**の通信 - 論理的な(仮想)通信路(**コネクション**)を構築し、その上でパケットを転送します。 よって、**コネクション指向**とも呼ばれています - 逆に後述のUDPは**コネクションレス** - 通信状態をモニタしエラー訂正などはTCPが担当 - TCPは**ステートフル**なプロトコルの例です 状態があり、それをモニタしています - **パケットの損傷、紛失、重複、順序の乱れを修復**し、 必要ならパケットを**再送**します - アプリケーションはエラーに気づきません </small> --- class: img-right,compact # TCP: フローコントロール(流量調節) <div class=footnote> <small><small> (脚注) 送れそうなら、どんどん送ります(転送速度をあげます) </small></small> </div>  <small> - 相手ホストの忙しさ(仕事量)の具合や回線品質によって送信頻度を自動的に調節します </small> --- class: img-right,compact # TCP: TCPとIPはコンビです <div class=footnote> <small><small> (脚注1) 「パケットを落とす」という表現があります (脚注2) <b>IPは普通郵便</b>(その家の郵便受けには入れますが相手に届いているかは未確認)、 <b>TCPは書留</b>(相手に届いたことまで確認する)というイメージはどうでしょうね? </small></small> </div>  <small> - TCPはIPとコンビで動作します - だからTCP/IPというセットの名称なのです - **誰(アプリ)宛**に渡すのか?は**TCP(トランスポート層)が面倒を見ます** - **IPは住所まで(だけ)**の面倒を見ます - IPは転送途中で何かあっても気にしません - きちんと**データが届いているか?はTCPが気にかけます**。 そういう<b>役割分担</b>(層=役割) </small> --- class: img-right,compact # TCP: 多重化(multiplexity) <div class=footnote> <small><small> (脚注1) 一つのWWWサーバに、 あるPC上から複数のアプリケーション(クライアント)が接続している場合、 クライアントのポート番号以外は、すべて同じになります i.e. 図の青線と赤線の通信では、 (サーバのIPアドレス,サーバのポート,クライアントのIPアドレス)の3つ組は同じですが、 クライアントのポートだけ異なります <br> (脚注2) 一つの通信路の上に多重化することもmultiplexityと言いますが、これは違います。 「ホスト間通信の多重化」=「必要なだけ複数のコネクションを作成」です。 HTTP/2やHTTP/3はアプリケーションプロトコルがmultiplexityの機能を持ちます (-> スライド末) </small></small> </div>  <small> - ポート番号とIPアドレスの対で通信路を区別するので、 ホスト間で同時に複数のTCP通信路を利用可能 - **サーバのIPアドレス,サーバのポート(80/tcp),クライアントのIPアドレス,クライアントのポート(ランダム)**の4つの情報の組で識別可能 </small> --- class: img-right,compact # データストリーム <div class=footnote> <small><small> (脚注1) 1オクテットという表現があるのは、昔のコンピュータでは1バイトが8ビットとは限らないため (脚注2) 銀行通帳 ... 印刷を考えると便利なのかもしれませんが、データが無いところは空白?...非効率? 大昔のpunchcardでprogrammingというやつですね。 </small></small> </div> <!--  -->    <small> - 入力したデータが反対側から**1オクテット**(8ビット=1バイト)ずつ出てきます <small> - 改行などは特別なコードを決めてありエディタやシェルなどは理解できます (ファイル表現の取り決め) - 例: Unixファイルの改行(LF: line feed) <br> **012**(8進数) **0A**(16進数) </small> - 反対の例:通帳など、1行80文字固定(右図の下) </small> --- class: img-right,compact # パケットへの分割 <div class=footnote> <small><small> (脚注1) ソケットプログラミング ... ネットワークのプログラミングでは、 いつもの標準入出力(e.g. STDIN,STDOUT)と異なるsocketという入出力機構を使います。 BSD UnixがTCP/IPを実装したときに、この仕組みを作りました (脚注2) セグメントはTCPヘッダとIPヘッダ分を差引いたサイズになります。 例: 1500 - 20 - 20。 この1500というマジックナンバーは イーサネットのペイロードサイズ=1500バイト(IP,TCPヘッダ含)から来ています。 なお、一般家庭などのB-FletsはPPPoEなので1500より小さくなります(詳細は略) </small></small> </div>  <small> - アプリケーションは任意の長さのデータをTCPで送信/受信できます(**socket**への入出力) - 入力されたデータストリームは、TCPがパケット群に分割、転送、(配送先で)再構成します (右図の箱の列を参照) - TCPがデータをある長さ(**セグメント**サイズ)に分割して送信し、 (受信側で)再構成します - セグメントサイズはTCPより下の層次第、可変 <br> (だいたい1400バイト前半が多いか?) </small> --- class: col-2,compact # TCPヘッダ <small> | 図中の表現 | 内容 | 長さ | |----------------------------|--------------------|------| | source port | 送信元のポート番号 | 16 | | destination port | 送信先のポート番号 | 16 | | **sequence number** | シークエンス番号 | 32 | | **acknowledgement number** | アクノリッジ番号 | 32 | | data offset | ヘッダの長さ | 4 | | reserved | 予約(未使用) | 6 | | **control bits** | 制御命令/状態 | 6 | | **window** | 流量制御 | 16 | | checksum | チェックサム | 16 | | urgent pointer | 緊急ポインタ | 16 | </small>  <div class=footnote> <small><small> (脚注1)ヘッダ構造の詳細は覚えなくてOK <br> (脚注2)予約の3ビット分はECNへ;RFC3168(2001) </small></small> </div> --- class: img-right,compact # TCPヘッダ <div class=footnote> <small><small> (脚注) ヘッダ構造は覚えなくてOK; ヘッダにポート番号がありますよね?そこだけ覚えておいて欲しいですね </small></small> </div>  <small> - 信頼性、フローコントロール、多重化のための情報がヘッダにあります - **ポート番号はありますがIPアドレスは無い** <small> - TCPの担当は**アプリケーションの区別(誰?)** - ポート番号とTCPを制御する情報のみ - インターネット層がIPアドレス(住所)を扱うので、 IPヘッダの方に、IPアドレスを書きます <br> <small> **TCPとIPはコンビで動作することを忘れずに!** </small> </small> </small> --- class: compact,img-right # TCPヘッダとTCPの動作(概略) <div class=footnote> <small><small> (脚注) 詳細はスライド末に参考資料として収録してあります。 このあたりのTCP詳細は応用情報処理試験の範囲すら越えていますが、 プロのエンジニアを目指す人にとってTCPの基本動作は必須要件なので各自で勉強してください (TCPの動作がわからないと基本的な障害対応すらできません)。 IPAの資格試験群は、ソフトウエア偏重なので、 TCPなんて分からなくてOKなどと勘違いしないように </small></small> </div>  <small> - TCPはコネクションを確立するところから開始 <small> - 仮想通信路の生成 or コネクションの初期化とも言う </small> - この初期化プロセスが**3-way ハンドシェイク** <small> - TCPヘッダの Control bits で命令(**SYN** = シンクロナイズ命令)を送り、 sequence number と acknowledge number をモニタして、 サーバとクライアントが互いに確認 (**ACK**, acknowledge が確認という意味)を取りながら行います (右図、詳細は[こちら](#tcp-details)以降を参照) </small> </small> --- name: pause class: compact,col-2 # <small>(アーカイブ動画で見ている人も)一時停止して休憩</small> <div class=footnote> <small><small> 30分ごとにヨタ話をしろというのが指導教官の教え <br> 正確には「アメリカでは30分ごとにジョークを言わないといけない」だけれど、そんな洒落乙なこと無理:-) </small></small> </div>   --- class: title, smokescreen, shelf, no-footer # <small>UDP (User Datagram Protocol)</small> --- class: img-right,compact # UDPの動作の概略  <small> - TCPと異なり、最小限なので**処理が軽いです** - 最低限の通信はできますが、 パケットの損傷、紛失、重複、順序の乱れなどについて何も配慮しません (-> アプリが実装する必要性) - 右図は、 UDPやIP、イーサネットのレベルのあちこちでパケットが損失しているイメージ図を表現しています。 TCPであればTCPが回復させますが、**UDPでは単にパケットが届かない**だけです (たいていは、**エラーの連絡もありません**) </small> --- class: col-2,compact # UDPヘッダ <div class=footnote> <small><small> (脚注) HTTP/3節も参照のこと </small></small> </div> <small> - 最小限の情報のみで**処理が軽い**ため、 最低限の通信が出来るだけです - (必要であれば)障害への対処は、すべて各ソフトウエアが自力で実装する必要があります - そのかわり、 **プログラマつまりユーザがプロトコルをすべてコントロールできるのがメリット** </small> <wbr>  | 図中の表現 | 内容 | 長さ | |----------------------------|--------------------|------| | source port | 送信元のポート番号 | 16 | | destination port | 送信先のポート番号 | 16 | | length | データの長さ | 16 | | checksum | チェックサム | 16 | --- class: compact # UDPの例 (長距離) <div class=footnote> <small><small> (脚注1) これをTCPでやると、とても重そうというか初期化のオーバーヘッドだけで、 ずいぶん時間を取られてしまいます。 順調なら TCP 3-way handshake の時間で DNS は答えをもらっていそうです。 だからDNSでは軽い動作も求められていると思うんですよね〜 <br> (脚注2) DNSクエリのデフォルトはUDPでも、サーバ間の設定ファイルの同期はTCPです。 <br> (脚注3) 音声・動画系のアプリでは、最初の認証をTCP、 実際のデータ転送はUDPといったハイブリッドな作りにするのでは? 商用が多いから、詳細はよくわかりませんけど... </small></small> </div class=footnote> <small> - DNS (詳細は前回を参照) - 小さなデータを、多くのサーバと、多くのやりとりが発生するプロトコル - IP電話や動画配信などの**音声,動画**系 - **少々のパケット損失が問題にならない**メディア </small> --- class: compact # UDPの例 (短距離) <div class=footnote> <small><small> (脚注) 組み込み機器などではsoftware(firmware)の格納領域が小さいため、 firmwareを大きくしないために、 TCPではなくUDPで転送するTFTPを使いたいという理由もあります </small></small> </div class=footnote> <small> - 視認範囲、1部屋などの規模感での話 - この近距離なら、UDPでも障害おこらないだろうという淡い期待が持てる:)と言いますか... - DHCP (Dynamic Host Configuration Protocol) - OSのネットワークまわりの自動設定 - TFTP (Trivial File Transfer Protocol) - ネットワーク機器の設定やバックアップ </small> --- class: compact # TCP vs UDP: 意義、比較 <div class=footnote> <small><small> (脚注) TCPの場合OSがエラー処理など何でも面倒をみてくれて便利です。 アプリ屋さんはデータ転信の詳細など一切気にせずにアプリを作れます。 だから多くのアプリがTCPベースなわけですよ </small></small> </div class=footnote> <small> - TCP - TCPは仮想通信路を確立して転送を行いますが、 その確立する処理自体が重たい - TCPは何でもやってくれて便利ですけど... - TCPはOSの機能なので(プログラマが何かしたくとも)<b>細かな変更は不可能</b>です - UDP - 軽い動作 - **プログラマが変更可能なプロトコル** - (トランスポート層の上で)TCP似の機能を自由に取捨選択して設計可能という意味 - 前回の**DNS**、このあと紹介する<b>QUIC(HTTP/3)</b>が好例 </small> --- class: title, smokescreen, shelf, no-footer # <small>HTTPそれから(HTTPS,HTTP/1.1)</small> --- class: compact # HTTP/1.0 のメリット・デメリット <div class=footnote> <small><small> (脚注1) 次頁以降、 HTTPSによるショッピング対策、 HTTP/1.1以降のstatelessへの対処について解説。 -> HTTP/2,/3 (参考資料) <br> (脚注2) GET ...などで分かるように(デバッグしやすい代わりに)冗長なので、このオーバヘッドが無駄なのですが、 WWWの出始めの時代は、 シンプルなページばかりだったので、このあたりは、まだ問題にされなかったのです(私見) </small></small> </div> <small> - メリット ... シンプル、分かりやすい、だからデバッグしやすい(のは良いのですが、やはり設計が古い...) - デメリット - **平文**かつ冗長なテキスト - 盗聴すれば丸見えなので、個人情報やクレジットカードは流せない - インターネットショッピングは無理 - **ステートレスプロトコル ** - 昔ならindex.htmlを1つダウンロードで終了でしたが、 いまどき1ページで部品が何十もあるので、部品ごとにHTTP/1.0を実行します。 ただでさえTCP自体が重たいのに、それを何十回も... - 50個の部品を50ヶ所のサーバからダウンロードする場合、改良は無理です。でも、 そのページを構成する .html .css .js などを同じサーバからダウンロードするケースでは改良の余地あり <br> -> HTTP/1.1、HTTP/2 を参照 </small> --- class: img-right,compact # HTTPSと暗号化と認証(1994年末〜) <div class=footnote> <small><small> (脚注1) かつては電子証明書ひとつ取得するのに10万円とかしていました。 これは「まともな会社」であることを確認するために、 所在地や実在性、登記簿の確認などをきちんとしていたからです。 これが「認証」です。 いまどきほとんどのサイトがLet's Encryptを利用して「暗号化」をしていますが、 これでは相手が「まとも」かどうかは確認できません <br> (脚注2) 経路上で盗聴できなくても、 サーバやクライアントをアタックすれば個人情報を漏洩させることができます。 近年は、これ(特にWWWブラウザ=クライアントを狙う方向性のアタック)が主流。 特にランサムウエアですよね〜 </small></small> </div>  <small> - インターネットショッピングに次の2項目は必須 - **暗号** ... 通信路上で個人情報やクレジットカード番号が盗聴されない対策 - **認証** ... このサイトは、まともな会社が運営していますという保証 - 例: 中間者攻撃(Man in the middle attack) <small> - Web Spoofing (図)は1990年代後半すでに問題でした。 図は「フェイクのサイトwww.amaz0n.co.jp経由でamazon.co.jpへアクセスさせる」様子。 真ん中のサーバ(amaz0n)でcrackerが盗聴し放題 </small> </small> --- class: img-right,compact # HTTPSと暗号化と認証(1994年末〜) <div class=footnote> <small><small> (脚注1) SSLはSecure Socket Layerの頭文字。 TLS(Transport Layer Security)はSSLをベースにIETFが規格化したものです。 基本的にSSLと一緒です。その後はIETFが規格を進化させてきたので今はTLSしか使いません。 現行バージョンはTLS 1.3 <br> (脚注2) (前ページのくりかえしですが) 近年、Googleが暗号化しろと五月蝿いので、みんなHTTPS対応していますが、 たいてい暗号化をしているだけなので注意が必要です (マトモな認証なし=そのサイト運営側がマトモか?は未確認です) 参考: <A HREF=https://www.nic.ad.jp/ja/basics/terms/lets-encrypt.html> Let's Encrypt </A> </small></small> </div>  <small> - HTTPSはHTTPとTCPの間にSSL層を追加したプロトコル(**階層モデル**なので簡単に出来ました) <small> - 現在はSSLではなく**TLS**を挟みます - 今は亡きNetscape社が提案し Netscape navigator(Mozilla firefoxの御先祖)に実装しました </small> - HTTPSは暗号化と認証機能を提供 <small> - **暗号**...個人情報やクレジットカードの盗聴・漏洩阻止 - **認証**...このサイトは、まともな会社が運営していますという保証 (別途、まともな**電子証明書**の手配が必要) </small> </small> --- class: col-2,compact # HTTP/1.1 (RFC2068,1997/01) <div class=footnote> <small><small> (脚注1) HTTP/1.1がスタンダードでHTTP/2への移行も進んできています。 個人のクライアント環境ではHTTP/3がデフォルトかな <br> (脚注2) 表側は暗号化しても裏側は平文(HTTP/1.1)で運用してもいいよね? (AWS用語で説明すると) ELBまでhttpsですが、ELBの裏つまりVPCの中はHTTP/1.1で運用する設計。 (VPC内には侵入されない大前提がありますが) このほうがオーバヘッドもかからないしね。 ゼロトラストセキュリティの時代なので末端まで全部httpsにしろという勢力もありますけど、 証明書の運用が面倒だし ... </small></small> </div> <small> - 毎回TCPを切断するのが重たい処理なので、 <b>TCPを使いまわせる</b>ようにしました <small> - 一度サーバとTCPの通信路を確立した後、 その通信路の上でやりとりを続けられます - それでも間に合わないので、 たいていのブラウザは同時に6個のTCP通信路を作り並列処理をしています </small> <wbr> - バーチャルドメインサポート <small> - HTTPヘッダのHost:フィールドでサーバ名を渡せるようにしました。 <b>URL(ドメイン)ごとに異なるIPアドレスのサーバを用意するのは IPアドレスの無駄</b>だから - たとえば、このWWWサーバ(182.48.54.220)では複数のドメインを運用しています - https://www.fml.org/ - https://technotes.fml.org/ - https://lectures.fml.org/ </small> </small> --- name: pause class: compact,col-2 # <small>(アーカイブ動画で見ている人も)一時停止して休憩</small> <div class=footnote> <small><small> 30分ごとにヨタ話をしろというのが指導教官の教え <br> 正確には「アメリカでは30分ごとにジョークを言わないといけない」だけれど、そんな洒落乙なこと無理:-) </small></small> </div>   --- class: title, smokescreen, shelf, no-footer # 参考資料 <div class=footnote> <small> 試験には出ません; TCPなんて<B>テオクレ</B>だよとAmazonとGoogleに言われました(;_;) </small> </div> --- class: col-2,compact # <small>時代はTCPからUDPベースへ(HTTP/2, HTTP/3)</small> <div class=footnote> <small><small> (脚注1) TCP/IPは1970年代半ばに設計開始 (脚注2) GAFAM等がIETFに貢献する一方、 草の根の力が弱くなってきた傾向が懸念される昨今 </small></small> </div> <small> - 元々のTCPでは(1)END-TO-ENDでの確実なデータ転送が主目標で (2)転送速度の問題は次点 - それでも、最適化をくりかえして、Gbpsくらいは出せますけれど - いま、データセンターの機材は25Gbps,40Gbps,100Gbpsの世界です - なにしろ半世紀前の設計なので、いろいろ古いといえば古いのです - 信頼できる自社ネットワーク内であれば TCPはオーバースペック(or 設計が古いので性能が出せないの)ではないのか? と思われている昨今 <wbr> - AWS (Amazon Web Service)の裏側はAmazon独自プロトコルだそうです - GoogleはChromeブラウザの改良を続行中 - ブラウザでGoogleを使ってもらうところが収入源だから当然ですよね? - Chromeを独自改良して、Chrome〜Googleサーバ間の高速化を探求・評価、 その実装をIETFに提案 - **HTTP/2**はGoogleの**SPDY**が大元 - **HTTP/3**はGoogleの**QUIC**が大元 <br> ついに**QUICはUDPベース**へ </small> --- class: col-2,compact # <small>HTTP/2(RFC7540,2015/05) SPDYベース</small> <div class=footnote> <small><small> (脚注) 【歴史的展望】 ちなみにiphone 3Gの発売が2008夏です。 プロトコルの設計・開発は10年くらいかかって普通でしょうから、 SPDYは、こんなにスマートフォンが当たり前になった世界を想定していなかったのだと思います (私見) </small></small> </div> <small> - Googleが考えたSPDY(2010年代前半〜)というプロトコルが大元です - <b>latency(待ち時間)の短縮</b>が主目標 - テキストではなくバイナリ形式です - 命令は1ビットでも伝えられます - テキスト(e.g. GET ...)は冗長 - HTTPヘッダの圧縮 - HTTPヘッダのほとんどは毎回同じなので、 重複排除や圧縮により通信量を削減可 - サーバプッシュ - サーバからクライアントへデータを送り込むことができます <br> 例: レンダリングを早く開始できるようにcssを優先的に送りこむ <wbr> - フローコントロール ... HTTP側にもTCPのような機能が搭載されています - <b>TCP上でHTTPという前提は継続</b> - HTTP/1.1の上位互換でURIはそのまま - 事実上、HTTP/2では暗号化(TLS)が前提 - ちなみにFirefoxとChromeはhttps(HTTP over TLS)のみをサポートすると明言しました - 参考文献 - [HTTP/2 explained](https://http2-explained.haxx.se/) - [cURL](https://curl.se/)という有名なデータ転送ソフトウエアの作者 Daniel StenbergによるHTTP/2の解説です </small> --- class: col-2,compact # <small>HTTP/3(近々リリース) QUICベース</small> <div class=footnote> <small><small> (脚注) 【歴史的展望】 スマートフォンが猛烈に普及して問題を感じ始めたからQUICの開発が始まったと考えられます(私見) </small></small> </div> <small> - **できれば新しいトランスポートプロトコルを作成して差し替えたいのが本音**ですが、 **運用的にはTCPかUDPしか選択肢がないという現実** <small> - 昔とちがい、ずいぶんネットワークの品質は向上! - TCPを前提にしなくても良い? - END-TO-ENDで通信可なプロトコルはTCPとUDPだけ - なぜなら、 **危ない**ので、 **ルータやファイアウォールで謎プロトコルは通さないことが多いから**。 これらは長年インターネットを運用してきた結果/しがらみ </small> <wbr> - Googleは**UDP上に(TCP似の機能をもった)独自のプロトコル(QUIC)を作り**、 QUICの上でHTTPを提供することにしました - GoogleはHTTP over QUICをChromeに実装し、Googleのサーバで評価後、IETFへ提案、 2021年5月、RFC 9000 として標準化 - 参考文献 - [HTTP/3 explained](https://http3-explained.haxx.se/) - [cURL](https://curl.se/)という有名なデータ転送ソフトウエアの作者 Daniel StenbergによるHTTP/3の解説です </small> --- class: img-right,compact # <small>HTTP/3 (QUICベース)の階層構造</small> <div class=footnote> <small><small> (脚注1) ふつうfirewallでUDPを通していないのでfirewallの設定変更をしないとHTTP/3が使えません <br> (脚注2) 大学ではHTTP/3が通りませんが、 通常、 自宅のルータは制限をかけていないので、 自宅ではHTTP/3が使われているはずです (自宅ではGoogleサーバとの通信が大学のときより一割くらい速く感じませんか?) </small></small> </div>  <small> - HTTP over QUIC - <b>UDPの上に独自の(TCPのような)QUICプロトコルを実装</b>しています - UDPの転送さえ何とかなれば、 その上で独自プロトコルによるHTTPの機能強化が実現できるところが重要です - <b>暗号化(TLS 1.3)は必須</b>です - 2010年代半ばあたりからGoogleはHTTPS必須だと言っていますね... - 諸問題や計測値は、この卒論を見てください - [HTTP/3 がシステム運用に与える影響の評価](https://researchmap.jp/fukamachi-fmlorg/presentations/48426749) </small> --- name: tcp-details class: title, smokescreen, shelf, no-footer # <small>TCP (Transmission Control Protocol) <br> より細かな動作</small> <div class=footnote> <small><small> 応用情報処理試験でも出題されないレベルですが、 プロになるなら分かっておいてほしい </small></small> </div> --- class: img-right,compact # TCP: 状態遷移図 <div class=footnote> <small><small> (脚注) 日本の業界人はESTAB を「えすたぶ」と発音しています。外人に通じるのかは不明ですけど </small></small> </div>  <small> - 状態遷移(state transition) - TCPの状態が移り変わっていく様子 - CLOSEDから始まり、いくつかの状態を経て再びCLOSEDになります - 一番上のCLOSEDと右下のCLOSEDは同じものです (図は、右下と上がつながっていると読んでほしいのです) - ESTABLISHED状態が実際のデータ転送を行っている一番大事な状態にあたります - 長くて言いにくいので業界人は、この状態をESTABなどと省略します - 「ACKビットが1」の状態がESTABです(「ACKが立っている」とも言います,後述) </small> --- class: col-2,compact # TCP: コントロールビット <small> - TCPヘッダのコントロールビット部(control bits) - 命令および現在の状態を伝えるもの - 1bitずつ違う意味になっています - 本来このように1bitで十分なので、 (debugしやすい)アプリケーションプロトコル群が冗長なのですね <wbr> | 0 | 1 | 2 | 3 | 4 | 5 | |-----|-----|-----|-----|-----|-----| | U | A | P | R | S | F | | URG | ACK | PSH | RST | SYN | FIN | </small> <div class=footnote> <small><small> (脚注)ECN(予約の3ビット分;RFC3168(2001))は含めていないoriginalコントロールビット </small></small> </div> --- class: img-right,compact # TCP: 通信路の確立 1  <small> - 3-way handshake - 有名な3-way handshakeです - (論理的な)**仮想通信路**を確立します - この通信路を**コネクション**と呼んでいます。 TCPは**コネクション指向**と言われています。 - コントロールビット**SYN**が確立のお願いで、 **ACK**が了解したという意味です - これを双方向に行い、 双方がACKを返せれば**ESTABLISHED**状態になり、 データ転送が行えるようになります - サーバとクライアント双方で、 それぞれのシークエンス番号(図中ではSEQ番号)を管理しています。 これは送ったデータのバイト数分増加する数字です </small> --- class: img-right,compact # TCP: 通信路の確立 2  <small> 1. クライアント(C)からサーバ(S)へ - コントロールビットの**SYN**部分を1 - **SEQ番号J**でサーバへ送信します。ACK番号は未定なので通常0 1. サーバが返事を返します - Cのお願いに了解の意味で**ACK**を1 - **ACK番号**にJ+1を設定 - SからCへのお願いの意味で**SYN**を1 - **SEQ番号**にSの番号Kを設定 1. クライアントが返事を返します - SからCへのSYNに了解で**ACK**を1 - **SEQ番号**にCの番号J+1を設定 - **ACK番号**にK+1を設定 </small> <div class=footnote> <small><small> (脚注1) 1に設定することを「ビットを立てる」と表現します <br> (脚注2) 3-way handshakeではデータ転送をしませんが、ACKを返すときにSEQ/ACK番号を+1します </small></small> </div> --- class: img-right,compact # TCP: 転送  <small> - 右図はHTTPを例にしています - クライアント(C)からサーバ(S)へ`GET / HTTP/1.0`を送信します。 ここではペイロード(データ)サイズが**16バイト**と想定 - C、Sそれぞれで送ったデータ量分SEQ番号は増えます。 変化後の値は**相手から受領確認で返ってくるACK番号と一致**するはずです - C側の**SEQ番号**は**(J+1)に+16**されます (Sが無事に受け取ったら**J+1+16**の**ACK**を返してくるはず) - SはCからの16バイトを受信したので**ACK番号**に**J+1+16**を設定し、 SEQ番号にはSからCに送る400バイトを加算した**K+1+400**を設定 </small> --- class: img-right,compact # TCP: 転送(損傷、紛失、重複、順序の乱れ)  <small> - SEQ番号から自分がどこまで送信したか?は分かり、 返信パケットのACK番号を見れば、相手がどこまで受け取っているのか?が分かります - SEQ/ACK番号の抜けや重複、順序の乱れを見ることで、それらの訂正が出来ます - 届いていないパケットがあれば、 一定時間後にTCPが決断して再送もしくは相手に再送依頼などします - TCPがバッファリングし、正しい順序に再構成後アプリケーションに渡します </small> --- class: img-right,compact # TCP: 転送(転送速度の向上)とフローコントロール  <small> - 一回毎に確認を待つのは非効率 - 1往復どれくらいか?というと、 北海道〜東京で往復50msくらいかかるので1秒で20往復しか出来ません。 これでは転送速度が30KB/秒くらい... - 確認を待たずに次々と送信しましょう - 確認を待たずに送れるサイズがTCPヘッダのwindowサイズ - そうそうエラーにはならずに次々とACKが返ってくると期待してますよ - フローコントロールの基本 - ヘッダのwindowでネゴしていきます - ホストが忙しいので少し待ってほしいならwindowは小さくしてほしい - 余裕が出来たらwindowを少し大きく </small> --- class: compact # TCP/IP周辺の出来事史 <small> | 年代 | 出来事 | 備考 | |------------|--------------------------------------|-------------------------------------------------| | 1950年代 | タイムシェアリングシステム(OS)研究 | 軍はCICもしくは防空センターの高度化に興味? | | 1951? | SAGE(半自動防空管制)開発開始 | MITリンカーン研究所(1951)、運用開始は1958 | | 1957 | スプートニク1号打ち上げ | 宇宙開発競争のはじまり、空から核ミサイル? | | 1958 | ARPAとNASAの誕生 | 宇宙開発の主導権はNASA | | 1960年代 | ARPAのIPTO部主導でARPANET開発 | IPTOの予算はARPA全体の0.5%(期待されてない?) | | | (ARPANETは60年代後半みたい?) | IPTO部長は対話的コンピューティング関係者 | | 1969/10/29 | ARPANETで最初のパケットが流れる | プロトコルはNCP, UCLA〜SRI間 | | 1970年代 | TCP/IPの設計と開発 | (ARPAと無関係ながら)OSではUnixがブレイク | | 1970年代末 | NCPからTCPへの移行を計画 | UCBがBSD UnixにTCPを実装する案件を受注 | | 1981-1983 | 4.2BSDでのTCP/IP実装 | Bill Joy(pascal,vi,termcap,のちのSUN CTO) | | 1983/01/01 | ARPANETがNCPからTCP/IPへ完全に移行 | 商用化とか対OSI(政治)とかいろいろあるみたい? | | 1991 | HPC Act (by Al Gore) | のちのクリントン政権での情報ハイウエイ構想 | | | | 商用インターネットの躍進がはじまる | | 1995 | Win95登場 | 一般人のインターネット率が急上昇していく | </small>