PresenceRouter.java 6.13 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/**
 * $RCSfile: PresenceRouter.java,v $
 * $Revision: 3138 $
 * $Date: 2005-12-01 02:13:26 -0300 (Thu, 01 Dec 2005) $
 *
 * Copyright (C) 2004 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.wildfire;

14 15 16 17 18
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.container.BasicModule;
import org.jivesoftware.wildfire.handler.PresenceSubscribeHandler;
import org.jivesoftware.wildfire.handler.PresenceUpdateHandler;
19 20
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
21
import org.xmpp.packet.Presence;
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

/**
 * <p>Route presence packets throughout the server.</p>
 * <p>Routing is based on the recipient and sender addresses. The typical
 * packet will often be routed twice, once from the sender to some internal
 * server component for handling or processing, and then back to the router
 * to be delivered to it's final destination.</p>
 *
 * @author Iain Shigeoka
 */
public class PresenceRouter extends BasicModule {

    private RoutingTable routingTable;
    private PresenceUpdateHandler updateHandler;
    private PresenceSubscribeHandler subscribeHandler;
    private PresenceManager presenceManager;
    private SessionManager sessionManager;
39
    private MulticastRouter multicastRouter;
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
    private String serverName;

    /**
     * Constructs a presence router.
     */
    public PresenceRouter() {
        super("XMPP Presence Router");
    }

    /**
     * Routes presence packets.
     *
     * @param packet the packet to route.
     * @throws NullPointerException if the packet is null.
     */
    public void route(Presence packet) {
        if (packet == null) {
            throw new NullPointerException();
        }
59
        ClientSession session = sessionManager.getSession(packet.getFrom());
60 61 62 63 64 65 66
        if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) {
            handle(packet);
        }
        else {
            packet.setTo(session.getAddress());
            packet.setFrom((JID)null);
            packet.setError(PacketError.Condition.not_authorized);
67
            session.process(packet);
68 69 70 71 72
        }
    }

    private void handle(Presence packet) {
        JID recipientJID = packet.getTo();
73 74 75 76 77 78 79 80 81 82
        // Check if the packet was sent to the server hostname
        if (recipientJID != null && recipientJID.getNode() == null &&
                recipientJID.getResource() == null && serverName.equals(recipientJID.getDomain())) {
            if (packet.getElement().element("addresses") != null) {
                // Presence includes multicast processing instructions. Ask the multicastRouter
                // to route this packet
                multicastRouter.route(packet);
                return;
            }
        }
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
        try {
            Presence.Type type = packet.getType();
            // Presence updates (null is 'available')
            if (type == null || Presence.Type.unavailable == type) {
                // check for local server target
                if (recipientJID == null || recipientJID.getDomain() == null ||
                        "".equals(recipientJID.getDomain()) || (recipientJID.getNode() == null &&
                        recipientJID.getResource() == null) &&
                        serverName.equals(recipientJID.getDomain())) {
                    updateHandler.process(packet);
                }
                else {
                    // The user sent a directed presence to an entity
                    ChannelHandler route = routingTable.getRoute(recipientJID);
                    if (route != null) {
98 99 100 101 102 103
                        Session session = sessionManager.getSession(packet.getFrom());
                        if (session != null && session.getStatus() == Session.STATUS_CLOSED) {
                            Log.warn("Rejected available presence: " + packet + " - " + session);
                            return;
                        }
                        // Register the sent directed presence
104
                        updateHandler.directedPresenceSent(packet, route, recipientJID.toString());
105 106
                        // Route the packet
                        route.process(packet);
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
                    }
                }

            }
            else if (Presence.Type.subscribe == type // presence subscriptions
                    || Presence.Type.unsubscribe == type
                    || Presence.Type.subscribed == type
                    || Presence.Type.unsubscribed == type)
            {
                subscribeHandler.process(packet);
            }
            else if (Presence.Type.probe == type) {
                // Handle a presence probe sent by a remote server
                presenceManager.handleProbe(packet);
            }
            else {
                // It's an unknown or ERROR type, just deliver it because there's nothing
                // else to do with it
                ChannelHandler route = routingTable.getRoute(recipientJID);
                if (route != null) {
                    route.process(packet);
                }
            }

        }
        catch (Exception e) {
            Log.error(LocaleUtils.getLocalizedString("admin.error.routing"), e);
            Session session = sessionManager.getSession(packet.getFrom());
            if (session != null) {
                Connection conn = session.getConnection();
                if (conn != null) {
                    conn.close();
                }
            }
        }
    }

    public void initialize(XMPPServer server) {
        super.initialize(server);
        serverName = server.getServerInfo().getName();
        routingTable = server.getRoutingTable();
        updateHandler = server.getPresenceUpdateHandler();
        subscribeHandler = server.getPresenceSubscribeHandler();
        presenceManager = server.getPresenceManager();
151
        multicastRouter = server.getMulticastRouter();
152 153 154
        sessionManager = server.getSessionManager();
    }
}