Photonが公表した技術報告は、macOSで約49日間の連続稼働後に、新しいTCP接続だけが張れなくなる一方、既存の接続やpingは生き続けるという、かなり変わった不具合像を示した。Photonは自社のiMessage監視フリートでこの挙動を観測し、2台のMacで再現したという。見た目にはネットワーク全体が落ちたように見えないのに、新規コネクションだけが失敗する。そこがこの話の厄介なところだ。

この問題が注目されるのは、単なる珍現象だからではない。Appleの公開XNUソースを追うと、TCPの時刻管理に使われる tcp_now が32-bitのミリ秒カウンタとして扱われ、calculate_tcp_clock()microuptime() から得た値が現在値より大きいときだけ更新する。つまり、時計は単調増加する前提で作られている。RFC 7323も、TCP timestamp clock は monotonic であるべきだとし、32-bitの1ms tick は wrap を前提に扱う必要があると説明している。ここでの焦点は、仕様が求める前提と、実装がどうその前提を維持しているかの接点にある。

AD

何が起きたのか

Photonの報告を読むと、症状はかなり限定的だ。既存のTCP接続はそのまま維持される。ICMP、つまりpingも通る。しかし新しいTCP接続を作ろうとすると失敗する。Photonの研究者がTechSpotに対して述べた「ICMP (ping) は動き、他は全て落ちている」という説明は、この切り分けを端的に示している。

この切り分けは、トラブルシューティングの現場で誤解を生みやすい。一般には「ネットワークが落ちた」と見えても、実際には名前解決、経路、ICMP、既存セッション、そして新規のTCPハンドシェイクがそれぞれ別の状態を持つ。今回のケースでは、そのうち新規TCP接続だけが壊れる。サービスの監視やバックエンド通信の一部が新しく張れないなら、アプリ側はタイムアウトや再試行を繰り返し、ネットワーク層そのものより上で問題が起きているように見えるかもしれない。

TechSpotとPhotonの説明が一致している点は、障害が一過性ではなく、連続稼働時間に結びついていることだ。約49日という数字は偶然ではなく、32-bitのミリ秒カウンタが取りうる上限、4,294,967,295 に対応する。49日17時間2分47.296秒という到達点は、まさにその桁の限界と重なる。ここから読み取れるのは、問題が外部要因のノイズではなく、カウンタの境界条件に近いところで発火している可能性が高い、ということだ。

Apple XNUの tcp_now はどう動いているのか

Appleの公開XNUソースには、bsd/netinet/tcp_subr.c 内の calculate_tcp_clock() がある。この関数は microuptime() から現在時刻を取り出し、それを uint32_t のミリ秒値として current_tcp_now に変換する。そして新しい値が現在の tcp_now より大きいときだけ、tcp_now を更新する。単純に見えるが、実装としてはかなり重要だ。TCPの時間基準が逆戻りしないようにするには、こうした単調増加の規則が欠かせない。

同じソースのコメントは、TCP clock がTCPレイヤーの境界で更新されることも示している。具体的には、パケット処理の前、接続がネットワークにアクセスする時、タイマーが動く時などだ。つまり、この時計は完全に独立したバックグラウンドクロックではなく、TCP処理の節目で前進する設計になっている。ここが今回の論点で、もしその時刻管理が何らかの条件で境界に到達し、更新条件と相性の悪い状態に入れば、新しい接続の成立だけが止まるという見え方になりうる。

ここで重要なのは、「49日で必ず壊れる」と断定するより、長時間稼働したMacでTCP clockの境界条件が露呈した、と捉えるほうが安全だという点だ。Photonが再現したのは2台のMacであり、観測元はiMessage監視フリートだった。つまり、一般家庭の短い再起動サイクルでは見えにくく、常時稼働に近い運用で表面化しやすい。

RFC 7323の背景も、この実装を読むうえで外せない。TCP timestamp は monotonic でなければならず、32-bitの1ms tick は wrap を前提に扱う必要がある。つまり、32-bit counter を使う以上、wrap そのものは珍しいことではない。問題は、wrap したあとにどう整合性を保つかだ。仕様が単に「単調であるべき」と言っているのではなく、古い timestamp を無効化するための扱いまで想定しているのは、その整合性が通信の生存条件だからだ。

AD

なぜ長時間稼働のMacで目立ちやすいのか

この話が「長く起動していたMacの特殊事例」で終わらないのは、Photonが iMessage 監視フリートを運用しているという事実そのものにある。TechSpotの要約と合わせると、同社がMacを使った監視系サービスを持ち、長時間稼働の前提でMacを使っていることがわかる。こうした環境では、短時間の利用よりも、数週間から数か月にわたって同じマシンを動かし続ける前提が強い。再起動でたまたま回避できる類の不具合でも、監視や常時待受の系ではその回避が現実的でない。

その意味で、今回の件は「Macの一般的な消費者利用」よりも、「サーバー的に使われるMac」や「常時稼働の監視端末」のほうが本質的にリスクが高い。なぜなら、そのような運用は新規TCP接続を継続的に作るからだ。既存接続だけが残っている状態でも、監視対象の切り替え、再接続、セッション更新が必要になる瞬間に失敗が出る。見かけ上は生きているのに、実務上は使えない、という最も扱いにくい障害パターンになる。

もっとも、ここでまだ断定できない点も残る。今回の材料では、影響範囲がどのmacOSバージョンに及ぶのか、IPv4とIPv6のどちらに依存するのか、あるいは特定のトラフィックパターンが関与しているのかは確定していない。Appleのsecurity releasesページには macOS Tahoe 26.4.109 Apr 2026 として掲載され、24 Mar 2026 付近の複数の更新も並んでいるが、それ自体はこの問題の修正確認ではなく、少なくとも公開リリースが継続していることを示すにとどまる。

いま見えている論点

現時点で見える論点は、単純な「バグがあった」ではなく、AppleのTCP実装が前提に置く時間管理と、長時間稼働する実運用のあいだにある隙間だ。tcp_now が32-bit millisecond counter である以上、約49日17時間2分47.296秒という境界は理論上存在する。RFC 7323 はその種の wrap を前提にしているが、実装上それをどう吸収するかで挙動は変わる。

Macを長期稼働させる運用者にとって、ここでの判断はかなり実務的だ。もし自分の環境が新規TCP接続に強く依存しているなら、単純な再起動運用で逃げられるのか、それとも監視・通信設計の側でローテーションやフェイルオーバーを組むべきなのかを見直す必要がある。もう一つの含意は、障害の監視設計そのものだ。ping が生きているだけでは異常検知にならず、新規コネクションの成立可否を見ない限り、この種の故障は見逃される。そこを外すと、Mac のネットワークはつながって見えても、必要な瞬間に新規通信を始められないままだ。


Sources