「jabber.jp が Google Talk と 相互接続できないのが某所で問題になっている。」 昨日、そんな声が社内から聞こえてきました。 jabber.jp というのは 2001年6月のサービス開始以来、 KLab で運用している jabber (通信に XMLプロトコル XMPP を使う、 インスタント メッセージング サービス) サーバです。 KLab 社内公式 IM (インスタント メッセンジャー) として大いに活用していますが、 社外のかたにも開放しています。
その時は、
「え? Google ? あそこって他サイトとの相互接続ってやってなかったんでは?」
と、思わず答えてしまいましたが、
いつのまにか
相互接続を開始していたんですね。
知らなかった... orz
jabber.org などとは
相互接続できていたので、
Google Talk と接続できないのはアチラの問題、と思い込んでいました (_O_)。
多くの方々に利用して頂いている jabber.jp で調査を行なうよりは、 (落ちても誰も文句言わない ;) 自宅サイト gcd.org も Google Talk と接続できないという 問題をかかえていたので、gcd.org で調査を始めました。
通信できないときに最初にすべきことと言えば、 まずはパケットが届いているか調べることですね。 tcpdump でパケットダンプを取りつつ、 Google Talk (gmail.com) に jabber クライアントでログインして GCD (jabber.gcd.org) へチャットしてみました。
senri:/home/sengoku # tcpdump -i ppp0 port 5269 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ppp0, link-type LINUX_SLL (Linux cooked), capture size 96 bytes 07:07:11.672591 IP iproxy.google.com.32489 > gcd.org.5269: S 2133894537:2133894537(0) win 5720 <mss 1430,sackOK,timestamp 379820136 0,nop,wscale 0> 07:07:13.004593 IP gcd.org.5269 > iproxy.google.com.32489: S 1097254147:1097254147(0) ack 2133894538 win 5608 <mss 1414,sackOK,timestamp 401538947 379820136,nop,wscale 2> 07:07:11.837330 IP iproxy.google.com.32489 > gcd.org.5269: . ack 1 win 5720 <nop,nop,timestamp 379820153 401538947> 07:07:11.837527 IP iproxy.google.com.32489 > gcd.org.5269: P 1:142(141) ack 1 win 5720 <nop,nop,timestamp 379820153 401538947> 07:07:11.837574 IP gcd.org.5269 > iproxy.google.com.32489: . ack 142 win 1670 <nop,nop,timestamp 401538988 379820153> 07:07:11.837762 IP gcd.org.5269 > iproxy.google.com.32489: P 1:187(186) ack 142 win 1670 <nop,nop,timestamp 401538988 379820153> 07:07:12.002559 IP iproxy.google.com.32489 > gcd.org.5269: . ack 187 win 5720 <nop,nop,timestamp 379820169 401538988> 07:07:12.003738 IP iproxy.google.com.32489 > gcd.org.5269: P 142:242(100) ack 187 win 5720 <nop,nop,timestamp 379820170 401538988> 07:07:12.046764 IP gcd.org.5269 > iproxy.google.com.32489: . ack 242 win 1670 <nop,nop,timestamp 401539040 379820170> 07:07:13.486820 IP gcd.org.41294 > 216.239.57.83.5269: S 1003009747:1003009747(0) win 5656 <mss 1414,sackOK,timestamp 401539400 0,nop,wscale 2>
最初 Google 側から GCD の 5269番ポートへ接続があって、 それに答えて GCD から Google へ dialback 接続を行なう... ところが、それに対する応答が無い。 実際、netstat で調べてみると SYN_SENT のままです。
senri:/home/sengoku # netstat -nap | grep s2s tcp 0 0 0.0.0.0:5269 0.0.0.0:* LISTEN 14525/s2s tcp 0 1 60.32.85.216:41294 216.239.57.83:5269 SYN_SENT 14525/s2s ...
見るからに、216.239.57.83 へ接続を試みていることが間違いのようです。 216.239.57.83 というのは gmail.com の A レコードの一つですね。
senri:/home/sengoku % host gmail.com. gmail.com has address 64.233.161.83 gmail.com has address 216.239.57.83 ←コレ gmail.com has address 64.233.171.83 gmail.com mail is handled by 50 gsmtp163.google.com. gmail.com mail is handled by 50 gsmtp183.google.com. gmail.com mail is handled by 5 gmail-smtp-in.l.google.com. gmail.com mail is handled by 10 alt1.gmail-smtp-in.l.google.com. gmail.com mail is handled by 10 alt2.gmail-smtp-in.l.google.com.
では、jabber サーバ間の通信では接続先をどのように探せばよいのだっけ、と 調べてみると、 SRV レコードに サーバのホスト名とポート番号を 登録しておくことになっているようです。 以前は A レコードを使っていたような気がするのですが、 A レコードを直接使ってしまうと、 jabber ID (JID) のドメイン名と jabber サーバのホスト名を一致させる必要があって 柔軟性を欠くから、 SRV レコードに変更したということなのでしょう。
私の自宅サイトのような小規模サイトなら jabber.gcd.org というホスト名で jabber サーバを立ち上げることはさほど問題ではありませんが、 Google のような大規模サイトだと、gmail.com というホスト名で jabber サーバを立ち上げてしまうと運用が面倒なことになりそうです。 gmail.com の SRV レコードを引いてみると、 xmpp-server.l.google.com という応答が返ってきました。 つまり (JID のドメイン名である) gmail.com とは 異なるサーバ xmpp-server.l.google.com で jabber サーバを動かしているということです。
senri:/home/sengoku % host -t srv _xmpp-server._tcp.gmail.com. _xmpp-server._tcp.gmail.com has SRV record 5 0 5269 xmpp-server.l.google.com. _xmpp-server._tcp.gmail.com has SRV record 20 0 5269 xmpp-server1.l.google.com. _xmpp-server._tcp.gmail.com has SRV record 20 0 5269 xmpp-server2.l.google.com. _xmpp-server._tcp.gmail.com has SRV record 20 0 5269 xmpp-server3.l.google.com. _xmpp-server._tcp.gmail.com has SRV record 20 0 5269 xmpp-server4.l.google.com. % host -t a xmpp-server.l.google.com. xmpp-server.l.google.com has address 64.233.167.125
というわけで通信できない原因が分かったので、 あとは GCD の jabber サーバに SRV レコードを参照させればいいだけですが、 幸い現在使っている jabberd2 サーバは SRV レコードを参照する機能を持っていました。 なので設定ファイル resolver.xml に次の行を追加するだけです:
<lookup> <srv>_xmpp-server._tcp</srv> <srv>_jabber._tcp</srv> </lookup>
また、SRV レコードを参照する jabber サーバ&クライアントのために、 ネームサーバに SRV レコードを登録しておいたほうがいいでしょう。 GCD ではネームサーバとして djbdns を使っているので、 次の行を tinydns のレコードファイルに追加します:
:_jabber._tcp.jabber.gcd.org:33:\000\012\000\000\024\225\006jabber\003gcd\003org\000 :_xmpp-server._tcp.jabber.gcd.org:33:\000\012\000\000\024\225\006jabber\003gcd\003org\000 :_xmpp-client._tcp.jabber.gcd.org:33:\000\012\000\000\024\146\006jabber\003gcd\003org\000
以上の修正を行なった上で、 GCD と Google Talk それぞれに jabber クライアントでログインして、 チャットしてみると、あっさりつながりました。 続いて同様の修正を jabber.jp に対しても行ないました。
というわけで、約5ヶ月の間ご迷惑をおかけしましたが、 jabber.jp と Google Talk は、 ようやく本日より相互接続できるようになりました。
jabber サーバの死活確認スクリプト
この jabber サーバには、なにかのタイミングでハングするバグがあるようだ。
他のソフトウェアへの乗り換えも含めて対策を検討中であるが、
とりあえずハングしていないかの死活確認は必須だろう。
CPAN の Net::Jabber を利用して簡単な死活確認スクリプトを書いてみた….
Comment by 仙石浩明の日記 — 2006年6月29日 @ 07:45