chore: assorted socket error handling

master
Sean McBride 5 years ago
parent 9ead528dfc
commit c1edca2a42

@ -12,7 +12,7 @@
#endif #endif
#define LISTENER_THREAD_CORE_ID 0 /* Dedicated Listener Core */ #define LISTENER_THREAD_CORE_ID 0 /* Dedicated Listener Core */
#define LISTENER_THREAD_MAX_EPOLL_EVENTS 1024 #define LISTENER_THREAD_MAX_EPOLL_EVENTS 2048
#define RUNTIME_LOG_FILE "awesome.log" #define RUNTIME_LOG_FILE "awesome.log"
#define RUNTIME_MAX_SANDBOX_REQUEST_COUNT (1 << 19) /* random! */ #define RUNTIME_MAX_SANDBOX_REQUEST_COUNT (1 << 19) /* random! */
@ -83,9 +83,12 @@ runtime_is_worker()
static inline void static inline void
runtime_log_requests_responses() runtime_log_requests_responses()
{ {
debuglog("Requests: %u\n2XX: %u\n4XX: %u\n5XX: %u\nOutstanding Requests: %u\n", runtime_total_requests, int64_t total_responses = runtime_total_2XX_responses + runtime_total_4XX_responses
runtime_total_2XX_responses, runtime_total_4XX_responses, runtime_total_5XX_responses, + runtime_total_5XX_responses;
runtime_total_requests - runtime_total_2XX_responses - runtime_total_4XX_responses int64_t outstanding_requests = (int64_t)runtime_total_requests - total_responses;
- runtime_total_5XX_responses);
debuglog("Requests: %u (%ld outstanding)\n\tResponses: %ld\n\t\t2XX: %u\n\t\t4XX: %u\n\t\t5XX: %u\n",
runtime_total_requests, outstanding_requests, total_responses, runtime_total_2XX_responses,
runtime_total_4XX_responses, runtime_total_5XX_responses);
}; };
#endif #endif

