Changeset - df369e65d8f0
[Not reviewed]
0 5 0
HanzZ - 13 years ago 2013-01-30 18:59:14
hanzz.k@gmail.com
libtransport: support service.server also in server-mode
5 files changed with 13 insertions and 5 deletions:
0 comments (0 inline, 0 general)
include/Swiften/Server/Server.cpp
Show inline comments
 
/*
 
 * Copyright (c) 2010 Remko Tronçon
 
 * Licensed under the GNU General Public License v3.
 
 * See Documentation/Licenses/GPLv3.txt for more information.
 
 */
 

	
 
#include "Swiften/Server/Server.h"
 

	
 
#include <string>
 
#include <boost/bind.hpp>
 

	
 
#include "Swiften/Base/String.h"
 
#include "Swiften/Base/foreach.h"
 
#include "Swiften/Network/Connection.h"
 
#include "Swiften/Network/ConnectionServer.h"
 
#include "Swiften/Network/ConnectionServerFactory.h"
 
#include "Swiften/Elements/Element.h"
 
#include "Swiften/Elements/Presence.h"
 
#include "Swiften/Elements/RosterPayload.h"
 
#include "Swiften/Network/NetworkFactories.h"
 
#include "Swiften/Session/SessionTracer.h"
 
#include "Swiften/Elements/IQ.h"
 
#include "Swiften/Elements/VCard.h"
 
#include "Swiften/Server/UserRegistry.h"
 
#include <string>
 
#include "Swiften/Network/ConnectionServer.h"
 
#include "Swiften/Network/ConnectionFactory.h"
 
#include "Swiften/Server/ServerFromClientSession.h"
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
#include "Swiften/Queries/IQRouter.h"
 
#include <iostream>
 

	
 

	
 
namespace Swift {
 

	
 
Server::Server(
 
		EventLoop* eventLoop,
 
		NetworkFactories* networkFactories,
 
		UserRegistry *userRegistry,
 
		const JID& jid,
 
		const std::string &address,
 
		int port) :
 
			userRegistry_(userRegistry),
 
			port_(port),
 
			eventLoop(eventLoop),
 
			networkFactories_(networkFactories),
 
			stopping(false),
 
			selfJID(jid),
 
