Changeset - 58fbe0d388c6
[Not reviewed]
0 6 0
HanzZ - 12 years ago 2013-02-12 09:30:24
hanzz.k@gmail.com
Communi: Handle and forward socket errors. Fixes for example situation when user tries to join the room on server which does not exist.
6 files changed with 48 insertions and 6 deletions:
0 comments (0 inline, 0 general)
backends/libcommuni/ircnetworkplugin.cpp
Show inline comments
 
@@ -92,13 +92,13 @@ MyIrcSession *IRCNetworkPlugin::createSession(const std::string &user, const std
 

	
 
	return session;
 
}
 

	
 
void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
 
	if (!m_servers.empty()) {
 
		// legacy name is users nickname
 
		// legacy name is user's nickname
 
		if (m_sessions[user] != NULL) {
 
			LOG4CXX_WARN(logger, user << ": Already logged in.");
 
			return;
 
		}
 

	
 
		m_sessions[user] = createSession(user, m_servers[m_currentServer], legacyName, password, "");
 
@@ -151,12 +151,16 @@ void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const s
 
	if (m_sessions[session] == NULL) {
 
		LOG4CXX_WARN(logger, user << ": Session name: " << session << ", No session for user");
 
		return;
 
	}
 

	
 
	std::string target = getTargetName(legacyName);
 
	// We are sending PM message. On XMPP side, user is sending PM using the particular channel,
 
	// for example #room@irc.freenode.org/hanzz. On IRC side, we are forwarding this message
 
	// just to "hanzz". Therefore we have to somewhere store, that message from "hanzz" should
 
	// be mapped to #room@irc.freenode.org/hanzz.
 
	if (legacyName.find("/") != std::string::npos) {
 
		m_sessions[session]->addPM(target, legacyName.substr(0, legacyName.find("@")));
 
	}
 

	
 
	LOG4CXX_INFO(logger, user << ": Session name: " << session << ", message to " << target);
 

	
backends/libcommuni/session.cpp
Show inline comments
 
@@ -67,13 +67,37 @@ void MyIrcSession::on_connected() {
 
		std::string what = getIdentify().substr(getIdentify().find(" ") + 1);
 
		sendCommand(IrcCommand::createMessage(FROM_UTF8(to), FROM_UTF8(what)));
 
	}
 
}
 

	
 
void MyIrcSession::on_socketError(QAbstractSocket::SocketError error) {
 
	on_disconnected();
 
	std::string reason;
 
	switch(error) {
 
		case QAbstractSocket::ConnectionRefusedError: reason = "The connection was refused by the peer (or timed out)."; break;
 
		case QAbstractSocket::RemoteHostClosedError: reason = "The remote host closed the connection."; break;
 
		case QAbstractSocket::HostNotFoundError: reason = "The host address was not found."; break;
 
		case QAbstractSocket::SocketAccessError: reason = "The socket operation failed because the application lacked the required privileges."; break;
 
		case QAbstractSocket::SocketResourceError: reason = "The local system ran out of resources."; break;
 
		case QAbstractSocket::SocketTimeoutError: reason = "The socket operation timed out."; break;
 
		case QAbstractSocket::DatagramTooLargeError: reason = "The datagram was larger than the operating system's limit."; break;
 
		case QAbstractSocket::NetworkError: reason = "An error occurred with the network."; break;
 
		case QAbstractSocket::SslHandshakeFailedError: reason = "The SSL/TLS handshake failed, so the connection was closed"; break;
 
		case QAbstractSocket::UnknownSocketError: reason = "An unidentified error occurred."; break;
 
		default: reason= "Unknown error."; break;
 
	};
 

	
 
	if (!suffix.empty()) {
 
		for(AutoJoinMap::iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) {
 
			np->handleParticipantChanged(user, TO_UTF8(nickName()), it->second->getChannel() + suffix, pbnetwork::PARTICIPANT_FLAG_ROOM_NOT_FOUND, pbnetwork::STATUS_NONE, reason);
 
		}
 
	}
 
	else {
 
		np->handleDisconnected(user, 0, reason);
 
		np->tryNextServer();
 
	}
 
	m_connected = false;
 
}
 

	
 
