Changeset - 808a9067c5f5
[Not reviewed]
0 10 0
HanzZ - 14 years ago 2011-07-17 23:05:54
hanzz.k@gmail.com
Improved backends creation, fixed race-condition during connection process
10 files changed with 102 insertions and 11 deletions:
0 comments (0 inline, 0 general)
include/Swiften/Server/Server.cpp
Show inline comments
 
@@ -100,27 +100,24 @@ void Server::stop() {
 
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_));
 
	//serverFromClientSession->setAllowSASLEXTERNAL();
 

	
 
	serverFromClientSession->onSessionStarted.connect(
 
			boost::bind(&Server::handleSessionStarted, this, serverFromClientSession));
 
	serverFromClientSession->onSessionFinished.connect(
 
			boost::bind(&Server::handleSessionFinished, this, 
 
			serverFromClientSession));
 
	serverFromClientSession->onPasswordInvalid.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);
 
}
 

	
 
@@ -128,21 +125,31 @@ 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, const PKCS12Certificate& cert) {
 
	tlsFactory = tlsContextFactory;
 
	this->cert = cert;
 
}
 

	
 
}
include/Swiften/Server/ServerFromClientSession.cpp
Show inline comments
 
@@ -38,44 +38,48 @@ ServerFromClientSession::ServerFromClientSession(
 
			id_(id),
 
			userRegistry_(userRegistry),
 
			authenticated_(false),
 
			initialized(false),
 
			allowSASLEXTERNAL(false),
 
			tlsLayer(0),
 
			tlsConnected(false) {
 
	userRegistry->onPasswordValid.connect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
 
	userRegistry->onPasswordInvalid.connect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
 
}
 

	
 
ServerFromClientSession::~ServerFromClientSession() {
 
	std::cout << "DESTRUCTOR;\n";
 
	if (tlsLayer) {
 
		delete tlsLayer;
 
	}
 
}
 

	
 
void ServerFromClientSession::handlePasswordValid(const std::string &user) {
 
	if (user != JID(user_, getLocalJID().getDomain()).toString())
 
		return;
 
	if (!isInitialized()) {
 
		userRegistry_->onPasswordValid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
 
		userRegistry_->onPasswordInvalid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
 
		getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
 
		authenticated_ = true;
 
		getXMPPLayer()->resetParser();
 
	}
 
}
 

	
 
void ServerFromClientSession::handlePasswordInvalid(const std::string &user) {
 
	if (user != JID(user_, getLocalJID().getDomain()).toString() || authenticated_)
 
		return;
 
	if (!isInitialized()) {
 
		user_ = "/././";
 
		userRegistry_->onPasswordValid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
 
		userRegistry_->onPasswordInvalid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
 
		getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
 
		finishSession(AuthenticationFailedError);
 
		onPasswordInvalid();
 
	}
 
}
 

	
 
void ServerFromClientSession::handleElement(boost::shared_ptr<Element> element) {
 
	if (isInitialized()) {
 
		onElementReceived(element);
 
	}
 
	else {
 
		if (AuthRequest* authRequest = dynamic_cast<AuthRequest*>(element.get())) {
include/Swiften/Server/ServerFromClientSession.h
Show inline comments
 
@@ -41,24 +41,28 @@ namespace Swift {
 
					UserRegistry* userRegistry);
 
			~ServerFromClientSession();
 

	
 
			boost::signal<void ()> onSessionStarted;
 
			boost::signal<void ()> onPasswordInvalid;
 
			void setAllowSASLEXTERNAL();
 
			const std::string &getUser() {
 
				return user_;
 
			}
 

	
 
			void addTLSEncryption(TLSServerContextFactory* tlsContextFactory, const PKCS12Certificate& cert);
 

	
 
			Swift::JID getBareJID() {
 
				return Swift::JID(user_, getLocalJID().getDomain());
 
			}
 

	
 
		private:
 
			void handleElement(boost::shared_ptr<Element>);
 
			void handleStreamStart(const ProtocolHeader& header);
 
			void handlePasswordValid(const std::string &user);
 
			void handlePasswordInvalid(const std::string &user);
 

	
 
			void setInitialized();
 
			bool isInitialized() const { 
 
				return initialized; 
 
			}
 

	
 
			void handleTLSError() { }
include/Swiften/Server/UserRegistry.h
Show inline comments
 
@@ -10,17 +10,19 @@
 
#include <Swiften/Base/SafeByteArray.h>
 
#include <boost/signal.hpp>
 

	
 
namespace Swift {
 
	class JID;
 

	
 
	class UserRegistry {
 
		public:
 
			virtual ~UserRegistry();
 

	
 
			virtual bool isValidUserPassword(const JID& user, const SafeByteArray& password) = 0;
 

	
 
			virtual void stopLogin(const JID &/*user*/) {};
 

	
 
			boost::signal<void (const std::string &user)> onPasswordValid;
 
			boost::signal<void (const std::string &user)> onPasswordInvalid;
 

	
 
	};
 
}
include/transport/networkpluginserver.h
Show inline comments
 
@@ -98,15 +98,16 @@ class NetworkPluginServer {
 
		void pingTimeout();
 
		void sendPing(Backend *c);
 
		Backend *getFreeClient();
 

	
 
		UserManager *m_userManager;
 
		VCardResponder *m_vcardResponder;
 
		RosterResponder *m_rosterResponder;
 
		Config *m_config;
 
		boost::shared_ptr<Swift::BoostConnectionServer> m_server;
 
		std::list<Backend *>  m_clients;
 
		Swift::Timer::ref m_pingTimer;
 
		Component *m_component;
 
		std::list<User *> m_waitingUsers;
 
};
 

	
 
}
include/transport/user.h
Show inline comments
 
@@ -72,24 +72,36 @@ class User {
 
		/// Handles presence from XMPP JID associated with this user.
 
		/// \param presence Swift::Presence.
 
		void handlePresence(Swift::Presence::ref presence);
 

	
 
		void handleSubscription(Swift::Presence::ref presence);
 

	
 
		/// Returns language.
 
		/// \return language
 
		const char *getLang() { return "en"; }
 

	
 
		void handleDisconnected(const std::string &error);
 

	
 
		bool isReadyToConnect() {
 
			return m_readyForConnect;
 
		}
 

	
 
		void setConnected(bool connected) {
 
			m_connected = connected;
 
		}
 

	
 
		bool isConnected() {
 
			return m_connected;
 
		}
 

	
 
		boost::signal<void ()> onReadyToConnect;
 
		boost::signal<void (Swift::Presence::ref presence)> onPresenceChanged;
 
		boost::signal<void (const std::string &room, const std::string &nickname, const std::string &password)> onRoomJoined;
 
		boost::signal<void (const std::string &room)> onRoomLeft;
 
		boost::signal<void ()> onDisconnected;
 

	
 
	private:
 
		void onConnectingTimeout();
 

	
 
		Swift::JID m_jid;
 
		Component *m_component;
 
		RosterManager *m_rosterManager;
spectrum/src/sample.cfg
Show inline comments
 
[service]
 
jid = localhost
 
password = secret
 
server = 127.0.0.1
 
port = 5222
 
server_mode = 1
 
backend_host=localhost # < this option doesn't work yet
 
backend_port=10001
 
admin_username=admin
 
admin_password=test
 
#cert= #patch to PKCS#12 certificate
 
#cert_password= #password to that certificate if any
 
users_per_backend=2
 
users_per_backend=1
 
backend=../../backends/libpurple/spectrum_libpurple_backend
 
#backend=../../backends/libircclient-qt/spectrum_libircclient-qt_backend
 
#protocol=prpl-jabber
 
protocol=prpl-msn
 
#protocol=prpl-icq
 

	
 
[logging]
 
#config=logging.cfg # log4cxx/log4j logging configuration file
 
#backend_config=backend_logging.cfg # log4cxx/log4j logging configuration file for backends
 

	
 
[database]
 
type = sqlite3 # or "none" without database backend
spectrum/src/sample2.cfg
Show inline comments
 
[service]
 
jid = localhost
 
password = secret
 
server = 127.0.0.1
 
port = 5222
 
server_mode = 1
 
backend_host=localhost # < this option doesn't work yet
 
backend_port=10001
 
#cert= #patch to PKCS#12 certificate
 
#cert_password= #password to that certificate if any
 
users_per_backend=2
 
users_per_backend=1
 
backend=spectrum_libpurple_backend
 
#backend=spectrum_libircclient-qt_backend
 
protocol=prpl-jabber
 
#protocol=prpl-msn
 
#protocol=prpl-icq
 

	
 
[logging]
 
#config=logging.cfg # log4cxx/log4j logging configuration file
 
#backend_config=backend_logging.cfg # log4cxx/log4j logging configuration file for backends
 

	
 
[database]
 
type = none # "sqlite3" or "none" without database backend
src/networkpluginserver.cpp
Show inline comments
 
@@ -180,24 +180,46 @@ void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Con
 
	LOG4CXX_INFO(logger, "New backend " << client << " connected. Current backend count=" << (m_clients.size() + 1));
 

	
 
	if (m_clients.size() == 0) {
 
		// first backend connected, start the server, we're ready.
 
		m_component->start();
 
	}
 

	
 
	m_clients.push_back(client);
 

	
 
	c->onDisconnected.connect(boost::bind(&NetworkPluginServer::handleSessionFinished, this, client));
 
	c->onDataRead.connect(boost::bind(&NetworkPluginServer::handleDataRead, this, client, _1));
 
	sendPing(client);
 

	
 
	// some users are in queue waiting for this backend
 
	while(!m_waitingUsers.empty()) {
 
		// There's no new backend, so stop associating users and wait for new backend,
 
		// which has been already spawned in getFreeClient() call.
 
		if (getFreeClient() == NULL)
 
			break;
 

	
 
		User *u = m_waitingUsers.front();
 
		m_waitingUsers.pop_front();
 

	
 
		LOG4CXX_INFO(logger, "Associating " << u->getJID().toString() << " with this backend");
 

	
 
		// associate backend with user
 
		handleUserCreated(u);
 

	
 
		// connect user if it's ready
 
		if (u->isReadyToConnect()) {
 
			handleUserReadyToConnect(u);
 
		}
 

	
 
	}
 
}
 

	
 
void NetworkPluginServer::handleSessionFinished(Backend *c) {
 
	LOG4CXX_INFO(logger, "Backend " << c << " disconnected. Current backend count=" << (m_clients.size() - 1));
 
	for (std::list<User *>::const_iterator it = c->users.begin(); it != c->users.end(); it++) {
 
		LOG4CXX_ERROR(logger, "Backend " << c << " disconnected (probably crashed) with active user " << (*it)->getJID().toString());
 
		(*it)->setData(NULL);
 
		(*it)->handleDisconnected("Internal Server Error, please reconnect.");
 
	}
 

	
 
	m_clients.remove(c);
 
	delete c;
 
@@ -208,24 +230,31 @@ void NetworkPluginServer::handleSessionFinished(Backend *c) {
 
			return;
 
		}
 
	}
 
	exec_(CONFIG_STRING(m_config, "service.backend").c_str(), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getConfigFile().c_str());
 
}
 

	
 
void NetworkPluginServer::handleConnectedPayload(const std::string &data) {
 
	pbnetwork::Connected payload;
 
	if (payload.ParseFromString(data) == false) {
 
		// TODO: ERROR
 
		return;
 
	}
 

	
 
	User *user = m_userManager->getUser(payload.user());
 
	if (!user) {
 
		return;
 
	}
 

	
 
	user->setConnected(true);
 
	m_component->m_userRegistry->onPasswordValid(payload.user());
 
}
 

	
 
void NetworkPluginServer::handleDisconnectedPayload(const std::string &data) {
 
	pbnetwork::Disconnected payload;
 
	if (payload.ParseFromString(data) == false) {
 
		// TODO: ERROR
 
		return;
 
	}
 

	
 
	m_component->m_userRegistry->onPasswordInvalid(payload.user());
 

	
 
@@ -515,26 +544,26 @@ void NetworkPluginServer::pingTimeout() {
 
		}
 
		else {
 
			exec_(CONFIG_STRING(m_config, "service.backend").c_str(), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getConfigFile().c_str());
 
		}
 
	}
 
	m_pingTimer->start();
 
}
 

	
 
void NetworkPluginServer::handleUserCreated(User *user) {
 
	Backend *c = getFreeClient();
 

	
 
	if (!c) {
 
		LOG4CXX_ERROR(logger, "There is no backend to handle user " << user->getJID().toString());
 
		user->handleDisconnected("Internal Server Error (no free backend to handle your session), please reconnect.");
 
		LOG4CXX_INFO(logger, "There is no backend to handle user " << user->getJID().toString() << ". Adding him to queue.");
 
		m_waitingUsers.push_back(user);
 
		return;
 
	}
 
	user->setData(c);
 
	c->users.push_back(user);
 

	
 
// 	UserInfo userInfo = user->getUserInfo();
 
	user->onReadyToConnect.connect(boost::bind(&NetworkPluginServer::handleUserReadyToConnect, this, user));
 
	user->onPresenceChanged.connect(boost::bind(&NetworkPluginServer::handleUserPresenceChanged, this, user, _1));
 
	user->onRoomJoined.connect(boost::bind(&NetworkPluginServer::handleRoomJoined, this, user, _1, _2, _3));
 
	user->onRoomLeft.connect(boost::bind(&NetworkPluginServer::handleRoomLeft, this, user, _1));
 
}
 

	
 
@@ -543,98 +572,111 @@ void NetworkPluginServer::handleUserReadyToConnect(User *user) {
 

	
 
	pbnetwork::Login login;
 
	login.set_user(user->getJID().toBare());
 
	login.set_legacyname(userInfo.uin);
 
	login.set_password(userInfo.password);
 

	
 
	std::string message;
 
	login.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGIN);
 

	
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 
}
 

	
 
