From cbf4b60df6c6c8c7208dc29708677d24b2724deb Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Fri, 30 Oct 2026 13:17:39 +0100 Subject: Enforce the invariant that each socket is only ever expected to be read from or written to, never both --- ot_http.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'ot_http.c') diff --git a/ot_http.c b/ot_http.c index e8ba3da..66f0102 100644 --- a/ot_http.c +++ b/ot_http.c @@ -118,11 +118,9 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { batch_add(cookie->batch, outbuf, ws->reply_size - written_size); /* writeable short data sockets just have a tcp timeout */ - if (!ws->keep_alive) { + if (!ws->keep_alive) fdstate_set_expiry(sock, 0); - http_interest_drop(sock, cookie, EVENT_IN); - } - http_interest_add(sock, cookie, EVENT_OUT); + http_interest_set(sock, cookie, EVENT_OUT); } } @@ -135,21 +133,16 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { #define HTTPERROR_403_IP return http_issue_error(sock, ws, CODE_HTTPERROR_403_IP) #define HTTPERROR_404 return http_issue_error(sock, ws, CODE_HTTPERROR_404) #define HTTPERROR_500 return http_issue_error(sock, ws, CODE_HTTPERROR_500) -static void http_interest(const int64_t sock, struct http_data *cookie, int what) { +/* A connection is either being read or being written, never both, so what it + waits for is set outright rather than added to and taken away again. The + event layer only hears about it when the answer changes. */ +void http_interest_set(const int64_t sock, struct http_data *cookie, int what) { if (cookie->interest == what) return; cookie->interest = what; event_modify((int)sock, what, fdstate_generation((int)sock)); } -void http_interest_add(const int64_t sock, struct http_data *cookie, int what) { - http_interest(sock, cookie, cookie->interest | what); -} - -void http_interest_drop(const int64_t sock, struct http_data *cookie, int what) { - http_interest(sock, cookie, cookie->interest & ~what); -} - ssize_t http_issue_error(const int64_t sock, struct ot_workstruct *ws, int code) { const char *error_code[] = {"302 Found", "400 Invalid Request", "400 Invalid Request", "400 Invalid Request", "402 Payment Required", "403 Not Modest", "403 Access Denied", "404 Not Found", "500 Internal Server Error"}; @@ -194,7 +187,7 @@ ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t /* If we came here, wait for the answer is over */ if (cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK) { - http_interest_drop(sock, cookie, EVENT_IN); + http_interest_set(sock, cookie, 0); cookie->flag &= ~STRUCT_HTTP_FLAG_WAITINGFORTASK; } @@ -245,7 +238,7 @@ ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t } fdstate_set_expiry(sock, time_future_seconds(OT_CLIENT_TIMEOUT_SEND)); - http_interest_add(sock, cookie, EVENT_OUT); + http_interest_set(sock, cookie, EVENT_OUT); return 0; } @@ -340,7 +333,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c /* Clients waiting for us should not easily timeout */ fdstate_set_expiry(sock, 0); fullscrape_deliver(sock, format); - http_interest_drop(sock, cookie, EVENT_IN); + http_interest_set(sock, cookie, 0); return ws->reply_size = -2; } #endif @@ -435,7 +428,7 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct * /* Clients waiting for us should not easily timeout */ fdstate_set_expiry(sock, 0); fullscrape_deliver(sock, format); - http_interest_drop(sock, cookie, EVENT_IN); + http_interest_set(sock, cookie, 0); return ws->reply_size = -2; } #endif -- cgit v1.3