むらかみの雑記帳

Android とか iOS とかソフトウェア開発に関するネタ帳

Proxy 自動設定の isInNet()

ブラウザの Proxy を自動設定するため、proxy.pac を自前でごりごり書いて使っている。

proxy.pac の中では isInNet() という関数があって、これを使うとアクセス先の IP アドレスが内部アドレスなのか外部アドレスか調べられるので便利。なのだが、引数がホスト名の場合、DNS のクエリがかかるのでちと遅くなるという問題がある。

特に以下のような場合には注意が必要。

  if (isInNet(host, "192.168.0.0", "255.255.0.0") ||
      isInNet(host, "172.16.0.0", "255.255.0.0"))

Wireshark で調べてみたら、上記の場合 DNS のクエリが2回出てしまう(Firefox の場合、IE は調べてない)。私の proxy.pac の場合、DNS クエリが 13 回も出てしまうというかなりアフォなことになっていた。

DNS クエリを1回で済ませようと思うなら、以下のように書かなければならない。

   var hostip = dnsResolve(host);

  if (isInNet(hostip, "192.168.0.0", "255.255.0.0") ||
      isInNet(hostip, "172.16.0.0", "255.255.0.0"))

こうすれば、DNS クエリは dnsResolve() 時の1回だけで済む。isInNet に IPv4 アドレスを渡したときは DNS は引かないためだ。

ついでに言うと、.NET Framework 2.0 では自動 Proxy の仕様が変わったらしく、isInNet には IP アドレスしか渡せなくなった模様。上記のように修正すれば、こちらも対応できるというメリットがある。