http://q.hatena.ne.jp/1228454656 に至った思考の経路

元の質問者の環境を下記のように仮定

(1) 物理的配線は ONU - ルータ - (* 1) - サーバ
  *1) この位置に HUB が入っている可能性があるが、HUB の有無は影響が無いので無視する。

(2) 回答で、ONU とルータの間に HUB をいれ、ルータを ONU に対して並列し、それぞれのルータから PPPoE のセッションを張ることが提案される。

 物理的配線)
    ONU ─ HUB ─ ルータA
        └──ルータB

(3) 回答ではルータからサーバへの配線、および、サーバの設定に関して言及されていないことから、下記の事を仮定。
 ・サーバの NIC は1つ
 ・サーバに割り当てられている IP アドレスは1つ
 ・ルーティングプロトコル(RIP、OSPF など)は有効になっておらず(少なくとも、WindowsLinux ではデフォルトでは無効)、デフォルトゲートウェイが設定されているのみ。

(4) また、元の質問者のルータに関して詳細は不明だが、最初の構成が、典型的なおうちサーバの構成と考え、
 ・サーバに割り当てている IP アドレスはプライベートアドレス。
 ・ルータにおいて 1 対 1 のスタティック NAT、もしくは、サーバが Web サーバであることから、宛先ポート 80 に対して NAPT 下におけるポーとフォワーディングにより、サーバとインターネット側の任意の端末との間におけるパケットの送受信が可能な状態にしていた。

(5) 上記の仮定から、回答者が示すルータを追加した後の構成を下記のように仮定。

 物理的配線)
  ONU ─ HUB ─ ルータA ─ HUB(*2) ─ サーバ
      └──ルータB ──┘

 *2) この HUB は必ずしも必要ではない。2つのルータの間をクロスケーブルで結ぶか、よほど古いルータで無い限り、Auto-MDI により、自動的に結線をクロスの状態に変更される。

(6) また、上記の配線をと、「NAT されている」仮定を組み合わせて、IP レベルでの論理的な構成は下記のようになる。

 論理的配線)

  クライアント ─ インターネット網 ─ ISP-A ─ ルータ A ─┬─ サーバ
              └───── ISP-B ─ ルータ B ─┘

 *3) 厳密には、ISP-A も ISP-B もインターネット網を構成している。
 *4)クライアントも通常は何らかの ISP の配下にある。クライアントが ISP-A の配下の場合もあれば、ISP-B の配下にある場合もあれば、そのどちらでもない場合もある。

(7) また、説明の都合上、IP のアドレス下記のように仮定する。

 クライアント:      11.22.33.44
 ルータ A: ISP 側: 22.33.44.55
            サーバ側:192.168.1.1
 ルータ B: ISP 側: 33.44.55.66
      サーバ側:192.168.1.2
 サーバ:      192.168.1.3

(8) 前述の (1)〜(3) の仮定から、サーバが持っているルーティングテーブルは、ルータ追加前と変更が無ければ下記のようになる。

  宛先ネットワークアドレス │ 送信先
  ─────────────┼────────────
  192.168.1.0/24      │自分のネットワーク
  0.0.0.0/0                │192.168.1.1

以上の構成からクライアントとサーバの間で送受信されるパケットに関して考察する。

(9) この構成下で、クライアントからサーバに向かって送られる IP パケットは下記のようになる。

 クライアントが 22.33.44.55 へパケットを送信)
                     │送信元アドレス│宛先アドレス
  ───────────────────┼───────┼───────
  クライアントが送出したパケット    │11.22.33.44   │22.33.44.55
  ルータ A が受け取ったパケット     │11.22.33.44   │22.33.44.55
  ルータ A がサーバへ送り出したパケット │11.22.33.44   │192.168.1.3
  サーバが受け取ったパケット      │11.22.33.44   │192.168.1.3

 クライアントが 33.44.55.66 へパケットを送信)
                     │送信元アドレス│宛先アドレス
  ───────────────────┼───────┼───────
  クライアントが送出したパケット    │11.22.33.44   │33.44.55.66
  ルータ A が受け取ったパケット     │11.22.33.44   │33.44.55.66
  ルータ A がサーバへ送り出したパケット │11.22.33.44   │192.168.1.3
  サーバが受け取ったパケット      │11.22.33.44   │192.168.1.3


(10) 逆に、サーバがクライアントへパケットを送信する場合、自身が保持するルーティングテーブルに従えば、デフォルトゲートウェイ((8) に従ってルータ A)に向かってパケットを送出することになる。

(11) 今、クライアントからサーバに向かって、TCP のコネクションを確立することを考える。TCP のコネクションを確立するためには、最初に RFC 793 の 3-way handshake が行われる。3-way handshake は下記の3つのパケットのやり取りが行われる。

 ・クライアントからサーバへ向かって、SYN フラグつきのパケットを送る。
 ・サーバは、SYN フラグつきのパケットを受け取ると、送り主に対して SYN/ACK フラグつきのパケットを送る。
 ・クライアントは、サーバから SYN/ACK フラグつきのパケットが戻ってきた事を確認して、ACK フラグつきのパケットをサーバへ送る。

 *5) 厳密には、シーケンス番号に対応する ACK の番号(受け取ったパケットのシーケンス番号に 1 を加えた数値)がセットされている必要がある。

