Merge branch 'feat/add_server_handshake_failure_user_cb' into 'master'

feat(esp_https_server): adds support for user callback on handshake failure

Closes IDFGH-17004

See merge request espressif/esp-idf!44856
This commit is contained in:
Mahavir Jain
2026-01-27 17:47:18 +05:30
3 changed files with 36 additions and 2 deletions
@@ -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;
@@ -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;
@@ -13,6 +13,9 @@
#include <esp_system.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#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;