SessionPacketRouter.java 3.83 KB
Newer Older
Alex Wenckus's avatar
Alex Wenckus committed
1 2 3 4 5
/**
 * $RCSfile: $
 * $Revision: $
 * $Date: $
 *
6
 * Copyright (C) 2007 Jive Software. All rights reserved.
Alex Wenckus's avatar
Alex Wenckus committed
7 8 9 10
 *
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution.
 */
11
package org.jivesoftware.openfire;
Alex Wenckus's avatar
Alex Wenckus committed
12

13
import org.dom4j.Element;
14 15
import org.jivesoftware.openfire.multiplex.UnknownStanzaException;
import org.jivesoftware.openfire.net.SASLAuthentication;
16
import org.jivesoftware.openfire.session.LocalClientSession;
Alex Wenckus's avatar
Alex Wenckus committed
17 18 19 20 21
import org.xmpp.packet.*;

import java.io.UnsupportedEncodingException;

/**
22 23
 * Handles the routing of packets to a particular session. It will invoke all of the appropriate
 * interceptors, before and after having the server process the message.
Alex Wenckus's avatar
Alex Wenckus committed
24 25 26
 *
 * @author Alexander Wenckus
 */
27
public class SessionPacketRouter implements PacketRouter {
Alex Wenckus's avatar
Alex Wenckus committed
28

29
    private LocalClientSession session;
Alex Wenckus's avatar
Alex Wenckus committed
30
    private PacketRouter router;
31
    private boolean skipJIDValidation = false;
Alex Wenckus's avatar
Alex Wenckus committed
32

33
    public SessionPacketRouter(LocalClientSession session) {
Alex Wenckus's avatar
Alex Wenckus committed
34 35 36 37
        this.session = session;
        router = XMPPServer.getInstance().getPacketRouter();
    }

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
    /**
     * Sets if TO addresses of Elements being routed should be validated. Doing stringprep operations
     * is very expensive and sometimes we already validated the TO address so there is no need to
     * validate again the address. For instance, when using Connection Managers the validation
     * is done by the Connection Manager so we can just trust the TO address. On the other hand,
     * the FROM address is set by the server so there is no need to validate it.<p>
     *
     * By default validation is enabled.
     *
     * @param skipJIDValidation true if validation of TO address is enabled.
     */
    public void setSkipJIDValidation(boolean skipJIDValidation) {
        this.skipJIDValidation = skipJIDValidation;
    }

Alex Wenckus's avatar
Alex Wenckus committed
53
    public void route(Element wrappedElement)
54
            throws UnsupportedEncodingException, UnknownStanzaException {
Alex Wenckus's avatar
Alex Wenckus committed
55 56 57 58 59 60 61 62
        String tag = wrappedElement.getName();
        if ("auth".equals(tag) || "response".equals(tag)) {
            SASLAuthentication.handle(session, wrappedElement);
        }
        else if ("iq".equals(tag)) {
            route(getIQ(wrappedElement));
        }
        else if ("message".equals(tag)) {
63
            route(new Message(wrappedElement, skipJIDValidation));
Alex Wenckus's avatar
Alex Wenckus committed
64 65
        }
        else if ("presence".equals(tag)) {
66
            route(new Presence(wrappedElement, skipJIDValidation));
Alex Wenckus's avatar
Alex Wenckus committed
67 68 69 70 71 72 73 74 75 76 77 78
        }
        else {
            throw new UnknownStanzaException();
        }
    }

    private IQ getIQ(Element doc) {
        Element query = doc.element("query");
        if (query != null && "jabber:iq:roster".equals(query.getNamespaceURI())) {
            return new Roster(doc);
        }
        else {
79
            return new IQ(doc, skipJIDValidation);
Alex Wenckus's avatar
Alex Wenckus committed
80 81 82
        }
    }

83
    public void route(Packet packet) {
84 85
        // Security: Don't allow users to send packets on behalf of other users
        packet.setFrom(session.getAddress());
86 87 88 89 90 91 92 93 94 95 96
        if(packet instanceof IQ) {
            route((IQ)packet);
        }
        else if(packet instanceof Message) {
            route((Message)packet);
        }
        else if(packet instanceof Presence) {
            route((Presence)packet);
        }
    }

Alex Wenckus's avatar
Alex Wenckus committed
97 98
    public void route(IQ packet) {
        packet.setFrom(session.getAddress());
99 100
        router.route(packet);
        session.incrementClientPacketCount();
Alex Wenckus's avatar
Alex Wenckus committed
101 102 103 104
    }

    public void route(Message packet) {
        packet.setFrom(session.getAddress());
105 106
        router.route(packet);
        session.incrementClientPacketCount();
Alex Wenckus's avatar
Alex Wenckus committed
107 108 109 110
    }

    public void route(Presence packet) {
        packet.setFrom(session.getAddress());
111 112
        router.route(packet);
        session.incrementClientPacketCount();
Alex Wenckus's avatar
Alex Wenckus committed
113 114
    }
}