diff options
Diffstat (limited to 'Slimber/Server.cpp')
| m--------- | Slimber | 0 | ||||
| -rw-r--r-- | Slimber/Server.cpp | 427 | 
2 files changed, 0 insertions, 427 deletions
diff --git a/Slimber b/Slimber new file mode 160000 +Subproject 723115ef8542c640580ea4751fca3c359a79dec diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp deleted file mode 100644 index 278a572..0000000 --- a/Slimber/Server.cpp +++ /dev/null @@ -1,427 +0,0 @@ -#include "Slimber/Server.h" - -#include <string> -#include <boost/bind.hpp> - -#include "Swiften/LinkLocal/LinkLocalConnector.h" -#include "Swiften/Network/Connection.h" -#include "Swiften/Session/SessionTracer.h" -#include "Swiften/Elements/Element.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/RosterPayload.h" -#include "Swiften/Network/BoostConnection.h" -#include "Swiften/Network/BoostConnectionServer.h" -#include "Swiften/Session/SessionTracer.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/VCard.h" -#include "Swiften/Server/UserRegistry.h" -#include "Swiften/Base/String.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" -#include "Swiften/LinkLocal/OutgoingLinkLocalSession.h" -#include "Swiften/LinkLocal/IncomingLinkLocalSession.h" -#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" -#include "Swiften/Network/ConnectionServer.h" -#include "Slimber/VCardCollection.h" -#include "Slimber/LinkLocalPresenceManager.h" -#include "Swiften/Server/ServerFromClientSession.h" - -namespace Swift { - -Server::Server( -		int clientConnectionPort,  -		int linkLocalConnectionPort,  -		LinkLocalServiceBrowser* linkLocalServiceBrowser, -		VCardCollection* vCardCollection) :  -			linkLocalServiceRegistered(false),  -			rosterRequested(false),  -			clientConnectionPort(clientConnectionPort),  -			linkLocalConnectionPort(linkLocalConnectionPort), -			linkLocalServiceBrowser(linkLocalServiceBrowser), -			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())); -	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)); - -	serverFromClientConnectionServer->start(); -	serverFromNetworkConnectionServer->start(); -} - -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) { -	if (serverFromClientSession) { -		connection->disconnect(); -	} -	serverFromClientSession = boost::shared_ptr<ServerFromClientSession>( -			new ServerFromClientSession(idGenerator.generateID(), connection,  -					&payloadParserFactories, &payloadSerializers, &userRegistry)); -	serverFromClientSession->onSessionStarted.connect( -			boost::bind(&Server::handleSessionStarted, this)); -	serverFromClientSession->onElementReceived.connect( -			boost::bind(&Server::handleElementReceived, this, _1,  -				serverFromClientSession)); -	serverFromClientSession->onSessionFinished.connect( -			boost::bind(&Server::handleSessionFinished, this,  -			serverFromClientSession)); -	//tracers.push_back(boost::shared_ptr<SessionTracer>( -	//		new SessionTracer(serverFromClientSession))); -	serverFromClientSession->startSession(); -} - -void Server::handleSessionStarted() { -	onSelfConnected(true); -} - -void Server::handleSessionFinished(boost::shared_ptr<ServerFromClientSession>) { -	serverFromClientSession.reset(); -	unregisterService(); -	selfJID = JID(); -	rosterRequested = false; -	onSelfConnected(false); -	lastPresence.reset(); -} - -void Server::unregisterService() { -	if (linkLocalServiceRegistered) { -		linkLocalServiceRegistered = false; -		linkLocalServiceBrowser->unregisterService(); -	} -} - -void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::shared_ptr<ServerFromClientSession> session) { -	boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element); -	if (!stanza) { -		return; -	} - -	stanza->setFrom(session->getRemoteJID()); -	if (!stanza->getTo().isValid()) { -		stanza->setTo(session->getLocalJID()); -	} - -	if (boost::shared_ptr<Presence> presence = boost::dynamic_pointer_cast<Presence>(stanza)) { -		if (presence->getType() == Presence::Available) { -			if (!linkLocalServiceRegistered) { -				linkLocalServiceRegistered = true; -				linkLocalServiceBrowser->registerService( -						session->getRemoteJID().toBare().toString(),  -						linkLocalConnectionPort, getLinkLocalServiceInfo(presence)); -			} -			else { -				linkLocalServiceBrowser->updateService( -						getLinkLocalServiceInfo(presence)); -			} -			lastPresence = presence; -		} -		else { -			unregisterService(); -		} -	} -	else if (!stanza->getTo().isValid() || stanza->getTo() == session->getLocalJID() || stanza->getTo() == session->getRemoteJID().toBare()) { -		if (boost::shared_ptr<IQ> iq = boost::dynamic_pointer_cast<IQ>(stanza)) { -			if (iq->getPayload<RosterPayload>()) { -				if (iq->getType() == IQ::Get) { -					session->sendElement(IQ::createResult(iq->getFrom(), iq->getID(), presenceManager->getRoster())); -					rosterRequested = true; -					foreach(const boost::shared_ptr<Presence> presence, presenceManager->getAllPresence()) { -						session->sendElement(presence); -					} -				} -				else { -					session->sendElement(IQ::createError(iq->getFrom(), iq->getID(), ErrorPayload::Forbidden, ErrorPayload::Cancel)); -				} -			} -			if (boost::shared_ptr<VCard> vcard = iq->getPayload<VCard>()) { -				if (iq->getType() == IQ::Get) { -					session->sendElement(IQ::createResult(iq->getFrom(), iq->getID(), vCardCollection->getOwnVCard())); -				} -				else { -					vCardCollection->setOwnVCard(vcard); -					session->sendElement(IQ::createResult(iq->getFrom(), iq->getID())); -					if (lastPresence) { -						linkLocalServiceBrowser->updateService(getLinkLocalServiceInfo(lastPresence)); -					} -				} -			} -			else { -				session->sendElement(IQ::createError(iq->getFrom(), iq->getID(), ErrorPayload::FeatureNotImplemented, ErrorPayload::Cancel)); -			} -		} -	} -	else { -		JID toJID = stanza->getTo(); -		boost::shared_ptr<Session> outgoingSession =  -				getLinkLocalSessionForJID(toJID); -		if (outgoingSession) { -			outgoingSession->sendElement(stanza); -		} -		else { -			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( -								*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); -					connector->connect(); -				} -				connector->queueElement(element); -			} -			else { -				session->sendElement(IQ::createError( -						stanza->getFrom(), stanza->getID(),  -						ErrorPayload::RecipientUnavailable, ErrorPayload::Wait)); -			} -		} -	} -} - -void Server::handleNewLinkLocalConnection(boost::shared_ptr<Connection> connection) { -	boost::shared_ptr<IncomingLinkLocalSession> session( -			new IncomingLinkLocalSession( -				selfJID, connection,  -				&payloadParserFactories, &payloadSerializers)); -	registerLinkLocalSession(session); -} - -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()); -} - -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 (!presenceManager->getServiceForJID(fromJID.toBare())) { -			return; // TODO: Send error back -		} -		stanza->setFrom(fromJID); -		serverFromClientSession->sendElement(stanza); -	} -} - -void Server::handleConnectFinished(boost::shared_ptr<LinkLocalConnector> connector, bool error) { -	if (error) { -		std::cerr << "Error connecting" << std::endl; -		// TODO: Send back queued stanzas -	} -	else { -		boost::shared_ptr<OutgoingLinkLocalSession> outgoingSession( -				new OutgoingLinkLocalSession( -					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()); -} - -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); -	//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) { -		if (session->getRemoteJID() == jid) { -			return session; -		} -	} -	return boost::shared_ptr<Session>(); -} - -boost::shared_ptr<LinkLocalConnector> Server::getLinkLocalConnectorForJID(const JID& 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()); -} - -void Server::handleRosterChanged(boost::shared_ptr<RosterPayload> roster) { -	if (rosterRequested) { -		assert(serverFromClientSession); -		boost::shared_ptr<IQ> iq = IQ::createRequest( -				IQ::Set, serverFromClientSession->getRemoteJID(),  -				idGenerator.generateID(), roster); -		iq->setFrom(serverFromClientSession->getRemoteJID().toBare()); -		serverFromClientSession->sendElement(iq); -	} -} - -void Server::handlePresenceChanged(boost::shared_ptr<Presence> presence) { -	if (rosterRequested) { -		serverFromClientSession->sendElement(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(); -	if (!vcard->getFamilyName().isEmpty() || !vcard->getGivenName().isEmpty()) { -		info.setFirstName(vcard->getGivenName()); -		info.setLastName(vcard->getFamilyName()); -	} -	else if (!vcard->getFullName().isEmpty()) { -		std::pair<String,String> p = vcard->getFullName().getSplittedAtFirst(' '); -		info.setFirstName(p.first); -		info.setLastName(p.second); -	} -	if (!vcard->getNickname().isEmpty()) { -		info.setNick(vcard->getNickname()); -	} -	if (!vcard->getEMail().isEmpty()) { -		info.setEMail(vcard->getEMail()); -	} -	info.setMessage(presence->getStatus()); -	switch (presence->getShow()) { -		case StatusShow::Online:  -		case StatusShow::None:  -		case StatusShow::FFC:  -			info.setStatus(LinkLocalServiceInfo::Available); -			break; -		case StatusShow::Away:  -		case StatusShow::XA:  -			info.setStatus(LinkLocalServiceInfo::Away); -			break; -		case StatusShow::DND:  -			info.setStatus(LinkLocalServiceInfo::DND); -			break; -	} -	info.setPort(linkLocalConnectionPort); -	return info; -} - -}  | 
 Swift