Disconnect the user from all its IRC servers whenever he returns an error

fix #2524
This commit is contained in:
Florent Le Coz
2014-05-15 00:32:31 +02:00
parent 712b7bdfdf
commit 12c8b1ae0b
3 changed files with 34 additions and 4 deletions
+1 -2
View File
@@ -41,11 +41,10 @@ static std::tuple<std::string, std::string> get_role_affiliation_from_irc_mode(c
return std::make_tuple("participant", "none"); return std::make_tuple("participant", "none");
} }
void Bridge::shutdown() void Bridge::shutdown(const std::string& exit_message)
{ {
for (auto it = this->irc_clients.begin(); it != this->irc_clients.end(); ++it) for (auto it = this->irc_clients.begin(); it != this->irc_clients.end(); ++it)
{ {
const std::string exit_message("Gateway shutdown");
it->second->send_quit_command(exit_message); it->second->send_quit_command(exit_message);
it->second->leave_dummy_channel(exit_message); it->second->leave_dummy_channel(exit_message);
} }
+2 -1
View File
@@ -27,11 +27,12 @@ public:
/** /**
* QUIT all connected IRC servers. * QUIT all connected IRC servers.
*/ */
void shutdown(); void shutdown(const std::string& exit_message);
/** /**
* Remove all inactive IrcClients * Remove all inactive IrcClients
*/ */
void clean(); void clean();
static Xmpp::body make_xmpp_body(const std::string& str); static Xmpp::body make_xmpp_body(const std::string& str);
/*** /***
** **
+31 -1
View File
@@ -34,6 +34,19 @@ using namespace std::string_literals;
unsigned long XmppComponent::current_id = 0; unsigned long XmppComponent::current_id = 0;
static std::set<std::string> kickable_errors{
"gone",
"internal-server-error",
"item-not-found",
"jid-malformed",
"recipient-unavailable",
"redirect",
"remote-server-not-found",
"remote-server-timeout",
"service-unavailable",
"malformed-error"
};
XmppComponent::XmppComponent(const std::string& hostname, const std::string& secret): XmppComponent::XmppComponent(const std::string& hostname, const std::string& secret):
ever_auth(false), ever_auth(false),
last_auth(false), last_auth(false),
@@ -128,7 +141,7 @@ void XmppComponent::shutdown()
{ {
for (auto it = this->bridges.begin(); it != this->bridges.end(); ++it) for (auto it = this->bridges.begin(); it != this->bridges.end(); ++it)
{ {
it->second->shutdown(); it->second->shutdown("Gateway shutdown");
} }
} }
@@ -359,6 +372,23 @@ void XmppComponent::handle_message(const Stanza& stanza)
if (subject) if (subject)
bridge->set_channel_topic(iid, subject->get_inner()); bridge->set_channel_topic(iid, subject->get_inner());
} }
else if (type == "error")
{
const XmlNode* error = stanza.get_child(COMPONENT_NS":error");
// Only a set of errors are considered “fatal”. If we encounter one of
// them, we purge (we disconnect the user from all the IRC servers).
// We consider this to be true, unless the error condition is
// specified and is not in the kickable_errors set
bool kickable_error = true;
if (error)
{
const XmlNode* condition = error->get_last_child();
if (kickable_errors.find(condition->get_name()) == kickable_errors.end())
kickable_error = false;
}
if (kickable_error)
bridge->shutdown("Error from remote client");
}
else else
{ {
if (body && !body->get_inner().empty()) if (body && !body->get_inner().empty())