メインコンテンツへスキップ
見出し画像

第 7 回|パケットを「見る」目を取り戻す ──『TCP/IP Illustrated』

    シリーズ - AI agent コーディング全盛時代のいまこそ学ぶソフトウェアサイエンス ─ 2026 年版 #7

    新しいマイクロサービスを 1 つデプロイしました。Claude Code が書いた gRPC のサーバとクライアント、両方とも動いている、と AI は言っています。実際、ローカルではテストが全部通っている。

    本番にデプロイすると、断続的にタイムアウトが起きます。1 分に 1 回くらい、クライアントから「deadline exceeded」が返ってくる。エラーレートは 0.3%。AI に「タイムアウトを修正して」と頼むと、リトライロジックを追加した diff が返ってきます。

    リトライで誤魔化されているけれど、根本原因は分かっていません。

    ターミナルで tcpdump -i eth0 -w trace.pcap port 50051 を走らせて、実際のパケットを覗くと、本当の問題が見えてきます。

    クライアントが送った SYN に対して、サーバが SYN+ACK を返した後、すぐに RST を打っていました。

    画像

    Linux カーネルの net.core.somaxconn が低くて、accept queue があふれている。Claude Code は、これに気付きません。気付けない、というほうが正確です。AI はパケットを見たことがないからです。

    本記事は、W. Richard Stevens の『TCP/IP Illustrated, Vol. 1』を扱います。ネットワーク技術書の決定版、AI 時代に最も読まれるべき古典のひとつです。

    なぜ、いまさら TCP/IP なのか

    画像

    ジュニアエンジニアの多くは、こう思っています。「いまどき TCP/IP なんて意識する必要ない、HTTP と REST と GraphQL のレイヤで仕事してるから」。

    これは、第 6 回の OS の話と同じ構造です。半分正しくて、半分大きく間違っています。

    HTTP の下には TCP があり、TCP の下には IP があり、IP の下には Ethernet があります。何かバグが起きた時、最終的な原因はこれらのどこかのレイヤです。AI は「タイムアウトを延ばしてみてください」「リトライを入れてみてください」と提案しますが、根本原因の特定には踏み込めません。

    なぜ AI が踏み込めないか。AI は、パケットを見たことがないからです。Stevens の本を読んだことがないからです(学習データには含まれているかもしれませんが、それを「体感」として持っていない)。

    Stevens の本を読むことは、AI が持っていないネットワークのデバッグ感を手に入れることです。

    読み終えたら、何が変わるか

    3 つの語彙が手に入ります。

    tcpdump や Wireshark でパケットを観察する習慣が身につきます。これは、AI が答えられない領域に踏み込む足場です。

    TCP の 3-way handshake、retransmission、congestion control の挙動を、頭の中で再現できるようになります。

    AI が「ネットワークが信頼できないから、リトライを入れます」と提案した時、「リトライの戦略は何か、idempotency は保証されているか、何回まで、間隔は」と問い返せるようになります。

    Stevens という伝説

    画像

    W. Richard Stevens(1951-1999)は、ネットワーク技術書の歴史で最も重要な著者です。

    彼が書いた本は、ネットワークと UNIX システムプログラミングを学ぶ人にとっての聖典でした。

    • 『TCP/IP Illustrated, Vol. 1: The Protocols』(1994)

    • 『TCP/IP Illustrated, Vol. 2: The Implementation』(1995)

    • 『TCP/IP Illustrated, Vol. 3: TCP for Transactions, HTTP, NNTP, and the UNIX Domain Protocols』(1996)

    • 『UNIX Network Programming』全 2 巻

    • 『Advanced Programming in the UNIX Environment』

    Stevens は 1999 年、48 歳で亡くなりました。早すぎる死でした。

    彼の本の特徴は、徹底的に実物を見せることです。プロトコルの説明だけでなく、tcpdump の出力、実際のパケットダンプ、システムコールの戻り値、これらを大量に載せて、読者が「本物」を見られるようにしました。

    『TCP/IP Illustrated』に推薦文を寄せた Vint Cerf(TCP/IP の発明者の 1 人)は、verbatim でこう書いています。

    The insights provided by this book will be invaluable.

    この本が提供する洞察は、計り知れない価値がある。

    そして 2011 年に、Kevin Fall が第 2 版を共著で出版しました。IPv6、TLS、HTTP/1.1 以降の更新が反映されています。

    tcpdump を使う、という習慣

    画像

    Stevens の本の最大の教えは、tcpdump を使え、というものです。

    tcpdump(または Wireshark)は、ネットワークインターフェースを通過するパケットをキャプチャ・表示するツールです。1988 年に Van Jacobson が作りました。

    ジュニアエンジニアが tcpdump を使えない理由は、シンプルです。怖いから、です。

    「ネットワークの低レベルの話」「root 権限が必要」「16 進表示で読めない」。こういう理由で、tcpdump は避けられがちです。

    Stevens の本は、これを正面から打ち破ります。本書の各章には、必ず tcpdump の出力例が載っています。読みながら、自分のマシンで同じコマンドを叩くと、同じパケットが見える。これを繰り返すと、tcpdump への恐怖が消えます。

    具体的な使い方を、3 行で書きます。

    # ローカルマシンの 80 番ポートを通る通信をキャプチャ
    sudo tcpdump -i any -n port 80
    
    # パケットを pcap ファイルに保存して、後で Wireshark で見る
    sudo tcpdump -i any -w trace.pcap port 443
    
    # DNS クエリだけを見る
    sudo tcpdump -i any -n port 53
    

    これで、自分のマシンを出入りするパケットが、文字で見えます。最初は呪文のように見えますが、Stevens の本を 1 章ずつ読みながら見ると、各フィールドの意味が分かってきます。

    これが、AI が持っていない目です。AI に「なぜタイムアウトする?」と聞いても、AI はパケットを見られない。あなたは、tcpdump で見られる。

    TCP の 3-way handshake

    画像

    Stevens の『TCP/IP Illustrated, Vol. 1』で、最も重要な章は第 18 章「TCP Connection Establishment and Termination」です。

    ここで扱われるのが、有名な 3-way handshake。

    クライアントが SYN を送る。サーバが SYN+ACK を返す。クライアントが ACK を返す。これでコネクションが確立される。

    教科書的な説明はここで終わりますが、Stevens の章では、ここから深掘りが始まります。

    SYN が届かなかったら、どうなる?
    SYN+ACK が届かなかったら?
    クライアントの ACK が届かなかったら?
    サーバが受け入れキューを超えていたら?

    それぞれのケースで、tcpdump の出力例が載っています。読者は、想像ではなく、実物を見て理解します。

    AI コーディング時代に、この知識がどう効くか。

    本番でタイムアウトが起きた時、tcpdump を見ると、サーバが SYN+ACK の後にすぐ RST を打っていました。これは、サーバの accept queue があふれている時に Linux カーネルが出す挙動です。修正方法は、net.core.somaxconn を上げる、または application layer のリスナー設定を見直すこと。

    AI に「タイムアウトを修正して」と頼んでも、ここまでは絶対に辿り着きません。AI は、リトライを足すか、タイムアウトを延ばすか、コネクションプールサイズを変えるか、こういう application layer の対症療法を提案します。根本対処は、tcpdump を見られる人間の仕事です。

    Retransmission:再送の世界

    画像

    Stevens の本の第 21 章は、TCP Timeout and Retransmission。

    パケットが失われた時、TCP はそれを再送します。再送には、いくつかの戦略があります。

    Karn のアルゴリズム、Jacobson の RTO 計算式、Fast Retransmit、SACK(Selective Acknowledgment)。これらは、TCP の中核アルゴリズムです。

    AI コーディング時代に、これがなぜ重要か。

    AI に「リトライを実装してください」と頼むと、AI は HTTP レベルのリトライを実装します。けれど、HTTP リトライと TCP 再送は別レイヤです。両方が同時に動くと、想定外の挙動が起きます。

    具体的には、HTTP リクエストがタイムアウトしてリトライした時、サーバ側ではすでにリクエストを受け取って処理を進めている、というケース。idempotency が保証されていなければ、二重に処理されます。

    これを AI に説明してもらうには、こう聞きます。

    「このリトライロジックですが、ネットワークレイヤと application レイヤのリトライが重なる可能性があります。idempotency キーは使っていますか?」

    AI は「使っていません」「使うべきです」「実装します」と返してくれます。けれど、この質問を投げられるのは、TCP 再送の存在を知っている人間だけです。

    Stevens の本を読むことは、AI に正しい質問を投げる能力を手に入れることです。

    Congestion Control:輻輳制御

    画像

    Stevens の本の第 22 章は、TCP Congestion Control。

    これは、TCP の最も美しい部分です。インターネットがあれだけのトラフィックを抱えても破綻しない理由は、TCP の輻輳制御アルゴリズムが、各コネクションの送信速度を自律的に調整しているからです。

    Slow Start、Congestion Avoidance、Fast Retransmit、Fast Recovery。これらの名前を、Stevens の本で習いました。

    Van Jacobson(tcpdump の作者でもある)が 1988 年に提案した輻輳制御アルゴリズムは、いまも TCP の標準的な挙動の基礎になっています。後継として BBR(Google)、CUBIC(Linux のデフォルト)など、新しいアルゴリズムが提案されていますが、Jacobson の枠組みは生きています。

    AI コーディング時代に、輻輳制御がどう効くか。

    API のパフォーマンスチューニングをする時、AI は「並列リクエスト数を増やしてください」と提案することがあります。けれど、並列度を上げすぎると、TCP の輻輳制御が働いて、結果的にスループットが落ちることがあります。

    これを理解していると、適切な並列度(concurrency limit)を設定できます。AI に「並列度はいくつが適切?」と聞いても、AI は答えられない。プロファイラを走らせて、実際の挙動を見て、輻輳制御の働きを観察して、決める必要があります。

    Stevens の本を読むと、TCP が「自分で勝手にやっている調整」を知ることになります。それを乱さない、application layer の設計ができるようになります。

    TLS と HTTPS の下に潜る

    画像

    Stevens の第 2 版(2011 年、Kevin Fall 共著)では、TLS と HTTPS の章が加わっています。

    ここで扱われるのは、TLS handshake の挙動、証明書の検証、Cipher Suite の選択、Session Resumption。

    AI に「HTTPS でデータを送信して」と頼むと、AI は fetch や axios を使うコードを出してきます。動きます。けれど、何が起きているかを AI は説明できません。

    実際に起きているのは、こうです。

    1. クライアントが TCP コネクションを張る(3-way handshake)

    2. ClientHello を送る(サポートしている Cipher Suite、TLS version)

    3. サーバが ServerHello + 証明書 + ServerKeyExchange を返す

    4. クライアントが証明書を検証する

    5. ClientKeyExchange を送って、共通鍵を作る

    6. Finished メッセージで、TLS コネクション確立

    7. ここから、暗号化された HTTP 通信が始まる

    これらが、fetch('https://api.example.com') の 1 行で起きています。

    性能問題が起きた時、これらのどこに時間がかかっているかを切り分ける必要があります。TCP 接続が遅いのか、TLS handshake が遅いのか、サーバの処理が遅いのか。

    tcpdump で見れば分かります。AI に聞いても分かりません。

    DNS:名前解決の沼

    画像

    Stevens の本には、DNS の章もあります(第 11 章「Name Resolution and the Domain Name System」)。

    DNS は、シンプルに見えて、深い沼です。

    api.example.com という名前を IP アドレスに変換する。それだけのように見えます。けれど、実際にはこうなっています。

    1. ローカルキャッシュを見る(OS の resolver cache、systemd-resolved、nscd)

    2. なければ、DNS サーバに問い合わせる(/etc/resolv.conf に書かれたサーバ)

    3. DNS サーバがキャッシュを持っていなければ、root server から順に辿る

    4. 最終的に、authoritative DNS server が答えを返す

    5. TTL に応じて、各レイヤでキャッシュされる

    各ステップに、タイムアウトとリトライがあります。DNS サーバが応答しなかったら、別のサーバに問い合わせる。それも応答しなかったら、エラーを返す。

    AI コーディング時代の悲劇は、DNS の問題を application layer のバグとして扱ってしまうことです。「サービスに繋がらない」「タイムアウトする」と AI に伝えると、AI は application のコードを直そうとします。実は DNS が壊れているだけかもしれない。

    切り分けの第一歩は、dig や nslookup で名前解決を確認することです。

    # 名前解決を見る
    dig api.example.com
    
    # DNS サーバを指定して確認
    dig @8.8.8.8 api.example.com
    
    # トレース付きで見る
    dig +trace api.example.com
    

    これらのコマンドは、tcpdump と同じく、AI が持っていない目です。

    IPv6 と現代

    第 2 版で大きく加わったのが、IPv6 の章です。

    IPv4 のアドレス空間(32 bit、約 43 億)は、2011 年頃には完全に枯渇しました。インターネットの拡張のために、IPv6(128 bit)への移行が長年進められています。

    AI コーディング時代の罠は、IPv4 だけを前提としたコードを書くことです。「IPv4 で 127.0.0.1 とすれば動く」と AI は思っていますが、本番環境では IPv6 only のネットワークも増えています。

    ローカルホストを指定する時、127.0.0.1 ではなく localhost を使う、というのが教科書的な対応ですが、Node.js のバージョンによって localhost が IPv4 にも IPv6 にも解決されることがあり、これが問題を起こすことがあります。

    Stevens の IPv6 章を読むと、こういう罠を予期できるようになります。

    ジュニアのための実習

    Stevens の本を実践的に学ぶ方法を、3 つ書きます。

    自分の Mac で tcpdump -i any -n -w trace.pcap を 30 秒間走らせます。その間に、Web ブラウザで普段使うサイトを 1 つ開きます。trace.pcap を Wireshark で開くと、何百ものパケットが見えます。どれが TCP の SYN か、どれが DNS のクエリか、どれが TLS のハンドシェイクか、Stevens の本と照らし合わせながら追ってみます。

    AI に書かせた gRPC や REST API のクライアントを、tcpdump 越しに観察します。本当に AI が言っているような順序でリクエストが飛んでいるか、確認します。たぶん、想定と違う挙動が見えます。

    curl の -v オプションを使い倒します。curl -v https://example.com で、HTTP リクエストの詳細が見えます。DNS 解決時間、TCP 接続時間、TLS handshake 時間、レスポンス到着時間、すべてが出ます。これらの数字が、AI に対する正確なフィードバックの材料になります。

    AI が本番のタイムアウト問題を解けなかった理由は、AI がパケットを見ていないからです。AI の学習データには、ネットワークの教科書も、tcpdump のドキュメントも、過去の障害レポートも含まれているはずです。けれど、それらは「言葉」として学習されたもので、「観察」として体に染み込んだものではありません。

    人間が tcpdump を使う、というのは、AI ができないことです。少なくとも、いまのところは。MCP server で AI に tcpdump を叩かせる、というアプローチも可能ですが、結果を解釈する目を人間が持っていないと、AI は迷子になります。

    Stevens の本を読むことは、AI が持っていない「観察の習慣」を、自分の中に作ることです。これが、AI 時代のシニアエンジニアと、AI に頼り切るジュニアの差を作ります。

    自分の Mac で sudo tcpdump -i any -n -c 100 を実行します。100 パケットだけキャプチャして、画面に流します。何が見えるか、まず眺めます。慣れるまでは、それでよいです。

    Stevens の『TCP/IP Illustrated, Vol. 1』第 2 版を中古で探します。新本は高いです。図書館でも借りられます。第 18 章「TCP Connection Establishment and Termination」だけ読みます。50 ページくらい。これだけで、TCP に対する理解が完全に変わります。

    いま自分が運用しているサービスで、ネットワーク経由の通信を 1 つ選び、curl の -v オプションで叩いてみます。DNS、TCP、TLS、HTTP、それぞれにかかっている時間を見ます。Stevens の本で読んだ各レイヤが、実際の数字として見えます。

    第 8 回は、同じ Stevens の『Advanced Programming in the UNIX Environment』(APUE)を扱います。今度は、ネットワークの下にある UNIX システムコールの世界です。

    Vint Cerf の言葉を引いて、この回を閉じます。

    Stevens' books are how we learned to think about networking.

    Stevens の本は、われわれがネットワークを考える方法を学んだやり方そのものだ。

    画像

    これは、TCP/IP を発明した本人が、Stevens の本に寄せた最高の賛辞です。

     
     
    コピー機修理から始め、26歳でLinuxに出会い、28歳で直談判して異動。40代で借金1,800万背負って再起。歴史の積み重ねなしに、最新技術は正しく使えない。Engineers Hub㈱ 代表 / 八ヶ岳南麓 / 自社サービス複数βテスト中

    あなたへのおすすめ