RFC 1180 - TCP/IP tutorial

RFC 1180 - TCP/IP tutorial のメモです

Abstract

TCP/IPの概要の説明。"TCP/IP" とは…TCPとIPに関係するすべてである。 関係するプロトコルUDP, ARP, ICMP で、関係するアプリケーションは TELNET, FTP, rcp などが該当する。 もっと正確には “internet technology” であり、internet technology が使われているネットワークのことを “internet” と呼ぶ。

Terminology

Internet を通るデータはどのプロトコルスタックにあるかで呼び方が変わる。

  • Ethernet flame
  • IP packet
  • UDP diagram
  • TCP segment
  • Application message

driver はネットワークハードウェアインターフェースに直接通信するソフトウェア。 module は driver やアプリケーションと通信するソフトウェア。

Basic Structure

インターネット上のコンピュータの内部のレイヤー構造を論理的に表した図。 module は、データを下流に運ぶ時はヘッダーを加えるマルチプレクサとして動作し、上流に運ぶ時はヘッダーを取り除いてデマルチプレクサの役割を果たす。 6バイトの Ethernet アドレスは Ethernet でユニークであり、Ethernet module から下側のインターフェースに紐付いている。 4バイトのIPアドレスは、internet でユニークであり、IP module の下側のインターフェースに紐付いている。

                     ----------------------------
                     |    network applications  |
                     |                          |
                     |...  \ | /  ..  \ | /  ...|
                     |     -----      -----     |
                     |     |TCP|      |UDP|     |
                     |     -----      -----     |
                     |         \      /         |
                     |         --------         |
                     |         |  IP  |         |
                     |  -----  -*------         |
                     |  |ARP|   |               |
                     |  -----   |               |
                     |      \   |               |
                     |      ------              |
                     |      |ENET|              |
                     |      ---@--              |
                     ----------|-----------------
                               |
         ----------------------o---------
             Ethernet Cable

IP アドレスによって、複数の物理ネットワークを1つの論理ネットワークとして扱える。 “interconnection of physical networks” が internet の起源である。IP はアプリケーションからネットワークハードウェアを隠蔽する。 新しい物理ネットワークを発明したとしても、IP module との driver さえ実装すればよい。

2つのコンピュータが internet で通信できるならば、それは “interoperability” である。interoperability こそが internet の核である。

Ethernet

Ethernet フレームは、宛先アドレス、送信元アドレス、type field、そしてデータから成る。すべてのインターフェースは、"FF-FF-FF-FF-FF-FF" をリッスンしており、これをブロードキャストアドレスと呼ぶ。 EthernetCSMA/CD (Carrier Sense and Multiple Access with Collision Detection) を使っている。これは、2つのデバイスが1つの通信路で通信する際、片方だけが送信でき片方だけが受信できる事を意味する。同時に送信し collision が起きた場合はランダム時間待った後、再送する。

ARP

IP packet を送信する時、IP アドレスを Ethernet アドレスに変換するプロトコルARP (Address Resolution Protocol) である。 受信の際はヘッダーに Ethernet アドレスと IPアドレスが付いているので、変換は必要ない。

変換は、ARP テーブルというコンピュータが持っている変換表で行う。ARP テーブルが必要な理由は、IP アドレスと Ethernet アドレスは独立しているからである。IP アドレスは管理者から割り当てられており、変わることもある。一方で、Ethernet アドレスは製造者がライセンスしていて、これもまた変わることがある。

変換表に対象のIPアドレスが無かった場合、ARP request をブロードキャストし、IPパケットはキューイングする。 それぞれのコンピュータは、Ethernet インターフェースで Ethernet flame を受信する。Ethernet driver は、type field で ARP と判断し ARP module に送る。ARP request は、「もしこのIPアドレスなら、Ethernet アドレスを教えてください」というものである。 もし自分のIPアドレスとマッチしていれば、Yes と返信する (ARP response)。 同様に ARP module で受信し、IPアドレスを見て、ARP テーブルを更新する。 その後、Ethernet module で キューイングされた IP packet にIPアドレスを書き込み、送信する。

