chore: assorted socket error handling

main
Sean McBride 4 years ago
parent 32099fa948
commit f7df3c876e

@ -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;
}

@ -1,6 +1,8 @@
#pragma once
#include <stdbool.h>
#include <stdio.h>
#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 *
**************************************************/

@ -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);
}

@ -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;

@ -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;
}

@ -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");
};
}
}

Loading…
Cancel
Save