From 363fbf7dab7c70b64ba8f03d42ce9c8a7decb5fe Mon Sep 17 00:00:00 2001 From: Euripedes Rocha Date: Tue, 13 Jun 2023 10:32:55 +0200 Subject: [PATCH] feat: Add option to bind interface of use Enable user to set which interface should be used for client network, allowing client to be binded to the interface selected by user forcing it to go through the selected interface. Closes https://github.com/espressif/esp-mqtt/issues/253 --- include/mqtt_client.h | 1 + lib/include/mqtt_client_priv.h | 1 + mqtt_client.c | 16 ++++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/include/mqtt_client.h b/include/mqtt_client.h index 8d85125..e03c615 100644 --- a/include/mqtt_client.h +++ b/include/mqtt_client.h @@ -334,6 +334,7 @@ typedef struct esp_mqtt_client_config_t { bool disable_auto_reconnect; /*!< Client will reconnect to server (when errors/disconnect). Set `disable_auto_reconnect=true` to disable */ esp_transport_handle_t transport; /*!< Custom transport handle to use. Warning: The transport should be valid during the client lifetime and is destroyed when esp_mqtt_client_destroy is called. */ + struct ifreq * if_name; /*!< The name of interface for data to go through. Use the default interface without setting */ } network; /*!< Network configuration */ /** * Client task configuration diff --git a/lib/include/mqtt_client_priv.h b/lib/include/mqtt_client_priv.h index 0b5ee48..5a7c16c 100644 --- a/lib/include/mqtt_client_priv.h +++ b/lib/include/mqtt_client_priv.h @@ -91,6 +91,7 @@ typedef struct { int message_retransmit_timeout; uint64_t outbox_limit; esp_transport_handle_t transport; + struct ifreq * if_name; } mqtt_config_storage_t; typedef enum { diff --git a/mqtt_client.c b/mqtt_client.c index 1792206..455f289 100644 --- a/mqtt_client.c +++ b/mqtt_client.c @@ -1,4 +1,5 @@ #include +#include #include "esp_err.h" #include "esp_log.h" #include "esp_heap_caps.h" @@ -303,6 +304,9 @@ static esp_err_t esp_mqtt_client_create_transport(esp_mqtt_client_handle_t clien esp_transport_handle_t tcp = esp_transport_tcp_init(); ESP_MEM_CHECK(TAG, tcp, return ESP_ERR_NO_MEM); esp_transport_set_default_port(tcp, MQTT_TCP_DEFAULT_PORT); + if (client->config->if_name) { + esp_transport_tcp_set_interface_name(tcp, client->config->if_name); + } esp_transport_list_add(client->transport_list, tcp, MQTT_OVER_TCP_SCHEME); if (strncasecmp(client->config->scheme, MQTT_OVER_WS_SCHEME, sizeof(MQTT_OVER_WS_SCHEME)) == 0) { #if MQTT_ENABLE_WS @@ -326,6 +330,9 @@ static esp_err_t esp_mqtt_client_create_transport(esp_mqtt_client_handle_t clien esp_transport_handle_t ssl = esp_transport_ssl_init(); ESP_MEM_CHECK(TAG, ssl, return ESP_ERR_NO_MEM); esp_transport_set_default_port(ssl, MQTT_SSL_DEFAULT_PORT); + if (client->config->if_name) { + esp_transport_ssl_set_interface_name(ssl, client->config->if_name); + } esp_transport_list_add(client->transport_list, ssl, MQTT_OVER_SSL_SCHEME); if (strncasecmp(client->config->scheme, MQTT_OVER_WSS_SCHEME, sizeof(MQTT_OVER_WSS_SCHEME)) == 0) { #if MQTT_ENABLE_WS @@ -487,6 +494,15 @@ esp_err_t esp_mqtt_set_config(esp_mqtt_client_handle_t client, const esp_mqtt_cl } else { client->config->reconnect_timeout_ms = MQTT_RECON_DEFAULT_MS; } + if (config->network.transport) { + client->config->transport = config->network.transport; + } + + if (config->network.if_name) { + client->config->if_name = calloc(1, sizeof(struct ifreq) + 1); + ESP_MEM_CHECK(TAG, client->config->if_name, goto _mqtt_set_config_failed); + memcpy(client->config->if_name, config->network.if_name, sizeof(struct ifreq)); + } if (config->broker.verification.alpn_protos) { for (int i = 0; i < client->config->num_alpn_protos; i++) {