]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
rlm_postgresql: Bound the total query time on non-Linux systems too (#3252)
authorTerry Burton <tez@terryburton.co.uk>
Thu, 16 Jan 2020 23:44:22 +0000 (23:44 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 16 Jan 2020 23:44:22 +0000 (18:44 -0500)
Non-Linux systems do not decrease the timeval passed in the timeout parameter
to select, so we keep track of the elapsed time ourselves.

src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c

index 69a7fa3312fde63f0d43e9cf104eb2173dbadd7b..a65622eca0d757423227d521d00ad9245f6011e6 100644 (file)
@@ -259,9 +259,9 @@ static CC_HINT(nonnull) sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_
 {
        rlm_sql_postgres_conn_t *conn = handle->conn;
        rlm_sql_postgres_t      *inst = config->driver;
-       struct timeval          timeout = {config->query_timeout, 0};
-       int                     sockfd, r;
-       fd_set                  read_fd;
+       fr_time_delta_t         timeout = fr_time_delta_from_sec(config->query_timeout);
+       fr_time_t               start;
+       int                     sockfd;
        PGresult                *tmp_result;
        int                     numfields = 0;
        ExecStatusType          status;
@@ -286,11 +286,23 @@ static CC_HINT(nonnull) sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_
         *  We try to avoid blocking by waiting until the driver indicates that
         *  the result is ready or our timeout expires
         */
+       start = fr_time();
        while (PQisBusy(conn->db)) {
+               int             r;
+               fd_set          read_fd;
+               fr_time_delta_t elapsed = 0;
+
                FD_ZERO(&read_fd);
                FD_SET(sockfd, &read_fd);
-               r = select(sockfd + 1, &read_fd, NULL, NULL, config->query_timeout ? &timeout : NULL);
+
+               if (config->query_timeout) {
+                       elapsed = fr_time() - start;
+                       if (elapsed >= timeout) goto too_long;
+               }
+
+               r = select(sockfd + 1, &read_fd, NULL, NULL, config->query_timeout ? &fr_time_delta_to_timeval(timeout - elapsed) : NULL);
                if (r == 0) {
+               too_long:
                        ERROR("Socket read timeout after %d seconds", config->query_timeout);
                        return RLM_SQL_RECONNECT;
                }