void NetworkPluginServer::handleUserPresenceChanged(User *user, Swift::Presence::ref presence) {
 
	if (presence->getShow() == Swift::StatusShow::None)
 
		return;
 

	
 
	UserInfo userInfo = user->getUserInfo();
 

	
 
	pbnetwork::Status status;
 
	status.set_username(user->getJID().toBare());
 
	status.set_status((int) presence->getShow());
 
	status.set_statusmessage(presence->getStatus());
 

	
 
	std::string message;
 
	status.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_STATUS_CHANGED);
 

	
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 
}
 

	
 
void NetworkPluginServer::handleRoomJoined(User *user, const std::string &r, const std::string &nickname, const std::string &password) {
 
	UserInfo userInfo = user->getUserInfo();
 

	
 
	pbnetwork::Room room;
 
	room.set_username(user->getJID().toBare());
 
	room.set_nickname(nickname);
 
	room.set_room(r);
 
	room.set_password(password);
 

	
 
	std::string message;
 
	room.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_JOIN_ROOM);
 
 
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 

	
 
	NetworkConversation *conv = new NetworkConversation(user->getConversationManager(), r, true);
 
	conv->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, this, _1, _2));
 
	conv->setNickname(nickname);
 
}
 

	
 
void NetworkPluginServer::handleRoomLeft(User *user, const std::string &r) {
 
	UserInfo userInfo = user->getUserInfo();
 

	
 
	pbnetwork::Room room;
 
	room.set_username(user->getJID().toBare());
 
	room.set_nickname("");
 
	room.set_room(r);
 
	room.set_password("");
 

	
 
	std::string message;
 
	room.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LEAVE_ROOM);
 
 
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 

	
 
	NetworkConversation *conv = (NetworkConversation *) user->getConversationManager()->getConversation(r);
 
	if (!conv) {
 
		return;
 
	}
 

	
 
	user->getConversationManager()->removeConversation(conv);
 

	
 
	delete conv;
 
}
 

	
 
