ユーザ用ツール

サイト用ツール


Sidebar

ミドルウェア系:openfire:クライアントからのresource値を元に動的にresource値を付与

クライアントからのresource値を元に動的にresource値を付与

  • クライアントがresource値を指定した場合に、HEX値を付与する実装について
  • 例えばGoogle Talkではそういう実装になっていて、クライアントから与えられるresource値をクライアントソフトの種類とし、その後ろにHEX値を連結されることで、同じクライアントソフトであっても複数のresource値を定義している。

そこで、openfireでも同様の処理を可能にするために、ストリームIDの実装を追った。

openfireをlibjingleでも使えるようにする

  • src/java/org/jivesoftware/openfire/session/LocalClientSession.java
289         sb.append("xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:client\" from=\"");
290         sb.append(serverName);
291         sb.append("\" id=\"");
292         sb.append(session.getStreamID().toString());
293         sb.append("\" xml:lang=\"");
294         sb.append(language);

上記のように(session.getStreamIDが呼ばれている。

275         // Create a ClientSession for this user.
276         LocalClientSession session = SessionManager.getInstance().createClientSession(connection);

createClientSessionクラスを追う。

  • src/java/org/jivesoftware/openfire/SessionManager.java
 321     public LocalClientSession createClientSession {
 322         return createClientSession(conn, nextStreamID());
 323     }
 
 332     public LocalClientSession createClientSession(Connection conn, StreamID id) {
 333         if (serverName == null) {
 334             throw new IllegalStateException("Server not initialized");
 335         }
 336         LocalClientSession session = new LocalClientSession(serverName, conn, id);
 337         conn.init(session);
 338         // Register to receive close notification on this session so we can
 339         // remove  and also send an unavailable presence if it wasn't
 340         // sent before
 341         conn.registerCloseListener(clientSessionListener, session);
 342
 343         // Add to pre-authenticated sessions.
 344         localSessionManager.getPreAuthenticatedSessions().put(session.getAddress().getResource(), session);
 345         // Increment the counter of user sessions
 346         connectionsCounter.incrementAndGet();
 347         return session;
 348     }

上記のように、createClientSession(Connection conn, StreamID id)の中でcreateClientSession(Connection conn, StreamID id)を読んでおり、 その中では、LocalClientSessionクラスをインスタンス化している。

LocalClientSessionクラスを追う。

  • src/java/org/jivesoftware/openfire/session/LocalClientSession.java
 60 public class LocalClientSession extends LocalSession implements ClientSession {

LocalClientSessionではLocalSessionを継承している。

  • src/java/org/jivesoftware/openfire/session/LocalSession.java
 46 public abstract class LocalSession implements Session {
 
160     /**
161      * Obtain the stream ID associated with this sesison. Stream ID's are generated by the server
162      * and should be unique and random.
163      *
164      * @return This session's assigned stream ID
165      */
166     public StreamID getStreamID() {
167         return streamID;
168     }

LocalSession内にgetStreamID()メソッドを見つけた。

  • src/java/org/jivesoftware/openfire/StreamID.java
 28 public interface StreamID {
 29
 30     /**
 31      * Obtain a unique identifier for easily identifying this stream in
 32      * a database.
 33      *
 34      * @return The unique ID for this stream
 35      */
 36     public String getID();
 37 }

StreamIDgetID()によりランダムな値を取得しているようだ。

また、urn:ietf:params:xml:ns:xmpp-bindをキーにソースを追っていくと、

  • src/java/org/jivesoftware/openfire/handler/IQBindHandler.java
 85         // Check if the client specified a desired resource
 86         String resource = packet.getChildElement().elementTextTrim("resource");
 87         if (resource == null || resource.length() == 0) {
 88             // None was defined so use the random generated resource
 89             resource = session.getAddress().getResource();
 90         }
 91         else {
 92             // Check that the desired resource is valid
 93             try {
 94                 resource = JID.resourceprep(resource);
 95             }
 96             catch (StringprepException e) {
 97                 reply.setChildElement(packet.getChildElement().createCopy());
 98                 reply.setError(PacketError.Condition.jid_malformed);
 99                 // Send the error directly since a route does not exist at this point.
100                 session.process(reply);
101                 return null;
102             }
103         }

において、resource値の割当実装を発見。上記を見る限り、クライアント指定のresourceがなければランダムなresource値(=streamID)を付与するルールになっている。

そのため、下記のようにクライアントから指定のresourceがあれば、その後ろにランダムなresource値を続けて付与するように実装を 変更した。

diff -u src/java/org/jivesoftware/openfire/handler/IQBindHandler.java{.orig,}
--- src/java/org/jivesoftware/openfire/handler/IQBindHandler.java.orig  2011-10-02 06:50:12.000000000 +0900
+++ src/java/org/jivesoftware/openfire/handler/IQBindHandler.java       2012-10-25 13:24:02.000000000 +0900
@@ -91,7 +91,7 @@
         else {
             // Check that the desired resource is valid
             try {
-                resource = JID.resourceprep(resource);
+                resource = JID.resourceprep(resource) + "." + session.getAddress().getResource();
             }
             catch (StringprepException e) {
                 reply.setChildElement(packet.getChildElement().createCopy());

これで、クライアントソフトからresrouce値、例えばsyncigaとか指定してやれば、実際に与えられるresource値はsyncigaH8DEGLM7とかになる。

ミドルウェア系/openfire/クライアントからのresource値を元に動的にresource値を付与.txt · 最終更新: 2013/04/29 12:04 by matsumoto_r