diff --git a/components/esp_https_server/include/esp_https_server.h b/components/esp_https_server/include/esp_https_server.h index ce93ef5940..99ff8a9538 100644 --- a/components/esp_https_server/include/esp_https_server.h +++ b/components/esp_https_server/include/esp_https_server.h @@ -39,11 +39,12 @@ typedef enum { /** * @brief Indicates the state at which the user callback is executed, - * i.e at session creation or session close + * i.e at session creation, session close, or session error */ typedef enum { HTTPD_SSL_USER_CB_SESS_CREATE, - HTTPD_SSL_USER_CB_SESS_CLOSE + HTTPD_SSL_USER_CB_SESS_CLOSE, + HTTPD_SSL_USER_CB_SESS_ERROR } httpd_ssl_user_cb_state_t; typedef esp_tls_handshake_callback esp_https_server_cert_select_cb; diff --git a/components/esp_https_server/src/https_server.c b/components/esp_https_server/src/https_server.c index 0585e5418f..ea94b3127a 100644 --- a/components/esp_https_server/src/https_server.c +++ b/components/esp_https_server/src/https_server.c @@ -234,6 +234,13 @@ fail: last_error.last_error = esp_tls_get_and_clear_last_error(error_handle, &last_error.esp_tls_error_code, &last_error.esp_tls_flags); http_dispatch_event_to_event_loop(HTTPS_SERVER_EVENT_ERROR, &last_error, sizeof(last_error)); } + // Call user callback if configured, allowing user to log failures + if (global_ctx->user_cb) { + esp_https_server_user_cb_arg_t user_cb_data = {0}; + user_cb_data.user_cb_state = HTTPD_SSL_USER_CB_SESS_ERROR; + user_cb_data.tls = tls; + (global_ctx->user_cb)((void *)&user_cb_data); + } esp_tls_server_session_delete(tls); } return ESP_FAIL; diff --git a/examples/protocols/https_server/simple/main/main.c b/examples/protocols/https_server/simple/main/main.c index cfb5192b24..6fe6aa23fd 100644 --- a/examples/protocols/https_server/simple/main/main.c +++ b/examples/protocols/https_server/simple/main/main.c @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #include "esp_netif.h" #include "esp_eth.h" #include "protocol_examples_common.h" @@ -133,6 +136,29 @@ static void https_server_user_callback(esp_https_server_user_cb_arg_t *user_cb) print_peer_cert_info(ssl_ctx); #endif break; + + case HTTPD_SSL_USER_CB_SESS_ERROR: + ESP_LOGD(TAG, "At session error (handshake failed)"); + // Get socket FD to log failing client IP address + sockfd = -1; + esp_ret = esp_tls_get_conn_sockfd(user_cb->tls, &sockfd); + if (esp_ret == ESP_OK && sockfd >= 0) { + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + if (getpeername(sockfd, (struct sockaddr*)&addr, &len) == 0) { + char ip_str[INET6_ADDRSTRLEN]; + if (addr.ss_family == AF_INET) { + inet_ntop(AF_INET, &((struct sockaddr_in*)&addr)->sin_addr, ip_str, sizeof(ip_str)); + } else if (addr.ss_family == AF_INET6) { + inet_ntop(AF_INET6, &((struct sockaddr_in6*)&addr)->sin6_addr, ip_str, sizeof(ip_str)); + } else { + strcpy(ip_str, "unknown"); + } + ESP_LOGW(TAG, "SSL handshake failed from client IP: %s", ip_str); + } + } + break; + default: ESP_LOGE(TAG, "Illegal state!"); return;