# HG changeset patch # User David Demelier # Date 1523432776 -7200 # Node ID 15b25f9e794f0455c28ba188dcf5fd99b8a8524a # Parent 3a6c8101349ee7c5c3af722197d8033ab2793f05 Irccd: server now throws on invalid state diff -r 3a6c8101349e -r 15b25f9e794f libirccd/irccd/daemon/server.cpp --- a/libirccd/irccd/daemon/server.cpp Tue Apr 10 21:23:01 2018 +0200 +++ b/libirccd/irccd/daemon/server.cpp Wed Apr 11 09:46:16 2018 +0200 @@ -128,7 +128,7 @@ void server::dispatch_connect(const irc::message&) { - state_ = state_t::connected; + state_ = state::connected; on_connect({shared_from_this()}); for (const auto& channel : rchannels_) @@ -401,7 +401,7 @@ const auto self = shared_from_this(); service_.post([this, self] () { - state_ = state_t::disconnected; + state_ = state::disconnected; conn_ = nullptr; reconnect(); }); @@ -413,6 +413,9 @@ void server::recv() { + if (state_ != state::connected) + throw server_error(server_error::not_connected); + conn_->recv([this] (auto code, auto message) { handle_recv(std::move(code), std::move(message)); }); @@ -420,7 +423,7 @@ void server::identify() { - assert(state_ == state_t::identifying); + assert(state_ == state::identifying); if (!password_.empty()) conn_->send(string_util::sprintf("PASS %s", password_)); @@ -431,7 +434,7 @@ void server::wait() { - assert(state_ == state_t::waiting); + assert(state_ == state::waiting); timer_.expires_from_now(boost::posix_time::seconds(recodelay_)); timer_.async_wait([this] (auto) { @@ -448,16 +451,16 @@ // Wait before reconnecting. if (recotries_ != 0) { if (recotries_ > 0 && recocur_ >= recotries_) { - state_ = state_t::disconnected; + state_ = state::disconnected; on_die({shared_from_this()}); } else { - state_ = state_t::waiting; + state_ = state::waiting; wait(); } } else - state_ = state_t::disconnected; + state_ = state::disconnected; } else { - state_ = state_t::identifying; + state_ = state::identifying; recocur_ = 0U; jchannels_.clear(); @@ -469,12 +472,12 @@ server::~server() { conn_ = nullptr; - state_ = state_t::disconnected; + state_ = state::disconnected; } void server::set_nickname(std::string nickname) { - if (state_ == state_t::connected) + if (state_ == state::connected) conn_->send(string_util::sprintf("NICK %s", nickname)); else nickname_ = std::move(nickname); @@ -487,7 +490,7 @@ void server::connect() noexcept { - assert(state_ == state_t::disconnected || state_ == state_t::waiting); + assert(state_ == state::disconnected || state_ == state::waiting); /* * This is needed if irccd is started before DHCP or if DNS cache is @@ -510,7 +513,7 @@ } else conn_ = irc::ip_connection::create(service_); - state_ = state_t::connecting; + state_ = state::connecting; conn_->connect(host_, std::to_string(port_), [this] (auto code) { handle_connect(std::move(code)); }); @@ -519,7 +522,7 @@ void server::disconnect() noexcept { conn_ = nullptr; - state_ = state_t::disconnected; + state_ = state::disconnected; on_disconnect({shared_from_this()}); } @@ -553,7 +556,7 @@ else *it = { channel, password }; - if (state_ == state_t::connected) { + if (state_ == state::connected) { if (password.empty()) send(string_util::sprintf("JOIN %s", channel)); else @@ -638,15 +641,17 @@ void server::send(std::string raw) { - assert(state_ == state_t::connected); assert(!raw.empty()); + if (state_ != state::connected) + throw server_error(server_error::not_connected); + conn_->send(std::move(raw), [this] (auto code) { if (code) { const auto self = shared_from_this(); service_.post([this, self] () { - state_ = state_t::disconnected; + state_ = state::disconnected; conn_ = nullptr; reconnect(); }); diff -r 3a6c8101349e -r 15b25f9e794f libirccd/irccd/daemon/server.hpp --- a/libirccd/irccd/daemon/server.hpp Tue Apr 10 21:23:01 2018 +0200 +++ b/libirccd/irccd/daemon/server.hpp Wed Apr 11 09:46:16 2018 +0200 @@ -264,7 +264,7 @@ /** * \brief Describe current server state. */ - enum class state_t { + enum class state { disconnected, //!< not connected at all, connecting, //!< network connection in progress, identifying, //!< sending nick, user and password commands, @@ -404,7 +404,7 @@ boost::signals2::signal on_whois; private: - state_t state_{state_t::disconnected}; + state state_{state::disconnected}; // Requested and joined channels. std::vector rchannels_; @@ -492,7 +492,7 @@ * * \return the state */ - inline state_t get_state() const noexcept + inline state get_state() const noexcept { return state_; } @@ -795,6 +795,7 @@ * * \param target the target nickname * \param channel the channel + * \throw server_error on errors */ virtual void invite(std::string target, std::string channel); @@ -803,6 +804,7 @@ * * \param channel the channel to join * \param password the optional password + * \throw server_error on errors */ virtual void join(std::string channel, std::string password = ""); @@ -813,6 +815,7 @@ * \param target the target to kick * \param channel from which channel * \param reason the optional reason + * \throw server_error on errors */ virtual void kick(std::string target, std::string channel, std::string reason = ""); @@ -822,6 +825,7 @@ * * \param target the nickname or the channel * \param message the message + * \throw server_error on errors */ virtual void me(std::string target, std::string message); @@ -830,6 +834,7 @@ * * \param target the target * \param message the message + * \throw server_error on errors */ virtual void message(std::string target, std::string message); @@ -841,6 +846,7 @@ * \param limit the optional limit * \param user the optional user * \param mask the optional ban mask + * \throw server_error on errors */ virtual void mode(std::string channel, std::string mode, @@ -852,6 +858,7 @@ * Request the list of names. * * \param channel the channel + * \throw server_error on errors */ virtual void names(std::string channel); @@ -860,6 +867,7 @@ * * \param target the target * \param message the notice message + * \throw server_error on errors */ virtual void notice(std::string target, std::string message); @@ -871,6 +879,7 @@ * * \param channel the channel to leave * \param reason the optional reason + * \throw server_error on errors */ virtual void part(std::string channel, std::string reason = ""); @@ -878,8 +887,9 @@ * Send a raw message to the IRC server. You don't need to add * message terminators. * - * \pre state() == state_t::connected + * \pre state() == state::connected * \param raw the raw message (without `\r\n\r\n`) + * \throw server_error on errors */ virtual void send(std::string raw); @@ -888,6 +898,7 @@ * * \param channel the channel * \param topic the desired topic + * \throw server_error on errors */ virtual void topic(std::string channel, std::string topic); @@ -895,6 +906,7 @@ * Request for whois information. * * \param target the target nickname + * \throw server_error on errors */ virtual void whois(std::string target); };