Add Bounded Ordinary HTTPS Idle Cleanup
This commit is contained in:
@@ -108,7 +108,28 @@ static void secure_wipe(void *p, size_t n) { assert(!locked); memset(p, 0, n); }
|
||||
HANDLER(root_handler) HANDLER(status_handler) HANDLER(traced_ticket_handler)
|
||||
HANDLER(traced_websocket_handler) HANDLER(asset_handler) HANDLER(web_cookie_auth_handler)
|
||||
HANDLER(traced_admin_ticket_handler) HANDLER(traced_admin_upgrade_handler)
|
||||
static void web_diagnostics_tls(void *arg) { (void)arg; assert(false); }
|
||||
typedef void esp_https_server_user_cb_arg_t;
|
||||
static unsigned tls_steps;
|
||||
static void web_httpd_idle_tls(void *arg) { assert(arg && tls_steps == 0); ++tls_steps; }
|
||||
static void web_diagnostics_tls(void *arg) { assert(arg && tls_steps == 1); ++tls_steps; }
|
||||
static void tls_session_callback(esp_https_server_user_cb_arg_t *arg);
|
||||
static bool idle_owned, idle_fenced;
|
||||
static esp_err_t idle_prepare_error, idle_attach_error, idle_detach_error;
|
||||
static unsigned idle_prepares, idle_attaches, idle_detaches, idle_stoppeds;
|
||||
static esp_err_t web_httpd_idle_prepare(void) {
|
||||
assert(!locked && !ssl_live && !idle_owned); ++idle_prepares; return idle_prepare_error;
|
||||
}
|
||||
static esp_err_t web_httpd_idle_attach(httpd_handle_t s) {
|
||||
assert(!locked && s == SERVER && ssl_live && !idle_owned); ++idle_attaches;
|
||||
idle_owned = idle_attach_error == ESP_OK; idle_fenced = false; return idle_attach_error;
|
||||
}
|
||||
static esp_err_t web_httpd_idle_detach(httpd_handle_t s) {
|
||||
assert(!locked && s == SERVER && ssl_live && !auth_live); ++idle_detaches;
|
||||
idle_fenced = idle_detach_error == ESP_OK; return idle_detach_error;
|
||||
}
|
||||
static void web_httpd_idle_stopped(httpd_handle_t s) {
|
||||
assert(!locked && s == SERVER && !ssl_live && idle_fenced); ++idle_stoppeds; idle_owned = false;
|
||||
}
|
||||
HANDLER(serial_settings_handler)
|
||||
HANDLER(web_serial_settings_handler) HANDLER(web_account_settings_handler)
|
||||
HANDLER(web_account_generate_password_handler) HANDLER(web_account_keys_handler)
|
||||
@@ -131,7 +152,8 @@ static esp_err_t httpd_ssl_start(httpd_handle_t *server, const httpd_ssl_config_
|
||||
assert(config->httpd.max_uri_handlers == 24 && config->port_secure == 443);
|
||||
assert(config->httpd.recv_wait_timeout == 1 && config->httpd.send_wait_timeout == 1);
|
||||
assert(config->tls_handshake_timeout_ms == 5000);
|
||||
assert(config->user_cb == web_diagnostics_tls);
|
||||
assert(config->user_cb == tls_session_callback);
|
||||
tls_steps = 0; config->user_cb(&tls_steps); assert(tls_steps == 2);
|
||||
assert(config->servercert_len == 1 && config->servercert[0] == 1);
|
||||
assert(config->prvtkey_len == 1 && config->prvtkey_pem[0] == 2);
|
||||
if (ssl_start_error != ESP_OK) return ssl_start_error;
|
||||
@@ -233,7 +255,7 @@ static esp_err_t web_serial_transport_detach_server(httpd_handle_t s) {
|
||||
event('S'); ++serial_detaches; serial_live = false; return ESP_OK;
|
||||
}
|
||||
static esp_err_t httpd_ssl_stop(httpd_handle_t s) {
|
||||
assert(s == SERVER && ssl_live && !auth_live); event('H'); ++ssl_stops;
|
||||
assert(s == SERVER && ssl_live && !auth_live && idle_fenced); event('H'); ++ssl_stops;
|
||||
if (ssl_stop_error == ESP_OK) ssl_live = false;
|
||||
return ssl_stop_error;
|
||||
}
|
||||
@@ -253,6 +275,9 @@ static void reset(void) {
|
||||
s_last_error = s_serial_transport_error = ESP_ERR_INVALID_STATE;
|
||||
memset(&s_counters, 0, sizeof(s_counters));
|
||||
mutex_fail = auth_live = ssl_live = admin_owned = serial_live = false;
|
||||
idle_owned = idle_fenced = false;
|
||||
idle_prepare_error = idle_attach_error = idle_detach_error = ESP_OK;
|
||||
idle_prepares = idle_attaches = idle_detaches = idle_stoppeds = 0;
|
||||
serial_init_error = admin_init_error = admin_attach_error = ESP_OK;
|
||||
auth_error = ssl_start_error = ssl_stop_error = admin_detach_error = ESP_OK;
|
||||
serial_inits = admin_inits = auth_starts = auth_stops = ssl_starts = ssl_stops = 0;
|
||||
@@ -267,7 +292,7 @@ static void fresh_registration(void) { registration_calls = registered_count = 0
|
||||
static void start(void) {
|
||||
assert(web_server_start() == ESP_OK);
|
||||
assert(s_server == SERVER && s_admin_transport_owned && s_serial_transport_attached);
|
||||
assert(auth_live && ssl_live && admin_owned && serial_live && !s_transitioning);
|
||||
assert(auth_live && ssl_live && admin_owned && serial_live && !s_transitioning && idle_owned);
|
||||
}
|
||||
static const httpd_uri_t *route(const char *uri) {
|
||||
const httpd_uri_t *found = NULL;
|
||||
@@ -468,12 +493,32 @@ int main(void) {
|
||||
assert(route("/api/settings/accounts/keys")->handler == web_account_keys_handler);
|
||||
assert(web_server_stop() == ESP_OK);
|
||||
puts("PASS optional account keys allocation failure preserves account/generation/auth/transports; restart recovers");
|
||||
puts("16 lifecycle groups passed (16 required fatal positions, 10 optional routes, plus failed unregister)");
|
||||
reset(); idle_prepare_error = ESP_ERR_NO_MEM;
|
||||
assert(web_server_start() == ESP_ERR_NO_MEM && !ssl_starts && !auth_live);
|
||||
assert(idle_prepares == 1 && !idle_attaches && !s_server);
|
||||
reset(); idle_attach_error = ESP_FAIL;
|
||||
assert(web_server_start() == ESP_FAIL && !ssl_live && !s_server);
|
||||
assert(idle_detaches == 1 && idle_stoppeds == 1 && !serial_attaches);
|
||||
puts("PASS idle timer preparation/attachment failures gate startup and clean partial HTTPD");
|
||||
reset(); start(); idle_detach_error = ESP_ERR_TIMEOUT;
|
||||
assert(web_server_stop() == ESP_ERR_TIMEOUT && ssl_live && idle_owned);
|
||||
assert(!ssl_stops && !admin_detaches && !serial_detaches && !idle_stoppeds);
|
||||
assert(!s_transitioning && s_server == SERVER && web_server_start() == ESP_ERR_INVALID_STATE);
|
||||
idle_detach_error = ESP_OK; ssl_stop_error = ESP_FAIL;
|
||||
assert(web_server_stop() == ESP_FAIL && idle_owned && !idle_stoppeds);
|
||||
ssl_stop_error = ESP_OK;
|
||||
assert(web_server_stop() == ESP_OK && !idle_owned && idle_stoppeds == 1);
|
||||
fresh_registration(); start(); assert(web_server_stop() == ESP_OK);
|
||||
puts("PASS idle submit fence failure forbids SSL destruction; failed stop retains ownership until retry/restart");
|
||||
puts("18 lifecycle groups passed (16 required fatal positions, 10 optional routes, plus failed unregister)");
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
|
||||
unit = FAKES + header + '\n' + constants + state + '\n'.join(uri_tables)
|
||||
callback = re.search(r'^static void tls_session_callback\(.*?^\}', source, re.M | re.S)
|
||||
assert callback
|
||||
unit += callback.group() + '\n'
|
||||
unit += function('ensure_mutex')
|
||||
unit += ''.join(function(name) for name in ('web_server_init', 'web_server_start', 'web_server_stop'))
|
||||
unit += TESTS
|
||||
|
||||
Reference in New Issue
Block a user