Merge branch 'feature/add-mdns-delegation' into 'master'

mdns: add host and service delegation

See merge request espressif/esp-idf!13063
This commit is contained in:
David Čermák
2021-06-10 13:58:32 +00:00
13 changed files with 975 additions and 227 deletions

View File

@@ -114,6 +114,50 @@ void mdns_free(void);
*/
esp_err_t mdns_hostname_set(const char * hostname);
/**
* @brief Adds a hostname and address to be delegated
* A/AAAA queries will be replied for the hostname and
* services can be added to this host.
*
* @param hostname Hostname to add
* @param address_list The IP address list of the host
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error
*
*/
esp_err_t mdns_delegate_hostname_add(const char * hostname, const mdns_ip_addr_t *address_list);
/**
* @brief Remove a delegated hostname
* All the services added to this host will also be removed.
*
* @param hostname Hostname to remove
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error
*
*/
esp_err_t mdns_delegate_hostname_remove(const char * hostname);
/**
* @brief Query whether a hostname has been added
*
* @param hostname Hostname to query
*
* @return
* - true The hostname has been added.
* - false The hostname has not been added.
*
*/
bool mdns_hostname_exists(const char * hostname);
/**
* @brief Set the default instance name for mDNS server
*
@@ -145,6 +189,41 @@ esp_err_t mdns_instance_name_set(const char * instance_name);
*/
esp_err_t mdns_service_add(const char * instance_name, const char * service_type, const char * proto, uint16_t port, mdns_txt_item_t txt[], size_t num_items);
/**
* @brief Add service to mDNS server with a delegated hostname
*
* @param instance_name instance name to set. If NULL,
* global instance name or hostname will be used
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param port service port
* @param txt string array of TXT data (eg. {{"var","val"},{"other","2"}})
* @param num_items number of items in TXT data
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error
* - ESP_FAIL failed to add service
*/
esp_err_t mdns_service_add_for_host(const char * instance_name, const char * service_type, const char * proto,
const char * hostname, uint16_t port, mdns_txt_item_t txt[], size_t num_items);
/**
* @brief Check whether a service has been added.
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, checks for the local hostname.
*
* @return
* - true Correspondding service has been added.
* - false Service not found.
*/
bool mdns_service_exists(const char * service_type, const char * proto, const char * hostname);
/**
* @brief Remove service from mDNS server
*
@@ -159,6 +238,21 @@ esp_err_t mdns_service_add(const char * instance_name, const char * service_type
*/
esp_err_t mdns_service_remove(const char * service_type, const char * proto);
/**
* @brief Remove service from mDNS server with hostname
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_remove_for_host(const char * service_type, const char * proto, const char *hostname);
/**
* @brief Set instance name for service
*
@@ -174,6 +268,23 @@ esp_err_t mdns_service_remove(const char * service_type, const char * proto);
*/
esp_err_t mdns_service_instance_name_set(const char * service_type, const char * proto, const char * instance_name);
/**
* @brief Set instance name for service with hostname
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param instance_name instance name to set
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_instance_name_set_for_host(const char * service_type, const char * proto, const char * hostname,
const char * instance_name);
/**
* @brief Set service port
*
@@ -189,6 +300,24 @@ esp_err_t mdns_service_instance_name_set(const char * service_type, const char *
*/
esp_err_t mdns_service_port_set(const char * service_type, const char * proto, uint16_t port);
/**
* @brief Set service port with hostname
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param port service port
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_port_set_for_host(const char * service_type, const char * proto, const char * hostname,
uint16_t port);
/**
* @brief Replace all TXT items for service
*
@@ -205,6 +334,24 @@ esp_err_t mdns_service_port_set(const char * service_type, const char * proto, u
*/
esp_err_t mdns_service_txt_set(const char * service_type, const char * proto, mdns_txt_item_t txt[], uint8_t num_items);
/**
* @brief Replace all TXT items for service with hostname
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param txt array of TXT data (eg. {{"var","val"},{"other","2"}})
* @param num_items number of items in TXT data
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_set_for_host(const char * service_type, const char * proto, const char * hostname,
mdns_txt_item_t txt[], uint8_t num_items);
/**
* @brief Set/Add TXT item for service TXT record
*
@@ -221,6 +368,25 @@ esp_err_t mdns_service_txt_set(const char * service_type, const char * proto, md
*/
esp_err_t mdns_service_txt_item_set(const char * service_type, const char * proto, const char * key, const char * value);
/**
* @brief Set/Add TXT item for service TXT record with hostname
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param key the key that you want to add/update
* @param value the new value of the key
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_item_set_for_host(const char * service_type, const char * proto, const char * hostname,
const char * key, const char * value);
/**
* @brief Remove TXT item for service TXT record
*
@@ -236,6 +402,23 @@ esp_err_t mdns_service_txt_item_set(const char * service_type, const char * prot
*/
esp_err_t mdns_service_txt_item_remove(const char * service_type, const char * proto, const char * key);
/**
* @brief Remove TXT item for service TXT record with hostname
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param key the key that you want to remove
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_item_remove_for_host(const char * service_type, const char * proto, const char * hostname,
const char * key);
/**
* @brief Remove and free all services from mDNS server
*

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,9 @@
#include "esp_event_base.h"
#include "esp_task.h"
#include "esp_timer.h"
#include "esp_netif_ip_addr.h"
#include "freertos/FreeRTOS.h"
#include "mdns.h"
//#define MDNS_ENABLE_DEBUG
@@ -182,6 +185,8 @@ typedef enum {
ACTION_TX_HANDLE,
ACTION_RX_HANDLE,
ACTION_TASK_STOP,
ACTION_DELEGATE_HOSTNAME_ADD,
ACTION_DELEGATE_HOSTNAME_REMOVE,
ACTION_MAX
} mdns_action_type_t;
@@ -210,7 +215,7 @@ typedef struct {
} mdns_header_t;
typedef struct {
char host[MDNS_NAME_BUF_LEN];
char host[MDNS_NAME_BUF_LEN]; // hostname for A/AAAA records, instance name for SRV records
char service[MDNS_NAME_BUF_LEN];
char proto[MDNS_NAME_BUF_LEN];
char domain[MDNS_NAME_BUF_LEN];
@@ -280,6 +285,7 @@ typedef struct {
const char * instance;
const char * service;
const char * proto;
const char * hostname;
uint16_t priority;
uint16_t weight;
uint16_t port;
@@ -299,14 +305,22 @@ typedef struct mdns_out_question_s {
const char * service;
const char * proto;
const char * domain;
bool own_dynamic_memory;
} mdns_out_question_t;
typedef struct mdns_host_item_t {
const char * hostname;
mdns_ip_addr_t *address_list;
struct mdns_host_item_t *next;
} mdns_host_item_t;
typedef struct mdns_out_answer_s {
struct mdns_out_answer_s * next;
uint16_t type;
uint8_t bye;
uint8_t flush;
mdns_service_t * service;
mdns_host_item_t* host;
const char * custom_instance;
const char * custom_service;
const char * custom_proto;
@@ -380,7 +394,10 @@ typedef struct mdns_server_s {
typedef struct {
mdns_action_type_t type;
union {
char * hostname;
struct {
char * hostname;
xTaskHandle calling_task;
} hostname_set;
char * instance;
struct {
esp_event_base_t event_base;
@@ -423,6 +440,10 @@ typedef struct {
struct {
mdns_rx_packet_t * packet;
} rx_handle;
struct {
const char * hostname;
mdns_ip_addr_t *address_list;
} delegate_hostname;
} data;
} mdns_action_t;

View File

@@ -4,6 +4,7 @@
#define MDNS_HOSTNAME "test-hostname"
#define MDNS_DELEGATE_HOSTNAME "delegate-hostname"
#define MDNS_INSTANCE "test-instance"
#define MDNS_SERVICE_NAME "_http"
#define MDNS_SERVICE_PROTO "_tcp"
@@ -42,6 +43,10 @@ TEST_CASE("mdns api return expected err-code and do not leak memory", "[mdns][le
{
mdns_txt_item_t serviceTxtData[CONFIG_MDNS_MAX_SERVICES] = { {NULL, NULL},
};
mdns_ip_addr_t addr;
addr.addr.type = ESP_IPADDR_TYPE_V4;
addr.addr.u_addr.ip4.addr = esp_ip4addr_aton("127.0.0.1");
addr.next = NULL;
for (int i=0; i<CONFIG_MDNS_MAX_SERVICES; ++i) {
serviceTxtData[i].key = "Key";
serviceTxtData[i].value = "Value";
@@ -51,8 +56,15 @@ TEST_CASE("mdns api return expected err-code and do not leak memory", "[mdns][le
TEST_ASSERT_EQUAL(ESP_OK, mdns_init() );
TEST_ASSERT_EQUAL(ESP_OK, mdns_hostname_set(MDNS_HOSTNAME) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_delegate_hostname_add(MDNS_DELEGATE_HOSTNAME, &addr) );
yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname
TEST_ASSERT_TRUE(mdns_hostname_exists(MDNS_DELEGATE_HOSTNAME) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_instance_name_set(MDNS_INSTANCE) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, serviceTxtData, CONFIG_MDNS_MAX_SERVICES) );
TEST_ASSERT_FALSE(mdns_service_exists(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add_for_host(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME,
MDNS_SERVICE_PORT, serviceTxtData, CONFIG_MDNS_MAX_SERVICES) );
TEST_ASSERT_TRUE(mdns_service_exists(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, serviceTxtData, CONFIG_MDNS_MAX_SERVICES) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_item_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, "key1", "value1") );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_item_remove(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, "key1") );
@@ -61,6 +73,9 @@ TEST_CASE("mdns api return expected err-code and do not leak memory", "[mdns][le
yield_to_all_priorities(); // Make sure that mdns task has executed to remove the service
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, NULL, 0) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_delegate_hostname_remove(MDNS_DELEGATE_HOSTNAME) );
yield_to_all_priorities(); // Make sure that mdns task has executed to remove the hostname
TEST_ASSERT_FALSE(mdns_service_exists(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_remove_all() );
yield_to_all_priorities(); // Make sure that mdns task has executed to remove all services

View File

@@ -106,6 +106,7 @@ typedef void * SemaphoreHandle_t;
typedef void * xQueueHandle;
typedef void * QueueHandle_t;
typedef void * TaskHandle_t;
typedef int BaseType_t;
typedef uint32_t TickType_t;
typedef uint32_t portTickType;

View File

@@ -98,3 +98,18 @@ void ForceTaskDelete(void)
{
g_queue_send_shall_fail = 1;
}
TaskHandle_t xTaskGetCurrentTaskHandle(void)
{
return NULL;
}
void xTaskNotifyGive(TaskHandle_t task)
{
return;
}
BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t * value, TickType_t wait_time)
{
return pdTRUE;
}

View File

@@ -24,4 +24,9 @@ esp_err_t esp_event_handler_unregister(const char * event_base, int32_t event_id
#define _mdns_udp_pcb_write(tcpip_if, ip_protocol, ip, port, data, len) len
// Task signify mock
TaskHandle_t xTaskGetCurrentTaskHandle(void);
void xTaskNotifyGive(TaskHandle_t task);
BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time );
#endif /* ESP32_MOCK_H_ */

