summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Slimber/Server.cpp')
-rw-r--r--Slimber/Server.cpp170
1 files changed, 130 insertions, 40 deletions
diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp
index a63201b..e07fb41 100644
--- a/Slimber/Server.cpp
+++ b/Slimber/Server.cpp
@@ -37,35 +37,98 @@ Server::Server(
clientConnectionPort(clientConnectionPort),
linkLocalConnectionPort(linkLocalConnectionPort),
linkLocalServiceBrowser(linkLocalServiceBrowser),
- vCardCollection(vCardCollection) {
+ vCardCollection(vCardCollection),
+ presenceManager(NULL),
+ stopping(false) {
+ linkLocalServiceBrowser->onServiceRegistered.connect(
+ boost::bind(&Server::handleServiceRegistered, this, _1));
+}
+
+Server::~Server() {
+ stop();
+}
+
+void Server::start() {
+ assert(!serverFromClientConnectionServer);
serverFromClientConnectionServer =
boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer(
clientConnectionPort, &boostIOServiceThread.getIOService()));
- serverFromClientConnectionServer->onNewConnection.connect(
- boost::bind(&Server::handleNewClientConnection, this, _1));
- serverFromClientConnectionServer->start();
+ serverFromClientConnectionServerSignalConnections.push_back(
+ serverFromClientConnectionServer->onNewConnection.connect(
+ boost::bind(&Server::handleNewClientConnection, this, _1)));
+ serverFromClientConnectionServerSignalConnections.push_back(
+ serverFromClientConnectionServer->onStopped.connect(
+ boost::bind(&Server::handleClientConnectionServerStopped, this, _1)));
+ assert(!serverFromNetworkConnectionServer);
+ serverFromNetworkConnectionServer =
+ boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer(
+ linkLocalConnectionPort, &boostIOServiceThread.getIOService()));
+ serverFromNetworkConnectionServerSignalConnections.push_back(
+ serverFromNetworkConnectionServer->onNewConnection.connect(
+ boost::bind(&Server::handleNewLinkLocalConnection, this, _1)));
+ serverFromNetworkConnectionServerSignalConnections.push_back(
+ serverFromNetworkConnectionServer->onStopped.connect(
+ boost::bind(&Server::handleLinkLocalConnectionServerStopped, this, _1)));
+
+ assert(!presenceManager);
presenceManager = new LinkLocalPresenceManager(linkLocalServiceBrowser);
presenceManager->onRosterChanged.connect(
boost::bind(&Server::handleRosterChanged, this, _1));
presenceManager->onPresenceChanged.connect(
boost::bind(&Server::handlePresenceChanged, this, _1));
- linkLocalServiceBrowser->onServiceRegistered.connect(
- boost::bind(&Server::handleServiceRegistered, this, _1));
-
- /*
- serverFromNetworkConnectionServer =
- boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer(
- linkLocalConnectionPort, &boostIOServiceThread.getIOService()));
- serverFromNetworkConnectionServer->onNewConnection.connect(
- boost::bind(&Server::handleNewLinkLocalConnection, this, _1));
+ serverFromClientConnectionServer->start();
serverFromNetworkConnectionServer->start();
- */
}
-Server::~Server() {
+void Server::stop() {
+ stop(boost::optional<ServerError>());
+}
+
+void Server::stop(boost::optional<ServerError> e) {
+ if (stopping) {
+ return;
+ }
+
+ stopping = true;
+
delete presenceManager;
+ presenceManager = NULL;
+
+ if (serverFromClientSession) {
+ serverFromClientSession->finishSession();
+ }
+ serverFromClientSession.reset();
+ foreach(boost::shared_ptr<Session> session, linkLocalSessions) {
+ session->finishSession();
+ }
+ linkLocalSessions.clear();
+ foreach(boost::shared_ptr<LinkLocalConnector> connector, connectors) {
+ connector->cancel();
+ }
+ connectors.clear();
+ tracers.clear();
+
+ if (serverFromNetworkConnectionServer) {
+ serverFromNetworkConnectionServer->stop();
+ foreach(boost::bsignals::connection& connection, serverFromNetworkConnectionServerSignalConnections) {
+ connection.disconnect();
+ }
+ serverFromNetworkConnectionServerSignalConnections.clear();
+ serverFromNetworkConnectionServer.reset();
+ }
+ if (serverFromClientConnectionServer) {
+ serverFromClientConnectionServer->stop();
+ foreach(boost::bsignals::connection& connection, serverFromClientConnectionServerSignalConnections) {
+ connection.disconnect();
+ }
+ serverFromClientConnectionServerSignalConnections.clear();
+ serverFromClientConnectionServer.reset();
+ }
+
+ stopping = false;
+ onStopped(e);
}
void Server::handleNewClientConnection(boost::shared_ptr<Connection> connection) {
@@ -83,8 +146,8 @@ void Server::handleNewClientConnection(boost::shared_ptr<Connection> connection)
serverFromClientSession->onSessionFinished.connect(
boost::bind(&Server::handleSessionFinished, this,
serverFromClientSession));
- tracers.push_back(boost::shared_ptr<SessionTracer>(
- new SessionTracer(serverFromClientSession)));
+ //tracers.push_back(boost::shared_ptr<SessionTracer>(
+ // new SessionTracer(serverFromClientSession)));
serverFromClientSession->startSession();
}
@@ -168,7 +231,6 @@ void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::sh
}
}
}
- /*
else {
JID toJID = stanza->getTo();
boost::shared_ptr<Session> outgoingSession =
@@ -177,20 +239,20 @@ void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::sh
outgoingSession->sendElement(stanza);
}
else {
- if (linkLocalServiceBrowser->hasItem(toJID)) {
+ boost::optional<LinkLocalService> service =
+ presenceManager->getServiceForJID(toJID);
+ if (service) {
boost::shared_ptr<LinkLocalConnector> connector =
getLinkLocalConnectorForJID(toJID);
if (!connector) {
connector = boost::shared_ptr<LinkLocalConnector>(
new LinkLocalConnector(
- toJID,
- linkLocalServiceBrowser->getHostname(toJID),
- linkLocalServiceBrowser->getPort(toJID),
- linkLocalServiceBrowser,
+ *service,
+ linkLocalServiceBrowser->getQuerier(),
boost::shared_ptr<BoostConnection>(new BoostConnection(&boostIOServiceThread.getIOService()))));
connector->onConnectFinished.connect(
boost::bind(&Server::handleConnectFinished, this, connector, _1));
- connectors_.push_back(connector);
+ connectors.push_back(connector);
connector->connect();
}
connector->queueElement(element);
@@ -202,10 +264,8 @@ void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::sh
}
}
}
- */
}
-/*
void Server::handleNewLinkLocalConnection(boost::shared_ptr<Connection> connection) {
boost::shared_ptr<IncomingLinkLocalSession> session(
new IncomingLinkLocalSession(
@@ -215,15 +275,17 @@ void Server::handleNewLinkLocalConnection(boost::shared_ptr<Connection> connecti
}
void Server::handleLinkLocalSessionFinished(boost::shared_ptr<Session> session) {
- std::cout << "Link local session from " << session->getRemoteJID() << " ended" << std::endl;
- linkLocalSessions_.erase(std::remove(linkLocalSessions_.begin(), linkLocalSessions_.end(), session), linkLocalSessions_.end());
+ //std::cout << "Link local session from " << session->getRemoteJID() << " ended" << std::endl;
+ linkLocalSessions.erase(
+ std::remove(linkLocalSessions.begin(), linkLocalSessions.end(), session),
+ linkLocalSessions.end());
}
void Server::handleLinkLocalElementReceived(boost::shared_ptr<Element> element, boost::shared_ptr<Session> session) {
if (boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element)) {
JID fromJID = session->getRemoteJID();
- if (!linkLocalServiceBrowser->hasItem(fromJID)) {
- return; // TODO: Queue
+ if (!presenceManager->getServiceForJID(fromJID.toBare())) {
+ return; // TODO: Send error back
}
stanza->setFrom(fromJID);
serverFromClientSession->sendElement(stanza);
@@ -238,27 +300,28 @@ void Server::handleConnectFinished(boost::shared_ptr<LinkLocalConnector> connect
else {
boost::shared_ptr<OutgoingLinkLocalSession> outgoingSession(
new OutgoingLinkLocalSession(
- selfJID, connector->getRemoteJID(), connector->getConnection(),
+ selfJID, connector->getService().getJID(), connector->getConnection(),
&payloadParserFactories, &payloadSerializers));
foreach(const boost::shared_ptr<Element> element, connector->getQueuedElements()) {
outgoingSession->queueElement(element);
}
registerLinkLocalSession(outgoingSession);
}
- connectors_.erase(std::remove(connectors_.begin(), connectors_.end(), connector), connectors_.end());
+ connectors.erase(std::remove(connectors.begin(), connectors.end(), connector), connectors.end());
}
-
void Server::registerLinkLocalSession(boost::shared_ptr<Session> session) {
- session->onSessionFinished.connect(boost::bind(&Server::handleLinkLocalSessionFinished, this, session));
- session->onElementReceived.connect(boost::bind(&Server::handleLinkLocalElementReceived, this, _1, session));
- linkLocalSessions_.push_back(session);
+ session->onSessionFinished.connect(
+ boost::bind(&Server::handleLinkLocalSessionFinished, this, session));
+ session->onElementReceived.connect(
+ boost::bind(&Server::handleLinkLocalElementReceived, this, _1, session));
+ linkLocalSessions.push_back(session);
//tracers.push_back(boost::shared_ptr<SessionTracer>(new SessionTracer(session)));
session->startSession();
}
boost::shared_ptr<Session> Server::getLinkLocalSessionForJID(const JID& jid) {
- foreach(const boost::shared_ptr<Session> session, linkLocalSessions_) {
+ foreach(const boost::shared_ptr<Session> session, linkLocalSessions) {
if (session->getRemoteJID() == jid) {
return session;
}
@@ -267,14 +330,13 @@ boost::shared_ptr<Session> Server::getLinkLocalSessionForJID(const JID& jid) {
}
boost::shared_ptr<LinkLocalConnector> Server::getLinkLocalConnectorForJID(const JID& jid) {
- foreach(const boost::shared_ptr<LinkLocalConnector> connector, connectors_) {
- if (connector->getRemoteJID() == jid) {
+ foreach(const boost::shared_ptr<LinkLocalConnector> connector, connectors) {
+ if (connector->getService().getJID() == jid) {
return connector;
}
}
return boost::shared_ptr<LinkLocalConnector>();
}
-*/
void Server::handleServiceRegistered(const DNSSDServiceID& service) {
selfJID = JID(service.getName());
@@ -297,6 +359,34 @@ void Server::handlePresenceChanged(boost::shared_ptr<Presence> presence) {
}
}
+void Server::handleClientConnectionServerStopped(boost::optional<BoostConnectionServer::Error> e) {
+ if (e) {
+ if (*e == BoostConnectionServer::Conflict) {
+ stop(ServerError(ServerError::C2SPortConflict));
+ }
+ else {
+ stop(ServerError(ServerError::C2SError));
+ }
+ }
+ else {
+ stop();
+ }
+}
+
+void Server::handleLinkLocalConnectionServerStopped(boost::optional<BoostConnectionServer::Error> e) {
+ if (e) {
+ if (*e == BoostConnectionServer::Conflict) {
+ stop(ServerError(ServerError::LinkLocalPortConflict));
+ }
+ else {
+ stop(ServerError(ServerError::LinkLocalError));
+ }
+ }
+ else {
+ stop();
+ }
+}
+
LinkLocalServiceInfo Server::getLinkLocalServiceInfo(boost::shared_ptr<Presence> presence) {
LinkLocalServiceInfo info;
boost::shared_ptr<VCard> vcard = vCardCollection->getOwnVCard();