@m_seki の

I like ruby tooから引っ越し

r32254 (trunk)についての言い訳をさせて下さい。

# すごい眠いので説明がおかしいかもしれない。

直接的には[Bug #4409]のバグフィックスです。

バグ!

RMI経由で手に入れたDRbObjectをそのオブジェクトがあるはずのサーバ側に送り返しても、自局のオブジェクトでないと間違ってDRbObjectのまま処理してしまう、というバグを直しました。

この現象はホスト名を省略してサービスを開始した場合におきます。
DRb.start_serviceでnilやホスト名(インターフェイス名)を省略した場合、同じポート番号で複数のインターフェイスに対してサービスします。

DRb.start_service('druby://:0', Foo.new)
DRb.start_service(nil, Foo.new)

たとえばこんな指定をした場合です。このとき、イーサネットなどのネットワークインターフェイスとローカルループバックの同じポート番号でサービスします。IPv4, v6の両方を持つ場合なんかもそうですね。

数年前の変更で、RMIの中でDRbObjectが作られる場合(参照が渡す場合)に「そのRMIの起点となったネットワークインターフェイス」から作られたURIを使うようになりました。これが今回のバグのはじまりです。クライアントに届くDRbObjectの__drburiと、そのサーバのDRb.uriの文字列が違うため、Marshal.loadの中で行う参照オブジェクト→本物のオブジェクト変換が行われなくなります。

修正

  • 数年前の変更を捨てる
  • 外部に送り出したURIを自分のものと認識できるようにする

のどちらにするか迷った結果、後者にしました。前者でもよかったんだけど、なんでこう修正したのかちゃんと思い出せなかったので捨てられなかったんです。

今回はDRbServerがacceptしたときにそのネットワークインターフェイス起因のURIをメモしておいて、Marshal.loadの際にそのURIでも検査するようにしました。なんか泥縄な感じ。