|
|
@ -49,24 +49,24 @@ sandbox_setup_arguments(struct sandbox *sandbox)
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Run the http-parser on the sandbox's request_response_data using the configured settings global
|
|
|
|
* Run the http-parser on the sandbox's request_response_data using the configured settings global
|
|
|
|
|
|
|
|
* Success means that a "chunk" was fully parsed, not that parsing of a full request is complete
|
|
|
|
* @param sandbox the sandbox containing the req_resp data that we want to parse
|
|
|
|
* @param sandbox the sandbox containing the req_resp data that we want to parse
|
|
|
|
* @param length The size of the request_response_data that we want to parse
|
|
|
|
* @param length The size of the data that we want to parse
|
|
|
|
* @returns 0 on success, -1 on failure
|
|
|
|
* @returns 0 on success, -1 on failure
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
int
|
|
|
|
sandbox_parse_http_request(struct sandbox *sandbox, size_t length)
|
|
|
|
sandbox_parse_http_request(struct sandbox *sandbox, size_t length_read)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
assert(sandbox != NULL);
|
|
|
|
assert(sandbox != NULL);
|
|
|
|
|
|
|
|
|
|
|
|
if (length == 0) return 0;
|
|
|
|
if (length_read == 0) return 0;
|
|
|
|
|
|
|
|
|
|
|
|
/* Why is our start address sandbox->request_response_data + sandbox->request_response_data_length?
|
|
|
|
size_t length_parsed = http_parser_execute(&sandbox->http_parser, http_parser_settings_get(),
|
|
|
|
it's like a cursor to keep track of what we've read so far */
|
|
|
|
sandbox->request_response_data
|
|
|
|
size_t size_parsed = http_parser_execute(&sandbox->http_parser, http_parser_settings_get(),
|
|
|
|
+ sandbox->request_response_data_length,
|
|
|
|
sandbox->request_response_data + sandbox->request_response_data_length,
|
|
|
|
length_read);
|
|
|
|
length);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (size_parsed != length) return -1;
|
|
|
|
if (length_parsed != length_read) return -1;
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -81,28 +81,32 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
|
|
|
|
assert(sandbox->module->max_request_size > 0);
|
|
|
|
assert(sandbox->module->max_request_size > 0);
|
|
|
|
assert(sandbox->request_response_data_length == 0);
|
|
|
|
assert(sandbox->request_response_data_length == 0);
|
|
|
|
|
|
|
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef USE_HTTP_UVIO
|
|
|
|
#ifndef USE_HTTP_UVIO
|
|
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
/* Read from the Socket */
|
|
|
|
/* Read from the Socket */
|
|
|
|
int length_read = recv(sandbox->client_socket_descriptor,
|
|
|
|
rc = read(sandbox->client_socket_descriptor, sandbox->request_response_data,
|
|
|
|
&sandbox->request_response_data[sandbox->request_response_data_length],
|
|
|
|
sandbox->module->max_request_size);
|
|
|
|
sandbox->module->max_request_size - sandbox->request_response_data_length, 0);
|
|
|
|
if (rc < 0) {
|
|
|
|
if (length_read < 0) {
|
|
|
|
if (errno == EAGAIN) continue;
|
|
|
|
if (errno == EAGAIN) goto eagain;
|
|
|
|
|
|
|
|
|
|
|
|
debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno));
|
|
|
|
/* All other errors */
|
|
|
|
goto err;
|
|
|
|
debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno));
|
|
|
|
}
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Parse what we've read */
|
|
|
|
/* Try to parse what we've read */
|
|
|
|
if (sandbox_parse_http_request(sandbox, rc) == -1) {
|
|
|
|
if (sandbox_parse_http_request(sandbox, length_read) < 0) {
|
|
|
|
debuglog("Error parsing socket %d\n", sandbox->client_socket_descriptor);
|
|
|
|
debuglog("Error parsing socket %d\n", sandbox->client_socket_descriptor);
|
|
|
|
goto err;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sandbox->request_response_data_length += rc;
|
|
|
|
|
|
|
|
} while (rc > 0);
|
|
|
|
sandbox->request_response_data_length += length_read;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!sandbox->http_request.message_end) goto eagain;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sandbox->request_length = sandbox->request_response_data_length;
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
rc = uv_read_start((uv_stream_t *)&sandbox->client_libuv_stream,
|
|
|
|
rc = uv_read_start((uv_stream_t *)&sandbox->client_libuv_stream,
|
|
|
@ -111,10 +115,7 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
|
|
|
|
worker_thread_process_io();
|
|
|
|
worker_thread_process_io();
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (!sandbox->http_request.message_end) goto eagain;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
|
|
|
|
sandbox->request_length = sandbox->request_response_data_length;
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
|
|
|
|
done:
|
|
|
|
done:
|
|
|
|
return rc;
|
|
|
|
return rc;
|
|
|
|
eagain:
|
|
|
|
eagain:
|
|
|
@ -310,11 +311,10 @@ current_sandbox_main(void)
|
|
|
|
|
|
|
|
|
|
|
|
sandbox_open_http(sandbox);
|
|
|
|
sandbox_open_http(sandbox);
|
|
|
|
|
|
|
|
|
|
|
|
/* Parse the request. Treat EAGAIN as an error after three retries*/
|
|
|
|
/* Parse the request, polling until complete */
|
|
|
|
int tries = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
do {
|
|
|
|
rc = sandbox_receive_and_parse_client_request(sandbox);
|
|
|
|
rc = sandbox_receive_and_parse_client_request(sandbox);
|
|
|
|
} while (rc == -EAGAIN && tries < 3);
|
|
|
|
} while (rc == -EAGAIN);
|
|
|
|
|
|
|
|
|
|
|
|
if (rc < 0) {
|
|
|
|
if (rc < 0) {
|
|
|
|
error_message = "Unable to receive and parse client request\n";
|
|
|
|
error_message = "Unable to receive and parse client request\n";
|
|
|
@ -324,7 +324,7 @@ current_sandbox_main(void)
|
|
|
|
/* Initialize the module */
|
|
|
|
/* Initialize the module */
|
|
|
|
struct module *current_module = sandbox_get_module(sandbox);
|
|
|
|
struct module *current_module = sandbox_get_module(sandbox);
|
|
|
|
int argument_count = module_get_argument_count(current_module);
|
|
|
|
int argument_count = module_get_argument_count(current_module);
|
|
|
|
// alloc_linear_memory();
|
|
|
|
|
|
|
|
module_initialize_globals(current_module);
|
|
|
|
module_initialize_globals(current_module);
|
|
|
|
module_initialize_memory(current_module);
|
|
|
|
module_initialize_memory(current_module);
|
|
|
|
|
|
|
|
|
|
|
@ -344,7 +344,6 @@ current_sandbox_main(void)
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef LOG_TOTAL_REQS_RESPS
|
|
|
|
#ifdef LOG_TOTAL_REQS_RESPS
|
|
|
|
runtime_total_2XX_responses++;
|
|
|
|
runtime_total_2XX_responses++;
|
|
|
|
runtime_log_requests_responses();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
sandbox->response_timestamp = __getcycles();
|
|
|
|
sandbox->response_timestamp = __getcycles();
|
|
|
@ -364,7 +363,7 @@ done:
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
assert(0);
|
|
|
|
assert(0);
|
|
|
|
err:
|
|
|
|
err:
|
|
|
|
fprintf(stderr, "%s", error_message);
|
|
|
|
debuglog("%s", error_message);
|
|
|
|
assert(sandbox->state == SANDBOX_RUNNING);
|
|
|
|
assert(sandbox->state == SANDBOX_RUNNING);
|
|
|
|
|
|
|
|
|
|
|
|
int to_send = strlen(HTTP_RESPONSE_400_BAD_REQUEST);
|
|
|
|
int to_send = strlen(HTTP_RESPONSE_400_BAD_REQUEST);
|
|
|
@ -385,7 +384,6 @@ err:
|
|
|
|
#ifdef LOG_TOTAL_REQS_RESPS
|
|
|
|
#ifdef LOG_TOTAL_REQS_RESPS
|
|
|
|
runtime_total_4XX_responses++;
|
|
|
|
runtime_total_4XX_responses++;
|
|
|
|
debuglog("At %llu, Sandbox %lu - 4XX\n", __getcycles(), sandbox->request_arrival_timestamp);
|
|
|
|
debuglog("At %llu, Sandbox %lu - 4XX\n", __getcycles(), sandbox->request_arrival_timestamp);
|
|
|
|
runtime_log_requests_responses();
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
software_interrupt_disable();
|
|
|
|
software_interrupt_disable();
|
|
|
|
sandbox_close_http(sandbox);
|
|
|
|
sandbox_close_http(sandbox);
|
|
|
@ -525,6 +523,9 @@ sandbox_set_as_initialized(struct sandbox *sandbox, struct sandbox_request *sand
|
|
|
|
memcpy(&sandbox->client_address, sandbox_request->socket_address, sizeof(struct sockaddr));
|
|
|
|
memcpy(&sandbox->client_address, sandbox_request->socket_address, sizeof(struct sockaddr));
|
|
|
|
|
|
|
|
|
|
|
|
sandbox->state = SANDBOX_INITIALIZED;
|
|
|
|
sandbox->state = SANDBOX_INITIALIZED;
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_initialized_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -557,10 +558,18 @@ sandbox_set_as_runnable(struct sandbox *sandbox, sandbox_state_t last_state)
|
|
|
|
switch (last_state) {
|
|
|
|
switch (last_state) {
|
|
|
|
case SANDBOX_INITIALIZED: {
|
|
|
|
case SANDBOX_INITIALIZED: {
|
|
|
|
sandbox->initializing_duration += duration_of_last_state;
|
|
|
|
sandbox->initializing_duration += duration_of_last_state;
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_initialized_sandboxes--;
|
|
|
|
|
|
|
|
runtime_total_runnable_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case SANDBOX_BLOCKED: {
|
|
|
|
case SANDBOX_BLOCKED: {
|
|
|
|
sandbox->blocked_duration += duration_of_last_state;
|
|
|
|
sandbox->blocked_duration += duration_of_last_state;
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_blocked_sandboxes--;
|
|
|
|
|
|
|
|
runtime_total_runnable_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
default: {
|
|
|
@ -605,10 +614,18 @@ sandbox_set_as_running(struct sandbox *sandbox, sandbox_state_t last_state)
|
|
|
|
switch (last_state) {
|
|
|
|
switch (last_state) {
|
|
|
|
case SANDBOX_RUNNABLE: {
|
|
|
|
case SANDBOX_RUNNABLE: {
|
|
|
|
sandbox->runnable_duration += duration_of_last_state;
|
|
|
|
sandbox->runnable_duration += duration_of_last_state;
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_runnable_sandboxes--;
|
|
|
|
|
|
|
|
runtime_total_running_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case SANDBOX_PREEMPTED: {
|
|
|
|
case SANDBOX_PREEMPTED: {
|
|
|
|
sandbox->preempted_duration += duration_of_last_state;
|
|
|
|
sandbox->preempted_duration += duration_of_last_state;
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_preempted_sandboxes--;
|
|
|
|
|
|
|
|
runtime_total_running_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
default: {
|
|
|
@ -650,6 +667,10 @@ sandbox_set_as_preempted(struct sandbox *sandbox, sandbox_state_t last_state)
|
|
|
|
switch (last_state) {
|
|
|
|
switch (last_state) {
|
|
|
|
case SANDBOX_RUNNING: {
|
|
|
|
case SANDBOX_RUNNING: {
|
|
|
|
sandbox->running_duration += duration_of_last_state;
|
|
|
|
sandbox->running_duration += duration_of_last_state;
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_running_sandboxes--;
|
|
|
|
|
|
|
|
runtime_total_preempted_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
default: {
|
|
|
@ -689,6 +710,10 @@ sandbox_set_as_blocked(struct sandbox *sandbox, sandbox_state_t last_state)
|
|
|
|
case SANDBOX_RUNNING: {
|
|
|
|
case SANDBOX_RUNNING: {
|
|
|
|
sandbox->running_duration += duration_of_last_state;
|
|
|
|
sandbox->running_duration += duration_of_last_state;
|
|
|
|
local_runqueue_delete(sandbox);
|
|
|
|
local_runqueue_delete(sandbox);
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_running_sandboxes--;
|
|
|
|
|
|
|
|
runtime_total_blocked_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
default: {
|
|
|
@ -732,6 +757,10 @@ sandbox_set_as_returned(struct sandbox *sandbox, sandbox_state_t last_state)
|
|
|
|
sandbox->running_duration += duration_of_last_state;
|
|
|
|
sandbox->running_duration += duration_of_last_state;
|
|
|
|
local_runqueue_delete(sandbox);
|
|
|
|
local_runqueue_delete(sandbox);
|
|
|
|
sandbox_free_linear_memory(sandbox);
|
|
|
|
sandbox_free_linear_memory(sandbox);
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_running_sandboxes--;
|
|
|
|
|
|
|
|
runtime_total_returned_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
default: {
|
|
|
@ -774,10 +803,18 @@ sandbox_set_as_error(struct sandbox *sandbox, sandbox_state_t last_state)
|
|
|
|
case SANDBOX_SET_AS_INITIALIZED:
|
|
|
|
case SANDBOX_SET_AS_INITIALIZED:
|
|
|
|
/* Technically, this is a degenerate sandbox that we generate by hand */
|
|
|
|
/* Technically, this is a degenerate sandbox that we generate by hand */
|
|
|
|
sandbox->initializing_duration += duration_of_last_state;
|
|
|
|
sandbox->initializing_duration += duration_of_last_state;
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_initialized_sandboxes--;
|
|
|
|
|
|
|
|
runtime_total_error_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case SANDBOX_RUNNING: {
|
|
|
|
case SANDBOX_RUNNING: {
|
|
|
|
sandbox->running_duration += duration_of_last_state;
|
|
|
|
sandbox->running_duration += duration_of_last_state;
|
|
|
|
local_runqueue_delete(sandbox);
|
|
|
|
local_runqueue_delete(sandbox);
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_running_sandboxes--;
|
|
|
|
|
|
|
|
runtime_total_error_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
default: {
|
|
|
@ -829,6 +866,10 @@ sandbox_set_as_complete(struct sandbox *sandbox, sandbox_state_t last_state)
|
|
|
|
case SANDBOX_RETURNED: {
|
|
|
|
case SANDBOX_RETURNED: {
|
|
|
|
sandbox->completion_timestamp = now;
|
|
|
|
sandbox->completion_timestamp = now;
|
|
|
|
sandbox->returned_duration += duration_of_last_state;
|
|
|
|
sandbox->returned_duration += duration_of_last_state;
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_returned_sandboxes--;
|
|
|
|
|
|
|
|
runtime_total_complete_sandboxes++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
default: {
|
|
|
@ -897,6 +938,9 @@ sandbox_allocate(struct sandbox_request *sandbox_request)
|
|
|
|
/* Set state to initializing */
|
|
|
|
/* Set state to initializing */
|
|
|
|
sandbox_set_as_initialized(sandbox, sandbox_request, now);
|
|
|
|
sandbox_set_as_initialized(sandbox, sandbox_request, now);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef LOG_SANDBOX_TOTALS
|
|
|
|
|
|
|
|
runtime_total_freed_requests++;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
free(sandbox_request);
|
|
|
|
free(sandbox_request);
|
|
|
|
done:
|
|
|
|
done:
|
|
|
|
return sandbox;
|
|
|
|
return sandbox;
|
|
|
|