もし該当IPアドレスを持つコンピュータがいなかった場合、パケットは破棄される。 この時、Ethernet より上位層は、Ethernet が壊れているのか、そのコンピュータが不在なのかは区別できない。

Internet Protocol

routing

routing は、direct routing と indirect routing の2つがある。 direct routing は、1つの物理ネットワーク上で、送信元IPアドレス/Ethernetアドレスが送信ホストのものであり、宛先IPアドレス/Ethernetアドレスが宛先ホストの場合である。この場合、Ethernetアドレスだけでホストを特定できるため、IP 自体はオーバーヘッドになる。 indirect routing は、複数のネットワークをまたぐ場合に起こる。direct routing が複数回発生し、Ethernet ヘッダーが変化する。

IP Address

IPアドレスネットワーク管理者によって割り振られる。4バイトのIPアドレスは network number と、host number に分かれている。上位側がネットワークの方である。クラスCの分け方では、上位3ビットによって、ネットワーク数が21ビット、ホスト数が8ビットという意味になる。IPアドレス空間は NIC (Network Information Center) によって管理されている。"Internet" ではNICによって割り当てられたアドレス使用が必須である。

IP Route Table

IP では、パケット送信の際、下位のインターフェースを知るために route table を使う。route table の1行は、IP network number, direct/indirect flag, router IP address, interface number の基本要素から成る。

User Datagram Protocol

UDP は、コネクションレス型データグラムデリバリーサービスである。

UDP はデリバリーを保証しない。UDP が提供すること:

  • ポート番号ベースでアプリケーションを多重化する
  • チェックサムで完全性を保証

Transmission Control Protocol

TCP はコネクション指向バイトストリームデリバリーサービスである。

  • ストリーム:始点と終点の境界がないデータ

TCPは通信状態を管理し、全二重の仮想回線を定義する。 送信する場合、受信側の確認応答を必須とする。 エンドのバッファ溢れを防ぐフロー制御を、スライディングウィンドウプロトコルによって行う。

感想

98%ぐらいは知ってる内容だった。次:RFC 826 - Ethernet Address Resolution Protocol: Or Converting Network Protocol Addresses to 48.bit Ethernet Address for Transmission on Ethernet Hardware

わかる、ということ

ここでいっている「わかる」、というのは「できる」と近い文脈で使われるものである。 具体的には「私はC言語がわかる」や「私はJavaができる」というものである。 どの程度わかれば、「わかる」と言えるのか、またどの程度できれば「できる」と 言えるのか。どの程度、というのは定量的に表せるものではないと思う。 すなわち、「多少わかる」や「結構できる」や「チョットデキル」はそういう意味で 不適である(最後のはネタだが)。では、どうなれば「わかる」と言えるのか?

考えた結論としては、「どこまで理解しているか(いないか)を知っている状態」が「わかる」である。 仕方なく「理解」という言葉を使ったが、この言葉はとりあえずここでは自分の言葉で概要を説明できる、ということにする。 物事は小さく分解すると、”深さ"が異なる、表面的な性質や本質的な性質に分けられる。 応用は基本の上に積み上がっていく、という極めて普遍的な事実にも帰着する。

つまり、わかるためには、その物事がどのようなスタックになっているかを把握することが 第一歩である。その上で、最も基本的なレイヤーから理解する。そうすれば、「私はどのレイヤーまで わかる」と言うことができ、その状況は他者に共有しやすいのではないか。

この文章を書いた背景は一応あって、次の事象を言語化したかったということである。 これはなんとなくみなさんが気付いていることだと思うが、 自分よりその物事をわかるであろう人(つまるところ自分よりレベルが上な人) が、自分はまだまだ全然わからないです、と言うのだ。 多少は謙遜もあるかもしれないが、それは本気で言っているのだ。 これは見えている世界が違うのだと思う。 見えている世界というのが、上で説明したレイヤーに該当する。

