Code

frontend: Guarantee that no async messages are sent before startup finished.
authorSebastian Harl <sh@tokkee.org>
Thu, 11 Sep 2014 06:48:40 +0000 (08:48 +0200)
committerSebastian Harl <sh@tokkee.org>
Thu, 11 Sep 2014 06:48:40 +0000 (08:48 +0200)
src/frontend/connection-private.h
src/frontend/connection.c
src/frontend/session.c
src/include/frontend/proto.h

index ef445d36bbbeb636bcf0a26d1355c0975b316ddb..a874751299ea0818635c4e542705a6fea6bb8983 100644 (file)
@@ -73,6 +73,7 @@ struct sdb_conn {
 
        /* user information */
        char *username; /* NULL if the user has not been authenticated */
+       _Bool ready; /* indicates that startup finished successfully */
 };
 #define CONN(obj) ((sdb_conn_t *)(obj))
 
index ce16a8b900085ecbac3eb5ef82b4af466400dcca..a7414017284a558cfc0000dfdd8ab5d80d3d1c5c 100644 (file)
@@ -133,6 +133,8 @@ connection_destroy(sdb_object_t *obj)
        assert(obj);
        conn = CONN(obj);
 
+       conn->ready = 0;
+
        if (conn->buf) {
                len = sdb_strbuf_len(conn->buf);
                if (len)
@@ -224,8 +226,8 @@ connection_log(int prio, const char *msg,
 
        conn = sdb_conn_get_ctx();
        /* no connection associated to this thread
-        * or user not authenticated yet => don't leak any information */
-       if ((! conn) || (! conn->username))
+        * or startup not done yet => don't leak any information */
+       if ((! conn) || (! conn->ready))
                return 0;
 
        /* XXX: make the log-level configurable by the client at runtime */
@@ -309,7 +311,7 @@ command_init(sdb_conn_t *conn)
 
        sdb_strbuf_skip(conn->buf, 0, 2 * sizeof(uint32_t));
 
-       if ((! conn->username) && (conn->cmd != CONNECTION_STARTUP))
+       if ((! conn->ready) && (conn->cmd != CONNECTION_STARTUP))
                errmsg = "Authentication required";
        else if (conn->cmd == CONNECTION_IDLE)
                errmsg = "Invalid command 0";
@@ -464,6 +466,7 @@ sdb_connection_send(sdb_conn_t *conn, uint32_t code,
                 * make sure we don't try to send further logs to the connection */
                close(conn->fd);
                conn->fd = -1;
+               conn->ready = 0;
 
                sdb_log(SDB_LOG_ERR, "frontend: Failed to send msg "
                                "(code: %u, len: %u) to client: %s", code, msg_len,
index 2b568b1948ee5366df066a1d2217ff48a1ba23bc..0587c50a5f2a405ea03f801c481d197ce488db02 100644 (file)
@@ -63,6 +63,7 @@ sdb_fe_session_start(sdb_conn_t *conn)
                return -1;
        }
        sdb_connection_send(conn, CONNECTION_OK, 0, NULL);
+       conn->ready = 1;
        return 0;
 } /* sdb_fe_session_start */
 
index 2e82738449cd6a50826e22648e0dcd735167fca4..1d549a933bad84f739611f0a61882e4e82e44735 100644 (file)
@@ -96,7 +96,8 @@ typedef enum {
         * further requests to the client for authentication (not implemented
         * yet). Once the setup and authentication was successful, the server
         * replies with CONNECTION_OK. No other messages may be sent to the server
-        * before this.
+        * before this. Also, the server does not send any asynchronous messages
+        * before startup is complete.
         */
        CONNECTION_STARTUP,