Merge branch 'master' of github.com:hanzz/libtransport
This commit is contained in:
commit
ecbfbd5b50
17 changed files with 217 additions and 70 deletions
|
@ -69,6 +69,8 @@ class Config {
|
|||
/// \param configfile path to config file
|
||||
bool load(const std::string &configfile);
|
||||
|
||||
bool reload();
|
||||
|
||||
/// Returns value of variable defined by key.
|
||||
|
||||
/// For variables in sections you can use "section.variable" key format.
|
||||
|
|
|
@ -42,7 +42,7 @@ class RosterResponder;
|
|||
|
||||
class NetworkPluginServer {
|
||||
public:
|
||||
struct Client {
|
||||
struct Backend {
|
||||
bool pongReceived;
|
||||
std::list<User *> users;
|
||||
Swift::SafeByteArray data;
|
||||
|
@ -57,12 +57,16 @@ class NetworkPluginServer {
|
|||
return m_clients.size();
|
||||
}
|
||||
|
||||
const std::list<Backend *> &getBackends() {
|
||||
return m_clients;
|
||||
}
|
||||
|
||||
void handleMessageReceived(NetworkConversation *conv, boost::shared_ptr<Swift::Message> &message);
|
||||
|
||||
private:
|
||||
void handleNewClientConnection(boost::shared_ptr<Swift::Connection> c);
|
||||
void handleSessionFinished(Client *c);
|
||||
void handleDataRead(Client *c, const Swift::SafeByteArray&);
|
||||
void handleSessionFinished(Backend *c);
|
||||
void handleDataRead(Backend *c, const Swift::SafeByteArray&);
|
||||
|
||||
void handleConnectedPayload(const std::string &payload);
|
||||
void handleDisconnectedPayload(const std::string &payload);
|
||||
|
@ -92,15 +96,15 @@ class NetworkPluginServer {
|
|||
void send(boost::shared_ptr<Swift::Connection> &, const std::string &data);
|
||||
|
||||
void pingTimeout();
|
||||
void sendPing(Client *c);
|
||||
Client *getFreeClient();
|
||||
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<Client *> m_clients;
|
||||
std::list<Backend *> m_clients;
|
||||
Swift::Timer::ref m_pingTimer;
|
||||
Component *m_component;
|
||||
};
|
||||
|
|
|
@ -52,6 +52,10 @@ class UserManager {
|
|||
/// \return User class associated with this user
|
||||
User *getUser(const std::string &barejid);
|
||||
|
||||
const std::map<std::string, User *> &getUsers() {
|
||||
return m_users;
|
||||
}
|
||||
|
||||
/// Returns number of online users.
|
||||
/// \return number of online users
|
||||
int getUserCount();
|
||||
|
|
|
@ -56,13 +56,13 @@ int main(int argc, char **argv)
|
|||
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
Component transport(&eventLoop, &config, NULL, &userRegistry);
|
||||
Logger logger(&transport);
|
||||
// Logger logger(&transport);
|
||||
|
||||
StorageBackend *storageBackend = NULL;
|
||||
|
||||
if (CONFIG_STRING(&config, "database.type") == "sqlite3") {
|
||||
storageBackend = new SQLite3Backend(&config);
|
||||
logger.setStorageBackend(storageBackend);
|
||||
// logger.setStorageBackend(storageBackend);
|
||||
if (!storageBackend->connect()) {
|
||||
std::cerr << "Can't connect to database.\n";
|
||||
}
|
||||
|
@ -70,10 +70,11 @@ int main(int argc, char **argv)
|
|||
|
||||
UserManager userManager(&transport, &userRegistry, storageBackend);
|
||||
if (storageBackend) {
|
||||
UserRegistration userRegistration(&transport, &userManager, storageBackend);
|
||||
logger.setUserRegistration(&userRegistration);
|
||||
UserRegistration *userRegistration = new UserRegistration(&transport, &userManager, storageBackend);
|
||||
userRegistration->start();
|
||||
// logger.setUserRegistration(&userRegistration);
|
||||
}
|
||||
logger.setUserManager(&userManager);
|
||||
// logger.setUserManager(&userManager);
|
||||
|
||||
NetworkPluginServer plugin(&transport, &config, &userManager);
|
||||
|
||||
|
|
|
@ -29,7 +29,9 @@ static void handleConnected(Swift::Client *client) {
|
|||
}
|
||||
|
||||
static void handleMessageReceived(Swift::Client *client, Swift::Message::ref message) {
|
||||
std::cout << "[ OK ] " << client->getJID().getDomain() << ": " << message->getBody() << "\n";
|
||||
std::string body = message->getBody();
|
||||
boost::replace_all(body, "\n", "\n[ OK ] " + client->getJID().getDomain() + ": ");
|
||||
std::cout << "[ OK ] " << client->getJID().getDomain() << ": " << body << "\n";
|
||||
if (--finished == 0) {
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
[service]
|
||||
admin_username=admin
|
||||
admin_password=test
|
||||
admin_username=admin_
|
||||
admin_password=test_
|
||||
|
||||
[servers]
|
||||
server=localhost
|
||||
server=icq.spectrum.im
|
||||
#server=localhost
|
||||
server=icq.spectrum.im
|
||||
server=msn.spectrum.im
|
|
@ -35,6 +35,14 @@ namespace Transport {
|
|||
|
||||
static LoggerPtr logger = Logger::getLogger("AdminInterface");
|
||||
|
||||
static std::string getArg(const std::string &body) {
|
||||
std::string ret;
|
||||
if (body.find(" ") == std::string::npos)
|
||||
return ret;
|
||||
|
||||
return body.substr(body.find(" ") + 1);
|
||||
}
|
||||
|
||||
AdminInterface::AdminInterface(Component *component, UserManager *userManager, NetworkPluginServer *server, StorageBackend *storageBackend) {
|
||||
m_component = component;
|
||||
m_storageBackend = storageBackend;
|
||||
|
@ -65,8 +73,75 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
|
|||
int backends = m_server->getBackendCount() - 1;
|
||||
message->setBody("Running (" + boost::lexical_cast<std::string>(users) + " users connected using " + boost::lexical_cast<std::string>(backends) + " backends)");
|
||||
}
|
||||
else if (message->getBody() == "online_users") {
|
||||
std::string lst;
|
||||
const std::map<std::string, User *> &users = m_userManager->getUsers();
|
||||
if (users.size() == 0)
|
||||
lst = "0";
|
||||
|
||||
for (std::map<std::string, User *>::const_iterator it = users.begin(); it != users.end(); it ++) {
|
||||
lst += (*it).first + "\n";
|
||||
}
|
||||
|
||||
message->setBody(lst);
|
||||
}
|
||||
else if (message->getBody() == "online_users_count") {
|
||||
int users = m_userManager->getUserCount();
|
||||
message->setBody(boost::lexical_cast<std::string>(users));
|
||||
}
|
||||
else if (message->getBody() == "reload") {
|
||||
bool done = m_component->getConfig()->reload();
|
||||
if (done) {
|
||||
message->setBody("Config reloaded");
|
||||
}
|
||||
else {
|
||||
message->setBody("Error during config reload");
|
||||
}
|
||||
}
|
||||
else if (message->getBody() == "online_users_per_backend") {
|
||||
std::string lst;
|
||||
int id = 1;
|
||||
|
||||
const std::list <NetworkPluginServer::Backend *> &backends = m_server->getBackends();
|
||||
for (std::list <NetworkPluginServer::Backend *>::const_iterator b = backends.begin(); b != backends.end(); b++) {
|
||||
NetworkPluginServer::Backend *backend = *b;
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + ":\n";
|
||||
if (backend->users.size() == 0) {
|
||||
lst += " waiting for users\n";
|
||||
}
|
||||
else {
|
||||
for (std::list<User *>::const_iterator u = backend->users.begin(); u != backend->users.end(); u++) {
|
||||
User *user = *u;
|
||||
lst += " " + user->getJID().toBare().toString() + "\n";
|
||||
}
|
||||
}
|
||||
id++;
|
||||
}
|
||||
|
||||
message->setBody(lst);
|
||||
}
|
||||
else if (message->getBody().find("has_online_user") == 0) {
|
||||
User *user = m_userManager->getUser(getArg(message->getBody()));
|
||||
std::cout << getArg(message->getBody()) << "\n";
|
||||
message->setBody(boost::lexical_cast<std::string>(user != NULL));
|
||||
}
|
||||
else if (message->getBody() == "backends_count") {
|
||||
int backends = m_server->getBackendCount() - 1;
|
||||
message->setBody(boost::lexical_cast<std::string>(backends));
|
||||
}
|
||||
else if (message->getBody().find("help") == 0) {
|
||||
std::string help;
|
||||
help += "status - shows instance status\n";
|
||||
help += "online_users - returns list of all online users\n";
|
||||
help += "online_users_count - number of online users\n";
|
||||
help += "online_users_per_backend - shows online users per backends\n";
|
||||
help += "has_online_user <bare_JID> - returns 1 if user is online\n";
|
||||
help += "backends_count - number of active backends\n";
|
||||
help += "reload - Reloads config file\n";
|
||||
message->setBody(help);
|
||||
}
|
||||
else {
|
||||
message->setBody("Unknown command");
|
||||
message->setBody("Unknown command. Try \"help\"");
|
||||
}
|
||||
|
||||
m_component->getStanzaChannel()->sendMessage(message);
|
||||
|
|
|
@ -46,6 +46,9 @@ bool Config::load(const std::string &configfile, boost::program_options::options
|
|||
("service.cert_password", value<std::string>()->default_value(""), "PKCS#12 Certificate password.")
|
||||
("service.admin_username", value<std::string>()->default_value(""), "Administrator username.")
|
||||
("service.admin_password", value<std::string>()->default_value(""), "Administrator password.")
|
||||
("identity.name", value<std::string>()->default_value("Spectrum 2 Transport"), "Name showed in service discovery.")
|
||||
("identity.category", value<std::string>()->default_value("gateway"), "Disco#info identity category. 'gateway' by default.")
|
||||
("identity.type", value<std::string>()->default_value(""), "Type of transport ('icq','msn','gg','irc', ...)")
|
||||
("registration.enable_public_registration", value<bool>()->default_value(true), "True if users should be able to register.")
|
||||
("registration.language", value<std::string>()->default_value("en"), "Default language for registration form")
|
||||
("registration.instructions", value<std::string>()->default_value(""), "Instructions showed to user in registration form")
|
||||
|
@ -74,4 +77,12 @@ bool Config::load(const std::string &configfile) {
|
|||
return load(configfile, opts);
|
||||
}
|
||||
|
||||
bool Config::reload() {
|
||||
if (m_file.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return load(m_file);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,16 +26,20 @@
|
|||
#include "Swiften/Queries/IQRouter.h"
|
||||
#include "Swiften/Elements/DiscoInfo.h"
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "transport/config.h"
|
||||
|
||||
using namespace Swift;
|
||||
using namespace boost;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DiscoInfoResponder::DiscoInfoResponder(Swift::IQRouter *router) : Swift::GetResponder<DiscoInfo>(router) {
|
||||
m_transportInfo.addIdentity(DiscoInfo::Identity("libtransport", "gateway", "identity"));
|
||||
DiscoInfoResponder::DiscoInfoResponder(Swift::IQRouter *router, Config *config) : Swift::GetResponder<DiscoInfo>(router) {
|
||||
m_config = config;
|
||||
m_transportInfo.addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"),
|
||||
CONFIG_STRING(m_config, "identity.category"),
|
||||
CONFIG_STRING(m_config, "identity.type")));
|
||||
|
||||
m_buddyInfo.addIdentity(DiscoInfo::Identity("libtransport", "client", "pc"));
|
||||
m_buddyInfo.addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"), "client", "pc"));
|
||||
std::list<std::string> features;
|
||||
features.push_back("jabber:iq:register");
|
||||
features.push_back("jabber:iq:gateway");
|
||||
|
|
|
@ -28,9 +28,11 @@
|
|||
|
||||
namespace Transport {
|
||||
|
||||
class Config;
|
||||
|
||||
class DiscoInfoResponder : public Swift::GetResponder<Swift::DiscoInfo> {
|
||||
public:
|
||||
DiscoInfoResponder(Swift::IQRouter *router);
|
||||
DiscoInfoResponder(Swift::IQRouter *router, Config *config);
|
||||
~DiscoInfoResponder();
|
||||
|
||||
void setTransportFeatures(std::list<std::string> &features);
|
||||
|
@ -43,6 +45,7 @@ class DiscoInfoResponder : public Swift::GetResponder<Swift::DiscoInfo> {
|
|||
|
||||
Swift::DiscoInfo m_transportInfo;
|
||||
Swift::DiscoInfo m_buddyInfo;
|
||||
Config *m_config;
|
||||
};
|
||||
|
||||
}
|
|
@ -173,7 +173,7 @@ NetworkPluginServer::~NetworkPluginServer() {
|
|||
}
|
||||
|
||||
void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Connection> c) {
|
||||
Client *client = new Client;
|
||||
Backend *client = new Backend;
|
||||
client->pongReceived = true;
|
||||
client->connection = c;
|
||||
|
||||
|
@ -191,7 +191,7 @@ void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Con
|
|||
sendPing(client);
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handleSessionFinished(Client *c) {
|
||||
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());
|
||||
|
@ -203,7 +203,7 @@ void NetworkPluginServer::handleSessionFinished(Client *c) {
|
|||
delete c;
|
||||
|
||||
// Execute new session only if there's no free one after this crash/disconnection
|
||||
for (std::list<Client *>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) {
|
||||
for (std::list<Backend *>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) {
|
||||
if ((*it)->users.size() < CONFIG_INT(m_config, "service.users_per_backend")) {
|
||||
return;
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ void NetworkPluginServer::handleAttentionPayload(const std::string &data) {
|
|||
conv->handleMessage(msg);
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handleDataRead(Client *c, const Swift::SafeByteArray &data) {
|
||||
void NetworkPluginServer::handleDataRead(Backend *c, const Swift::SafeByteArray &data) {
|
||||
c->data.insert(c->data.end(), data.begin(), data.end());
|
||||
while (c->data.size() != 0) {
|
||||
unsigned int expected_size;
|
||||
|
@ -509,7 +509,7 @@ void NetworkPluginServer::send(boost::shared_ptr<Swift::Connection> &c, const st
|
|||
|
||||
void NetworkPluginServer::pingTimeout() {
|
||||
// check ping responses
|
||||
for (std::list<Client *>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) {
|
||||
for (std::list<Backend *>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) {
|
||||
if ((*it)->pongReceived) {
|
||||
sendPing((*it));
|
||||
}
|
||||
|
@ -521,10 +521,10 @@ void NetworkPluginServer::pingTimeout() {
|
|||
}
|
||||
|
||||
void NetworkPluginServer::handleUserCreated(User *user) {
|
||||
Client *c = getFreeClient();
|
||||
Backend *c = getFreeClient();
|
||||
if (!c) {
|
||||
LOG4CXX_ERROR(logger, "There is no backend to handle user " << user->getJID().toString());
|
||||
user->handleDisconnected("Internal Server Error, please reconnect.");
|
||||
user->handleDisconnected("Internal Server Error (no free backend to handle your session), please reconnect.");
|
||||
return;
|
||||
}
|
||||
user->setData(c);
|
||||
|
@ -550,7 +550,7 @@ void NetworkPluginServer::handleUserReadyToConnect(User *user) {
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGIN);
|
||||
|
||||
Client *c = (Client *) user->getData();
|
||||
Backend *c = (Backend *) user->getData();
|
||||
send(c->connection, message);
|
||||
}
|
||||
|
||||
|
@ -570,7 +570,7 @@ void NetworkPluginServer::handleUserPresenceChanged(User *user, Swift::Presence:
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_STATUS_CHANGED);
|
||||
|
||||
Client *c = (Client *) user->getData();
|
||||
Backend *c = (Backend *) user->getData();
|
||||
send(c->connection, message);
|
||||
}
|
||||
|
||||
|
@ -588,7 +588,7 @@ void NetworkPluginServer::handleRoomJoined(User *user, const std::string &r, con
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_JOIN_ROOM);
|
||||
|
||||
Client *c = (Client *) user->getData();
|
||||
Backend *c = (Backend *) user->getData();
|
||||
send(c->connection, message);
|
||||
|
||||
NetworkConversation *conv = new NetworkConversation(user->getConversationManager(), r, true);
|
||||
|
@ -610,7 +610,7 @@ void NetworkPluginServer::handleRoomLeft(User *user, const std::string &r) {
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LEAVE_ROOM);
|
||||
|
||||
Client *c = (Client *) user->getData();
|
||||
Backend *c = (Backend *) user->getData();
|
||||
send(c->connection, message);
|
||||
|
||||
NetworkConversation *conv = (NetworkConversation *) user->getConversationManager()->getConversation(r);
|
||||
|
@ -635,7 +635,7 @@ void NetworkPluginServer::handleUserDestroyed(User *user) {
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGOUT);
|
||||
|
||||
Client *c = (Client *) user->getData();
|
||||
Backend *c = (Backend *) user->getData();
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
|
@ -677,7 +677,7 @@ void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost
|
|||
|
||||
WRAP(message, type);
|
||||
|
||||
Client *c = (Client *) conv->getConversationManager()->getUser()->getData();
|
||||
Backend *c = (Backend *) conv->getConversationManager()->getUser()->getData();
|
||||
send(c->connection, message);
|
||||
}
|
||||
}
|
||||
|
@ -694,7 +694,7 @@ void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_ATTENTION);
|
||||
|
||||
Client *c = (Client *) conv->getConversationManager()->getUser()->getData();
|
||||
Backend *c = (Backend *) conv->getConversationManager()->getUser()->getData();
|
||||
send(c->connection, message);
|
||||
return;
|
||||
}
|
||||
|
@ -719,7 +719,7 @@ void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_CONV_MESSAGE);
|
||||
|
||||
Client *c = (Client *) conv->getConversationManager()->getUser()->getData();
|
||||
Backend *c = (Backend *) conv->getConversationManager()->getUser()->getData();
|
||||
send(c->connection, message);
|
||||
}
|
||||
}
|
||||
|
@ -739,7 +739,7 @@ void NetworkPluginServer::handleBuddyRemoved(Buddy *b) {
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_REMOVED);
|
||||
|
||||
Client *c = (Client *) user->getData();
|
||||
Backend *c = (Backend *) user->getData();
|
||||
send(c->connection, message);
|
||||
}
|
||||
|
||||
|
@ -762,7 +762,7 @@ void NetworkPluginServer::handleBuddyUpdated(Buddy *b, const Swift::RosterItemPa
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_CHANGED);
|
||||
|
||||
Client *c = (Client *) user->getData();
|
||||
Backend *c = (Backend *) user->getData();
|
||||
send(c->connection, message);
|
||||
}
|
||||
|
||||
|
@ -782,7 +782,7 @@ void NetworkPluginServer::handleVCardUpdated(User *user, boost::shared_ptr<Swift
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_VCARD);
|
||||
|
||||
Client *c = (Client *) user->getData();
|
||||
Backend *c = (Backend *) user->getData();
|
||||
send(c->connection, message);
|
||||
}
|
||||
|
||||
|
@ -797,11 +797,11 @@ void NetworkPluginServer::handleVCardRequired(User *user, const std::string &nam
|
|||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_VCARD);
|
||||
|
||||
Client *c = (Client *) user->getData();
|
||||
Backend *c = (Backend *) user->getData();
|
||||
send(c->connection, message);
|
||||
}
|
||||
|
||||
void NetworkPluginServer::sendPing(Client *c) {
|
||||
void NetworkPluginServer::sendPing(Backend *c) {
|
||||
|
||||
std::string message;
|
||||
pbnetwork::WrapperMessage wrap;
|
||||
|
@ -813,14 +813,17 @@ void NetworkPluginServer::sendPing(Client *c) {
|
|||
LOG4CXX_INFO(logger, "PING to " << c);
|
||||
}
|
||||
|
||||
NetworkPluginServer::Client *NetworkPluginServer::getFreeClient() {
|
||||
NetworkPluginServer::Client *c = NULL;
|
||||
NetworkPluginServer::Backend *NetworkPluginServer::getFreeClient() {
|
||||
NetworkPluginServer::Backend *c = NULL;
|
||||
bool spawnNew = false;
|
||||
for (std::list<Client *>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) {
|
||||
for (std::list<Backend *>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) {
|
||||
// This backend is free.
|
||||
if ((*it)->users.size() < CONFIG_INT(m_config, "service.users_per_backend")) {
|
||||
if ((*it)->users.size() + 1 == CONFIG_INT(m_config, "service.users_per_backend")) {
|
||||
// After this user, this backend could be full, so we have to spawn new one...
|
||||
if ((*it)->users.size() + 1 >= CONFIG_INT(m_config, "service.users_per_backend")) {
|
||||
spawnNew = true;
|
||||
}
|
||||
|
||||
if (c == NULL) {
|
||||
c = *it;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,9 @@ RosterManager::~RosterManager() {
|
|||
|
||||
for (std::map<std::string, Buddy *>::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) {
|
||||
Buddy *buddy = (*it).second;
|
||||
if (!buddy) {
|
||||
continue;
|
||||
}
|
||||
delete buddy;
|
||||
}
|
||||
if (m_rosterStorage)
|
||||
|
@ -141,7 +144,10 @@ Buddy *RosterManager::getBuddy(const std::string &name) {
|
|||
void RosterManager::sendRIE() {
|
||||
m_RIETimer->stop();
|
||||
|
||||
LOG4CXX_INFO(logger, "Sending RIE stanza to " << m_user->getJID().toString());
|
||||
Swift::Presence::ref highest = m_component->getPresenceOracle()->getHighestPriorityPresence(m_user->getJID().toBare());
|
||||
|
||||
LOG4CXX_INFO(logger, "Sending RIE stanza to " << highest->getFrom().toString());
|
||||
|
||||
Swift::RosterItemExchangePayload::ref payload = Swift::RosterItemExchangePayload::ref(new Swift::RosterItemExchangePayload());
|
||||
for (std::map<std::string, Buddy *>::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) {
|
||||
Buddy *buddy = (*it).second;
|
||||
|
@ -154,7 +160,7 @@ void RosterManager::sendRIE() {
|
|||
payload->addItem(item);
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::GenericRequest<Swift::RosterItemExchangePayload> > request(new Swift::GenericRequest<Swift::RosterItemExchangePayload>(Swift::IQ::Set, m_user->getJID(), payload, m_component->getIQRouter()));
|
||||
boost::shared_ptr<Swift::GenericRequest<Swift::RosterItemExchangePayload> > request(new Swift::GenericRequest<Swift::RosterItemExchangePayload>(Swift::IQ::Set, highest->getFrom(), payload, m_component->getIQRouter()));
|
||||
request->send();
|
||||
}
|
||||
|
||||
|
@ -211,6 +217,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
|
|||
}
|
||||
else {
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
Swift::Presence::ref presence;
|
||||
response->setTo(presence->getFrom());
|
||||
response->setFrom(presence->getTo());
|
||||
|
||||
|
@ -220,6 +227,11 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
|
|||
// buddy is already there, so nothing to do, just answer
|
||||
case Swift::Presence::Subscribe:
|
||||
response->setType(Swift::Presence::Subscribed);
|
||||
presence = buddy->generatePresenceStanza(255);
|
||||
if (presence) {
|
||||
presence->setTo(presence->getFrom());
|
||||
m_component->getStanzaChannel()->sendPresence(presence);
|
||||
}
|
||||
break;
|
||||
// remove buddy
|
||||
case Swift::Presence::Unsubscribe:
|
||||
|
@ -228,11 +240,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
|
|||
break;
|
||||
// just send response
|
||||
case Swift::Presence::Unsubscribed:
|
||||
response->setType(Swift::Presence::Unsubscribe);
|
||||
break;
|
||||
// just send response
|
||||
case Swift::Presence::Subscribed:
|
||||
response->setType(Swift::Presence::Subscribe);
|
||||
// response->setType(Swift::Presence::Unsubscribe);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
@ -263,9 +271,6 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
|
|||
response->setType(Swift::Presence::Unsubscribe);
|
||||
break;
|
||||
// just send response
|
||||
case Swift::Presence::Subscribed:
|
||||
response->setType(Swift::Presence::Subscribe);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -312,6 +317,9 @@ Swift::RosterPayload::ref RosterManager::generateRosterPayload() {
|
|||
|
||||
for (std::map<std::string, Buddy *>::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) {
|
||||
Buddy *buddy = (*it).second;
|
||||
if (!buddy) {
|
||||
continue;
|
||||
}
|
||||
Swift::RosterItemPayload item;
|
||||
item.setJID(buddy->getJID().toBare());
|
||||
item.setName(buddy->getAlias());
|
||||
|
@ -325,6 +333,9 @@ Swift::RosterPayload::ref RosterManager::generateRosterPayload() {
|
|||
void RosterManager::sendCurrentPresences(const Swift::JID &to) {
|
||||
for (std::map<std::string, Buddy *>::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) {
|
||||
Buddy *buddy = (*it).second;
|
||||
if (!buddy) {
|
||||
continue;
|
||||
}
|
||||
Swift::Presence::ref presence = buddy->generatePresenceStanza(255);
|
||||
if (presence) {
|
||||
presence->setTo(to);
|
||||
|
|
|
@ -272,7 +272,7 @@ long SQLite3Backend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
|
|||
void SQLite3Backend::updateBuddy(long userId, const BuddyInfo &buddyInfo) {
|
||||
// UPDATE " + m_prefix + "buddies SET groups=?, nickname=?, flags=?, subscription=? WHERE user_id=? AND uin=?
|
||||
BEGIN(m_updateBuddy);
|
||||
BIND_STR(m_updateBuddy, buddyInfo.groups[0]); // TODO: serialize groups
|
||||
BIND_STR(m_updateBuddy, buddyInfo.groups.size() == 0 ? "" : buddyInfo.groups[0]); // TODO: serialize groups
|
||||
BIND_STR(m_updateBuddy, buddyInfo.alias);
|
||||
BIND_INT(m_updateBuddy, buddyInfo.flags);
|
||||
BIND_STR(m_updateBuddy, buddyInfo.subscription);
|
||||
|
|
|
@ -69,7 +69,7 @@ Component::Component(Swift::EventLoop *loop, Config *config, Factory *factory, T
|
|||
|
||||
m_factories = new BoostNetworkFactories(loop);
|
||||
|
||||
m_reconnectTimer = m_factories->getTimerFactory()->createTimer(1000);
|
||||
m_reconnectTimer = m_factories->getTimerFactory()->createTimer(3000);
|
||||
m_reconnectTimer->onTick.connect(bind(&Component::start, this));
|
||||
|
||||
if (CONFIG_BOOL(m_config, "service.server_mode")) {
|
||||
|
@ -98,6 +98,7 @@ Component::Component(Swift::EventLoop *loop, Config *config, Factory *factory, T
|
|||
m_server->onDataWritten.connect(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("", "");
|
||||
m_component->onConnected.connect(bind(&Component::handleConnected, this));
|
||||
|
@ -116,7 +117,7 @@ Component::Component(Swift::EventLoop *loop, Config *config, Factory *factory, T
|
|||
m_presenceOracle = new PresenceOracle(m_stanzaChannel);
|
||||
m_presenceOracle->onPresenceChange.connect(bind(&Component::handlePresence, this, _1));
|
||||
|
||||
m_discoInfoResponder = new DiscoInfoResponder(m_iqRouter);
|
||||
m_discoInfoResponder = new DiscoInfoResponder(m_iqRouter, m_config);
|
||||
m_discoInfoResponder->start();
|
||||
|
||||
m_discoItemsResponder = new DiscoItemsResponder(m_iqRouter);
|
||||
|
@ -159,6 +160,7 @@ void Component::setBuddyFeatures(std::list<std::string> &features) {
|
|||
|
||||
void Component::start() {
|
||||
if (m_component) {
|
||||
LOG4CXX_INFO(logger, "Connecting XMPP server " << CONFIG_STRING(m_config, "service.server") << " port " << CONFIG_INT(m_config, "service.port"));
|
||||
m_reconnectCount++;
|
||||
m_component->connect(CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
|
||||
m_reconnectTimer->stop();
|
||||
|
@ -190,6 +192,17 @@ void Component::handleConnectionError(const ComponentError &error) {
|
|||
onConnectionError(error);
|
||||
// if (m_reconnectCount == 2)
|
||||
// Component::instance()->userManager()->removeAllUsers();
|
||||
std::string str = "Unknown error";
|
||||
switch (error.getType()) {
|
||||
case ComponentError::UnknownError: str = "Unknown error"; break;
|
||||
case ComponentError::ConnectionError: str = "Connection error"; break;
|
||||
case ComponentError::ConnectionReadError: str = "Connection read error"; break;
|
||||
case ComponentError::ConnectionWriteError: str = "Connection write error"; break;
|
||||
case ComponentError::XMLError: str = "XML Error"; break;
|
||||
case ComponentError::AuthenticationFailedError: str = "Authentication failed error"; break;
|
||||
case ComponentError::UnexpectedElementError: str = "Unexpected element error"; break;
|
||||
}
|
||||
LOG4CXX_INFO(logger, "Disconnected from XMPP server. Error: " << str);
|
||||
|
||||
m_reconnectTimer->start();
|
||||
}
|
||||
|
|
19
src/user.cpp
19
src/user.cpp
|
@ -115,11 +115,12 @@ void User::handlePresence(Swift::Presence::ref presence) {
|
|||
|
||||
Swift::Presence::ref highest = m_presenceOracle->getHighestPriorityPresence(m_jid.toBare());
|
||||
if (highest) {
|
||||
highest->setTo(presence->getFrom().toBare());
|
||||
highest->setFrom(m_component->getJID());
|
||||
m_component->getStanzaChannel()->sendPresence(highest);
|
||||
LOG4CXX_INFO(logger, m_jid.toString() << ": Changing legacy network presence to " << highest->getType());
|
||||
onPresenceChanged(highest);
|
||||
Swift::Presence::ref response = Swift::Presence::create(highest);
|
||||
response->setTo(presence->getFrom().toBare());
|
||||
response->setFrom(m_component->getJID());
|
||||
m_component->getStanzaChannel()->sendPresence(response);
|
||||
LOG4CXX_INFO(logger, m_jid.toString() << ": Changing legacy network presence to " << response->getType());
|
||||
onPresenceChanged(response);
|
||||
}
|
||||
else {
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
|
@ -158,11 +159,15 @@ void User::handleDisconnected(const std::string &error) {
|
|||
msg->setFrom(m_component->getJID());
|
||||
m_component->getStanzaChannel()->sendMessage(msg);
|
||||
|
||||
// In server mode, server finishes the session and pass unavailable session to userManager,
|
||||
// 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()));
|
||||
}
|
||||
|
||||
m_userManager->removeUser(this);
|
||||
else {
|
||||
m_userManager->removeUser(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -98,6 +98,10 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
|
|||
|
||||
User *user = getUser(userkey);
|
||||
if (!user) {
|
||||
if (CONFIG_STRING(m_component->getConfig(), "service.admin_username") == presence->getFrom().getNode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No user and unavailable presence -> answer with unavailable
|
||||
if (presence->getType() == Swift::Presence::Unavailable) {
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
|
@ -225,11 +229,11 @@ void UserManager::handleSubscription(Swift::Presence::ref presence) {
|
|||
response->setType(Swift::Presence::Subscribed);
|
||||
m_component->getStanzaChannel()->sendPresence(response);
|
||||
|
||||
response = Swift::Presence::create();
|
||||
response->setFrom(presence->getTo());
|
||||
response->setTo(presence->getFrom());
|
||||
response->setType(Swift::Presence::Subscribe);
|
||||
m_component->getStanzaChannel()->sendPresence(response);
|
||||
// response = Swift::Presence::create();
|
||||
// response->setFrom(presence->getTo());
|
||||
// response->setTo(presence->getFrom());
|
||||
// response->setType(Swift::Presence::Subscribe);
|
||||
// m_component->getStanzaChannel()->sendPresence(response);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,11 +25,15 @@
|
|||
#include "transport/user.h"
|
||||
#include "Swiften/Elements/ErrorPayload.h"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include "log4cxx/logger.h"
|
||||
|
||||
using namespace Swift;
|
||||
using namespace log4cxx;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
static LoggerPtr logger = Logger::getLogger("UserRegistration");
|
||||
|
||||
UserRegistration::UserRegistration(Component *component, UserManager *userManager, StorageBackend *storageBackend) : Swift::Responder<Swift::InBandRegistrationPayload>(component->m_iqRouter) {
|
||||
m_component = component;
|
||||
m_config = m_component->m_config;
|
||||
|
|
Loading…
Add table
Reference in a new issue