Disconnect the user from all its IRC servers whenever he returns an error
fix #2524
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
/***
|
/***
|
||||||
**
|
**
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
Reference in New Issue
Block a user