View File

@@ -7,13 +7,13 @@
#include "mdns_private.h"
void (*mdns_test_static_execute_action)(mdns_action_t *) = NULL;
mdns_srv_item_t * (*mdns_test_static_mdns_get_service_item)(const char * service, const char * proto) = NULL;
mdns_srv_item_t * (*mdns_test_static_mdns_get_service_item)(const char * service, const char * proto, const char *hostname) = NULL;
mdns_search_once_t * (*mdns_test_static_search_init)(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, uint8_t max_results) = NULL;
esp_err_t (*mdns_test_static_send_search_action)(mdns_action_type_t type, mdns_search_once_t * search) = NULL;
void (*mdns_test_static_search_free)(mdns_search_once_t * search) = NULL;
static void _mdns_execute_action(mdns_action_t * action);
static mdns_srv_item_t * _mdns_get_service_item(const char * service, const char * proto);
static mdns_srv_item_t * _mdns_get_service_item(const char * service, const char * proto, const char *hostname);
static mdns_search_once_t * _mdns_search_init(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, uint8_t max_results);
static esp_err_t _mdns_send_search_action(mdns_action_type_t type, mdns_search_once_t * search);
static void _mdns_search_free(mdns_search_once_t * search);
@@ -49,5 +49,5 @@ mdns_search_once_t * mdns_test_search_init(const char * name, const char * servi
mdns_srv_item_t * mdns_test_mdns_get_service_item(const char * service, const char * proto)
{
return mdns_test_static_mdns_get_service_item(service, proto);
return mdns_test_static_mdns_get_service_item(service, proto, NULL);
}