xmpp仕様簡単解説
DESCRIPTION
XMPPの仕様を簡単に解説しますTRANSCRIPT
規格
• RFC2779: IM requirements• RFC3920: XMPP Core• RFC3921: XMPP IM & Presence• XEP-0030: Service Discovery• XEP-0045: Multi-User Chat
沢山あるけど,基本はこんな感じ
JID
jid = [ node “ @ ” ] domain [ “ / ” resource ]
domain = fqdn / address-literal
fqdn = ( sub-domain 1 * ( “ . “ sub-domain ) )
sub-domain = ( internationalized domain label )
address-literal = IPv4address / IPv6address
各パーツは 1023B 以下“ @ “ とか “ / “ とかも含めて 3071B 以下
メッセージ転送 ( client / server )
• JID の to 属性の hostname がサーバ名と一致• to 属性に書かれた JID が以下の場合
• < user @ example . com >• < user @ example . com / resource >
< user @ example . com >
< user @ example . com / resouce >
一致するアカウントがなければ無視,もしくはエラー
一致するリソースがなければ• presense: 無視• iq: エラー• message: < user @ domain >
と同様の処理
リソースが複数ある場合( message の場合)• プライオリ値最大のリソースに配信• priority 宣言がなければ 0 相当• priority が負の場合には配信禁止
メッセージ転送 ( server / server )
1. _xmpp-server . _tcp . example . com で DNS を検索2. _im . < proto > . example . com で DNS を検索( IM の場合)
_pres . < proto > . example . com で DNS を検索( presence, iq の場合)3. DNS で A レコードを検索して, TCP 5269 にアクセス(サーバ間通信)
• サーバクライアント間通信の場合,サーバが使うのは TCP 5222
セッション
TCP
TLS
SASL
Resource Binding ( user @ domain / resource )
クライアント サーバ
< session / >
< message / >, < presence / >
option
メッセージのやりとりをするまでに必要な設定
message syntax
• < message type = “ chat “ / >• < message type = “ error “ / >• < message type = “ groupchat “ / >• < message type = “ headline “ / >
• 配信やブロードキャストで使用• < message type = “ normal “ / >
• type で何も指定していなかったり,理解できない指定があった場合に適用
• message の子要素は option• 以下の要素は namespace を指定せずに使用可
• < message >< subject / >< / message >• < message >< body / >< / message >• < message >< thread / >< / message >
IQ ( Info / Query ) syntax
RequestingEntity
RespondingEntity
< iq type = ‘ get ‘ id = ‘ 1 ‘ >
< iq type = ‘ result ‘ id = ‘ 1 ‘ >
< iq type = ‘ set ‘ id = ‘ 2 ‘ >
< iq type = ‘ error ‘ id = ‘ 2 ‘ >
type 属性は 4 種類理由がない限り必須
id 属性も理由がない限り必須
Psi2OpenFire (設定)
• Psi の設定• Connection proxy: None• Compress traffic: No• Send "keep-alive" packets: Yes• Manually Specify Server Host/Port: No• Encrypt connection: When available• Ignore SSL warnings: No ← こうすると,エラーが出て来るけど continue する• Probe legacy SSL port: No ← ここを No にすると明示的に TLS を使う• Allow plaintext authentication: Never
• XML Console を開くと,赤字で C2S ストリーム,黄字で S2C ストリーム表示• OpenFire はほぼ Default 設定で,ユーザを一人分設定
Psi2OpenFire ( TLS 開設まで)-- C2S—
<?xml version="1.0"?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="foo.hoge.co.jp" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace" >
-- S2C --
<?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="foo.hoge.co.jp" id="b9a694d9" xml:lang="en" version="1.0">
-- S2C ---- TLS による通信要求 --
<stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>CRAM-MD5</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><auth xmlns="http://jabber.org/features/iq-auth"/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
-- C2S ---- TLS による通信開始 --
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
-- S2C ---- サーバが TLS 開始を確認 --
<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>よくみると,サーバは一度に要求してるが,クライアントはひとつずつ応えている
セッション
TCP
TLS
SASL
Resource Binding ( user @ domain / resource )
クライアント サーバ
< session / >
< message / >, < presence / >
option
メッセージのやりとりをするまでに必要な設定
Psi2OpenFire ( SASL 開設まで)
-- C2S ---- TLS による通信開始 --
<?xml version="1.0"?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="foo.hoge.co.jp" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace" >
-- S2C ---- サーバからの応答開始 --
<?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="foo.hoge.co.jp" id="b9a694d9" xml:lang="en" version="1.0">
-- S2C ---- SASL 要求 --<stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>CRAM-MD5</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><auth xmlns="http://jabber.org/features/iq-auth"/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
-- C2S --<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl“ mechanism="DIGEST-MD5" />
-- S2C --<challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">...</challenge>
-- C2S ---- クライアントがレスポンスを送信 --<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">...</response>
-- S2C ---- サーバが認証成功宣言 --<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl">...</success>
GTalk は SSL を使ってるのでTLS での通信要求はでない
セッション
TCP
TLS
SASL
Resource Binding ( user @ domain / resource )
クライアント サーバ
< session / >
< message / >, < presence / >
option
メッセージのやりとりをするまでに必要な設定
Psi2OpenFire (圧縮モード設定まで)
-- C2S ---- SASL ベースで再度アクセス --
<?xml version="1.0"?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="foo.hoge.co.jp" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace" >
-- S2C ---- サーバ応答 --
<?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="foo.hoge.co.jp" id="b9a694d9" xml:lang="en" version="1.0">
-- S2C ---- traffic を圧縮するかどうかを確認してる ---- Psi で "Compress traffic" にチェックしてないので無反応 --
<stream:features><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></stream:features>
Psi2OpenFire ( Roster 取得まで)
-- C2S ---- Client asks server to bind a resource: ---- RFC3920 7. Resource Binding --
<iq type="set" id="bind_1" ><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>Psi</resource></bind></iq>
-- S2C ---- Server informs client of successful resource binding: ---- RFC3920 7. Resource Binding --
<iq xmlns="jabber:client" type="result" id="bind_1" to="foo.hoge.co.jp/b9a694d9" ><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>[email protected]/Psi</jid></bind></iq>
-- C2S ---- Client requests session with server: ---- RFC3921 3. Session Establishment --
<iq type="set" id="aab5a" ><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>
-- S2C ----Server informs client that session has been created ---- この段階で "active resource" としてサーバに登録された --
<iq type="result" id="aab5a" to="[email protected]/Psi" ><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>
-- C2S ---- Client requests current roster from server: ---- 7.3. Retrieving One's Roster on Login --
<iq type="get" id="aab6a" ><query xmlns="jabber:iq:roster"/></iq>
-- S2C ---- Client receives roster from server: --
<iq type="result" id="aab6a" to="[email protected]/Psi" ><query xmlns="jabber:iq:roster"/></iq>
resource ってのは,[email protected] / Psi の“ Psi “ の部分
Psi2OpenFire ( Priority 設定まで)
-- C2S ---- Presence priority: ---- RFC3921 5.4. Specifying Presence Priority --
<presence><priority>5</priority><c xmlns="http://jabber.org/protocol/caps" node="http://psi-im.org/caps" ver="0.11-dev-rev8" ext="cs ep-notify html" /></presence>
Psi2GoogleTalk ( Roster 取得)
-- C2S ---- Client requests current roster from server: ---- 7.3. Retrieving One's Roster on Login --
<iq type="get" id="aab6a" ><query xmlns="jabber:iq:roster"/></iq>
-- S2C ---- Client receives roster from server: --
<iq type="result" to="[email protected]/griffin9EB3DE9D" id="aab6a" ><query xmlns="jabber:iq:roster"><item subscription=“both” name=“ 誰か " jid=“[email protected]" /><item subscription="both" jid="[email protected]" /><item subscription="both" jid="[email protected]" ><group>Buddies</group></item></query></iq>
Psi2GoogleTalk ( vCard 取得)
-- C2S ---- vCard Action: Resulting Stanza ---- XEP-0054 6.2 URI Query Types --
<iq type="get" to="[email protected]" id="aab9a" ><vCard xmlns="vcard-temp“ version="2.0“ prodid="-//HandGen//NONSGML vGen v1.0//EN" /></iq>
<iq [email protected] type="result“ [email protected]/griffin9EB3DE9D id="aab9a" ><vCard xmlns="vcard-temp"><FN>Keiichi daiba</FN><PHOTO><TYPE>image/jpeg</TYPE><BINVAL>...</BINVAL></PHOTO></vCard></iq>
バイナリデータを Basa64? 変換して埋め込んである
Psi2GoogleTalk (メッセージ送受信)
-- BOT にメッセージを送る --
<message type="chat" to="[email protected]" id="aabea" ><body>general</body><active xmlns="http://jabber.org/protocol/chatstates"/></message>
<message from="[email protected]" type="chat" to="[email protected]/griffinEB79CC3A" ><body> 全般 </body></message>
Psi2OpenFire (ルーム作成)
-- C2S ---- チャットルーム作成 --
<presence to="[email protected]/test" ><priority>0</priority><x xmlns="http://jabber.org/protocol/muc"><history maxchars="0" /></x></presence>
-- S2C –-- 成功 --
<presence [email protected]/test to=“[email protected]/Psi" ><priority>0</priority>
<x xmlns="http://jabber.org/protocol/muc#user"><item affiliation="owner“ role="moderator“ jid=“[email protected]/Psi" /><status code="201" /></x></presence>
“ conference “ は OpenFire のデフォルト設定ルーム名 “ test “ ,ニックネームも “ test “
-- C2S --
<iq type="set" to="[email protected]" id="aac1a" ><query xmlns="http://jabber.org/protocol/muc#owner"><x xmlns="jabber:x:data" type="submit" /></query></iq>
-- S2C –
<message [email protected] type="groupchat“ to=“[email protected]/Psi" ><body> This room is locked from entry until configuration is confirmed.</body></message>
<message [email protected] type="groupchat“ to=“[email protected]/Psi" ><body>This room is now unlocked.</body></message>
作成した状態では LOCK されてるのでsubmit して UNLOCK
Psi2OpenFire (設定確認)
-- C2S ---- 設定確認 –
<iq from=‘[email protected]/Psi' id='config1' to='[email protected]' type='get'><query xmlns='http://jabber.org/protocol/muc#owner'/></iq>
-- S2C ---- 確認したデータ --<iq [email protected] type="result“ id="config1“ to=“[email protected]/Psi" ><query xmlns="http://jabber.org/protocol/muc#owner"><x xmlns="jabber:x:data" type="form" ><title>Room configuration</title><instructions>...</instructions><field type="hidden" var="FORM_TYPE" ><value>http://jabber.org/protocol/muc#roomconfig</value></field><field type="text-single“ label="Room Name“ var="muc#roomconfig_roomname" ><value>test</value></field>...
<field type="list-single“ label="Maximum Room Occupants“ var="muc#roomconfig_maxusers" ><value>30</value><option label="10" ><value>10</value></option><option label="20" ><value>20</value></option><option label="30" ><value>30</value></option><option label="40" ><value>40</value></option><option label="50" ><value>50</value></option><option label="None" ><value>0</value></option></field>...</x></query></iq>
初期設定で,参加可能な人数は 30
パラメータを何も指定しないとすべての設定を返す
Psi2OpenFire (設定変更)
-- 設定変更 ---- C2S --
<iq from=‘[email protected]/Psi' id='create2' to='[email protected]' type='set'><query xmlns='http://jabber.org/protocol/muc#owner'><x xmlns='jabber:x:data' type='submit'><field var='muc#roomconfig_maxusers'> <value>0</value></field></x></query></iq>
-- S2C --
<iq [email protected] type="result“ id="create2“ to=“[email protected]/Psi" />
Psi の XML コンソールを使って手動で XML 送信< value > 0 < / value > が最大入室無制限