			stanzaChannel_(){
 
			stanzaChannel_(),
 
			address_(address){
 
	stanzaChannel_ = new ServerStanzaChannel();
 
	iqRouter_ = new IQRouter(stanzaChannel_);
 
	tlsFactory = NULL;
 
	parserFactory_ = new PlatformXMLParserFactory();
 
}
 

	
 
Server::~Server() {
 
	stop();
 
	delete iqRouter_;
 
	delete stanzaChannel_;
 
	delete parserFactory_;
 
}
 

	
 
void Server::start() {
 
	if (serverFromClientConnectionServer) {
 
		return;
 
	}
 
	if (address_ == "0.0.0.0") {
 
		serverFromClientConnectionServer = networkFactories_->getConnectionServerFactory()->createConnectionServer(port_);
 
	}
 
	else {
 
		serverFromClientConnectionServer = networkFactories_->getConnectionServerFactory()->createConnectionServer(Swift::HostAddress(address_), port_);
 
	}
 
	serverFromClientConnectionServerSignalConnections.push_back(
 
		serverFromClientConnectionServer->onNewConnection.connect(
 
				boost::bind(&Server::handleNewClientConnection, this, _1)));
 
// 	serverFromClientConnectionServerSignalConnections.push_back(
 
// 		serverFromClientConnectionServer->onStopped.connect(
 
// 				boost::bind(&Server::handleClientConnectionServerStopped, this, _1)));
 

	
 
	serverFromClientConnectionServer->start();
 
}
 

	
 
void Server::stop() {
 
	if (stopping) {
 
		return;
 
	}
 

	
 
	stopping = true;
 

	
 
// 	foreach(boost::shared_ptr<ServerFromClientSession> session, serverFromClientSessions) {
 
// 		session->finishSession();
 
// 	}
 
	serverFromClientSessions.clear();
 

	
 
	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) {
 

	
 
	boost::shared_ptr<ServerFromClientSession> serverFromClientSession = boost::shared_ptr<ServerFromClientSession>(
 
			new ServerFromClientSession(idGenerator.generateID(), connection, 
 
					getPayloadParserFactories(), getPayloadSerializers(), userRegistry_, parserFactory_));
 
	//serverFromClientSession->setAllowSASLEXTERNAL();
 

	
 
	serverFromClientSession->onSessionStarted.connect(
 
			boost::bind(&Server::handleSessionStarted, this, serverFromClientSession));
 
	serverFromClientSession->onSessionFinished.connect(
 
			boost::bind(&Server::handleSessionFinished, this, 
 
			serverFromClientSession));
 
	serverFromClientSession->onDataRead.connect(boost::bind(&Server::handleDataRead, this, _1));
 
	serverFromClientSession->onDataWritten.connect(boost::bind(&Server::handleDataWritten, this, _1));
 

	
 
	if (tlsFactory) {
 
		serverFromClientSession->addTLSEncryption(tlsFactory, cert);
 
	}
 

	
 
	serverFromClientSession->startSession();
 

	
 
	serverFromClientSessions.push_back(serverFromClientSession);
 
}
 

	
 
void Server::handleDataRead(const SafeByteArray& data) {
 
	onDataRead(data);
 
}
 

	
 
void Server::handleDataWritten(const SafeByteArray& data) {
 
	onDataWritten(data);
 
}
 

	
 
void Server::handleSessionStarted(boost::shared_ptr<ServerFromClientSession> session) {
 
	dynamic_cast<ServerStanzaChannel *>(stanzaChannel_)->addSession(session);
 
}
 

	
 
void Server::handleSessionFinished(boost::shared_ptr<ServerFromClientSession> session) {
 
// 	if (!session->getRemoteJID().isValid()) {
 
// 		Swift::Presence::ref presence = Swift::Presence::create();
 
// 		presence->setFrom(session->getBareJID());
 
// 		presence->setType(Swift::Presence::Unavailable);
 
// 		dynamic_cast<ServerStanzaChannel *>(stanzaChannel_)->onPresenceReceived(presence);
 
// 	}
 
	serverFromClientSessions.erase(std::remove(serverFromClientSessions.begin(), serverFromClientSessions.end(), session), serverFromClientSessions.end());
 
	session->onSessionStarted.disconnect(
 
			boost::bind(&Server::handleSessionStarted, this, session));
 
	session->onSessionFinished.disconnect(
 
			boost::bind(&Server::handleSessionFinished, this, session));
 
}
 

	
 
void Server::addTLSEncryption(TLSServerContextFactory* tlsContextFactory, CertificateWithKey::ref cert) {
 
	tlsFactory = tlsContextFactory;
 
	this->cert = cert;
 
}
 

	
 
}
include/Swiften/Server/Server.h
Show inline comments
 
/*
 
 * Copyright (c) 2010 Remko Tronçon
 
 * Licensed under the GNU General Public License v3.
 
 * See Documentation/Licenses/GPLv3.txt for more information.
 
 */
 

	
 
#pragma once
 

	
 
#include <boost/shared_ptr.hpp>
 
#include <boost/optional.hpp>
 
#include <vector>
 

	
 
#include "Swiften/Network/BoostIOServiceThread.h"
 
#include "Swiften/Network/ConnectionServer.h"
 
#include "Swiften/Server/UserRegistry.h"
 
#include "Swiften/Server/ServerSession.h"
 
#include "Swiften/Base/IDGenerator.h"
 
#include "Swiften/Server/ServerFromClientSession.h"
 
#include "Swiften/JID/JID.h"
 
#include "Swiften/Base/ByteArray.h"
 
#include "Swiften/Entity/Entity.h"
 
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
 
#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"
 
#include <Swiften/TLS/CertificateWithKey.h>
 
#include <Swiften/Parser/PlatformXMLParserFactory.h>
 

	
 
namespace Swift {
 
	class ConnectionServer;
 
	class SessionTracer;
 