(12) サーバが 3-way handshake の2つのパケットをクライアントに返そうとしてパケットを組み立てると、その IP パケットの送信元アドレス、宛先アドレスは下記のようになる。

  送信元アドレス│宛先アドレス
  ───────┼───────
  192.168.1.3   │11.22.33.44

(13) このパケットは、サーバのルーティングテーブルに従えば、ルータ A を経由してクライアントに届けられる。

                          │送信元アドレス│宛先アドレス
  ────────────────────────┼───────┼───────
  サーバが送出したパケット            │192.168.1.3   │11.22.33.44
  ルータ A が受け取ったパケット          │192.168.1.3   │11.22.33.44
  ルータ A がインターネット側へ送り出したパケット │22.33.44.55   │11.22.33.44
  クライアントが受け取ったパケット        │22.33.44.55   │11.22.33.44

(14) (13) に示すパケットは、もし、サーバがルーティングテーブルに従ってパケットを送出すれば、(9) で示した2つのケースのいずれの場合でも同じになる。

(15) そうすると、

 ・クライアントが 22.33.44.55 に向かって TCP のコネクションを確立しようとした場合は、送った相手と同じ IP アドレスから SYN/ACK のパケットが届く。
 ・クライアントが 33.44.55.66 に向かって TCP のコネクションを確立しようとした場合は、送った相手と違う IP アドレスから SYN/ACK のパケットが届く。

という事が発生する。

(16) 違う IP アドレスから 3-way handshake の2つ目のパケットが届いても、以降の TCP の処理に関係ない(2つ目のパケットの送信元アドレスは、どこから届こうが関係無しに、3つ目の ACK パケットを送出して、TCP のコネクションが確立する)のであれば、クライアントがどちらの IP アドレスに繋ごうとしても(また、サーバがどっちのルータを経路として選択しても)TCP としての通信が成立するので問題ない。

 *6) 但し、外へ送信されるパケットが片方の ISP しか経由しない、という問題は残るが、ここではその問題は考慮しない。


ここで、もうひとつの仮定をする。

(17) TCP の 3-way handshake が成立するために、1つ目の SYN フラグつきのパケットの宛先アドレスと2つ目の SYN/ACK 付きパケットの送信元アドレスが合致している必要がある、とする。

(18) (17) の仮定が成り立てば、クライアントが 33.44.55.66 へ TCP のコネクションを確立しようとした時に受け取る2つ目のパケットが 22.33.44.55 から届くと、(18) の仮定により、TCP のコネクションが確立できない。

(19) (17) の仮定が成り立つ場合に、クライアントがどちらの IP アドレスへ接続しようとしても、コネクションが成立するためには、サーバ側で、3-way handshake の1つ目のパケットが経由したルータと同じルータに対して、2つ目のパケットを送出する必要がある。

(20) (9) を見ると、サーバ受け取るパケットの IP アドレスからは、どっちのルータを経由したパケットなのかは判別できない。判別できる情報は、イーサフレームの送信元 MAC アドレスである。

(21) TCP のレイヤーではイーサフレームの情報に依存しない。なぜなら、IP より下のレイヤーがイーサネットとは限らず、PPP(PPPoE を含む)、フレームリレー、FDDI など、様々なレイヤーが考えられ、それらの違いは IP のレイヤーで吸収される。

(22) (21) のことから、TCP のレイヤーでは、handshake に対する2つ目のパケットを送る際に下位のレイヤーに指定するのは IP アドレスのみである。

(23) (22) のことから IP のレイヤーは、(12) で示されているアドレス情報を持つパケットを生成する。

(24) アドレス情報からルーティングテーブルを参照すると(7) に従って、デフォルトゲートウェイに指定されたルータを選択することになる。これでは、(19) の条件を満たすことが出来ない。

(25) (19) の条件を満たすためには、下記に上げるいずれかのメカニズムが必要となる。
 (i) サーバのルーティングテーブルが、クライアントから SYN フラグ付きパケットに反応して更新される。
 (ii) ルーティングテーブルとは別のロジックによって経路選択が行われる(例えば、送信元 IP アドレスと送信元 MAC アドレスのペアを保持し、送信元 IP アドレスがこの情報に見つかった場合に、その情報を優先して送信先MAC アドレスを採用する)。

(26) (25)-(i) に関して、少なくとも筆者は、ルーティングプロトコル(RIP、OSPF、BGP)によって更新されるケースを除いて、手動設定された内容以外の情報が追加・削除されるケースは知らない。もし、(23)-(i) のようなメカニズムでルーティングテーブルが更新されるとすれば、サーバのルーティングテーブルは勝手に追加されたエントリでいっぱいになっていることが容易に想像できる。


以上をまとめると、

・(16) が成立すれば、外へ出て行くパケットがどちらの ISP を経由しても、TCP のコネクションは成立し問題ない(但し、サーバの設定、動作原理次第では、送出されるパケットが片方の ISP に偏る可能性がある)。

・(16) が成立しないとなれば、TCP のコネクションが成立するためには、クライアントが送った最初の SYN フラグ付きパケットが経由したルータを、サーバが必ず選択するメカニズムが必要。