chore: assorted socket error handling

main
Sean McBride 4 years ago
parent 9d19d55179
commit 012729ada1

@ -14,9 +14,7 @@
static inline void static inline void
client_socket_close(int client_socket) client_socket_close(int client_socket)
{ {
int rc = epoll_ctl(worker_thread_epoll_file_descriptor, EPOLL_CTL_DEL, client_socket, NULL); // debuglog("Closing Socket\n");
if (unlikely(rc < 0)) panic_err();
if (close(client_socket) < 0) debuglog("Error closing client socket - %s", strerror(errno)); 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 client_socket - the client we are rejecting
* @param status_code - either 503 or 400 * @param status_code - either 503 or 400
*/ */
static inline void static inline int
client_socket_send(int client_socket, int status_code) client_socket_send(int client_socket, int status_code)
{ {
const char *response; const char *response;
int rc;
switch (status_code) { switch (status_code) {
case 503: case 503:
response = HTTP_RESPONSE_503_SERVICE_UNAVAILABLE; response = HTTP_RESPONSE_503_SERVICE_UNAVAILABLE;
@ -37,12 +36,15 @@ client_socket_send(int client_socket, int status_code)
break; break;
case 400: case 400:
response = HTTP_RESPONSE_400_BAD_REQUEST; response = HTTP_RESPONSE_400_BAD_REQUEST;
#ifdef LOG_TOTAL_REQS_RESPS
atomic_fetch_add(&runtime_total_4XX_responses, 1);
#endif
break; break;
default: default:
panic("%d is not a valid status code\n", status_code); panic("%d is not a valid status code\n", status_code);
} }
int rc;
int sent = 0; int sent = 0;
int to_send = strlen(response); int to_send = strlen(response);
@ -56,9 +58,11 @@ client_socket_send(int client_socket, int status_code)
sent += rc; sent += rc;
}; };
rc = 0;
done: done:
return; return rc;
send_err: send_err:
debuglog("Error sending to client: %s", strerror(errno)); debuglog("Error sending to client: %s", strerror(errno));
rc = -1;
goto done; goto done;
} }

@ -1,6 +1,8 @@
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h>
#include "http.h" #include "http.h"
/* all in-memory ptrs.. don't mess around with that! */ /* 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 */ 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 * * General HTTP Request Functions *
**************************************************/ **************************************************/

@ -321,6 +321,9 @@ sandbox_close_http(struct sandbox *sandbox)
{ {
assert(sandbox != NULL); 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); client_socket_close(sandbox->client_socket_descriptor);
} }

@ -56,7 +56,7 @@ sandbox_request_allocate(struct module *module, char *arguments, int socket_desc
sandbox_request->admissions_estimate = admissions_estimate; sandbox_request->admissions_estimate = admissions_estimate;
#ifdef LOG_REQUEST_ALLOCATION #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); sandbox_request->module->port);
#endif #endif
return sandbox_request; return sandbox_request;

@ -84,7 +84,8 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
} }
#ifdef LOG_HTTP_PARSER #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 #endif
size_t nparsed = http_parser_execute(parser, settings, buf, recved); 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; 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; sandbox->request_response_data_length += nparsed;
} }
@ -324,15 +333,8 @@ err:
/* Send a 400 error back to the client */ /* Send a 400 error back to the client */
client_socket_send(sandbox->client_socket_descriptor, 400); 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(); software_interrupt_disable();
client_socket_close(sandbox->client_socket_descriptor); sandbox_close_http(sandbox);
sandbox_set_as_error(sandbox, SANDBOX_RUNNING); sandbox_set_as_error(sandbox, SANDBOX_RUNNING);
goto done; goto done;
} }

@ -227,6 +227,8 @@ worker_thread_execute_epoll_loop(void)
if (sandbox->state == SANDBOX_BLOCKED) worker_thread_wakeup_sandbox(sandbox); if (sandbox->state == SANDBOX_BLOCKED) worker_thread_wakeup_sandbox(sandbox);
} else if (epoll_events[i].events & (EPOLLERR | EPOLLHUP)) { } 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 */ /* Close socket and set as error on socket error or unexpected client hangup */
struct sandbox *sandbox = (struct sandbox *)epoll_events[i].data.ptr; struct sandbox *sandbox = (struct sandbox *)epoll_events[i].data.ptr;
int error = 0; int error = 0;
@ -251,9 +253,11 @@ worker_thread_execute_epoll_loop(void)
panic("Expected to have closed socket"); panic("Expected to have closed socket");
default: default:
client_socket_send(sandbox->client_socket_descriptor, 503); 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); sandbox_set_as_error(sandbox, sandbox->state);
} }
} else {
panic("Mystery epoll event!\n");
}; };
} }
} }

Loading…
Cancel
Save