void NetworkPluginServer::handleUserDestroyed(User *user) {
 
	std::cout << "HANDLE_DESTROYED\n";
 
	m_waitingUsers.remove(user);
 
	UserInfo userInfo = user->getUserInfo();
 

	
 
	pbnetwork::Logout logout;
 
	logout.set_user(user->getJID().toBare());
 
	logout.set_legacyname(userInfo.uin);
 

	
 
	std::string message;
 
	logout.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGOUT);
 
 
 
	Backend *c = (Backend *) user->getData();
 
@@ -671,24 +713,27 @@ void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost
 
		}
 
		if (type != pbnetwork::WrapperMessage_Type_TYPE_BUDDY_CHANGED) {
 
			pbnetwork::Buddy buddy;
 
			buddy.set_username(conv->getConversationManager()->getUser()->getJID().toBare());
 
			buddy.set_buddyname(conv->getLegacyName());
 

	
 
			std::string message;
 
			buddy.SerializeToString(&message);
 

	
 
			WRAP(message, type);
 

	
 
			Backend *c = (Backend *) conv->getConversationManager()->getUser()->getData();
 
			if (!c) {
 
				return;
 
			}
 
			send(c->connection, message);
 
		}
 
	}
 

	
 
	boost::shared_ptr<Swift::AttentionPayload> attentionPayload = msg->getPayload<Swift::AttentionPayload>();
 
	if (attentionPayload) {
 
		pbnetwork::ConversationMessage m;
 
		m.set_username(conv->getConversationManager()->getUser()->getJID().toBare());
 
		m.set_buddyname(conv->getLegacyName());
 
		m.set_message(msg->getBody());
 

	
 
		std::string message;
 
@@ -713,102 +758,117 @@ void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost
 
		pbnetwork::ConversationMessage m;
 
		m.set_username(conv->getConversationManager()->getUser()->getJID().toBare());
 
		m.set_buddyname(conv->getLegacyName());
 
		m.set_message(msg->getBody());
 
		m.set_xhtml(xhtml);
 

	
 
		std::string message;
 
		m.SerializeToString(&message);
 

	
 
		WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_CONV_MESSAGE);
 

	
 
		Backend *c = (Backend *) conv->getConversationManager()->getUser()->getData();
 
		if (!c) {
 
			return;
 
		}
 
		send(c->connection, message);
 
	}
 
}
 

	
 
