書いてる人: 高橋カヲル | [mixi] | [PGP] | [TETRiS DS] | [portscout] | [RSS]
リハビリ@七条KING。郵便物受取りのついで。階段の弱さが不安定さの原因よな。 325476 タイプは得意なんだが、 234567 はもうダメ。
すこし間があいたので、潜水で 25m いけるかチェックしようとしたら邪魔が入って萎え。ちんたら泳いでるならまだ許せるが、コースの途中で横切るんじゃねえよよ。
一晩寝たのでまとめよう。実験環境は
まあ経路にアレゲルータ(ブラックホールルータ)がいなければ問題ない話なんだが、「世間の対策を待っているうちに時間切れになる」ので自衛しなけりゃならない。
alice も bob も常に DF ビットの立った IP パケットを送るとしよう。アレゲルータはひとまず「ICMP をすべて落としてしまう」ことにする。
alice が NetBSD なら traceroute -P が便利。
-P Set the "don't fragment" bit, and use the next hop
mtu each time we get the "need fragmentation"
error, thus probing the path MTU.
traceroute が投げるパケットは udp だから、 mss の書き換えは効かない。 mssfixup にだまされずに PMTUD の様子を調べることができる。 DF ビットを落とされるとさすがに調べられない。
scrub out on $ext_if all no-df random-id
なんて激しい rule を書いてから traceroute -P の挙動の差を調べるとよくわかる。こんな乱暴なことは実験中だけ。
trent が mss 書き換えを何もしなかった場合の往路について考える。 alice は自分の MTU の限界ギリギリである 1500オクテットの IP パケットを bob に向かって送る。 1500オクテットでは大きすぎて trent の ng0 を通過できない。 trent が alice に ICMP NF (need fragment) を返し、 alice は 1454 オクテットのパケットを bob に向かって送る。ここですんなり bob に届いてしまえば往路は問題ない。つまり trent (の ng0) が往路の最小 MTU だった場合だ。
alice --- 最小 MTU(trent) --- bob (アレゲルータ無し) alice --- 最小 MTU(trent) --- アレゲルータ --- bob
trent が往路の最小 MTU でなくても、アレゲルータより手前に最小 MTU があれば、再度 ICMP NF が戻ってきて往路は問題ない。 alice から見れば trent だろうがそれより向こうだろうが、 ICMP が帰ってくることに代わりはない。
alice --- trent --- 最小 MTU --- bob alice --- trent --- 最小 MTU --- アレゲルータ --- bob
しかし
alice --- trent --- アレゲルータ --- 最小 MTU --- bob alice --- trent --- アレゲルータ --- 最小 MTU --- bob
だとどうだろう。アレゲルータによって ICMP が落とされてしまう。 bob にパケットが届かず、かといって ICMP が戻ってくるわけでもない。タイムアウトを待つことになるわけだ。
alice --- 最小 MTU --- bob alice --- アレゲルータ --- 最小 MTU --- bob
は救えるが、
alice --- 最小 MTU --- アレゲルータ --- bob alice --- アレゲルータ --- 最小 MTU --- アレゲルータ --- bob
なんかだともうどうしようもない。お手上げ。
フレッツで PPPoE している場合だと trent (の ng0) が往路の最小 MTU だという場合が多い。
alice --- 最小 MTU(trent) --- bob (アレゲルータ無し) alice --- 最小 MTU(trent) --- アレゲルータ --- bob
のパターンが多くなるというわけだ。前者は問題なく通信できるから放置。後者のパターンを救うために bob から送ってもらうパケットのサイズを (アレゲルータに関係なく届く程度に)を小さくしてもらう、という戦略が考えられる。 alice が bob に通知する mss を trent が小さく書き換える。
scrub out on $ext_if all max-mss X
bob に通知される mss が X オクテット以下になるわけだから、 bob から送られてくるパケットのサイズが小さくなることを期待できる。具体的なサイズは X + 20 (IP ヘッダ) + 20 (TCP ヘッダ) [オクテット]。 bob から送られてくるパケットのサイズが、復路の最小 MTU より小さくなっていれば、復路のパケットはアレゲルータが挟まっていても届く。これで救えるのは以下の条件をすべて満たすケース
X は 1414 以下にしないと意味がない (フレッツの場合)。ヘッダサイズが 20+20 という保証はないらしいので、実際にはそのぶんのマージンをとって設定する。
alice --- アレゲルータ --- 最小 MTU --- bob alice --- アレゲルータ --- 最小 MTU --- アレゲルータ --- bob
も救ってやりたいなら alice に通知される mss も縮めてしまう手がある。
scrub in on $ext_if all max-mss X scrub out on $ext_if all max-mss X
これで救えるのは以下の条件をすべて満たすケース
trent が最小 MTU ではないケース (最小 MTU < 1454) を救いたいわけだから、 X にギリギリの 1414 を設定したのでは意味がない。経路の最小 MTUを見積もって激しくマージンをとるべき。
alice --- 最小 MTU(trent) --- アレゲルータ --- bob のパターンだけ救えればいいなら、
scrub out on $ext_if all max-mss 1414
1414 より小さめにする。マージンと最速 MTU を意識して 1408 = 1448 - 40 や、 1360 = 1400 - 40 あたりに設定するのも手。alice --- アレゲルータ --- 最小 MTU --- アレゲルータ --- bob も救ってやりたいなら
scrub in on $ext_if all max-mss X scrub out on $ext_if all max-mss X
自分が見積もった最小MTU - 40 を X に設定する。
Powered by 早起き生活