@ -73,14 +73,14 @@ runtime_initialize(void)
/** /**
* Rejects Requests as determined by admissions control * Rejects Requests as determined by admissions control
* @param socket_descriptor - the client we are rejecting * @param client_socket - the client we are rejecting
*/ */
static inline void static inline void
listener_thread_reject(int socket_descriptor) listener_thread_reject(int client_socket)
{ {
assert(socket_descriptor >= 0); assert(client_socket >= 0);
int send_rc = send(socket_descriptor, HTTP_RESPONSE_504_SERVICE_UNAVAILABLE, int send_rc = send(client_socket, HTTP_RESPONSE_504_SERVICE_UNAVAILABLE,
strlen(HTTP_RESPONSE_504_SERVICE_UNAVAILABLE), 0); strlen(HTTP_RESPONSE_504_SERVICE_UNAVAILABLE), 0);
if (send_rc < 0) goto send_504_err; if (send_rc < 0) goto send_504_err;
@ -90,7 +90,7 @@ listener_thread_reject(int socket_descriptor)
#endif #endif
close: close:
if (close(socket_descriptor) < 0) panic("Error closing client socket - %s", strerror(errno)); if (close(client_socket) < 0) panic("Error closing client socket - %s", strerror(errno));
return; return;
send_504_err: send_504_err:
debuglog("Error sending 504: %s", strerror(errno)); debuglog("Error sending 504: %s", strerror(errno));
@ -116,31 +116,48 @@ listener_thread_main(void *dummy)
while (true) { while (true) {
int request_count = epoll_wait(runtime_epoll_file_descriptor, epoll_events, int request_count = epoll_wait(runtime_epoll_file_descriptor, epoll_events,
LISTENER_THREAD_MAX_EPOLL_EVENTS, -1); LISTENER_THREAD_MAX_EPOLL_EVENTS, -1);
if (request_count < 0) panic("epoll_wait: %s", strerror(errno));
if (request_count == 0) panic("Unexpectedly returned with epoll_wait timeout not set\n");
/* Capture Start Time to calculate absolute deadline */ /* Capture Start Time to calculate absolute deadline */
uint64_t request_arrival_timestamp = __getcycles(); uint64_t request_arrival_timestamp = __getcycles();
for (int i = 0; i < request_count; i++) { for (int i = 0; i < request_count; i++) {
if (epoll_events[i].events & EPOLLERR) { if (epoll_events[i].events & EPOLLERR) panic("epoll_wait: %s", strerror(errno));
perror("epoll_wait");
assert(false);
}
/* Accept Client Request */ /* Accept Client Request */
struct sockaddr_in client_address; struct sockaddr_in client_address;
socklen_t client_length = sizeof(client_address); socklen_t client_length = sizeof(client_address);
struct module * module = (struct module *)epoll_events[i].data.ptr; struct module * module = (struct module *)epoll_events[i].data.ptr;
assert(module); assert(module);
int es = module->socket_descriptor; int server_socket = module->socket_descriptor;
int socket_descriptor = accept(es, (struct sockaddr *)&client_address, &client_length); int client_socket = accept(server_socket, (struct sockaddr *)&client_address, &client_length);
if (socket_descriptor < 0) { if (client_socket < 0) panic("accept: %s", strerror(errno));
perror("accept");
assert(false);
}
#ifdef LOG_TOTAL_REQS_RESPS #ifdef LOG_TOTAL_REQS_RESPS
runtime_total_requests++; runtime_total_requests++;
runtime_log_requests_responses(); runtime_log_requests_responses();
#endif #endif
/* Peek to ensure the socket isn't empty. Return 400 and close if empty */
char peek_buffer[10];
int bytes = recv(client_socket, &peek_buffer, 9, MSG_PEEK);
if (bytes < 0) panic("Peek: %s\n", strerror(errno));
if (bytes == 0) {
send(client_socket, HTTP_RESPONSE_400_BAD_REQUEST,
strlen(HTTP_RESPONSE_400_BAD_REQUEST), 0);
if (close(client_socket) < 0) {
panic("Error closing client socket - %s", strerror(errno));
}
#ifdef LOG_TOTAL_REQS_RESPS
runtime_total_4XX_responses++;
debuglog("Listener Core rejected empty request\n");
runtime_log_requests_responses();
#endif
/* Advance in for loop to next socket */
continue;
};
/* Perform Admission Control */ /* Perform Admission Control */
uint32_t estimated_execution = perf_window_get_percentile(&module->perf_window, 0.5); uint32_t estimated_execution = perf_window_get_percentile(&module->perf_window, 0.5);
@ -153,13 +170,13 @@ listener_thread_main(void *dummy)
double admissions_estimate = (double)estimated_execution / module->relative_deadline; double admissions_estimate = (double)estimated_execution / module->relative_deadline;
if (runtime_admitted + admissions_estimate >= runtime_worker_threads_count) { if (runtime_admitted + admissions_estimate >= runtime_worker_threads_count) {
listener_thread_reject(socket_descriptor); listener_thread_reject(client_socket);
continue; continue;
} }
/* Allocate a Sandbox Request */ /* Allocate a Sandbox Request */
struct sandbox_request *sandbox_request = struct sandbox_request *sandbox_request =
sandbox_request_allocate(module, module->name, socket_descriptor, sandbox_request_allocate(module, module->name, client_socket,
(const struct sockaddr *)&client_address, request_arrival_timestamp, (const struct sockaddr *)&client_address, request_arrival_timestamp,
admissions_estimate); admissions_estimate);

@ -74,14 +74,15 @@ static inline int
sandbox_receive_and_parse_client_request(struct sandbox *sandbox) sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
{ {
assert(sandbox != NULL); assert(sandbox != NULL);
assert(sandbox->module->max_request_size > 0);
sandbox->request_response_data_length = 0; assert(sandbox->request_response_data_length == 0);
#ifndef USE_HTTP_UVIO #ifndef USE_HTTP_UVIO
int r = 0; int r = 0;
r = recv(sandbox->client_socket_descriptor, (sandbox->request_response_data), sandbox->module->max_request_size, r = recv(sandbox->client_socket_descriptor, sandbox->request_response_data, sandbox->module->max_request_size,
0); 0);
if (r == 0) debuglog("Socket %d returned 0 bytes\n", sandbox->client_socket_descriptor);
if (r < 0) { if (r < 0) {
debuglog("Error reading request data from client socket - %s", strerror(errno)); debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno));
return r; return r;
} }
while (r > 0) { while (r > 0) {
@ -94,7 +95,7 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
(sandbox->request_response_data + sandbox->request_response_data_length), (sandbox->request_response_data + sandbox->request_response_data_length),
sandbox->module->max_request_size - sandbox->request_response_data_length, 0); sandbox->module->max_request_size - sandbox->request_response_data_length, 0);
if (r < 0) { if (r < 0) {
debuglog("Error reading request data from client socket - %s", strerror(errno)); debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno));
return r; return r;
} }
} }
@ -105,7 +106,7 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
worker_thread_process_io(); worker_thread_process_io();
#endif #endif
if (sandbox->request_response_data_length == 0) { if (sandbox->request_response_data_length == 0) {
debuglog("request_response_data_length was unexpectedly 0"); debuglog("request_response_data_length was unexpectedly 0\n");
return 0; return 0;
} }
sandbox->request_length = sandbox->request_response_data_length; sandbox->request_length = sandbox->request_response_data_length;

Loading…
Cancel
Save