Commit 9f16356a authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Clustering work.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@8353 b35dd754-fafc-0310-a699-88a17e54d16e
parent 542205c4
......@@ -12,8 +12,6 @@
package org.jivesoftware.openfire;
import org.dom4j.Element;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.openfire.handler.IQHandler;
......@@ -24,10 +22,9 @@ import org.jivesoftware.openfire.privacy.PrivacyListManager;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.openfire.user.UserManager;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.PacketError;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.xmpp.packet.*;
import java.util.ArrayList;
import java.util.List;
......@@ -244,10 +241,9 @@ public class IQRouter extends BasicModule {
try {
// Check for registered components, services or remote servers
if (recipientJID != null) {
RoutableChannelHandler serviceRoute = routingTable.getRoute(recipientJID);
if (serviceRoute != null && !(serviceRoute instanceof ClientSession)) {
if (routingTable.hasComponentRoute(recipientJID) || routingTable.hasServerRoute(recipientJID)) {
// A component/service/remote server was found that can handle the Packet
serviceRoute.process(packet);
routingTable.routePacket(recipientJID, packet);
return;
}
}
......@@ -266,10 +262,9 @@ public class IQRouter extends BasicModule {
}
else {
// Check if communication to local users is allowed
if (recipientJID != null &&
userManager.isRegisteredUser(recipientJID.getNode())) {
PrivacyList list = PrivacyListManager.getInstance()
.getDefaultPrivacyList(recipientJID.getNode());
if (recipientJID != null && userManager.isRegisteredUser(recipientJID.getNode())) {
PrivacyList list =
PrivacyListManager.getInstance().getDefaultPrivacyList(recipientJID.getNode());
if (list != null && list.shouldBlockPacket(packet)) {
// Communication is blocked
if (IQ.Type.set == packet.getType() || IQ.Type.get == packet.getType()) {
......@@ -300,41 +295,10 @@ public class IQRouter extends BasicModule {
handler.process(packet);
}
}
}
else {
// JID is of the form <node@domain/resource>
boolean handlerFound = false;
// IQ packets should be sent to users even before they send an available presence.
// So if the target address belongs to this server then use the sessionManager
// instead of the routingTable since unavailable clients won't have a route to them
if (XMPPServer.getInstance().isLocal(recipientJID)) {
ClientSession session = sessionManager.getSession(recipientJID);
if (session != null) {
if (session.canProcess(packet)) {
session.process(packet);
handlerFound = true;
}
}
else {
Log.info("Packet sent to unreachable address " + packet);
}
}
else {
ChannelHandler route = routingTable.getRoute(recipientJID);
if (route != null) {
route.process(packet);
handlerFound = true;
}
else {
Log.info("Packet sent to unreachable address " + packet);
}
}
// If a route to the target address was not found then try to answer a
// service_unavailable error code to the sender of the IQ packet
if (!handlerFound && IQ.Type.result != packet.getType() && IQ.Type.error != packet.getType()) {
sendErrorPacket(packet, PacketError.Condition.service_unavailable);
}
routingTable.routePacket(recipientJID, packet);
}
}
catch (Exception e) {
......@@ -349,8 +313,7 @@ public class IQRouter extends BasicModule {
}
}
private void sendErrorPacket(IQ originalPacket, PacketError.Condition condition)
throws UnauthorizedException {
private void sendErrorPacket(IQ originalPacket, PacketError.Condition condition) {
if (IQ.Type.error == originalPacket.getType()) {
Log.error("Cannot reply an IQ error to another IQ error: " + originalPacket);
return;
......@@ -364,23 +327,11 @@ public class IQRouter extends BasicModule {
handle(reply);
return;
}
// Locate a route to the sender of the IQ and ask it to process
// the packet. Use the routingTable so that routes to remote servers
// may be found
ChannelHandler route = routingTable.getRoute(originalPacket.getFrom());
if (route != null) {
route.process(reply);
}
else {
// No root was found so try looking for local sessions that have never
// sent an available presence or haven't authenticated yet
Session session = sessionManager.getSession(originalPacket.getFrom());
if (session != null) {
session.process(reply);
}
else {
Log.warn("Error packet could not be delivered " + reply);
}
// Route the error packet to the original sender of the IQ.
try {
routingTable.routePacket(reply.getTo(), reply);
} catch (UnauthorizedException e) {
// Should never happen
}
}
......@@ -398,4 +349,22 @@ public class IQRouter extends BasicModule {
}
return handler;
}
}
\ No newline at end of file
/**
* Notification message indicating that a packet has failed to be routed to the receipient.
*
* @param packet IQ packet that failed to be sent to the receipient.
*/
public void routingFailed(Packet packet) {
IQ iq = (IQ) packet;
// If a route to the target address was not found then try to answer a
// service_unavailable error code to the sender of the IQ packet
if (IQ.Type.result != iq.getType() && IQ.Type.error != iq.getType()) {
Log.info("Packet sent to unreachable address " + packet);
sendErrorPacket(iq, PacketError.Condition.service_unavailable);
}
else {
Log.warn("Error or result packet could not be delivered " + packet);
}
}
}
......@@ -18,10 +18,7 @@ import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;
import org.xmpp.packet.*;
import java.util.*;
......@@ -100,8 +97,8 @@ public class MessageRouter extends BasicModule {
routeToBareJID(recipientJID, packet);
}
else {
// Deliver stanza to best route
routingTable.getBestRoute(recipientJID).process(packet);
// Deliver stanza to requested route
routingTable.routePacket(recipientJID, packet);
}
}
catch (Exception e) {
......@@ -279,4 +276,13 @@ public class MessageRouter extends BasicModule {
multicastRouter = server.getMulticastRouter();
serverName = server.getServerInfo().getName();
}
/**
* Notification message indicating that a packet has failed to be routed to the receipient.
*
* @param packet Message packet that failed to be sent to the receipient.
*/
public void routingFailed(Packet packet) {
messageStrategy.storeOffline((Message) packet);
}
}
......@@ -11,12 +11,12 @@
package org.jivesoftware.openfire;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.openfire.privacy.PrivacyList;
import org.jivesoftware.openfire.privacy.PrivacyListManager;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.PacketError;
......@@ -67,7 +67,7 @@ public class OfflineMessageStrategy extends BasicModule {
public void storeOffline(Message message) {
if (message != null) {
// Do nothing if the message was sent to the server itself or to an anonymous user
// Do nothing if the message was sent to the server itself, an anonymous user or a non-existent user
JID recipientJID = message.getTo();
if (recipientJID == null || serverAddress.equals(recipientJID) ||
recipientJID.getNode() == null ||
......
......@@ -11,8 +11,6 @@
package org.jivesoftware.openfire;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.openfire.handler.PresenceSubscribeHandler;
import org.jivesoftware.openfire.handler.PresenceUpdateHandler;
......@@ -20,10 +18,9 @@ import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.session.Session;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.xmpp.packet.*;
/**
* <p>Route presence packets throughout the server.</p>
......@@ -132,11 +129,11 @@ public class PresenceRouter extends BasicModule {
// The user sent a directed presence to an entity
// Broadcast it to all connected resources
for (ChannelHandler route : routingTable.getRoutes(recipientJID)) {
for (JID jid : routingTable.getRoutes(recipientJID)) {
// Register the sent directed presence
updateHandler.directedPresenceSent(packet, route, recipientJID.toString());
updateHandler.directedPresenceSent(packet, jid, recipientJID.toString());
// Route the packet
route.process(packet);
routingTable.routePacket(jid, packet);
}
}
......@@ -151,11 +148,7 @@ public class PresenceRouter extends BasicModule {
else if (Presence.Type.probe == type) {
// Handle a presence probe sent by a remote server
if (!XMPPServer.getInstance().isLocal(recipientJID)) {
// Target is a component of the server so forward it
ChannelHandler route = routingTable.getRoute(recipientJID);
if (route != null) {
route.process(packet);
}
routingTable.routePacket(recipientJID, packet);
}
else {
// Handle probe to a local user
......@@ -165,10 +158,7 @@ public class PresenceRouter extends BasicModule {
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);
}
routingTable.routePacket(recipientJID, packet);
}
}
......@@ -194,4 +184,13 @@ public class PresenceRouter extends BasicModule {
multicastRouter = server.getMulticastRouter();
sessionManager = server.getSessionManager();
}
/**
* Notification message indicating that a packet has failed to be routed to the receipient.
*
* @param packet Presence packet that failed to be sent to the receipient.
*/
public void routingFailed(Packet packet) {
// presence packets are dropped silently
}
}
......@@ -12,11 +12,11 @@
package org.jivesoftware.openfire.component;
import org.dom4j.Element;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.openfire.session.ComponentSession;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.xmpp.component.Component;
import org.xmpp.component.ComponentException;
import org.xmpp.component.ComponentManager;
......@@ -85,7 +85,7 @@ public class InternalComponentManager extends BasicModule implements ComponentMa
serviceAddress = new JID(null, "component." + serverDomain, null);
if (!server.isSetupMode()) {
// Add a route to this service
server.getRoutingTable().addRoute(getAddress(), this);
server.getRoutingTable().addComponentRoute(getAddress(), this);
}
}
......@@ -93,7 +93,7 @@ public class InternalComponentManager extends BasicModule implements ComponentMa
super.stop();
if (getAddress() != null) {
// Remove the route to this service
XMPPServer.getInstance().getRoutingTable().removeRoute(getAddress());
XMPPServer.getInstance().getRoutingTable().removeComponentRoute(getAddress());
}
}
......@@ -111,7 +111,7 @@ public class InternalComponentManager extends BasicModule implements ComponentMa
JID componentJID = new JID(subdomain + "." + serverDomain);
// Add the route to the new service provided by the component
XMPPServer.getInstance().getRoutingTable().addRoute(componentJID,
XMPPServer.getInstance().getRoutingTable().addComponentRoute(componentJID,
new RoutableComponent(componentJID, component));
// Initialize the new component
......@@ -135,7 +135,7 @@ public class InternalComponentManager extends BasicModule implements ComponentMa
// Unregister the componet's domain
components.remove(subdomain);
// Remove the route
XMPPServer.getInstance().getRoutingTable().removeRoute(componentJID);
XMPPServer.getInstance().getRoutingTable().removeComponentRoute(componentJID);
if (e instanceof ComponentException) {
// Rethrow the exception
throw (ComponentException)e;
......@@ -156,7 +156,7 @@ public class InternalComponentManager extends BasicModule implements ComponentMa
// Remove the route for the service provided by the component
if (XMPPServer.getInstance().getRoutingTable() != null) {
XMPPServer.getInstance().getRoutingTable().removeRoute(componentJID);
XMPPServer.getInstance().getRoutingTable().removeComponentRoute(componentJID);
}
// Remove the disco item from the server for the component that is being removed
......
......@@ -13,10 +13,6 @@ package org.jivesoftware.openfire.filetransfer.proxy;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.PropertyEventDispatcher;
import org.jivesoftware.util.PropertyEventListener;
import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.container.BasicModule;
......@@ -26,6 +22,10 @@ import org.jivesoftware.openfire.disco.DiscoServerItem;
import org.jivesoftware.openfire.disco.ServerItemsProvider;
import org.jivesoftware.openfire.filetransfer.FileTransferManager;
import org.jivesoftware.openfire.forms.spi.XDataFormImpl;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.PropertyEventDispatcher;
import org.jivesoftware.util.PropertyEventListener;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
......@@ -196,7 +196,7 @@ public class FileTransferProxy extends BasicModule
private void startProxy() {
connectionManager.processConnections(bindInterface, getProxyPort());
routingTable.addRoute(getAddress(), this);
routingTable.addComponentRoute(getAddress(), this);
XMPPServer server = XMPPServer.getInstance();
server.getIQDiscoItemsHandler().addServerItemsProvider(this);
......@@ -207,7 +207,7 @@ public class FileTransferProxy extends BasicModule
XMPPServer.getInstance().getIQDiscoItemsHandler()
.removeComponentItem(getAddress().toString());
routingTable.removeRoute(getAddress());
routingTable.removeComponentRoute(getAddress());
connectionManager.disable();
}
......
......@@ -11,8 +11,6 @@
package org.jivesoftware.openfire.handler;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.openfire.roster.Roster;
......@@ -21,6 +19,8 @@ import org.jivesoftware.openfire.roster.RosterManager;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
......@@ -120,14 +120,12 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand
// Do not forward the packet to the recipient if the presence is of type subscribed
// and the recipient user has not changed its subscription state.
if (!(type == Presence.Type.subscribed && recipientRoster != null &&
!recipientSubChanged)) {
if (!(type == Presence.Type.subscribed && recipientRoster != null && !recipientSubChanged)) {
// If the user is already subscribed to the *local* user's presence then do not
// forward the subscription request and instead send an auto-reply on behalf
// of the user
if (type == Presence.Type.subscribe && recipientRoster != null &&
!recipientSubChanged) {
if (type == Presence.Type.subscribe && recipientRoster != null && !recipientSubChanged) {
try {
RosterItem.SubType subType = recipientRoster.getRosterItem(senderJID)
.getSubStatus();
......@@ -151,13 +149,13 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand
// a module, the module will be able to handle the packet. If the handler is a
// Session the packet will be routed to the client. If a route cannot be found
// then the packet will be delivered based on its recipient and sender.
List<ChannelHandler> handlers = routingTable.getRoutes(recipientJID);
if (!handlers.isEmpty()) {
for (ChannelHandler handler : handlers) {
List<JID> jids = routingTable.getRoutes(recipientJID);
if (!jids.isEmpty()) {
for (JID jid : jids) {
Presence presenteToSend = presence.createCopy();
// Stamp the presence with the user's bare JID as the 'from' address
presenteToSend.setFrom(senderJID.toBareJID());
handler.process(presenteToSend);
routingTable.routePacket(jid, presenteToSend);
}
}
else {
......
......@@ -13,8 +13,6 @@ package org.jivesoftware.openfire.mediaproxy;
import org.dom4j.Attribute;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.container.BasicModule;
......@@ -23,14 +21,16 @@ import org.jivesoftware.openfire.disco.DiscoItemsProvider;
import org.jivesoftware.openfire.disco.DiscoServerItem;
import org.jivesoftware.openfire.disco.ServerItemsProvider;
import org.jivesoftware.openfire.forms.spi.XDataFormImpl;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
import java.util.*;
import java.net.UnknownHostException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.*;
/**
* A proxy service for UDP traffic such as RTP. It provides Jingle transport candidates
......@@ -94,7 +94,7 @@ public class MediaProxyService extends BasicModule
} catch (SocketException e) {
}
routingTable.addRoute(getAddress(), this);
routingTable.addComponentRoute(getAddress(), this);
XMPPServer.getInstance().getIQDiscoItemsHandler().addServerItemsProvider(this);
} else {
if (echo != null) echo.cancel();
......@@ -106,7 +106,7 @@ public class MediaProxyService extends BasicModule
super.stop();
mediaProxy.stopProxy();
XMPPServer.getInstance().getIQDiscoItemsHandler().removeComponentItem(getAddress().toString());
routingTable.removeRoute(getAddress());
routingTable.removeComponentRoute(getAddress());
if (echo != null) echo.cancel();
}
......
......@@ -14,12 +14,12 @@ package org.jivesoftware.openfire.muc.spi;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.QName;
import org.jivesoftware.util.ElementUtil;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.*;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.ElementUtil;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Presence;
......@@ -117,6 +117,7 @@ public class MUCRoleImpl implements MUCRole {
this.role = role;
this.affiliation = affiliation;
// Cache the user's session (will only work for local users)
//TODO Probably remove this instance variable that was added for optimization
this.session = XMPPServer.getInstance().getSessionManager().getSession(presence.getFrom());
extendedInformation =
......
......@@ -13,7 +13,6 @@ package org.jivesoftware.openfire.muc.spi;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jivesoftware.util.*;
import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.container.BasicModule;
......@@ -29,14 +28,15 @@ import org.jivesoftware.openfire.muc.*;
import org.jivesoftware.openfire.stats.Statistic;
import org.jivesoftware.openfire.stats.StatisticsManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.*;
import org.xmpp.component.ComponentManager;
import org.xmpp.packet.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
......@@ -295,7 +295,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
}
public JID getAddress() {
return new JID(null, getServiceDomain(), null);
return new JID(null, getServiceDomain(), null, true);
}
/**
......@@ -801,7 +801,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
public void start() {
super.start();
// Add the route to this service
routingTable.addRoute(getAddress(), this);
routingTable.addComponentRoute(getAddress(), this);
ArrayList<String> params = new ArrayList<String>();
params.clear();
params.add(getServiceDomain());
......@@ -822,7 +822,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
public void stop() {
super.stop();
// Remove the route to this service
routingTable.removeRoute(getAddress());
routingTable.removeComponentRoute(getAddress());
timer.cancel();
logAllConversation();
// Remove the statistics.
......
......@@ -75,7 +75,7 @@ public class Route extends Packet {
}
/**
* Sets the wrapped stanza by this Route packet. Route packets may have a single child
* Sets the wrapped stanza by this Route packet. ClientRoute packets may have a single child
* element. This is a convenience method to avoid manipulating this underlying packet's
* Element instance directly.
*
......
......@@ -11,12 +11,11 @@
package org.jivesoftware.openfire.net;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
......@@ -34,6 +33,9 @@ public class SocketPacketWriteHandler implements ChannelHandler {
private SessionManager sessionManager;
private OfflineMessageStrategy messageStrategy;
private RoutingTable routingTable;
private IQRouter iqRouter;
private MessageRouter messageRouter;
private PresenceRouter presenceRouter;
public SocketPacketWriteHandler(SessionManager sessionManager, RoutingTable routingTable,
OfflineMessageStrategy messageStrategy) {
......@@ -41,6 +43,9 @@ public class SocketPacketWriteHandler implements ChannelHandler {
this.messageStrategy = messageStrategy;
this.routingTable = routingTable;
this.server = XMPPServer.getInstance();
iqRouter = server.getIQRouter();
messageRouter = server.getMessageRouter();
presenceRouter = server.getPresenceRouter();
}
public void process(Packet packet) throws UnauthorizedException, PacketException {
......@@ -48,29 +53,12 @@ public class SocketPacketWriteHandler implements ChannelHandler {
JID recipient = packet.getTo();
// Check if the target domain belongs to a remote server or a component
if (server.matchesComponent(recipient) || server.isRemote(recipient)) {
// Locate the route to the remote server or component and ask it
// to process the packet
ChannelHandler route = routingTable.getRoute(recipient);
if (route != null) {
route.process(packet);
}
else {
// No root was found so either drop or store the packet
handleUnprocessedPacket(packet);
}
return;
routingTable.routePacket(recipient, packet);
}
// The target domain belongs to the local server
if (recipient == null || (recipient.getNode() == null && recipient.getResource() == null)) {
// no TO was found so send back the packet to the sender
ClientSession senderSession = sessionManager.getSession(packet.getFrom());
if (senderSession != null) {
senderSession.process(packet);
}
else {
// The sender is no longer available so drop the packet
dropPacket(packet);
}
routingTable.routePacket(packet.getFrom(), packet);
}
else {
Session session = sessionManager.getBestRoute(recipient);
......@@ -94,24 +82,13 @@ public class SocketPacketWriteHandler implements ChannelHandler {
private void handleUnprocessedPacket(Packet packet) {
if (packet instanceof Message) {
messageStrategy.storeOffline((Message)packet);
messageRouter.routingFailed(packet);
}
else if (packet instanceof Presence) {
// presence packets are dropped silently
//dropPacket(packet);
presenceRouter.routingFailed(packet);
}
else {
// IQ packets are logged but dropped
dropPacket(packet);
iqRouter.routingFailed(packet);
}
}
/**
* Drop the packet.
*
* @param packet The packet being dropped
*/
private void dropPacket(Packet packet) {
Log.warn(LocaleUtils.getLocalizedString("admin.error.routing") + "\n" + packet.toString());
}
}
......@@ -13,16 +13,14 @@ package org.jivesoftware.openfire.net;
import org.dom4j.Element;
import org.dom4j.io.XMPPPacketReader;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.openfire.Connection;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.RoutableChannelHandler;
import org.jivesoftware.openfire.RoutingTable;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.server.OutgoingSessionPromise;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
......@@ -425,13 +423,7 @@ public abstract class SocketReader implements Runnable {
return false;
}
// Check if the host matches a subdomain of this host
RoutableChannelHandler route = routingTable.getRoute(new JID(host));
if (route == null || route instanceof OutgoingSessionPromise) {
return true;
}
else {
return false;
}
return !routingTable.hasComponentRoute(new JID(host));
}
/**
......
......@@ -13,10 +13,6 @@ package org.jivesoftware.openfire.pubsub;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.RoutableChannelHandler;
import org.jivesoftware.openfire.RoutingTable;
......@@ -32,6 +28,10 @@ import org.jivesoftware.openfire.forms.spi.XDataFormImpl;
import org.jivesoftware.openfire.forms.spi.XFormFieldImpl;
import org.jivesoftware.openfire.pubsub.models.AccessModel;
import org.jivesoftware.openfire.pubsub.models.PublisherModel;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import org.xmpp.packet.*;
import java.util.*;
......@@ -391,7 +391,7 @@ public class PubSubModule extends BasicModule implements ServerItemsProvider, Di
public void start() {
super.start();
// Add the route to this service
routingTable.addRoute(getAddress(), this);
routingTable.addComponentRoute(getAddress(), this);
// Start the pubsub engine
engine.start();
ArrayList<String> params = new ArrayList<String>();
......@@ -403,7 +403,7 @@ public class PubSubModule extends BasicModule implements ServerItemsProvider, Di
public void stop() {
super.stop();
// Remove the route to this service
routingTable.removeRoute(getAddress());
routingTable.removeComponentRoute(getAddress());
// Stop the pubsub engine. This will gives us the chance to
// save queued items to the database.
engine.shutdown();
......
......@@ -576,17 +576,16 @@ public class Roster implements Cacheable, Externalizable {
}
// Broadcast presence to subscribed entities
for (RosterItem item : rosterItems.values()) {
if (item.getSubStatus() == RosterItem.SUB_BOTH
|| item.getSubStatus() == RosterItem.SUB_FROM) {
if (item.getSubStatus() == RosterItem.SUB_BOTH || item.getSubStatus() == RosterItem.SUB_FROM) {
packet.setTo(item.getJid());
if (list != null && list.shouldBlockPacket(packet)) {
// Outgoing presence notifications are blocked for this contact
continue;
}
JID searchNode = new JID(item.getJid().getNode(), item.getJid().getDomain(), null);
for (ChannelHandler session : routingTable.getRoutes(searchNode)) {
JID searchNode = new JID(item.getJid().getNode(), item.getJid().getDomain(), null, true);
for (JID jid : routingTable.getRoutes(searchNode)) {
try {
session.process(packet);
routingTable.routePacket(jid, packet);
}
catch (Exception e) {
// Theoretically only happens if session has been closed.
......@@ -602,9 +601,9 @@ public class Roster implements Cacheable, Externalizable {
// Outgoing presence notifications are blocked for this contact
continue;
}
for (ChannelHandler session : routingTable.getRoutes(new JID(contact))) {
for (JID jid: routingTable.getRoutes(new JID(contact))) {
try {
session.process(packet);
routingTable.routePacket(jid, packet);
}
catch (Exception e) {
// Theoretically only happens if session has been closed.
......
......@@ -11,7 +11,6 @@
package org.jivesoftware.openfire.roster;
import org.jivesoftware.openfire.ChannelHandler;
import org.jivesoftware.openfire.RoutingTable;
import org.jivesoftware.openfire.SharedGroupException;
import org.jivesoftware.openfire.XMPPServer;
......@@ -719,10 +718,7 @@ public class RosterManager extends BasicModule implements GroupEventListener, Us
presence.setType(Presence.Type.unsubscribe);
}
try {
ChannelHandler handler = routingTable.getRoute(recipient);
if (handler != null) {
handler.process(presence);
}
routingTable.routePacket(recipient, presence);
}
catch (UnauthorizedException e) {
// Do nothing
......@@ -959,4 +955,4 @@ public class RosterManager extends BasicModule implements GroupEventListener, Us
// Remove this module as a listener of group events
GroupEventDispatcher.removeListener(this);
}
}
\ No newline at end of file
}
......@@ -11,14 +11,13 @@
package org.jivesoftware.openfire.server;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.openfire.ChannelHandler;
import org.jivesoftware.openfire.RoutableChannelHandler;
import org.jivesoftware.openfire.RoutingTable;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.session.OutgoingServerSession;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.xmpp.packet.*;
import java.util.HashMap;
......@@ -200,13 +199,7 @@ public class OutgoingSessionPromise implements RoutableChannelHandler {
.authenticateDomain(packet.getFrom().getDomain(), packet.getTo().getDomain());
if (created) {
// A connection to the remote server was created so get the route and send the packet
ChannelHandler route = routingTable.getRoute(packet.getTo());
if (route != null) {
route.process(packet);
}
else {
throw new Exception("Failed to create connection to remote server");
}
routingTable.routePacket(packet.getTo(), packet);
}
else {
throw new Exception("Failed to create connection to remote server");
......@@ -234,10 +227,7 @@ public class OutgoingSessionPromise implements RoutableChannelHandler {
reply.setFrom(to);
reply.setChildElement(((IQ) packet).getChildElement().createCopy());
reply.setError(PacketError.Condition.remote_server_not_found);
ChannelHandler route = routingTable.getRoute(reply.getTo());
if (route != null) {
route.process(reply);
}
routingTable.routePacket(reply.getTo(), reply);
}
else if (packet instanceof Presence) {
Presence reply = new Presence();
......@@ -245,10 +235,7 @@ public class OutgoingSessionPromise implements RoutableChannelHandler {
reply.setTo(from);
reply.setFrom(to);
reply.setError(PacketError.Condition.remote_server_not_found);
ChannelHandler route = routingTable.getRoute(reply.getTo());
if (route != null) {
route.process(reply);
}
routingTable.routePacket(reply.getTo(), reply);
}
else if (packet instanceof Message) {
Message reply = new Message();
......@@ -258,10 +245,7 @@ public class OutgoingSessionPromise implements RoutableChannelHandler {
reply.setType(((Message)packet).getType());
reply.setThread(((Message)packet).getThread());
reply.setError(PacketError.Condition.remote_server_not_found);
ChannelHandler route = routingTable.getRoute(reply.getTo());
if (route != null) {
route.process(reply);
}
routingTable.routePacket(reply.getTo(), reply);
}
}
catch (UnauthorizedException e) {
......
......@@ -14,9 +14,6 @@ package org.jivesoftware.openfire.server;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.XMPPPacketReader;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.auth.AuthFactory;
import org.jivesoftware.openfire.net.DNSUtil;
......@@ -26,6 +23,9 @@ import org.jivesoftware.openfire.net.SocketConnection;
import org.jivesoftware.openfire.session.IncomingServerSession;
import org.jivesoftware.openfire.session.OutgoingServerSession;
import org.jivesoftware.openfire.spi.BasicStreamIDFactory;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
......@@ -496,13 +496,7 @@ public class ServerDialback {
// trick is useful when subdomains of this server are registered in the DNS so remote
// servers may establish connections directly to a subdomain of this server
if (host_unknown && recipient.contains(serverName)) {
RoutableChannelHandler route = routingTable.getRoute(new JID(recipient));
if (route == null || route instanceof OutgoingSessionPromise) {
host_unknown = true;
}
else {
host_unknown = false;
}
host_unknown = !routingTable.hasComponentRoute(new JID(recipient));
}
return host_unknown;
}
......
......@@ -11,10 +11,7 @@
package org.jivesoftware.util.cache;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.Externalizable;
import java.io.IOException;
import java.io.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
......@@ -202,6 +199,14 @@ public class ExternalizableUtil {
return strategy.readByteArray(in);
}
public void writeSerializable(DataOutput out, Serializable value) throws IOException {
strategy.writeSerializable(out, value);
}
public Serializable readSerializable(DataInput in) throws IOException {
return strategy.readSerializable(in);
}
public void writeSafeUTF(DataOutput out, String value) throws IOException {
strategy.writeSafeUTF(out, value);
}
......
......@@ -10,10 +10,7 @@
*/
package org.jivesoftware.util.cache;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.Externalizable;
import java.io.IOException;
import java.io.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
......@@ -120,6 +117,10 @@ public interface ExternalizableUtilStrategy {
byte[] readByteArray(DataInput in) throws IOException;
void writeSerializable(DataOutput out, Serializable value) throws IOException;
Serializable readSerializable(DataInput in) throws IOException;
void writeSafeUTF(DataOutput out, String value) throws IOException;
String readSafeUTF(DataInput in) throws IOException;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment