changeset 672:15b25f9e794f

Irccd: server now throws on invalid state
author David Demelier <markand@malikania.fr>
date Wed, 11 Apr 2018 09:46:16 +0200
parents 3a6c8101349e
children f3d1f6f80ace
files libirccd/irccd/daemon/server.cpp libirccd/irccd/daemon/server.hpp
diffstat 2 files changed, 37 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- 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();
             });
--- 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<void (whois_event)> on_whois;
 
 private:
-    state_t state_{state_t::disconnected};
+    state state_{state::disconnected};
 
     // Requested and joined channels.
     std::vector<channel> 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);
 };