	class EventLoop;
 
	class NetworkFactories;
 
	class StanzaChannel;
 
	class IQRouter;
 
	class TLSServerContextFactory;
 

	
 
	class Server : public Entity {
 
		public:
 
			Server(EventLoop* eventLoop, NetworkFactories* networkFactories, UserRegistry *userRegistry, const JID& jid, int port);
 
			Server(EventLoop* eventLoop, NetworkFactories* networkFactories, UserRegistry *userRegistry, const JID& jid, const std::string &address, int port);
 
			~Server();
 

	
 
			void start();
 
			void stop();
 

	
 
			int getPort() const {
 
				return port_;
 
			}
 

	
 
			StanzaChannel* getStanzaChannel() const {
 
				return stanzaChannel_;
 
			}
 

	
 
			IQRouter* getIQRouter() const {
 
				return iqRouter_;
 
			}
 

	
 
			boost::shared_ptr<ConnectionServer> getConnectionServer() const {
 
				return serverFromClientConnectionServer;
 
			}
 

	
 
			boost::signal<void (const SafeByteArray&)> onDataRead;
 
			boost::signal<void (const SafeByteArray&)> onDataWritten;
 

	
 
			void addTLSEncryption(TLSServerContextFactory* tlsContextFactory, CertificateWithKey::ref cert);
 

	
 
		private:
 
			void handleNewClientConnection(boost::shared_ptr<Connection> c);
 
			void handleSessionStarted(boost::shared_ptr<ServerFromClientSession>);
 
			void handleSessionFinished(boost::shared_ptr<ServerFromClientSession>);
 
			void handleElementReceived(boost::shared_ptr<Element> element, boost::shared_ptr<ServerFromClientSession> session);
 
			void handleDataRead(const SafeByteArray&);
 
			void handleDataWritten(const SafeByteArray&);
 

	
 
		private:
 
			IDGenerator idGenerator;
 
			UserRegistry *userRegistry_;
 
			int port_;
 
			EventLoop* eventLoop;
 
			NetworkFactories* networkFactories_;
 
			bool stopping;
 
			boost::shared_ptr<ConnectionServer> serverFromClientConnectionServer;
 
			std::vector<boost::bsignals::connection> serverFromClientConnectionServerSignalConnections;
 
			std::list<boost::shared_ptr<ServerFromClientSession> > serverFromClientSessions;
 
			JID selfJID;
 
			StanzaChannel *stanzaChannel_;
 
			IQRouter *iqRouter_;
 
			TLSServerContextFactory *tlsFactory;
 
			CertificateWithKey::ref cert;
 
			PlatformXMLParserFactory *parserFactory_;
 