今なにをやるか

私は今修士課程2年で、修了後は就職するつもりなので、つまり順当に行けば大学に在籍するのはあと1年間である。 最近になってこの1年間の価値は大きいと考え、じゃあなにをするのかを考えた。

働くということ

社会に出て働き金を稼ぐということは、自分が求められている価値をなんらかの形で提供することである。 自分はいわゆるWeb系で働くつもりなので、提供するのはプログラミングに付随するエンジニアリングになる。

これまで、自分は主に情報工学を学びながら、多少プログラミングをした。 特に、Webサービスや自動化するスクリプトを書くのが好きだった。 しかし、それらが本質的になぜうまく動いているのかは理解していなかった。 でもそれでよかった。動けばよかった。なぜならそれらは仕事ではなかったからだ。

これまでは、なんかすごい道具を買ってきて、なんとなくうまくいきそうで作ってみてそれが動けば目的は達成だった。 仮にプロフェッショナルに仕事を依頼し、同様に動くものを作ってもらうとして、 なぜそれらの道具でうまくいくのか、なぜその道具を選ぶのか、その道具はなにでてきているのか、などの問いに答えられなかったとしたら、 それでも依頼を続けるだろうか。

原理的な知識無しには、本当はなにもできていないのではないか。 機械学習のことはあまり知らないので本当は話に出したくないのだが、最近台頭したフレームワークを使ってみたら、 なんかすごい結果がでた、さらにパラメータを試行錯誤すると、もっとすごくなった、という話はざらにあると思う。 この裏側には、コンピュータを安く買えるようになったとか、アルゴリズムが進歩したとか、使いやすいフレームワークになったとか 色々あると思うが、言いたいこととしては、とにかく参入の敷居が下がったということだ。

ここからは空想だが、近い将来、誰でもボタンを数回押すだけで目的が達成できるようになったとしよう。 すると、ボタンを押すことが仕事になるだろうか?一方で、ボタンを数回押すだけで目的が達成できるようになった、という仕組みを作った人は必ずいる。 そちら側にいない限り、価値を提供し続けることは難しくなる。

学生という立場

学生は基本的には暇なので、結構なんでもできる。 遊び呆けることもできるし、アルバイトやインターンの身分で実際の業務に携わることもできる。

社会にでてから学ぶことは、基本的には業務に関する情報である。 新卒研修というので基礎的な素養を叩き込むのが一般的と思われるが、それがどの程度の効果なのかは真に定量的には保証されていないと思う (ペーパーテストやプログラミングテストは真の意味で適さないと私は考えている)。

学生がやるべきことは、その業務の前提となる素養を身につける勉強をすることなのではないか。 もしかしたらすごく当たり前のことを言っているかもしれない。しかし、そのことに最近気がついた。 修士という立場上、研究は必須であるが、資本主義社会において企業は常にイノベーションを起こして成長が必要であり、 素養を身につけるという本質は変わっていない。

バイトで適当に小遣いを稼いだり、適当にプロダクトを作って喜んでいる場合ではないということである。 学生は、その身分の間でしかできない、勉強と研究をするべきということに気がついた。

なにを学ぶか

世の中にいる同世代もしくはもっと下の世代で、OSSで活躍したり、コンテストで表彰経験のある人というのは、 早い段階で、基礎的な部分を学習し、その上で応用やイノベーションを起こしているのだと思う。 その前提において、自分が極めて底辺に位置するということがわかったので、そこは開き直って最初からやっていこうと思う。

まずUnixを学ぶ。WebもUnix思想に大きく影響を受けているし、Webアーキテクチャを語る上でUnixの話は避けて通れないはずである。 なにより今この文章を書いているMacbookUnixだし、Webサーバが動いているのは普通Unixである。 その上で、システムパフォーマンス、特にネットワークを学びたいと思う。 理由は、自分がインフラ領域をやりたいと思っているのと、今配属している研究室がネットワーク分野だからという理由である。 最近簡単なプロセスの本とソケットプログラミングの本を読んだ感想としては、面白かった。もっと学びたいと思った。 昔これらを学んだときに分からなかった面白さが理解できるレベルにやっとなったということかもしれない。 スパイラルアップで学習することが長期的に見て一番効率がいいということも最近気がついた。

