1 11 12 package org.jivesoftware.messenger; 13 14 import org.jivesoftware.messenger.audit.AuditStreamIDFactory; 15 import org.jivesoftware.messenger.auth.UnauthorizedException; 16 import org.jivesoftware.messenger.container.BasicModule; 17 import org.jivesoftware.messenger.handler.PresenceUpdateHandler; 18 import org.jivesoftware.messenger.server.IncomingServerSession; 19 import org.jivesoftware.messenger.server.OutgoingServerSession; 20 import org.jivesoftware.messenger.spi.BasicStreamIDFactory; 21 import org.jivesoftware.messenger.user.UserManager; 22 import org.jivesoftware.messenger.user.UserNotFoundException; 23 import org.jivesoftware.messenger.component.ComponentSession; 24 import org.jivesoftware.messenger.component.InternalComponentManager; 25 import org.jivesoftware.util.JiveGlobals; 26 import org.jivesoftware.util.LocaleUtils; 27 import org.jivesoftware.util.Log; 28 import org.xmpp.packet.JID; 29 import org.xmpp.packet.Message; 30 import org.xmpp.packet.Packet; 31 import org.xmpp.packet.Presence; 32 33 import java.util.*; 34 import java.util.concurrent.ConcurrentHashMap ; 35 import java.util.concurrent.CopyOnWriteArrayList ; 36 37 44 public class SessionManager extends BasicModule { 45 46 private int sessionCount = 0; 47 public static final int NEVER_KICK = -1; 48 49 private PresenceUpdateHandler presenceHandler; 50 private PacketRouter router; 51 private String serverName; 52 private JID serverAddress; 53 private UserManager userManager; 54 private int conflictLimit; 55 56 private ClientSessionListener clientSessionListener = new ClientSessionListener(); 57 private ComponentSessionListener componentSessionListener = new ComponentSessionListener(); 58 private IncomingServerSessionListener incomingServerListener = new IncomingServerSessionListener(); 59 private OutgoingServerSessionListener outgoingServerListener = new OutgoingServerSessionListener(); 60 61 65 private Map <String , ClientSession> preAuthenticatedSessions = new ConcurrentHashMap <String , ClientSession>(); 66 67 72 private Map <String , SessionMap> sessions = new ConcurrentHashMap <String , SessionMap>(); 73 74 79 private Map <String , ClientSession> anonymousSessions = new ConcurrentHashMap <String , ClientSession>(); 80 81 85 private List <ComponentSession> componentsSessions = new CopyOnWriteArrayList <ComponentSession>(); 86 87 93 private Map <String , IncomingServerSession> incomingServerSessions = new ConcurrentHashMap <String , IncomingServerSession>(); 94 95 101 private Map <String , OutgoingServerSession> outgoingServerSessions = new ConcurrentHashMap <String , OutgoingServerSession>(); 102 103 107 private RoutingTable routingTable; 108 109 private StreamIDFactory streamIDFactory; 110 111 115 private Timer timer = new Timer("Sessions cleanup"); 116 117 120 private ServerCleanupTask serverCleanupTask; 121 122 127 public static SessionManager getInstance() { 128 return XMPPServer.getInstance().getSessionManager(); 129 } 130 131 public SessionManager() { 132 super("Session Manager"); 133 if (JiveGlobals.getBooleanProperty("xmpp.audit.active")) { 134 streamIDFactory = new AuditStreamIDFactory(); 135 } 136 else { 137 streamIDFactory = new BasicStreamIDFactory(); 138 } 139 140 String conflictLimitProp = JiveGlobals.getProperty("xmpp.session.conflict-limit"); 141 if (conflictLimitProp == null) { 142 conflictLimit = 0; 143 JiveGlobals.setProperty("xmpp.session.conflict-limit", Integer.toString(conflictLimit)); 144 } 145 else { 146 try { 147 conflictLimit = Integer.parseInt(conflictLimitProp); 148 } 149 catch (NumberFormatException e) { 150 conflictLimit = 0; 151 JiveGlobals.setProperty("xmpp.session.conflict-limit", Integer.toString(conflictLimit)); 152 } 153 } 154 } 155 156 160 private class SessionMap { 161 private Map <String ,ClientSession> resources = new ConcurrentHashMap <String ,ClientSession>(); 162 private LinkedList priorityList = new LinkedList(); 163 164 169 void addSession(ClientSession session) { 170 String resource = session.getAddress().getResource(); 171 Presence presence = session.getPresence(); 172 int priority = presence == null ? 0 : presence.getPriority(); 173 resources.put(resource, session); 174 sortSession(resource, priority); 175 } 176 177 183 private void sortSession(String resource, int priority) { 184 synchronized (priorityList) { 185 if (priorityList.size() > 0) { 186 Iterator iter = priorityList.iterator(); 187 for (int i = 0; iter.hasNext(); i++) { 188 ClientSession sess = resources.get(iter.next()); 189 if (sess != null && sess.getPresence().getPriority() <= priority) { 190 priorityList.add(i, resource); 191 break; 192 } 193 } 194 } 195 if (!priorityList.contains(resource)) { 196 priorityList.addLast(resource); 197 } 198 } 199 } 200 201 207 public void changePriority(JID sender, int priority) { 208 String resource = sender.getResource(); 209 if (resources.containsKey(resource)) { 210 synchronized (priorityList) { 211 priorityList.remove(resource); 212 sortSession(resource, priority); 213 } 214 } 215 } 216 217 222 void removeSession(Session session) { 223 String resource = session.getAddress().getResource(); 224 resources.remove(resource); 225 synchronized (priorityList) { 226 priorityList.remove(resource); 227 } 228 } 229 230 236 ClientSession getSession(String resource) { 237 return resources.get(resource); 238 } 239 240 246 boolean hasSession(String resource) { 247 return resources.containsKey(resource); 248 } 249 250 259 ClientSession getDefaultSession(boolean filterAvailable) { 260 if (priorityList.isEmpty()) { 261 return null; 262 } 263 264 if (!filterAvailable) { 265 return resources.get(priorityList.getFirst()); 266 } 267 else { 268 synchronized (priorityList) { 269 for (int i=0; i < priorityList.size(); i++) { 270 ClientSession s = resources.get(priorityList.get(i)); 271 if (s != null && s.getPresence().isAvailable()) { 272 return s; 273 } 274 } 275 } 276 return null; 277 } 278 } 279 280 285 boolean isEmpty() { 286 return resources.isEmpty(); 287 } 288 289 294 private void broadcast(Packet packet) throws UnauthorizedException, PacketException { 295 for (Session session : resources.values()) { 296 packet.setTo(session.getAddress()); 297 session.process(packet); 298 } 299 } 300 301 308 public Iterator getSessions() { 309 LinkedList<Session> list = new LinkedList<Session>(); 310 for (Session session : resources.values()) { 311 list.add(session); 312 } 313 return list.iterator(); 314 } 315 316 321 public Collection<ClientSession> getAvailableSessions() { 322 LinkedList<ClientSession> list = new LinkedList<ClientSession>(); 323 for (ClientSession session : resources.values()) { 324 if (session.getPresence().isAvailable()) { 325 list.add(session); 326 } 327 } 328 return list; 329 } 330 331 337 public void sessionAvailable(ClientSession session) { 338 changePriority(session.getAddress(), session.getPresence().getPriority()); 339 } 340 341 347 public void sessionUnavailable(ClientSession session) { 348 changePriority(session.getAddress(), 0); 349 } 350 } 351 352 357 public StreamID nextStreamID() { 358 return streamIDFactory.createStreamID(); 359 } 360 361 368 public Session createClientSession(Connection conn) throws UnauthorizedException { 369 if (serverName == null) { 370 throw new UnauthorizedException("Server not initialized"); 371 } 372 StreamID id = nextStreamID(); 373 ClientSession session = new ClientSession(serverName, conn, id); 374 conn.init(session); 375 conn.registerCloseListener(clientSessionListener, session); 379 380 preAuthenticatedSessions.put(session.getAddress().toString(), session); 382 return session; 383 } 384 385 public Session createComponentSession(Connection conn) throws UnauthorizedException { 386 if (serverName == null) { 387 throw new UnauthorizedException("Server not initialized"); 388 } 389 StreamID id = nextStreamID(); 390 ComponentSession session = new ComponentSession(serverName, conn, id); 391 conn.init(session); 392 conn.registerCloseListener(componentSessionListener, session); 395 396 componentsSessions.add(session); 398 return session; 399 } 400 401 410 public IncomingServerSession createIncomingServerSession(Connection conn, StreamID id) 411 throws UnauthorizedException { 412 if (serverName == null) { 413 throw new UnauthorizedException("Server not initialized"); 414 } 415 IncomingServerSession session = new IncomingServerSession(serverName, conn, id); 416 conn.init(session); 417 conn.registerCloseListener(incomingServerListener, session); 420 421 return session; 422 } 423 424 430 public void outgoingServerSessionCreated(OutgoingServerSession session) { 431 session.getConnection().registerCloseListener(outgoingServerListener, session); 434 } 435 436 444 public void registerIncomingServerSession(String hostname, IncomingServerSession session) { 445 incomingServerSessions.put(hostname, session); 446 } 447 448 455 public void unregisterIncomingServerSession(String hostname) { 456 incomingServerSessions.remove(hostname); 457 } 458 459 469 public void registerOutgoingServerSession(String hostname, OutgoingServerSession session) { 470 outgoingServerSessions.put(hostname, session); 471 } 472 473 482 public void unregisterOutgoingServerSession(String hostname) { 483 outgoingServerSessions.remove(hostname); 484 } 485 486 489 public boolean addSession(ClientSession session) { 490 boolean success = false; 491 String username = session.getAddress().getNode().toLowerCase(); 492 SessionMap resources = null; 493 494 synchronized(username.intern()) { 495 resources = sessions.get(username); 496 if (resources == null) { 497 resources = new SessionMap(); 498 sessions.put(username, resources); 499 } 500 resources.addSession(session); 501 preAuthenticatedSessions.remove(new JID(null, session.getAddress().getDomain(), 503 session.getStreamID().toString()).toString()); 504 success = true; 505 } 506 return success; 507 } 508 509 517 public void sessionAvailable(ClientSession session) { 518 if (anonymousSessions.containsValue(session)) { 519 routingTable.addRoute(session.getAddress(), session); 522 } 523 else { 524 Session defaultSession = null; 526 try { 527 SessionMap sessionMap = sessions.get(session.getUsername()); 528 if (sessionMap == null) { 529 Log.warn("No SessionMap found for session" + "\n" + session); 530 } 531 sessionMap.sessionAvailable(session); 533 defaultSession = sessionMap.getDefaultSession(true); 534 JID node = new JID(defaultSession.getAddress().getNode(), 535 defaultSession.getAddress().getDomain(), null); 536 routingTable.addRoute(node, defaultSession); 538 routingTable.addRoute(session.getAddress(), session); 540 broadcastPresenceToOtherResource(session); 542 } 543 catch (UserNotFoundException e) { 544 } 546 } 547 } 548 549 556 private void broadcastPresenceToOtherResource(ClientSession session) 557 throws UserNotFoundException { 558 Presence presence = null; 559 Collection<ClientSession> availableSession; 560 SessionMap sessionMap = sessions.get(session.getUsername()); 561 if (sessionMap != null) { 562 availableSession = new ArrayList <ClientSession>(sessionMap.getAvailableSessions()); 563 for (ClientSession userSession : availableSession) { 564 if (userSession != session) { 565 if (session.getPresence().isAvailable()) { 568 presence = userSession.getPresence().createCopy(); 569 presence.setTo(session.getAddress()); 570 session.process(presence); 571 } 572 presence = session.getPresence().createCopy(); 575 presence.setTo(userSession.getAddress()); 576 userSession.process(presence); 577 } 578 } 579 } 580 } 581 582 589 public void sessionUnavailable(ClientSession session) { 590 if (session.getAddress() != null && routingTable != null && 591 session.getAddress().toBareJID().trim().length() != 0) { 592 routingTable.removeRoute(session.getAddress()); 594 try { 595 if (session.getUsername() == null) { 596 return; 598 } 599 SessionMap sessionMap = sessions.get(session.getUsername()); 600 if (sessionMap == null) { 603 JID userJID = new JID(session.getUsername(), serverName, ""); 604 try { 605 routingTable.getRoute(userJID); 606 routingTable.removeRoute(new JID(session.getAddress().getNode(), 608 session.getAddress().getDomain(), "")); 609 } 610 catch (NoSuchRouteException e) { 611 } 613 } 614 else if (sessionMap.getAvailableSessions().isEmpty()) { 616 routingTable.removeRoute(new JID(session.getAddress().getNode(), 618 session.getAddress().getDomain(), "")); 619 broadcastPresenceToOtherResource(session); 621 } 622 else { 623 sessionMap.sessionUnavailable(session); 625 Session defaultSession = sessionMap.getDefaultSession(true); 627 routingTable.addRoute(new JID(defaultSession.getAddress().getNode(), 628 defaultSession.getAddress().getDomain(), ""), 629 defaultSession); 630 broadcastPresenceToOtherResource(session); 632 } 633 } 634 catch (UserNotFoundException e) { 635 } 637 } 638 } 639 640 646 public void changePriority(JID sender, int priority) { 647 if (sender.getNode() == null) { 648 return; 650 } 651 String username = sender.getNode().toLowerCase(); 652 synchronized (username.intern()) { 653 SessionMap resources = sessions.get(username); 654 if (resources == null) { 655 return; 656 } 657 resources.changePriority(sender, priority); 658 659 Session defaultSession = resources.getDefaultSession(true); 661 routingTable.addRoute(new JID(defaultSession.getAddress().getNode(), 663 defaultSession.getAddress().getDomain(), ""), 664 defaultSession); 665 } 666 } 667 668 669 678 public Session getBestRoute(JID recipient) { 679 if (serverName == null || !serverName.equals(recipient.getDomain())) { 681 return null; 682 } 683 ClientSession session = null; 684 String resource = recipient.getResource(); 685 String username = recipient.getNode(); 686 if (username == null || "".equals(username)) { 687 if (resource != null) { 688 session = anonymousSessions.get(resource); 689 if (session == null){ 690 session = getSession(recipient); 691 } 692 } 693 } 694 else { 695 username = username.toLowerCase(); 696 synchronized (username.intern()) { 697 SessionMap sessionMap = sessions.get(username); 698 if (sessionMap != null) { 699 if (resource == null) { 700 session = sessionMap.getDefaultSession(false); 701 } 702 else { 703 session = sessionMap.getSession(resource); 704 if (session == null) { 705 session = sessionMap.getDefaultSession(false); 706 } 707 } 708 } 709 } 710 } 711 if (session != null && session.getConnection().isClosed()) { 714 removeSession(session); 715 return getBestRoute(recipient); 716 } 717 return session; 718 } 719 720 public boolean isActiveRoute(String username, String resource) { 721 boolean hasRoute = false; 722 723 if (username == null || "".equals(username)) { 724 if (resource != null) { 725 hasRoute = anonymousSessions.containsKey(resource); 726 } 727 } 728 else { 729 username = username.toLowerCase(); 730 Session session = null; 731 synchronized (username.intern()) { 732 SessionMap sessionMap = sessions.get(username); 733 if (sessionMap != null) { 734 if (resource == null) { 735 hasRoute = !sessionMap.isEmpty(); 736 } 737 else { 738 if (sessionMap.hasSession(resource)) { 739 session = sessionMap.getSession(resource); 740 } 741 } 742 } 743 } 744 if (session != null && !session.getConnection().isClosed()) { 748 hasRoute = session.getConnection().validate(); 749 } 750 751 } 752 return hasRoute; 753 } 754 755 761 public ClientSession getSession(JID from) { 762 if (from == null) { 764 return null; 765 } 766 return getSession(from.getNode(), from.getDomain(), from.getResource()); 767 } 768 769 779 public ClientSession getSession(String username, String domain, String resource) { 780 if (serverName == null || !serverName.equals(domain)) { 783 return null; 784 } 785 786 ClientSession session = null; 787 StringBuilder buf = new StringBuilder (); 789 if (username != null) { 790 buf.append(username).append("@"); 791 } 792 buf.append(domain); 793 if (resource != null) { 794 buf.append("/").append(resource); 795 } 796 session = preAuthenticatedSessions.get(buf.toString()); 798 if(session != null){ 799 return session; 800 } 801 802 if (resource == null) { 803 return null; 804 } 805 if (username == null || "".equals(username)) { 806 session = anonymousSessions.get(resource); 807 } 808 else { 809 username = username.toLowerCase(); 810 synchronized (username.intern()) { 811 SessionMap sessionMap = sessions.get(username); 812 if (sessionMap != null) { 813 session = sessionMap.getSession(resource); 814 } 815 } 816 } 817 return session; 818 } 819 820 821 public Collection<ClientSession> getSessions() { 822 List <ClientSession> allSessions = new ArrayList <ClientSession>(); 823 copyUserSessions(allSessions); 824 copyAnonSessions(allSessions); 825 return allSessions; 826 } 827 828 829 public Collection<ClientSession> getSessions(SessionResultFilter filter) { 830 List <ClientSession> results = new ArrayList <ClientSession>(); 831 if (filter != null) { 832 if (filter.getUsername() == null) { 834 copyAnonSessions(results); 836 copyUserSessions(results); 837 } 838 else { 839 try { 840 copyUserSessions(userManager.getUser(filter.getUsername()).getUsername(), 841 results); 842 } 843 catch (UserNotFoundException e) { 844 } 845 } 846 847 Date createMin = filter.getCreationDateRangeMin(); 848 Date createMax = filter.getCreationDateRangeMax(); 849 Date activityMin = filter.getLastActivityDateRangeMin(); 850 Date activityMax = filter.getLastActivityDateRangeMax(); 851 852 List <ClientSession> filteredResults = new ArrayList <ClientSession>(); 856 for (ClientSession session : results) { 857 if (createMin != null || createMax != null) { 859 if (!isBetweenDates(session.getCreationDate(), createMin, createMax)) { 860 session = null; 861 } 862 } 863 if ((activityMin != null || activityMax != null) && session != null) { 865 if (!isBetweenDates(session.getLastActiveDate(), activityMin, activityMax)) { 866 session = null; 867 } 868 } 869 if (session != null) { 870 if (!isBetweenPacketCount(session.getNumClientPackets(), 871 filter.getClientPacketRangeMin(), 872 filter.getClientPacketRangeMax())) { 873 session = null; 874 } 875 } 876 if (session != null) { 877 if (!isBetweenPacketCount(session.getNumServerPackets(), 878 filter.getServerPacketRangeMin(), 879 filter.getServerPacketRangeMax())) { 880 session = null; 881 } 882 } 883 if (session != null) { 884 filteredResults.add(session); 885 } 886 } 887 888 Collections.sort(filteredResults, filter.getSortComparator()); 890 891 int maxResults = filter.getNumResults(); 892 if (maxResults == SessionResultFilter.NO_RESULT_LIMIT) { 893 maxResults = filteredResults.size(); 894 } 895 896 List <ClientSession> finalResults = new ArrayList <ClientSession>(); 899 int startIndex = filter.getStartIndex(); 900 Iterator<ClientSession> sortedIter = filteredResults.iterator(); 901 for (int i = 0; sortedIter.hasNext() && finalResults.size() < maxResults; i++) { 902 ClientSession result = sortedIter.next(); 903 if (i >= startIndex) { 904 finalResults.add(result); 905 } 906 } 907 return finalResults; 908 } 909 return results; 910 } 911 912 920 public IncomingServerSession getIncomingServerSession(String hostname) { 921 return incomingServerSessions.get(hostname); 922 } 923 924 932 public OutgoingServerSession getOutgoingServerSession(String hostname) { 933 return outgoingServerSessions.get(hostname); 934 } 935 936 946 private boolean isBetweenDates(Date date, Date min, Date max) { 947 boolean between = true; 948 if (min != null) { 949 if (date.before(min)) { 950 between = false; 951 } 952 } 953 if (max != null && between) { 954 if (date.after(max)) { 955 between = false; 956 } 957 } 958 return between; 959 } 960 961 971 private boolean isBetweenPacketCount(long count, long min, long max) { 972 boolean between = true; 973 if (min != SessionResultFilter.NO_PACKET_LIMIT) { 974 if (count < min) { 975 between = false; 976 } 977 } 978 if (max != SessionResultFilter.NO_PACKET_LIMIT && between) { 979 if (count > max) { 980 between = false; 981 } 982 } 983 return between; 984 } 985 986 private void copyAnonSessions(List sessions) { 987 for (Session session : anonymousSessions.values()) { 989 sessions.add(session); 990 } 991 } 992 993 private void copyUserSessions(List sessions) { 994 for (String username : getSessionUsers()) { 996 Collection<ClientSession> usrSessions = getSessions(username); 997 for (Session session : usrSessions) { 998 sessions.add(session); 999 } 1000 } 1001 } 1002 1003 private void copyUserSessions(String username, List sessionList) { 1004 SessionMap sessionMap = sessions.get(username); 1006 if (sessionMap != null) { 1007 Iterator sessionItr = sessionMap.getSessions(); 1008 while (sessionItr.hasNext()) { 1009 sessionList.add(sessionItr.next()); 1010 } 1011 } 1012 } 1013 1014 public Iterator getAnonymousSessions() { 1015 return Arrays.asList(anonymousSessions.values().toArray()).iterator(); 1016 } 1017 1018 public Collection<ClientSession> getSessions(String username) { 1019 List <ClientSession> sessionList = new ArrayList <ClientSession>(); 1020 if (username != null) { 1021 copyUserSessions(username, sessionList); 1022 } 1023 return sessionList; 1024 } 1025 1026 public int getTotalSessionCount() { 1027 return sessionCount; 1028 } 1029 1030 public int getSessionCount() { 1031 int sessionCount = 0; 1032 for (String username : getSessionUsers()) { 1033 sessionCount += getSessionCount(username); 1034 } 1035 sessionCount += anonymousSessions.size(); 1036 return sessionCount; 1037 } 1038 1039 public int getAnonymousSessionCount() { 1040 return anonymousSessions.size(); 1041 } 1042 1043 public int getSessionCount(String username) { 1044 if (username == null) { 1045 return 0; 1046 } 1047 int sessionCount = 0; 1048 SessionMap sessionMap = sessions.get(username); 1049 if (sessionMap != null) { 1050 sessionCount = sessionMap.resources.size(); 1051 } 1052 return sessionCount; 1053 } 1054 1055 public Collection<String > getSessionUsers() { 1056 return Collections.unmodifiableCollection(sessions.keySet()); 1057 } 1058 1059 1064 public Collection<ComponentSession> getComponentSessions() { 1065 return Collections.unmodifiableCollection(componentsSessions); 1066 } 1067 1068 1074 public ComponentSession getComponentSession(String domain) { 1075 for (ComponentSession session : componentsSessions) { 1076 if (domain.equals(session.getAddress().getDomain())) { 1077 return session; 1078 } 1079 } 1080 return null; 1081 } 1082 1083 1090 public Collection<String > getIncomingServers() { 1091 return Collections.unmodifiableCollection(incomingServerSessions.keySet()); 1092 } 1093 1094 1101 public Collection<String > getOutgoingServers() { 1102 return Collections.unmodifiableCollection(outgoingServerSessions.keySet()); 1103 } 1104 1105 1111 public void broadcast(Packet packet) throws UnauthorizedException { 1112 Iterator values = sessions.values().iterator(); 1113 while (values.hasNext()) { 1114 ((SessionMap)values.next()).broadcast(packet); 1115 } 1116 1117 for (Session session : anonymousSessions.values()) { 1118 session.process(packet); 1119 } 1120 } 1121 1122 1129 public void userBroadcast(String username, Packet packet) throws UnauthorizedException, PacketException { 1130 SessionMap sessionMap = sessions.get(username); 1131 if (sessionMap != null) { 1132 sessionMap.broadcast(packet); 1133 } 1134 } 1135 1136 1141 public void removeSession(ClientSession session) { 1142 if (session == null || serverName == null) { 1147 return; 1148 } 1149 SessionMap sessionMap = null; 1150 if (anonymousSessions.containsValue(session)) { 1151 anonymousSessions.remove(session.getAddress().getResource()); 1152 sessionCount--; 1153 } 1154 else { 1155 if (session.getAddress() != null && session.getAddress().getNode() != null) { 1157 String username = session.getAddress().getNode().toLowerCase(); 1158 synchronized (username.intern()) { 1159 sessionMap = sessions.get(username); 1160 if (sessionMap != null) { 1161 sessionMap.removeSession(session); 1162 sessionCount--; 1163 if (sessionMap.isEmpty()) { 1164 sessions.remove(username); 1165 } 1166 } 1167 } 1168 } 1169 } 1170 Presence presence = session.getPresence(); 1172 if (presence == null || presence.isAvailable()) { 1173 Presence offline = new Presence(); 1174 offline.setFrom(session.getAddress()); 1175 offline.setTo(new JID(null, serverName, null)); 1176 offline.setType(Presence.Type.unavailable); 1177 router.route(offline); 1178 } 1179 else if (preAuthenticatedSessions.containsValue(session)) { 1180 preAuthenticatedSessions.remove(session.getAddress().toString()); 1182 } 1183 } 1184 1185 public void addAnonymousSession(ClientSession session) { 1186 anonymousSessions.put(session.getAddress().getResource(), session); 1187 preAuthenticatedSessions.remove(session.getAddress().toString()); 1189 } 1190 1191 public int getConflictKickLimit() { 1192 return conflictLimit; 1193 } 1194 1195 1201 public Collection<String > getPreAuthenticatedKeys() { 1202 return preAuthenticatedSessions.keySet(); 1203 } 1204 1205 public void setConflictKickLimit(int limit) { 1206 conflictLimit = limit; 1207 JiveGlobals.setProperty("xmpp.session.conflict-limit", Integer.toString(conflictLimit)); 1208 } 1209 1210 private class ClientSessionListener implements ConnectionCloseListener { 1211 1216 public void onConnectionClose(Object handback) { 1217 try { 1218 ClientSession session = (ClientSession)handback; 1219 try { 1220 if (session.getPresence().isAvailable()) { 1221 Presence presence = new Presence(); 1225 presence.setType(Presence.Type.unavailable); 1226 presence.setFrom(session.getAddress()); 1227 presenceHandler.process(presence); 1228 } 1229 } 1230 finally { 1231 removeSession(session); 1233 } 1234 } 1235 catch (Exception e) { 1236 Log.error(LocaleUtils.getLocalizedString("admin.error.close"), e); 1238 } 1239 } 1240 } 1241 1242 private class ComponentSessionListener implements ConnectionCloseListener { 1243 1248 public void onConnectionClose(Object handback) { 1249 ComponentSession session = (ComponentSession)handback; 1250 try { 1251 String domain = session.getAddress().getDomain(); 1253 String subdomain = domain.substring(0, domain.indexOf(serverName) - 1); 1254 InternalComponentManager.getInstance().removeComponent(subdomain); 1255 } 1256 catch (Exception e) { 1257 Log.error(LocaleUtils.getLocalizedString("admin.error.close"), e); 1259 } 1260 finally { 1261 componentsSessions.remove(session); 1263 } 1264 } 1265 } 1266 1267 private class IncomingServerSessionListener implements ConnectionCloseListener { 1268 1273 public void onConnectionClose(Object handback) { 1274 IncomingServerSession session = (IncomingServerSession)handback; 1275 for (String hostname : session.getValidatedDomains()) { 1277 unregisterIncomingServerSession(hostname); 1278 } 1279 } 1280 } 1281 1282 private class OutgoingServerSessionListener implements ConnectionCloseListener { 1283 1288 public void onConnectionClose(Object handback) { 1289 OutgoingServerSession session = (OutgoingServerSession)handback; 1290 for (String hostname : session.getHostnames()) { 1292 unregisterOutgoingServerSession(hostname); 1293 XMPPServer.getInstance().getRoutingTable().removeRoute(new JID(hostname)); 1295 } 1296 } 1297 } 1298 1299 public void initialize(XMPPServer server) { 1300 super.initialize(server); 1301 presenceHandler = server.getPresenceUpdateHandler(); 1302 router = server.getPacketRouter(); 1303 userManager = server.getUserManager(); 1304 routingTable = server.getRoutingTable(); 1305 serverName = server.getServerInfo().getName(); 1306 serverAddress = new JID(serverName); 1307 1308 if (JiveGlobals.getBooleanProperty("xmpp.audit.active")) { 1309 streamIDFactory = new AuditStreamIDFactory(); 1310 } 1311 else { 1312 streamIDFactory = new BasicStreamIDFactory(); 1313 } 1314 1315 String conflictLimitProp = JiveGlobals.getProperty("xmpp.session.conflict-limit"); 1316 if (conflictLimitProp == null) { 1317 conflictLimit = 0; 1318 JiveGlobals.setProperty("xmpp.session.conflict-limit", Integer.toString(conflictLimit)); 1319 } 1320 else { 1321 try { 1322 conflictLimit = Integer.parseInt(conflictLimitProp); 1323 } 1324 catch (NumberFormatException e) { 1325 conflictLimit = 0; 1326 JiveGlobals.setProperty("xmpp.session.conflict-limit", Integer.toString(conflictLimit)); 1327 } 1328 } 1329 serverCleanupTask = new ServerCleanupTask(); 1332 timer.schedule(serverCleanupTask, getServerSessionTimeout(), getServerSessionTimeout()); 1333 } 1334 1335 1336 1342 public void sendServerMessage(String subject, String body) { 1343 sendServerMessage(null, subject, body); 1344 } 1345 1346 1358 public void sendServerMessage(JID address, String subject, String body) { 1359 Message packet = createServerMessage(subject, body); 1360 try { 1361 if (address == null || address.getNode() == null || address.getNode().length() < 1) { 1362 broadcast(packet); 1363 } 1364 else if (address.getResource() == null || address.getResource().length() < 1) { 1365 userBroadcast(address.getNode(), packet); 1366 } 1367 else { 1368 ClientSession session = getSession(address); 1369 if (session != null) { 1370 session.process(packet); 1371 } 1372 } 1373 } 1374 catch (UnauthorizedException e) { 1375 } 1376 } 1377 1378 private Message createServerMessage(String subject, String body) { 1379 Message message = new Message(); 1380 message.setFrom(serverAddress); 1381 if (subject != null) { 1382 message.setSubject(subject); 1383 } 1384 message.setBody(body); 1385 return message; 1386 } 1387 1388 public void stop() { 1389 Log.debug("Stopping server"); 1390 timer.cancel(); 1391 serverName = null; 1392 if (JiveGlobals.getBooleanProperty("shutdownMessage.enabled")) { 1393 sendServerMessage(null, LocaleUtils.getLocalizedString("admin.shutdown.now")); 1394 } 1395 try { 1396 for (Session session : getSessions()) { 1397 try { 1398 session.getConnection().close(); 1399 } 1400 catch (Throwable t) { 1401 } 1402 } 1403 } 1404 catch (Exception e) { 1405 } 1406 } 1407 1408 1411 1416 public void setServerSessionTimeout(int timeout) { 1417 if (getServerSessionTimeout() == timeout) { 1418 return; 1419 } 1420 if (serverCleanupTask != null) { 1422 serverCleanupTask.cancel(); 1423 } 1424 serverCleanupTask = new ServerCleanupTask(); 1426 timer.schedule(serverCleanupTask, getServerSessionTimeout(), getServerSessionTimeout()); 1427 JiveGlobals.setProperty("xmpp.server.session.timeout", Integer.toString(timeout)); 1429 } 1430 1431 1436 public int getServerSessionTimeout() { 1437 return JiveGlobals.getIntProperty("xmpp.server.session.timeout", 5 * 60 * 1000); 1438 } 1439 1440 public void setServerSessionIdleTime(int idleTime) { 1441 if (getServerSessionIdleTime() == idleTime) { 1442 return; 1443 } 1444 JiveGlobals.setProperty("xmpp.server.session.idle", Integer.toString(idleTime)); 1446 } 1447 1448 public int getServerSessionIdleTime() { 1449 return JiveGlobals.getIntProperty("xmpp.server.session.idle", 30 * 60 * 1000); 1450 } 1451 1452 1455 private class ServerCleanupTask extends TimerTask { 1456 1459 public void run() { 1460 if (getServerSessionIdleTime() == -1) { 1462 return; 1463 } 1464 final long deadline = System.currentTimeMillis() - getServerSessionIdleTime(); 1465 for (OutgoingServerSession session : outgoingServerSessions.values()) { 1467 try { 1468 if (session.getLastActiveDate().getTime() < deadline) { 1469 session.getConnection().close(); 1470 } 1471 } 1472 catch (Throwable e) { 1473 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 1474 } 1475 } 1476 for (IncomingServerSession session : incomingServerSessions.values()) { 1478 try { 1479 if (session.getLastActiveDate().getTime() < deadline) { 1480 session.getConnection().close(); 1481 } 1482 } 1483 catch (Throwable e) { 1484 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 1485 } 1486 } 1487 } 1488 } 1489} 1490 | Popular Tags |