			std::string address_;
 
	};
 
}
spectrum/src/sample2.cfg
Show inline comments
 
[service]
 
# 1 if Spectrum should run in server mode.
 
server_mode = 1
 

	
 
# The name of user/group Spectrum runs as.
 
#user=spectrum
 
#group=spectrum
 

	
 
# JID of Spectrum instance.
 
jid = localhost
 

	
 
# Password used to connect the XMPP server in gateway mode.
 
# In server mode, this option is ignored.
 
password = secret
 

	
 
# XMPP server to which Spectrum connects in gateway mode.
 
# In server mode, this option is ignored.
 
# To bind to all ipv4 interfaces, use server=0.0.0.0
 
server = 127.0.0.1
 

	
 
# XMPP server port.
 
port = 5222
 

	
 
# Interface on which Spectrum listens for backends.
 
backend_host = localhost
 

	
 
# Port on which Spectrum listens for backends.
 
# By default Spectrum chooses random backend port and there's
 
# no need to change it normally
 
#backend_port=10001
 

	
 
# Full path to PKCS#12 cetficiate used for TLS in server mode.
 
#cert=
 

	
 
# Certificate password if any.
 
#cert_password= 
 

	
 
# Number of users per one legacy network backend.
 
users_per_backend=10
 

	
 
# Full path to backend binary.
 
backend=/usr/bin/spectrum2_libpurple_backend
 
#backend=/usr/bin/spectrum2_libcommuni_backend
 
# For skype:
 
#backend=/usr/bin/xvfb-run -a -s "-screen 0 10x10x8" -f /tmp/x-skype-gw /usr/bin/spectrum2_skype_backend
 

	
 
# Libpurple protocol-id for spectrum_libpurple_backend
 
protocol=prpl-jabber
 
#protocol=prpl-msn
 
#protocol=prpl-icq
 

	
 
# prpl-any means that user sets his protocol in his JID which has to be
 
# in following format: protocol.username@domain.tld
 
# So for example: prpl-jabber.hanzz.k%gmail.com@domain.tld
 
#protocol=prpl-any
 

	
 
[identity]
 
# Name of Spectrum instance in service discovery
 
name=Spectrum Jabber Transport
 

	
 
# Type of transport ("msn", "icq", "xmpp").
 
# Check http://xmpp.org/registrar/disco-categories.html#gateway
 
type=xmpp
 

	
 
# Category of transport, default is "gateway
 
#category=gateway
 

	
 
[logging]
 
# log4cxx/log4j logging configuration file in ini format used for main spectrum2 instance.
 
config = /etc/spectrum2/logging.cfg
 

	
 
# log4cxx/log4j logging configuration file in ini format used for backends.
 
backend_config = /etc/spectrum2/backend-logging.cfg
 

	
 
[database]
 
# Database backend type
 
# "sqlite3", "mysql", "pqxx", or "none" without database backend
 
type = none
 

	
 
# For SQLite3: Full path to database
 
# For MySQL and PostgreSQL: name of database
 
# default database = /var/lib/spectrum2/$jid/database.sql
 
#database = jabber_transport
 

	
 
# Server.
 
#server = localhost
 

	
 
# Port.
 
#port = 0
 

	
 
# User.
 
#user = spectrum
 

	
 
# Paasword.
 
#password = secret
 

	
 
# Prefix used for tables
 
#prefix = jabber_
 

	
 
# Connection string (for pqxx only!)
 
# If you set this, it ignores every other database option except for type and prefix.
 
#connectionstring = host=localhost user=specturm password=secret
 

	
 
[registration]
 
# Enable public registrations
 
enable_public_registration=1
 

	
 
# Text to display upon user registration form
 
#username_label=Jabber JID (e.g. user@server.tld):
 
#instructions=Enter your remote jabber JID and password as well as your local username and password
 

	
 
# If True a local jabber account on <local_account_server> is needed 
 
# for transport registration, the idea is to enable public registration
 
# from other servers, but only for users, who have already local accounts
src/tests/userregistry.cpp
Show inline comments
 
#include "transport/userregistry.h"
 
#include "transport/config.h"
 
#include <cppunit/TestFixture.h>
 
#include <cppunit/extensions/HelperMacros.h>
 
#include <Swiften/EventLoop/DummyEventLoop.h>
 
#include <Swiften/Server/Server.h>
 
#include <Swiften/Network/DummyNetworkFactories.h>
 
#include <Swiften/Network/DummyConnectionServer.h>
 
#include <Swiften/Network/ConnectionFactory.h>
 
#include <Swiften/Network/DummyTimerFactory.h>
 

	
 
using namespace Transport;
 

	
 
class UserRegistryTest : public CPPUNIT_NS :: TestFixture {
 
	CPPUNIT_TEST_SUITE(UserRegistryTest);
 
	CPPUNIT_TEST(login);
 
	CPPUNIT_TEST(loginInvalidPassword);
 
	CPPUNIT_TEST(loginTwoClientsValidPasswords);
 
	CPPUNIT_TEST(loginTwoClientsDifferentPasswords);
 
	CPPUNIT_TEST(loginDisconnect);
 
	CPPUNIT_TEST(removeLater);
 
	CPPUNIT_TEST_SUITE_END();
 

	
 
	public:
 
