1 11 12 package org.jivesoftware.messenger; 13 14 import org.dom4j.Element; 15 import org.jivesoftware.messenger.container.BasicModule; 16 import org.jivesoftware.messenger.handler.IQHandler; 17 import org.jivesoftware.util.LocaleUtils; 18 import org.jivesoftware.util.Log; 19 import org.xmpp.packet.IQ; 20 import org.xmpp.packet.JID; 21 import org.xmpp.packet.PacketError; 22 23 import java.util.ArrayList ; 24 import java.util.List ; 25 import java.util.Map ; 26 import java.util.concurrent.ConcurrentHashMap ; 27 28 36 public class IQRouter extends BasicModule { 37 38 private RoutingTable routingTable; 39 private List <IQHandler> iqHandlers = new ArrayList <IQHandler>(); 40 private Map <String , IQHandler> namespace2Handlers = new ConcurrentHashMap <String , IQHandler>(); 41 private SessionManager sessionManager; 42 43 46 public IQRouter() { 47 super("XMPP IQ Router"); 48 } 49 50 63 public void route(IQ packet) { 64 if (packet == null) { 65 throw new NullPointerException (); 66 } 67 Session session = sessionManager.getSession(packet.getFrom()); 68 if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED 69 || (isLocalServer(packet.getTo()) 70 && ("jabber:iq:auth".equals(packet.getChildElement().getNamespaceURI()) 71 || "jabber:iq:register".equals(packet.getChildElement().getNamespaceURI()))) 72 ) { 73 handle(packet); 74 } 75 else { 76 IQ reply = IQ.createResultIQ(packet); 77 reply.setChildElement(packet.getChildElement().createCopy()); 78 packet.setError(PacketError.Condition.not_authorized); 79 sessionManager.getSession(packet.getFrom()).process(reply); 80 } 81 } 82 83 94 public void addHandler(IQHandler handler) { 95 if (iqHandlers.contains(handler)) { 96 throw new IllegalArgumentException ("IQHandler already provided by the server"); 97 } 98 handler.initialize(XMPPServer.getInstance()); 100 namespace2Handlers.put(handler.getInfo().getNamespace(), handler); 102 } 103 104 115 public void removeHandler(IQHandler handler) { 116 if (iqHandlers.contains(handler)) { 117 throw new IllegalArgumentException ("Cannot remove an IQHandler provided by the server"); 118 } 119 namespace2Handlers.remove(handler.getInfo().getNamespace()); 121 } 122 123 public void initialize(XMPPServer server) { 124 super.initialize(server); 125 routingTable = server.getRoutingTable(); 126 iqHandlers.addAll(server.getIQHandlers()); 127 sessionManager = server.getSessionManager(); 128 } 129 130 136 private boolean isLocalServer(JID recipientJID) { 137 return recipientJID == null || recipientJID.getDomain() == null 138 || "".equals(recipientJID.getDomain()) || recipientJID.getResource() == null 139 || "".equals(recipientJID.getResource()); 140 } 141 142 private void handle(IQ packet) { 143 JID recipientJID = packet.getTo(); 144 try { 145 if (recipientJID != null) { 147 try { 148 RoutableChannelHandler serviceRoute = routingTable.getRoute(recipientJID); 149 if (!(serviceRoute instanceof ClientSession)) { 150 serviceRoute.process(packet); 152 return; 153 } 154 } 155 catch (NoSuchRouteException e) { 156 } 158 } 159 if (isLocalServer(recipientJID)) { 160 Element childElement = packet.getChildElement(); 162 String namespace = null; 163 if (childElement != null) { 164 namespace = childElement.getNamespaceURI(); 165 } 166 if (namespace == null) { 167 if (packet.getType() != IQ.Type.result) { 168 Log.warn("Unknown packet " + packet); 170 } 171 } 172 else { 173 IQHandler handler = getHandler(namespace); 174 if (handler == null) { 175 IQ reply = IQ.createResultIQ(packet); 176 if (recipientJID == null) { 177 reply.setChildElement(packet.getChildElement().createCopy()); 179 reply.setError(PacketError.Condition.service_unavailable); 180 } 181 else if (recipientJID.getNode() == null || 182 "".equals(recipientJID.getNode())) { 183 reply.setChildElement(packet.getChildElement().createCopy()); 185 reply.setError(PacketError.Condition.feature_not_implemented); 186 } 187 else { 188 reply.setChildElement(packet.getChildElement().createCopy()); 191 reply.setError(PacketError.Condition.service_unavailable); 192 } 193 194 try { 195 routingTable.getRoute(packet.getFrom()).process(reply); 199 } 200 catch (NoSuchRouteException e) { 201 Session session = sessionManager.getSession(packet.getFrom()); 204 if (session != null) { 205 session.process(reply); 206 } 207 else { 208 Log.warn("Packet could not be delivered " + packet); 209 } 210 } 211 } 212 else { 213 handler.process(packet); 214 } 215 } 216 217 } 218 else { 219 boolean handlerFound = false; 221 if (XMPPServer.getInstance().isLocal(recipientJID)) { 225 Session session = sessionManager.getBestRoute(recipientJID); 226 if (session != null) { 227 session.process(packet); 228 handlerFound = true; 229 } 230 else { 231 Log.info("Packet sent to unreachable address " + packet); 232 } 233 } 234 else { 235 try { 236 ChannelHandler route = routingTable.getRoute(recipientJID); 237 route.process(packet); 238 handlerFound = true; 239 } 240 catch (NoSuchRouteException e) { 241 Log.info("Packet sent to unreachable address " + packet); 242 } 243 } 244 if (!handlerFound && IQ.Type.result != packet.getType()) { 247 IQ reply = IQ.createResultIQ(packet); 248 reply.setChildElement(packet.getChildElement().createCopy()); 249 reply.setError(PacketError.Condition.service_unavailable); 250 try { 251 routingTable.getRoute(packet.getFrom()).process(reply); 255 } 256 catch (NoSuchRouteException e) { 257 Session session = sessionManager.getSession(packet.getFrom()); 260 if (session != null) { 261 session.process(reply); 262 } 263 else { 264 Log.warn("Packet could not be delivered " + reply); 265 } 266 } 267 } 268 } 269 } 270 catch (Exception e) { 271 Log.error(LocaleUtils.getLocalizedString("admin.error.routing"), e); 272 Session session = sessionManager.getSession(packet.getFrom()); 273 if (session != null) { 274 Connection conn = session.getConnection(); 275 if (conn != null) { 276 conn.close(); 277 } 278 } 279 } 280 } 281 282 private IQHandler getHandler(String namespace) { 283 IQHandler handler = namespace2Handlers.get(namespace); 284 if (handler == null) { 285 for (IQHandler handlerCandidate : iqHandlers) { 286 IQHandlerInfo handlerInfo = handlerCandidate.getInfo(); 287 if (handlerInfo != null && namespace.equalsIgnoreCase(handlerInfo.getNamespace())) { 288 handler = handlerCandidate; 289 namespace2Handlers.put(namespace, handler); 290 break; 291 } 292 } 293 } 294 return handler; 295 } 296 } 297 | Popular Tags |