教科書にない、PMTUDにまつわる挙動

# 全てはQUICから
[本家](https://www.chromium.org/quic)の[資料](https://docs.google.com/presentation/d/15e1bLKYeN56GL1oTJSF9OZiUsI-rcxisLo9dEyDkWQs/edit#slide=id.gc34025b9a_0_0)によると、92%がworksと書いてある。
当然、自分も無意識に使っているはず。どんなものか見てみたい。
そこで、Wireshark。すると…
<img width="849" alt="Hello.png" src="https://qiita-image-store.s3.amazonaws.com/0/104225/6a92551d-3318-02dd-1418-7967c7eb8861.png">
確かに出ているが、一瞬だけ。その後は、見慣れたSSL/TLSが、どばーっと。
いきなり8%にご当選か。不幸だー。

Google様のテクノロジーの恩恵を受けたいじゃないの。

# 環境
我が家にはNOC(A)とNOC(B)があり、NOC(A)=v4/v6デュアルスタックのISP、NOC(B)=v4シングルスタックのISP。
NOC(A)-NOC(B)間は、IPIP(v6)でトンネルしており、NOC(B)のv6は、NOC(A)のISP経由になる。
よって、NOC(A)-NOC(B)のPath MTUは、1500-40=1460だ。
これなら、1350+8+40=1398のQUICのClient Helloは、通りそうじゃない。
でも、実際に見ると、TCPにFallbackしている。また、Chromeを動かすホストをv4シングルにすると、ちゃんとQUICになる。
UDPなQUICはMSS Clampingも効かないので、MTUが1460になるように、Path MTU discoveryの挙動を確認してみよう。(フラグ)

# MTUにまつわる罠たち
調べる過程で目撃してしまった、MTUの味わい深い世界を、お楽しみ下さい。
UDPなQUICに無関係なものも含む。

## SEILの経路MTU探索抑制機能
NOC(B)のルーターは[SEIL/x86](http://www.seil.jp/product/seil-x86.html)。
[マニュアル](http://www.seil.jp/doc/index.html#fn/option/cmd/option_ipv6_avoid_path_mtu_discovery.html)によると、v6+トンネルの場合、PMTUDを抑止する機能があるらしい。
しかも、デフォルトでon。
条件も合っていそうだし、踏んでしまったか。

## RTX1200の`ip tunnel mtu`
NOC(A)のルーターはRTX1200。
`ip tunnel mtu 1460`を設定しているのに、挙動を見ると、1280固定で動作しているように見える。
機種と条件が違うが、こちらの[リリースノート](http://www.rtpro.yamaha.co.jp/RT/relnote/Rev.10.00/relnote_10_00_61.html)だと、「1280固定のはずが`ip tunnel mtu`の値で動作」というバグがあったらしい。
[マニュアル](http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/index.html)をよく見ると、`ip tunnnel mtu`はあるが、`ipv6 tunnel mtu`は無い。
over v6のトンネルは、1280固定が、仕様? (詳細未確認)
この時点で、QUIC over UDP over IPv6 over IPv6は、ギブアップか。

## 大きいICMPを不正と扱うICMP
`ping -s`などでMTUを測定していると発生。IDSなどで不正と検知し、落とされてしまう。
[YAMAHAの場合](http://www.rtpro.yamaha.co.jp/RT/docs/firewall/index.html#section3)は1025バイト以上が条件の模様。
[こちら](https://www.janog.gr.jp/meeting/janog34/doc/janog34-6pmtu-kunitake-1.pdf)も大変詳しい。
しかし、MTUを通知するICMPに載せる元パケットのサイズが実装依存とは…大きいパケットを送ろうとして、大きすぎることを通知するデータが大きすぎると、ブラックホール。

## TCP Segmentation Offload (TSO)
QUICとは関係の無いTCPについてだが、ICMPのport unreachable(MTU=1460)を受けた後のセッッションでも、1460-40-20=1400を超えるTCPセグメントを投げるホストがいる。
しかも、受けた方は、MSS Clampingのように、TCPレベルでMTUに合わせたセグメントを受信している。
さらに、`netstat -4 -nrC`で、ルーティングキャッシュに乗らないように見える。
なにこれ、こわい…。

これは、TSOによるものだった。[こちら](
http://blog.keshi.org/hogememo/2010/10/09/tcp-segmentation-offload-trap)に詳しい。
VMwareでの詳細は[こちら](https://kb.vmware.com/kb/2092912)。

### TSOをOffにできないドライバ
[上記記事](http://blog.keshi.org/hogememo/2010/10/09/tcp-segmentation-offload-trap)では、`ethtool -K eth0 tso off`で無効にならないドライバがある模様。
I350 + VMware + open-vm-toolsでも、無効にならないように見える(詳細未確認)。

## ICMPで通知されるMTUよりも小さなMTUを使うホスト
iPhoneが、ICMP destination unreachableを受けると、1280で出してくるように見えるログをチラ見した気がする(詳細未確認)。
[PLPMTUD](https://tools.ietf.org/html/rfc4821)に関連か? [RFC2923](https://tools.ietf.org/html/rfc2923)?

## MSS Clampingを手動でMTUに設定
ただの自分のちょんぼです。
特にv6は、MTUなら1280でMSS Clampingしないと通らないところに、結構ぶつかる気がする。
そこで、autoでなく手動設定して、はまる。
MSSは、MTUからIPとTCPのヘッダ分減らさないと。v6なら、1280-40-20=1220。

# (おまけ)Chromeの挙動
QUIC v6 > TLS v6 > QUIC v4 > TLS v4 という優先順位のようだ。
PMTUが1280な経路はもはや少数派、というご判断なのだろうか…。
QUIC v4優先設定とかないかな(要調査)。

# 宿題
## QUIC関連
- [Internet draft](https://tools.ietf.org/html/draft-tsvwg-quic-protocol-00)によると、Path MTU discoveryはwork in progress
- QUICのお勉強…[こちら](http://keens.github.io/blog/2017/01/02/quicnonakamigawakaranaikarashiyouyondemita/)が参考になりそう

## MTU関連
- 世界のMTU/MSS状況、特にv6
- NICとドライバーのTSO対応状況
- ICMPを受けた後のTCPの挙動
- PLPMTUDと`tcp_mtu_probing`と`tcp_base_mss`の関係