		void setUp (void) {
 
			state1 = Init;
 
			state2 = Init;
 
			std::istringstream ifs;
 
			cfg = new Config();
 
			cfg->load(ifs);
 

	
 
			loop = new Swift::DummyEventLoop();
 
			factories = new Swift::DummyNetworkFactories(loop);
 

	
 
			userRegistry = new UserRegistry(cfg, factories);
 
			userRegistry->onConnectUser.connect(bind(&UserRegistryTest::handleConnectUser, this, _1));
 
			userRegistry->onDisconnectUser.connect(bind(&UserRegistryTest::handleDisconnectUser, this, _1));
 

	
 
			server = new Swift::Server(loop, factories, userRegistry, "localhost", 5222);
 
			server = new Swift::Server(loop, factories, userRegistry, "localhost", "0.0.0.0", 5222);
 
			server->start();
 
			connectionServer = server->getConnectionServer();
 

	
 
			client1 = factories->getConnectionFactory()->createConnection();
 
			dynamic_cast<Swift::DummyConnectionServer *>(connectionServer.get())->acceptConnection(client1);
 

	
 
			dynamic_cast<Swift::DummyConnection *>(client1.get())->onDataSent.connect(boost::bind(&UserRegistryTest::handleDataReceived, this, _1, client1));
 

	
 
			client2 = factories->getConnectionFactory()->createConnection();
 
			dynamic_cast<Swift::DummyConnectionServer *>(connectionServer.get())->acceptConnection(client2);
 

	
 
			dynamic_cast<Swift::DummyConnection *>(client2.get())->onDataSent.connect(boost::bind(&UserRegistryTest::handleDataReceived, this, _1, client2));
 

	
 
			loop->processEvents();
 
		}
 

	
 
		void tearDown (void) {
 
			delete server;
 
			dynamic_cast<Swift::DummyConnection *>(client1.get())->onDataSent.disconnect(boost::bind(&UserRegistryTest::handleDataReceived, this, _1, client1));
 
			client1.reset();
 
			dynamic_cast<Swift::DummyConnection *>(client2.get())->onDataSent.disconnect(boost::bind(&UserRegistryTest::handleDataReceived, this, _1, client2));
 
			client2.reset();
 
			connectionServer.reset();
 
			delete userRegistry;
 
			delete factories;
 
			delete loop;
 
			delete cfg;
 
			received1.clear();
 
			received2.clear();
 
		}
 

	
 
		void send(boost::shared_ptr<Swift::Connection> conn, const std::string &data) {
 
			dynamic_cast<Swift::DummyConnection *>(conn.get())->receive(Swift::createSafeByteArray(data));
 
			loop->processEvents();
 
		}
 

	
 
