mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Modify esp-tls and tcp_transport to support keep alive for tcp and ssl connection
This commit is contained in:
parent
a395f3592b
commit
f946e296a2
@ -148,6 +148,34 @@ static void ms_to_timeval(int timeout_ms, struct timeval *tv)
|
|||||||
tv->tv_usec = (timeout_ms % 1000) * 1000;
|
tv->tv_usec = (timeout_ms % 1000) * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int esp_tls_tcp_enable_keep_alive(int fd, tls_keep_alive_cfg_t *cfg)
|
||||||
|
{
|
||||||
|
int keep_alive_enable = 1;
|
||||||
|
int keep_alive_idle = cfg->keep_alive_idle;
|
||||||
|
int keep_alive_interval = cfg->keep_alive_interval;
|
||||||
|
int keep_alive_count = cfg->keep_alive_count;
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Enable TCP keep alive. idle: %d, interval: %d, count: %d", keep_alive_idle, keep_alive_interval, keep_alive_count);
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keep_alive_enable, sizeof(keep_alive_enable)) != 0) {
|
||||||
|
ESP_LOGE(TAG, "Fail to setsockopt SO_KEEPALIVE");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keep_alive_idle, sizeof(keep_alive_idle)) != 0) {
|
||||||
|
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPIDLE");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keep_alive_interval, sizeof(keep_alive_interval)) != 0) {
|
||||||
|
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPINTVL");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keep_alive_count, sizeof(keep_alive_count)) != 0) {
|
||||||
|
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPCNT");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static esp_err_t esp_tcp_connect(const char *host, int hostlen, int port, int *sockfd, const esp_tls_t *tls, const esp_tls_cfg_t *cfg)
|
static esp_err_t esp_tcp_connect(const char *host, int hostlen, int port, int *sockfd, const esp_tls_t *tls, const esp_tls_cfg_t *cfg)
|
||||||
{
|
{
|
||||||
esp_err_t ret;
|
esp_err_t ret;
|
||||||
@ -186,6 +214,12 @@ static esp_err_t esp_tcp_connect(const char *host, int hostlen, int port, int *s
|
|||||||
ms_to_timeval(cfg->timeout_ms, &tv);
|
ms_to_timeval(cfg->timeout_ms, &tv);
|
||||||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||||
|
if (cfg->keep_alive_cfg && cfg->keep_alive_cfg->keep_alive_enable) {
|
||||||
|
if (esp_tls_tcp_enable_keep_alive(fd, cfg->keep_alive_cfg) < 0) {
|
||||||
|
ESP_LOGE(TAG, "Error setting keep-alive");
|
||||||
|
goto err_freesocket;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cfg->non_block) {
|
if (cfg->non_block) {
|
||||||
int flags = fcntl(fd, F_GETFL, 0);
|
int flags = fcntl(fd, F_GETFL, 0);
|
||||||
|
@ -101,6 +101,16 @@ typedef struct psk_key_hint {
|
|||||||
const char* hint; /*!< hint in PSK authentication mode in string format */
|
const char* hint; /*!< hint in PSK authentication mode in string format */
|
||||||
} psk_hint_key_t;
|
} psk_hint_key_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Keep alive parameters structure
|
||||||
|
*/
|
||||||
|
typedef struct tls_keep_alive_cfg {
|
||||||
|
bool keep_alive_enable; /*!< Enable keep-alive timeout */
|
||||||
|
int keep_alive_idle; /*!< Keep-alive idle time (second) */
|
||||||
|
int keep_alive_interval; /*!< Keep-alive interval time (second) */
|
||||||
|
int keep_alive_count; /*!< Keep-alive packet retry send count */
|
||||||
|
} tls_keep_alive_cfg_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ESP-TLS configuration parameters
|
* @brief ESP-TLS configuration parameters
|
||||||
*
|
*
|
||||||
@ -188,7 +198,7 @@ typedef struct esp_tls_cfg {
|
|||||||
const psk_hint_key_t* psk_hint_key; /*!< Pointer to PSK hint and key. if not NULL (and certificates are NULL)
|
const psk_hint_key_t* psk_hint_key; /*!< Pointer to PSK hint and key. if not NULL (and certificates are NULL)
|
||||||
then PSK authentication is enabled with configured setup.
|
then PSK authentication is enabled with configured setup.
|
||||||
Important note: the pointer must be valid for connection */
|
Important note: the pointer must be valid for connection */
|
||||||
|
tls_keep_alive_cfg_t *keep_alive_cfg; /*!< Enable TCP keep-alive timeout for SSL connection */
|
||||||
} esp_tls_cfg_t;
|
} esp_tls_cfg_t;
|
||||||
|
|
||||||
#ifdef CONFIG_ESP_TLS_SERVER
|
#ifdef CONFIG_ESP_TLS_SERVER
|
||||||
|
@ -16,11 +16,21 @@
|
|||||||
#define _ESP_TRANSPORT_H_
|
#define _ESP_TRANSPORT_H_
|
||||||
|
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Keep alive parameters structure
|
||||||
|
*/
|
||||||
|
typedef struct esp_transport_keepalive {
|
||||||
|
bool keep_alive_enable; /*!< Enable keep-alive timeout */
|
||||||
|
int keep_alive_idle; /*!< Keep-alive idle time (second) */
|
||||||
|
int keep_alive_interval; /*!< Keep-alive interval time (second) */
|
||||||
|
int keep_alive_count; /*!< Keep-alive packet retry send count */
|
||||||
|
} esp_transport_keep_alive_t;
|
||||||
|
|
||||||
typedef struct esp_transport_internal* esp_transport_list_handle_t;
|
typedef struct esp_transport_internal* esp_transport_list_handle_t;
|
||||||
typedef struct esp_transport_item_t* esp_transport_handle_t;
|
typedef struct esp_transport_item_t* esp_transport_handle_t;
|
||||||
@ -313,8 +323,22 @@ esp_err_t esp_transport_set_parent_transport_func(esp_transport_handle_t t, payl
|
|||||||
*/
|
*/
|
||||||
esp_tls_error_handle_t esp_transport_get_error_handle(esp_transport_handle_t t);
|
esp_tls_error_handle_t esp_transport_get_error_handle(esp_transport_handle_t t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set keep-alive configuration
|
||||||
|
*
|
||||||
|
* @param[in] t The transport handle
|
||||||
|
* @param[in] keep_alive_cfg The keep-alive config
|
||||||
|
*/
|
||||||
|
void esp_transport_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get keep-alive config of this transport
|
||||||
|
*
|
||||||
|
* @param[in] t The transport handle
|
||||||
|
*
|
||||||
|
* @return The keep-alive configuration
|
||||||
|
*/
|
||||||
|
void *esp_transport_get_keep_alive(esp_transport_handle_t t);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -146,6 +146,13 @@ void esp_transport_ssl_skip_common_name_check(esp_transport_handle_t t);
|
|||||||
*/
|
*/
|
||||||
void esp_transport_ssl_set_psk_key_hint(esp_transport_handle_t t, const psk_hint_key_t* psk_hint_key);
|
void esp_transport_ssl_set_psk_key_hint(esp_transport_handle_t t, const psk_hint_key_t* psk_hint_key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set keep-alive status in current ssl context
|
||||||
|
*
|
||||||
|
* @param[in] t ssl transport
|
||||||
|
* @param[in] keep_alive_cfg The handle for keep-alive configuration
|
||||||
|
*/
|
||||||
|
void esp_transport_ssl_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,6 +21,14 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set TCP keep-alive configuration
|
||||||
|
*
|
||||||
|
* @param[in] t The transport handle
|
||||||
|
* @param[in] keep_alive_cfg The keep-alive config
|
||||||
|
*/
|
||||||
|
void esp_transport_tcp_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create TCP transport, the transport handle must be release esp_transport_destroy callback
|
* @brief Create TCP transport, the transport handle must be release esp_transport_destroy callback
|
||||||
*
|
*
|
||||||
|
@ -44,7 +44,7 @@ struct esp_transport_item_t {
|
|||||||
connect_async_func _connect_async; /*!< non-blocking connect function of this transport */
|
connect_async_func _connect_async; /*!< non-blocking connect function of this transport */
|
||||||
payload_transfer_func _parent_transfer; /*!< Function returning underlying transport layer */
|
payload_transfer_func _parent_transfer; /*!< Function returning underlying transport layer */
|
||||||
esp_tls_error_handle_t error_handle; /*!< Pointer to esp-tls error handle */
|
esp_tls_error_handle_t error_handle; /*!< Pointer to esp-tls error handle */
|
||||||
|
esp_transport_keep_alive_t *keep_alive_cfg; /*!< TCP keep-alive config */
|
||||||
STAILQ_ENTRY(esp_transport_item_t) next;
|
STAILQ_ENTRY(esp_transport_item_t) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -305,4 +305,19 @@ void esp_transport_set_errors(esp_transport_handle_t t, const esp_tls_error_hand
|
|||||||
if (t) {
|
if (t) {
|
||||||
memcpy(t->error_handle, error_handle, sizeof(esp_tls_last_error_t));
|
memcpy(t->error_handle, error_handle, sizeof(esp_tls_last_error_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void esp_transport_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg)
|
||||||
|
{
|
||||||
|
if (t && keep_alive_cfg) {
|
||||||
|
t->keep_alive_cfg = keep_alive_cfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *esp_transport_get_keep_alive(esp_transport_handle_t t)
|
||||||
|
{
|
||||||
|
if (t) {
|
||||||
|
return t->keep_alive_cfg;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -282,6 +282,14 @@ void esp_transport_ssl_skip_common_name_check(esp_transport_handle_t t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void esp_transport_ssl_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg)
|
||||||
|
{
|
||||||
|
transport_ssl_t *ssl = esp_transport_get_context_data(t);
|
||||||
|
if (t && ssl) {
|
||||||
|
ssl->cfg.keep_alive_cfg = (tls_keep_alive_cfg_t *)keep_alive_cfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esp_transport_handle_t esp_transport_ssl_init(void)
|
esp_transport_handle_t esp_transport_ssl_init(void)
|
||||||
{
|
{
|
||||||
esp_transport_handle_t t = esp_transport_init();
|
esp_transport_handle_t t = esp_transport_init();
|
||||||
|
@ -51,11 +51,40 @@ static int resolve_dns(const char *host, struct sockaddr_in *ip)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tcp_enable_keep_alive(int fd, esp_transport_keep_alive_t *keep_alive_cfg)
|
||||||
|
{
|
||||||
|
int keep_alive_enable = 1;
|
||||||
|
int keep_alive_idle = keep_alive_cfg->keep_alive_idle;
|
||||||
|
int keep_alive_interval = keep_alive_cfg->keep_alive_interval;
|
||||||
|
int keep_alive_count = keep_alive_cfg->keep_alive_count;
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Enable TCP keep alive. idle: %d, interval: %d, count: %d", keep_alive_idle, keep_alive_interval, keep_alive_count);
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keep_alive_enable, sizeof(keep_alive_enable)) != 0) {
|
||||||
|
ESP_LOGE(TAG, "Fail to setsockopt SO_KEEPALIVE");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keep_alive_idle, sizeof(keep_alive_idle)) != 0) {
|
||||||
|
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPIDLE");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keep_alive_interval, sizeof(keep_alive_interval)) != 0) {
|
||||||
|
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPINTVL");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keep_alive_count, sizeof(keep_alive_count)) != 0) {
|
||||||
|
ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPCNT");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms)
|
static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms)
|
||||||
{
|
{
|
||||||
struct sockaddr_in remote_ip;
|
struct sockaddr_in remote_ip;
|
||||||
struct timeval tv = { 0 };
|
struct timeval tv = { 0 };
|
||||||
transport_tcp_t *tcp = esp_transport_get_context_data(t);
|
transport_tcp_t *tcp = esp_transport_get_context_data(t);
|
||||||
|
esp_transport_keep_alive_t *keep_alive_cfg = esp_transport_get_keep_alive(t);
|
||||||
|
|
||||||
bzero(&remote_ip, sizeof(struct sockaddr_in));
|
bzero(&remote_ip, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
@ -80,7 +109,15 @@ static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int
|
|||||||
|
|
||||||
setsockopt(tcp->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
setsockopt(tcp->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||||
setsockopt(tcp->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
setsockopt(tcp->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||||
|
// Set socket keep-alive option
|
||||||
|
if (keep_alive_cfg && keep_alive_cfg->keep_alive_enable) {
|
||||||
|
if (tcp_enable_keep_alive(tcp->sock, keep_alive_cfg) < 0) {
|
||||||
|
ESP_LOGE(TAG, "Error to set tcp [socket=%d] keep-alive", tcp->sock);
|
||||||
|
close(tcp->sock);
|
||||||
|
tcp->sock = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
ESP_LOGD(TAG, "[sock=%d],connecting to server IP:%s,Port:%d...",
|
ESP_LOGD(TAG, "[sock=%d],connecting to server IP:%s,Port:%d...",
|
||||||
tcp->sock, ipaddr_ntoa((const ip_addr_t*)&remote_ip.sin_addr.s_addr), port);
|
tcp->sock, ipaddr_ntoa((const ip_addr_t*)&remote_ip.sin_addr.s_addr), port);
|
||||||
if (connect(tcp->sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr)) != 0) {
|
if (connect(tcp->sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr)) != 0) {
|
||||||
@ -180,6 +217,11 @@ static esp_err_t tcp_destroy(esp_transport_handle_t t)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void esp_transport_tcp_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg)
|
||||||
|
{
|
||||||
|
esp_transport_set_keep_alive(t, keep_alive_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
esp_transport_handle_t esp_transport_tcp_init(void)
|
esp_transport_handle_t esp_transport_tcp_init(void)
|
||||||
{
|
{
|
||||||
esp_transport_handle_t t = esp_transport_init();
|
esp_transport_handle_t t = esp_transport_init();
|
||||||
|
Loading…
Reference in New Issue
Block a user