From 012729ada1ed35df980c77b9f2929890156a0e02 Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Tue, 13 Oct 2020 14:30:38 -0400 Subject: [PATCH] chore: assorted socket error handling --- runtime/include/client_socket.h | 16 ++++++++++------ runtime/include/http_request.h | 17 +++++++++++++++++ runtime/include/sandbox.h | 3 +++ runtime/include/sandbox_request.h | 2 +- runtime/src/sandbox.c | 20 +++++++++++--------- runtime/src/worker_thread.c | 6 +++++- 6 files changed, 47 insertions(+), 17 deletions(-) diff --git a/runtime/include/client_socket.h b/runtime/include/client_socket.h index 276a6ff..33f3276 100644 --- a/runtime/include/client_socket.h +++ b/runtime/include/client_socket.h @@ -14,9 +14,7 @@ static inline void client_socket_close(int client_socket) { - int rc = epoll_ctl(worker_thread_epoll_file_descriptor, EPOLL_CTL_DEL, client_socket, NULL); - if (unlikely(rc < 0)) panic_err(); - + // debuglog("Closing Socket\n"); if (close(client_socket) < 0) debuglog("Error closing client socket - %s", strerror(errno)); } @@ -26,10 +24,11 @@ client_socket_close(int client_socket) * @param client_socket - the client we are rejecting * @param status_code - either 503 or 400 */ -static inline void +static inline int client_socket_send(int client_socket, int status_code) { const char *response; + int rc; switch (status_code) { case 503: response = HTTP_RESPONSE_503_SERVICE_UNAVAILABLE; @@ -37,12 +36,15 @@ client_socket_send(int client_socket, int status_code) break; case 400: response = HTTP_RESPONSE_400_BAD_REQUEST; +#ifdef LOG_TOTAL_REQS_RESPS + atomic_fetch_add(&runtime_total_4XX_responses, 1); +#endif + break; default: panic("%d is not a valid status code\n", status_code); } - int rc; int sent = 0; int to_send = strlen(response); @@ -56,9 +58,11 @@ client_socket_send(int client_socket, int status_code) sent += rc; }; + rc = 0; done: - return; + return rc; send_err: debuglog("Error sending to client: %s", strerror(errno)); + rc = -1; goto done; } diff --git a/runtime/include/http_request.h b/runtime/include/http_request.h index 0c8da42..f7d0e12 100644 --- a/runtime/include/http_request.h +++ b/runtime/include/http_request.h @@ -1,6 +1,8 @@ #pragma once #include +#include + #include "http.h" /* all in-memory ptrs.. don't mess around with that! */ @@ -26,6 +28,21 @@ struct http_request { bool message_end; /* boolean flag set when body processing is complete */ }; +static inline void +http_request_print(struct http_request *self) +{ + printf("Header Count %d\n", self->header_count); + printf("Header Content:\n"); + for (int i = 0; i < self->header_count; i++) { + for (int j = 0; j < self->headers[i].key_length; j++) { putchar(self->headers[i].key[j]); } + putchar(':'); + for (int j = 0; j < self->headers[i].value_length; j++) { putchar(self->headers[i].value[j]); } + putchar('\n'); + } + printf("Body Length %d\n", self->body_length); + printf("Body Read Length %d\n", self->body_read_length); +} + /*************************************************** * General HTTP Request Functions * **************************************************/ diff --git a/runtime/include/sandbox.h b/runtime/include/sandbox.h index ab19ad6..c665050 100644 --- a/runtime/include/sandbox.h +++ b/runtime/include/sandbox.h @@ -321,6 +321,9 @@ sandbox_close_http(struct sandbox *sandbox) { assert(sandbox != NULL); + int rc = epoll_ctl(worker_thread_epoll_file_descriptor, EPOLL_CTL_DEL, sandbox->client_socket_descriptor, NULL); + if (unlikely(rc < 0)) panic_err(); + client_socket_close(sandbox->client_socket_descriptor); } diff --git a/runtime/include/sandbox_request.h b/runtime/include/sandbox_request.h index 1b9c9be..c6c4558 100644 --- a/runtime/include/sandbox_request.h +++ b/runtime/include/sandbox_request.h @@ -56,7 +56,7 @@ sandbox_request_allocate(struct module *module, char *arguments, int socket_desc sandbox_request->admissions_estimate = admissions_estimate; #ifdef LOG_REQUEST_ALLOCATION - debuglog("Allocating %lu of %s:%d\n", sandbox_request->request_arrival_timestamp, sandbox_request->module->name, + debuglog("Sandbox Request %lu: of %s:%d\n", sandbox_request->id, sandbox_request->module->name, sandbox_request->module->port); #endif return sandbox_request; diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index 2487177..10b34f2 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -84,7 +84,8 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox) } #ifdef LOG_HTTP_PARSER - debuglog("Sandbox: %lu http_parser_execute(%p, %p, %p, %lu)", sandbox->id, parser, settings, buf, len); + debuglog("Sandbox: %lu http_parser_execute(%p, %p, %p, %zu\n)", sandbox->id, parser, settings, buf, + recved); #endif size_t nparsed = http_parser_execute(parser, settings, buf, recved); @@ -96,6 +97,14 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox) goto err; } + if (recved == 0 && !sandbox->http_request.message_end) { +#ifdef LOG_HTTP_PARSER + debuglog("Sandbox %lu: Received 0, but parsing was incomplete\n", sandbox->id); + http_request_print(&sandbox->http_request); +#endif + goto err; + } + sandbox->request_response_data_length += nparsed; } @@ -324,15 +333,8 @@ err: /* Send a 400 error back to the client */ client_socket_send(sandbox->client_socket_descriptor, 400); -#ifdef LOG_TOTAL_REQS_RESPS - if (rc >= 0) { - atomic_fetch_add(&runtime_total_4XX_responses, 1); - debuglog("At %llu, Sandbox %lu - 4XX\n", __getcycles(), sandbox->id); - } -#endif - software_interrupt_disable(); - client_socket_close(sandbox->client_socket_descriptor); + sandbox_close_http(sandbox); sandbox_set_as_error(sandbox, SANDBOX_RUNNING); goto done; } diff --git a/runtime/src/worker_thread.c b/runtime/src/worker_thread.c index 6f54d82..caea395 100644 --- a/runtime/src/worker_thread.c +++ b/runtime/src/worker_thread.c @@ -227,6 +227,8 @@ worker_thread_execute_epoll_loop(void) if (sandbox->state == SANDBOX_BLOCKED) worker_thread_wakeup_sandbox(sandbox); } else if (epoll_events[i].events & (EPOLLERR | EPOLLHUP)) { + /* Mystery: This seems to never fire. Why? */ + /* Close socket and set as error on socket error or unexpected client hangup */ struct sandbox *sandbox = (struct sandbox *)epoll_events[i].data.ptr; int error = 0; @@ -251,9 +253,11 @@ worker_thread_execute_epoll_loop(void) panic("Expected to have closed socket"); default: client_socket_send(sandbox->client_socket_descriptor, 503); - client_socket_close(sandbox->client_socket_descriptor); + sandbox_close_http(sandbox); sandbox_set_as_error(sandbox, sandbox->state); } + } else { + panic("Mystery epoll event!\n"); }; } }