Fix a race between scheduling a new request onto an idle connection and
authorclaudio <claudio@openbsd.org>
Tue, 30 Jan 2024 10:16:13 +0000 (10:16 +0000)
committerclaudio <claudio@openbsd.org>
Tue, 30 Jan 2024 10:16:13 +0000 (10:16 +0000)
closing the same connection.

When closing an idle connection that connection needs to be moved off the
idle queue and back onto the active queue. Do this in the two possible
cases (directly in http_close() and in http_handle() for the STATE_IDLE
case). In both cases it is possible that the system needs to repoll the
connection and while waiting a request could be scheduled on that connection
if it remains on the idle queue.

Problem hit by job@
OK tb@

usr.sbin/rpki-client/http.c

index c460c20..08dbaff 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: http.c,v 1.78 2023/06/28 17:36:09 op Exp $ */
+/*     $OpenBSD: http.c,v 1.79 2024/01/30 10:16:13 claudio Exp $ */
 /*
  * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
  * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
@@ -1836,6 +1836,8 @@ http_close(struct http_connection *conn)
        assert(conn->state == STATE_IDLE || conn->state == STATE_CLOSE);
 
        conn->state = STATE_CLOSE;
+       LIST_REMOVE(conn, entry);
+       LIST_INSERT_HEAD(&active, conn, entry);
 
        if (conn->tls != NULL) {
                switch (tls_close(conn->tls)) {
@@ -1985,6 +1987,8 @@ http_handle(struct http_connection *conn)
                return http_close(conn);
        case STATE_IDLE:
                conn->state = STATE_RESPONSE_HEADER;
+               LIST_REMOVE(conn, entry);
+               LIST_INSERT_HEAD(&active, conn, entry);
                return http_read(conn);
        case STATE_FREE:
                errx(1, "bad http state");