void NetworkPluginServer::handleBuddyRemoved(Buddy *b) {
 
	User *user = b->getRosterManager()->getUser();
 

	
 
	pbnetwork::Buddy buddy;
 
	buddy.set_username(user->getJID().toBare());
 
	buddy.set_buddyname(b->getName());
 
	buddy.set_alias(b->getAlias());
 
	buddy.set_groups(b->getGroups().size() == 0 ? "" : b->getGroups()[0]);
 
	buddy.set_status(Swift::StatusShow::None);
 

	
 
	std::string message;
 
	buddy.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_REMOVED);
 

	
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 
}
 

	
 
void NetworkPluginServer::handleBuddyUpdated(Buddy *b, const Swift::RosterItemPayload &item) {
 
	User *user = b->getRosterManager()->getUser();
 

	
 
	dynamic_cast<LocalBuddy *>(b)->setAlias(item.getName());
 
	dynamic_cast<LocalBuddy *>(b)->setGroups(item.getGroups());
 
	user->getRosterManager()->storeBuddy(b);
 

	
 
	pbnetwork::Buddy buddy;
 
	buddy.set_username(user->getJID().toBare());
 
	buddy.set_buddyname(b->getName());
 
	buddy.set_alias(b->getAlias());
 
	buddy.set_groups(b->getGroups().size() == 0 ? "" : b->getGroups()[0]);
 
	buddy.set_status(Swift::StatusShow::None);
 

	
 
	std::string message;
 
	buddy.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_CHANGED);
 

	
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 
}
 

	
 