まずは気楽にベストエフォートでやっていこうと思います。

2017年4月7日

大学

今年度初めて研究室に行った。事務処理が面倒すぎて死んでいた

Working With TCP Sockets

読み始めた。3割ぐらい読んだけどわかりやすくていい感じがしている。

Working With TCP Sockets (English Edition)

Working With TCP Sockets (English Edition)

読みたい本はどんどん増えるが、とにかく本を読むのが遅いし、どんどん本が積まれていっている状況をなんとかしたい

2017年4月3日

今日は特になにもやらなかった

2017年春アニメ

視聴登録したやつ

 $ curl -sS "https://api.annict.com/v1/me/works?access_token=$ANNICT_ACCESS_TOKEN&filter_season=2017-spring&filter_status=watching" | jq '.works[].title' -r
恋愛暴君
有頂天家族2
Re:CREATORS (レクリエイターズ)
武装少女マキャヴェリズム
ロクでなし魔術講師と禁忌教典
クロックワーク・プラネット
月がきれい
ソード・オラトリア
ID-0
ひなこのーと
エロマンガ先生
ゼロから始める魔法の書
冴えない彼女の育てかた♭
サクラクエスト
サクラダリセット
終末なにしてますか? 忙しいですか? 救ってもらっていいですか?

annict.com

2017年4月2日

AWS

つづき

NAT

NAT Gateway を試した。NAT Gateway を Public subnet に設置し、Elastic IP で Publilc IP を付与する。Private subnet 内に EC2 インスタンスを立てて、外へ向けて traceroute すると、NAT を経由しての疎通を確認した。 DB などの Private subnet 内のインスタンスからインターネットに出たい場合に使えばいいっぽい。

Rundeck

できた。Slack 連携した。

mackerel

試した。1分足らずでエージェントインストールとホスト監視設定までできてすごい。Slack 連携した。

サービス移行

VPS で動かしていたサービスAWS に移行するのが目的。まず DNS 管理を Route53 に移行した。以前は Cloudflare で HTTPS 化していたのだが、後学のためにも自前で証明書を管理することにした。

Let’s Encrypt

きちんと理解していなかったので調べた。下記エントリが分かりやすかった。

jxck.hatenablog.com

CA が発行する証明書のうち、DV (Domain Validation) は、ドメイン所有のみを証明するため、信頼性は劣るが、短期間で確認・発行できる。Let’s Encrypt は、DV を発行する CA である。DV 証明書の発行手順は、ACME プロトコルで標準化されている (仕様策定中)。

sorah さんが開発している acmesmith という gem を突然思い出したので試した。サクッと証明書ができてすごい。

github.com

2017年4月1日

AWS

DNS

EC2 インスタンスを起動すると、ip-10-0-xx-yy.ap-northeast-1.compute.internal のような Private DNS が割り当てられている。インスタンスの IP を固定するために、Elastic IP を使う。インスタンスに Elastic IP を紐付けることで、Public IP と Public DNS を得られる。Public DNS は、ec2-ww-xx-yy-zz.ap-northeast-1.compute.amazonaws.com の形式になる。 Route 53 で、aws 用のサブドメインの Hosted Zone を設定した。CNAME でインスタンスFQDN を引ける用に設定した。

参考:AWS EC2 インスタンス間の名前解決に Route 53 を使う - Shin x blog

IAM

だいたい理解したが何もやらなかったので今度やる。

Rundeck

これまで VPS で雑に動かしていた cron job を、新しく用意した Rundeck サーバで動かすように移行した。itamae のレシピを作成しながら構築している分時間がかかった。 色々いじっていたら systemctl rundeckd start で立ち上がらなくなってしまいつらい状態