void MyIrcSession::on_disconnected() {
 
	if (suffix.empty()) {
 
		np->handleDisconnected(user, 0, "");
 
		np->tryNextServer();
backends/libcommuni/session.h
Show inline comments
 
@@ -66,24 +66,26 @@ public:
 

	
 
	typedef std::map<std::string, boost::shared_ptr<AutoJoinChannel> > AutoJoinMap;
 
	typedef std::map<std::string, std::map<std::string, IRCBuddy> > IRCBuddyMap;
 

	
 
	MyIrcSession(const std::string &user, IRCNetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0);
 
	virtual ~MyIrcSession();
 
	std::string suffix;
 
	int rooms;
 

	
 
	void addAutoJoinChannel(const std::string &channel, const std::string &password) {
 
		m_autoJoin[channel] = boost::make_shared<AutoJoinChannel>(channel, password, 12 + m_autoJoin.size());
 
	}
 

	
 
	void removeAutoJoinChannel(const std::string &channel) {
 
		m_autoJoin.erase(channel);
 
		removeIRCBuddies(channel);
 
	}
 

	
 
	// We are sending PM message. On XMPP side, user is sending PM using the particular channel,
 
	// for example #room@irc.freenode.org/hanzz. On IRC side, we are forwarding this message
 
	// just to "hanzz". Therefore we have to somewhere store, that message from "hanzz" should
 
	// be mapped to #room@irc.freenode.org/hanzz.
 
	void addPM(const std::string &name, const std::string &room) {
 
		m_pms[name] = room;
 
	}
 

	
 
	void setIdentify(const std::string &identify) {
 
		m_identify = identify;
 
@@ -117,12 +119,15 @@ public:
 
	void on_nickChanged(IrcMessage *message);
 
	void on_modeChanged(IrcMessage *message);
 
	void on_topicChanged(IrcMessage *message);
 
	void on_messageReceived(IrcMessage *message);
 
	void on_numericMessageReceived(IrcMessage *message);
 

	
 
	std::string suffix;
 
	int rooms;
 

	
 
protected Q_SLOTS:
 
	void on_connected();
 
	void on_disconnected();
 
	void on_socketError(QAbstractSocket::SocketError error);
 

	
 
	void onMessageReceived(IrcMessage* message);
include/transport/conversation.h
Show inline comments
 
@@ -37,13 +37,14 @@ class Conversation {
 
			PARTICIPANT_FLAG_NONE = 0,
 
			PARTICIPANT_FLAG_MODERATOR = 1,
 
			PARTICIPANT_FLAG_CONFLICT = 2,
 
			PARTICIPANT_FLAG_BANNED = 4,
 
			PARTICIPANT_FLAG_NOT_AUTHORIZED = 8,
 
			PARTICIPANT_FLAG_ME = 16,
 
			PARTICIPANT_FLAG_KICKED = 32
 
			PARTICIPANT_FLAG_KICKED = 32,
 
			PARTICIPANT_FLAG_ROOM_NOT_FOUD = 64
 
		} ParticipantFlag;
 

	
 
		typedef struct _Participant {
 
			ParticipantFlag flag;
 
			int status;
 
			std::string statusMessage;
include/transport/protocol.proto
Show inline comments
 
@@ -92,12 +92,13 @@ enum ParticipantFlag {
 
	PARTICIPANT_FLAG_MODERATOR = 1;
 
	PARTICIPANT_FLAG_CONFLICT = 2;
 
	PARTICIPANT_FLAG_BANNED = 4;
 
	PARTICIPANT_FLAG_NOT_AUTHORIZED = 8;
 
	PARTICIPANT_FLAG_ME = 16;
 
	PARTICIPANT_FLAG_KICKED = 32;
 
	PARTICIPANT_FLAG_ROOM_NOT_FOUND = 64;
 
}
 

	
 
message Participant {
 
	required string userName = 1;
 
	required string room = 2;
 
	required string nickname = 3;
src/conversation.cpp
Show inline comments
 
@@ -254,13 +254,20 @@ Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int
 
			return presence;
 
		}
 
		else if (flag & PARTICIPANT_FLAG_NOT_AUTHORIZED) {
 
			delete p;
 
			presence->setType(Swift::Presence::Error);
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::NotAuthorized, Swift::ErrorPayload::Auth)));
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::NotAuthorized, Swift::ErrorPayload::Auth, statusMessage)));
 
			return presence;
 
		}
 
		else if (flag & PARTICIPANT_FLAG_ROOM_NOT_FOUD) {
 
			delete p;
 
			presence->setType(Swift::Presence::Error);
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::ItemNotFound, Swift::ErrorPayload::Cancel, statusMessage)));
 
			return presence;
 
		}
 
		else {
 
			Swift::MUCUserPayload::StatusCode c;
 
			c.code = 110;
 
			p->addStatusCode(c);
0 comments (0 inline, 0 general)