void NetworkPluginServer::handleBuddyAdded(Buddy *buddy, const Swift::RosterItemPayload &item) {
 
	handleBuddyUpdated(buddy, item);
 
}
 

	
 
void NetworkPluginServer::handleVCardUpdated(User *user, boost::shared_ptr<Swift::VCard> v) {
 
	pbnetwork::VCard vcard;
 
	vcard.set_username(user->getJID().toBare());
 
	vcard.set_buddyname("");
 
	vcard.set_id(0);
 
	vcard.set_photo(&v->getPhoto()[0], v->getPhoto().size());
 

	
 
	std::string message;
 
	vcard.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_VCARD);
 

	
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 
}
 

	
 
void NetworkPluginServer::handleVCardRequired(User *user, const std::string &name, unsigned int id) {
 
	pbnetwork::VCard vcard;
 
	vcard.set_username(user->getJID().toBare());
 
	vcard.set_buddyname(name);
 
	vcard.set_id(id);
 

	
 
	std::string message;
 
	vcard.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_VCARD);
 

	
 
	Backend *c = (Backend *) user->getData();
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 
}
 

	
 
void NetworkPluginServer::sendPing(Backend *c) {
 

	
 
	std::string message;
 
	pbnetwork::WrapperMessage wrap;
 
	wrap.set_type(pbnetwork::WrapperMessage_Type_TYPE_PING);
 
	wrap.SerializeToString(&message);
 

	
 
	send(c->connection, message);
 
	c->pongReceived = false;
 
@@ -829,20 +889,20 @@ NetworkPluginServer::Backend *NetworkPluginServer::getFreeClient() {
 
			if (c == NULL) {
 
				c = *it;
 
			}
 
			else {
 
				if ((*it)->users.size() + 1 != CONFIG_INT(m_config, "service.users_per_backend")) {
 
					spawnNew = false;
 
					break;
 
				}
 
			}
 
		}
 
	}
 

	
 
	if (spawnNew) {
 
	if (spawnNew || c == NULL) {
 
		exec_(CONFIG_STRING(m_config, "service.backend").c_str(), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getConfigFile().c_str());
 
	}
 

	
 
	return c;
 
}
 

	
 
}
src/user.cpp
Show inline comments
 