		void sendCredentials(boost::shared_ptr<Swift::Connection> conn, const std::string &username, const std::string &password, const std::string &b64) {
 
			std::vector<std::string> &received = conn == client1 ? received1 : received2;
 
			send(conn, "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
 
			CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 
			CPPUNIT_ASSERT(received[0].find("<?xml version=\"1.0\"?>") == 0);
 
			CPPUNIT_ASSERT(received[1].find("PLAIN") != std::string::npos);
 
			received.clear();
 

	
 
			// username:test
 
			send(conn, "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>" + b64 + "</auth>");
 
			if (conn == client1)
 
				CPPUNIT_ASSERT_EQUAL(Connecting, state1);
 
// 			else
 
// 				CPPUNIT_ASSERT_EQUAL(Connecting, state2);
 
			CPPUNIT_ASSERT_EQUAL(password, userRegistry->getUserPassword(username));
 
			CPPUNIT_ASSERT_EQUAL(std::string(""), userRegistry->getUserPassword("unknown@localhost"));
 
		}
 

	
 
		void bindSession(boost::shared_ptr<Swift::Connection> conn) {
 
			std::vector<std::string> &received = conn == client1 ? received1 : received2;
 

	
 
			send(conn, "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
 
			CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 
			CPPUNIT_ASSERT(received[0].find("<?xml version=\"1.0\"?>") == 0);
 
			CPPUNIT_ASSERT(received[1].find("urn:ietf:params:xml:ns:xmpp-bind") != std::string::npos);
 
			CPPUNIT_ASSERT(received[1].find("urn:ietf:params:xml:ns:xmpp-session") != std::string::npos);
 
			
 
		}
 

	
 
		void handleDataReceived(const Swift::SafeByteArray &data, boost::shared_ptr<Swift::Connection> conn) {
 
			if (conn == client1) {
 
				received1.push_back(safeByteArrayToString(data));
 
// 				std::cout << received1.back() << "\n";
 
			}
 
			else {
 
				received2.push_back(safeByteArrayToString(data));
 
// 				std::cout << received2.back() << "\n";
 
			}
 
		}
 

	
 
		void handleConnectUser(const Swift::JID &user) {
 
			state1 = Connecting;
 
		}
 

	
 
		void handleDisconnectUser(const Swift::JID &user) {
 
			state1 = Disconnected;
 
		}
 

	
 
		void login() {
 
			sendCredentials(client1, "username@localhost", "test", "AHVzZXJuYW1lAHRlc3Q=");
 

	
 
			userRegistry->onPasswordValid("username@localhost");
 
			loop->processEvents();
 
			CPPUNIT_ASSERT_EQUAL(std::string(""), userRegistry->getUserPassword("username@localhost"));
 
			CPPUNIT_ASSERT_EQUAL(1, (int) received1.size());
 
			CPPUNIT_ASSERT_EQUAL(std::string("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"></success>"), received1[0]);
 
			received1.clear();
 

	
 
			bindSession(client1);
 
			
src/transport.cpp
Show inline comments
 
/**
 
 * libtransport -- C++ library for easy XMPP Transports development
 
 *
 
 * Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
 
 *
 
 * This program is free software; you can redistribute it and/or modify
 
 * it under the terms of the GNU General Public License as published by
 
 * the Free Software Foundation; either version 2 of the License, or
 
 * (at your option) any later version.
 
 *
 
 * This program is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
 
 */
 

	
 
#include "transport/transport.h"
 
#include <boost/bind.hpp>
 
#include <boost/smart_ptr/make_shared.hpp>
 
#include <boost/algorithm/string/predicate.hpp>
 
#include "transport/storagebackend.h"
 
#include "transport/factory.h"
 
#include "transport/userregistry.h"
 
#include "transport/logging.h"
 
#include "storageparser.h"
 
#ifdef _WIN32
 
#include <Swiften/TLS/CAPICertificate.h>
 
#include "Swiften/TLS/Schannel/SchannelServerContext.h"
 
#include "Swiften/TLS/Schannel/SchannelServerContextFactory.h"
 
#else
 
#include "Swiften/TLS/PKCS12Certificate.h"
 
#include "Swiften/TLS/CertificateWithKey.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLServerContext.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLServerContextFactory.h"
 
#endif
 
#include "Swiften/Parser/PayloadParsers/AttentionParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/GatewayPayloadParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h"
 
#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/MUCPayloadParser.h"
 
#include "transport/BlockParser.h"
 
#include "transport/BlockSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/InvisibleParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h"
 
#include "Swiften/Parser/GenericPayloadParserFactory.h"
 

	
 
using namespace Swift;
 
using namespace boost;
 

	
 
namespace Transport {
 
	
 
DEFINE_LOGGER(logger, "Component");
 
DEFINE_LOGGER(logger_xml, "Component.XML");
 

	
 
Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Factory *factory, Transport::UserRegistry *userRegistry) {
 
	m_component = NULL;
 
	m_userRegistry = NULL;
 
	m_server = NULL;
 
	m_reconnectCount = 0;
 
	m_config = config;
 
	m_factory = factory;
 
	m_loop = loop;
 
	m_userRegistry = userRegistry;
 

	
 
	m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));
 

	
 
	m_factories = factories;
 

	
 
	m_reconnectTimer = m_factories->getTimerFactory()->createTimer(3000);
 
	m_reconnectTimer->onTick.connect(bind(&Component::start, this)); 
 

	
 
	if (CONFIG_BOOL(m_config, "service.server_mode")) {
 
		LOG4CXX_INFO(logger, "Creating component in server mode on port " << CONFIG_INT(m_config, "service.port"));
 
		m_server = new Swift::Server(loop, m_factories, m_userRegistry, m_jid, CONFIG_INT(m_config, "service.port"));
 
		m_server = new Swift::Server(loop, m_factories, m_userRegistry, m_jid, CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
 
		if (!CONFIG_STRING(m_config, "service.cert").empty()) {
 
#ifndef _WIN32
 
//TODO: fix
 
			LOG4CXX_INFO(logger, "Using PKCS#12 certificate " << CONFIG_STRING(m_config, "service.cert"));
 
			LOG4CXX_INFO(logger, "SSLv23_server_method used.");
 
			TLSServerContextFactory *f = new OpenSSLServerContextFactory();
 
			CertificateWithKey::ref certificate = boost::make_shared<PKCS12Certificate>(CONFIG_STRING(m_config, "service.cert"), createSafeByteArray(CONFIG_STRING(m_config, "service.cert_password")));
 
			m_server->addTLSEncryption(f, certificate);
 
#endif
 
			
 
		}
 
		else {
 
			LOG4CXX_WARN(logger, "No PKCS#12 certificate used. TLS is disabled.");
 
		}
 
// 		m_server->start();
 
		m_stanzaChannel = m_server->getStanzaChannel();
 
		m_iqRouter = m_server->getIQRouter();
 

	
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
 

	
 
		m_server->addPayloadSerializer(new Swift::AttentionSerializer());
 
		m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer());
 
		m_server->addPayloadSerializer(new Transport::BlockSerializer());
 
		m_server->addPayloadSerializer(new Swift::InvisibleSerializer());
 
		m_server->addPayloadSerializer(new Swift::StatsSerializer());
 
		m_server->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
 
		m_server->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
 

	
 
		m_server->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
 
		m_server->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
 
	}
 
	else {
 
		LOG4CXX_INFO(logger, "Creating component in gateway mode");
 
		m_component = new Swift::Component(loop, m_factories, m_jid, CONFIG_STRING(m_config, "service.password"));
 
		m_component->setSoftwareVersion("Spectrum", SPECTRUM_VERSION);
 
		m_component->onConnected.connect(bind(&Component::handleConnected, this));
 
		m_component->onError.connect(boost::bind(&Component::handleConnectionError, this, _1));
 
		m_component->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
 
		m_component->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
 

	
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
 

	
 
		m_component->addPayloadSerializer(new Swift::AttentionSerializer());
 
		m_component->addPayloadSerializer(new Swift::XHTMLIMSerializer());
 
		m_component->addPayloadSerializer(new Transport::BlockSerializer());
 
		m_component->addPayloadSerializer(new Swift::InvisibleSerializer());
 
		m_component->addPayloadSerializer(new Swift::StatsSerializer());
 
		m_component->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
 
		m_component->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
 

	
 
		m_stanzaChannel = m_component->getStanzaChannel();
 
		m_iqRouter = m_component->getIQRouter();
 
	}
 

	
 
	m_capsMemoryStorage = new CapsMemoryStorage();
 
	m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter);
 
	m_entityCapsManager = new EntityCapsManager(m_capsManager, m_stanzaChannel);
 
 	m_entityCapsManager->onCapsChanged.connect(boost::bind(&Component::handleCapsChanged, this, _1));
 
	
 
	m_presenceOracle = new Transport::PresenceOracle(m_stanzaChannel);
 
	m_presenceOracle->onPresenceChange.connect(bind(&Component::handlePresence, this, _1));
 

	
 

	
 

	
 
// 
 
// 	m_registerHandler = new SpectrumRegisterHandler(m_component);
 
// 	m_registerHandler->start();
 
}
 

	
 
Component::~Component() {
 
	delete m_presenceOracle;
 
	delete m_entityCapsManager;
 
	delete m_capsManager;
 
	delete m_capsMemoryStorage;
 
	if (m_component)
 
		delete m_component;
 
	if (m_server) {
 
		m_server->stop();
 
		delete m_server;
 
	}
 
}
 

	
0 comments (0 inline, 0 general)