summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Server/ServerStanzaRouter.cpp')
-rw-r--r--Swiften/Server/ServerStanzaRouter.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/Swiften/Server/ServerStanzaRouter.cpp b/Swiften/Server/ServerStanzaRouter.cpp
new file mode 100644
index 0000000..5661de5
--- /dev/null
+++ b/Swiften/Server/ServerStanzaRouter.cpp
@@ -0,0 +1,67 @@
+#include "Swiften/Server/ServerStanzaRouter.h"
+#include "Swiften/Server/ServerSession.h"
+
+#include <cassert>
+#include <algorithm>
+
+namespace Swift {
+
+namespace {
+ struct PriorityLessThan {
+ bool operator()(const ServerSession* s1, const ServerSession* s2) const {
+ return s1->getPriority() < s2->getPriority();
+ }
+ };
+
+ struct HasJID {
+ HasJID(const JID& jid) : jid(jid) {}
+ bool operator()(const ServerSession* session) const {
+ return session->getJID().equals(jid, JID::WithResource);
+ }
+ JID jid;
+ };
+}
+
+ServerStanzaRouter::ServerStanzaRouter() {
+}
+
+bool ServerStanzaRouter::routeStanza(boost::shared_ptr<Stanza> stanza) {
+ JID to = stanza->getTo();
+ assert(to.isValid());
+
+ // For a full JID, first try to route to a session with the full JID
+ if (!to.isBare()) {
+ std::vector<ServerSession*>::const_iterator i = std::find_if(clientSessions_.begin(), clientSessions_.end(), HasJID(to));
+ if (i != clientSessions_.end()) {
+ (*i)->sendStanza(stanza);
+ return true;
+ }
+ }
+
+ // Look for candidate sessions
+ to = to.toBare();
+ std::vector<ServerSession*> candidateSessions;
+ for (std::vector<ServerSession*>::const_iterator i = clientSessions_.begin(); i != clientSessions_.end(); ++i) {
+ if ((*i)->getJID().equals(to, JID::WithoutResource) && (*i)->getPriority() >= 0) {
+ candidateSessions.push_back(*i);
+ }
+ }
+ if (candidateSessions.empty()) {
+ return false;
+ }
+
+ // Find the session with the highest priority
+ std::vector<ServerSession*>::const_iterator i = std::max_element(clientSessions_.begin(), clientSessions_.end(), PriorityLessThan());
+ (*i)->sendStanza(stanza);
+ return true;
+}
+
+void ServerStanzaRouter::addClientSession(ServerSession* clientSession) {
+ clientSessions_.push_back(clientSession);
+}
+
+void ServerStanzaRouter::removeClientSession(ServerSession* clientSession) {
+ clientSessions_.erase(std::remove(clientSessions_.begin(), clientSessions_.end(), clientSession), clientSessions_.end());
+}
+
+}