@@ -163,41 +163,42 @@ void User::handleSubscription(Swift::Presence::ref presence) {
 
	m_rosterManager->handleSubscription(presence);
 
}
 

	
 
void User::onConnectingTimeout() {
 
	if (m_connected || m_readyForConnect)
 
		return;
 
	m_reconnectTimer->stop();
 
	m_readyForConnect = true;
 
	onReadyToConnect();
 
}
 

	
 
void User::handleDisconnected(const std::string &error) {
 

	
 
	if (error.empty()) {
 
		LOG4CXX_INFO(logger, m_jid.toString() << ": Disconnected from legacy network");
 
	}
 
	else {
 
		LOG4CXX_INFO(logger, m_jid.toString() << ": Disconnected from legacy network with error " << error);
 
	}
 
	onDisconnected();
 

	
 
	boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
	msg->setBody(error);
 
	msg->setTo(m_jid.toBare());
 
	msg->setFrom(m_component->getJID());
 
	m_component->getStanzaChannel()->sendMessage(msg);
 

	
 
	// In server mode, server finishes the session and pass unavailable session to userManager,
 
	// In server mode, server finishes the session and pass unavailable session to userManager if we're connected to legacy network,
 
	// so we can't removeUser() in server mode, because it would be removed twice.
 
	// Once in finishSession and once in m_userManager->removeUser.
 
	if (m_component->inServerMode()) {
 
		dynamic_cast<Swift::ServerStanzaChannel *>(m_component->getStanzaChannel())->finishSession(m_jid, boost::shared_ptr<Swift::Element>(new Swift::StreamError()));
 
		if (!m_readyForConnect) {
 
		if (!m_connected) {
 
			m_userManager->removeUser(this);
 
		}
 
	}
 
	else {
 
		m_userManager->removeUser(this);
 
	}
 
}
 

	
 
}
0 comments (0 inline, 0 general)