From ffc820e234ebba39a0f04607f9a0fb044fe31b73 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 24 Mar 2014 20:31:02 +0100 Subject: Reconnected immediately to the XMPP whenever it closes the connection --- src/main.cpp | 11 +++++++++++ src/network/socket_handler.cpp | 3 +++ src/xmpp/xmpp_component.cpp | 5 +++++ src/xmpp/xmpp_component.hpp | 4 ++++ src/xmpp/xmpp_parser.cpp | 15 +++++++++++++++ src/xmpp/xmpp_parser.hpp | 8 ++++++++ 6 files changed, 46 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 6b24662..d40c457 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -114,6 +114,17 @@ int main(int ac, char** av) Logger::instance().reset(); reload.store(false); } + // Reconnect to the XMPP server if this was not intended. This may have + // happened because we sent something invalid to it and it decided to + // close the connection. This is a bug that should be fixed, but we + // still reconnect automatically instead of dropping everything + if (!exiting && !xmpp_component->is_connected() && + !xmpp_component->is_connecting()) + { + xmpp_component->reset(); + p.add_socket_handler(xmpp_component); + xmpp_component->start(); + } // If the only existing connection is the one to the XMPP component: // close the XMPP stream. if (exiting && xmpp_component->is_connecting()) diff --git a/src/network/socket_handler.cpp b/src/network/socket_handler.cpp index f344786..6f91e74 100644 --- a/src/network/socket_handler.cpp +++ b/src/network/socket_handler.cpp @@ -222,6 +222,9 @@ void SocketHandler::close() { this->connected = false; this->connecting = false; + this->in_buf.clear(); + this->out_buf.clear(); + this->port.clear(); this->poller->remove_socket_handler(this->get_socket()); ::close(this->socket); // recreate the socket for a potential future usage diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index d30f778..5400535 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -167,6 +167,11 @@ void XmppComponent::on_remote_stream_close(const XmlNode& node) this->doc_open = false; } +void XmppComponent::reset() +{ + this->parser.reset(); +} + void XmppComponent::on_stanza(const Stanza& stanza) { log_debug("XMPP RECEIVING: " << stanza.to_string()); diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp index 0c040f4..3e401e5 100644 --- a/src/xmpp/xmpp_component.hpp +++ b/src/xmpp/xmpp_component.hpp @@ -41,6 +41,10 @@ public: * Connect to the XMPP server. */ void start(); + /** + * Reset the component so we can use the component on a new XMPP stream + */ + void reset(); /** * Serialize the stanza and add it to the out_buf to be sent to the * server. diff --git a/src/xmpp/xmpp_parser.cpp b/src/xmpp/xmpp_parser.cpp index 064453e..867648b 100644 --- a/src/xmpp/xmpp_parser.cpp +++ b/src/xmpp/xmpp_parser.cpp @@ -30,6 +30,11 @@ static void character_data_handler(void *user_data, const XML_Char *s, int len) XmppParser::XmppParser(): level(0), current_node(nullptr) +{ + this->init_xml_parser(); +} + +void XmppParser::init_xml_parser() { // Create the expat parser this->parser = XML_ParserCreateNS("UTF-8", ':'); @@ -65,6 +70,16 @@ int XmppParser::parse(const int len, const bool is_final) return res; } +void XmppParser::reset() +{ + XML_ParserFree(this->parser); + this->init_xml_parser(); + if (this->current_node) + delete this->current_node; + this->current_node = nullptr; + this->level = 0; +} + void* XmppParser::get_buffer(const size_t size) const { return XML_GetBuffer(this->parser, static_cast(size)); diff --git a/src/xmpp/xmpp_parser.hpp b/src/xmpp/xmpp_parser.hpp index df9cda7..b87ee6d 100644 --- a/src/xmpp/xmpp_parser.hpp +++ b/src/xmpp/xmpp_parser.hpp @@ -34,6 +34,10 @@ public: ~XmppParser(); public: + /** + * Init the XML parser and install the callbacks + */ + void init_xml_parser(); /** * Feed the parser with some XML data */ @@ -42,6 +46,10 @@ public: * Parse the data placed in the parser buffer */ int parse(const int size, const bool is_final); + /** + * Reset the parser, so it can be used from scratch afterward + */ + void reset(); /** * Get a buffer provided by the xml parser. */ -- cgit v1.2.3