Merge branch 'feature/mdns-value-len' into 'master'

mdns: allow explicit txt value length

See merge request espressif/esp-idf!13981
pull/6904/head
David Čermák 2021-06-23 14:53:48 +00:00
commit 3452c5f194
4 zmienionych plików z 140 dodań i 31 usunięć

Wyświetl plik

@ -79,6 +79,7 @@ typedef struct mdns_result_s {
uint16_t port; /*!< service port */
// TXT
mdns_txt_item_t * txt; /*!< txt record */
uint8_t *txt_value_len; /*!< array of txt value len of each record */
size_t txt_count; /*!< number of txt items */
// A and AAAA
mdns_ip_addr_t * addr; /*!< linked list of IP addresses found */
@ -173,6 +174,8 @@ esp_err_t mdns_instance_name_set(const char * instance_name);
/**
* @brief Add service to mDNS server
*
* @note The value length of txt items will be automatically decided by strlen
*
* @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)
@ -189,10 +192,11 @@ 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
*
* @note The value length of txt items will be automatically decided by strlen
*
* @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)
@ -321,6 +325,8 @@ esp_err_t mdns_service_port_set_for_host(const char * service_type, const char *
/**
* @brief Replace all TXT items for service
*
* @note The value length of txt items will be automatically decided by strlen
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param txt array of TXT data (eg. {{"var","val"},{"other","2"}})
@ -337,6 +343,8 @@ esp_err_t mdns_service_txt_set(const char * service_type, const char * proto, md
/**
* @brief Replace all TXT items for service with hostname
*
* @note The value length of txt items will be automatically decided by strlen
*
* @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.
@ -355,6 +363,8 @@ esp_err_t mdns_service_txt_set_for_host(const char * service_type, const char *
/**
* @brief Set/Add TXT item for service TXT record
*
* @note The value length will be automatically decided by strlen
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param key the key that you want to add/update
@ -368,10 +378,29 @@ esp_err_t mdns_service_txt_set_for_host(const char * service_type, const char *
*/
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
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param key the key that you want to add/update
* @param value the new value of the key
* @param value_len the length of the value
*
* @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_with_explicit_value_len(const char *service_type, const char *proto,
const char *key, const char *value, uint8_t value_len);
/**
* @brief Set/Add TXT item for service TXT record with hostname
*
* @note The value length will be automatically decided by strlen
*
* @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.
@ -387,6 +416,26 @@ esp_err_t mdns_service_txt_item_set(const char * service_type, const char * prot
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 Set/Add TXT item for service TXT record with hostname and txt value length
*
* @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
* @param value_len the length of the value
*
* @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_with_explicit_value_len(const char *service_type, const char *proto,
const char *hostname, const char *key,
const char *value, uint8_t value_len);
/**
* @brief Remove TXT item for service TXT record
*

Wyświetl plik

@ -43,7 +43,7 @@ static void _mdns_search_finish_done(void);
static mdns_search_once_t * _mdns_search_find_from(mdns_search_once_t * search, mdns_name_t * name, uint16_t type, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char * hostname, esp_ip_addr_t * ip, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char * hostname, uint16_t port, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, uint8_t *txt_value_len, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search, const char * instance, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static bool _mdns_append_host_list_in_services(mdns_out_answer_t ** destination, mdns_srv_item_t * services[], size_t services_len, bool flush, bool bye);
static bool _mdns_append_host_list(mdns_out_answer_t ** destination, bool flush, bool bye);
@ -418,6 +418,17 @@ static inline uint8_t _mdns_append_type(uint8_t * packet, uint16_t * index, uint
return 10;
}
static inline uint8_t _mdns_append_string_with_len(uint8_t * packet, uint16_t * index, const char * string, uint8_t len)
{
if ((*index + len + 1) >= MDNS_MAX_PACKET_SIZE) {
return 0;
}
_mdns_append_u8(packet, index, len);
memcpy(packet + *index, string, len);
*index += len;
return len + 1;
}
/**
* @brief appends single string to a packet, incrementing the index
*
@ -656,10 +667,12 @@ static uint16_t _mdns_append_txt_record(uint8_t * packet, uint16_t * index, mdns
char * tmp;
mdns_txt_linked_item_t * txt = service->txt;
while (txt) {
tmp = (char *)malloc(2 + strlen(txt->key) + strlen(txt->value));
uint8_t txt_data_len = strlen(txt->key) + txt->value_len + 1;
tmp = (char *)malloc(txt_data_len);
if (tmp) {
sprintf(tmp, "%s=%s", txt->key, txt->value);
uint8_t l = _mdns_append_string(packet, index, tmp);
int offset = sprintf(tmp, "%s=", txt->key);
memcpy(tmp + offset, txt->value, txt->value_len);
uint8_t l = _mdns_append_string_with_len(packet, index, tmp, txt_data_len);
free(tmp);
if (!l) {
return 0;
@ -2072,6 +2085,7 @@ static mdns_txt_linked_item_t * _mdns_allocate_txt(size_t num_items, mdns_txt_it
free(new_item);
break;
}
new_item->value_len = strlen(new_item->value);
new_item->next = new_txt;
new_txt = new_item;
}
@ -2842,7 +2856,8 @@ static int _mdns_txt_item_name_get_len(const uint8_t * data, size_t len)
/**
* @brief Create TXT result array from parsed TXT data
*/
static void _mdns_result_txt_create(const uint8_t * data, size_t len, mdns_txt_item_t ** out_txt, size_t * out_count)
static void _mdns_result_txt_create(const uint8_t *data, size_t len, mdns_txt_item_t **out_txt, uint8_t **out_value_len,
size_t *out_count)
{
*out_txt = NULL;
*out_count = 0;
@ -2862,7 +2877,14 @@ static void _mdns_result_txt_create(const uint8_t * data, size_t len, mdns_txt_i
HOOK_MALLOC_FAILED;
return;
}
uint8_t * txt_value_len = (uint8_t *)malloc(num_items);
if (!txt_value_len) {
free(txt);
HOOK_MALLOC_FAILED;
return;
}
memset(txt, 0, sizeof(mdns_txt_item_t) * num_items);
memset(txt_value_len, 0, num_items);
size_t txt_num = 0;
while (i < len) {
@ -2886,29 +2908,33 @@ static void _mdns_result_txt_create(const uint8_t * data, size_t len, mdns_txt_i
goto handle_error;//error
}
mdns_txt_item_t * t = &txt[txt_num++];
mdns_txt_item_t * t = &txt[txt_num];
uint8_t * value_len = &txt_value_len[txt_num];
txt_num++;
memcpy(key, data + i, name_len);
key[name_len] = 0;
i += name_len + 1;
t->key = key;
int value_len = partLen - name_len - 1;
if (value_len > 0) {
char * value = (char *)malloc(value_len + 1);
int new_value_len = partLen - name_len - 1;
if (new_value_len > 0) {
char * value = (char *)malloc(new_value_len + 1);
if (!value) {
HOOK_MALLOC_FAILED;
goto handle_error;//error
}
memcpy(value, data + i, value_len);
value[value_len] = 0;
i += value_len;
memcpy(value, data + i, new_value_len);
value[new_value_len] = 0;
*value_len = new_value_len;
i += new_value_len;
t->value = value;
}
}
*out_txt = txt;
*out_count = txt_num;
*out_value_len = txt_value_len;
return;
handle_error :
@ -2917,6 +2943,7 @@ handle_error :
free((char *)t->key);
free((char *)t->value);
}
free(txt_value_len);
free(txt);
}
@ -3246,6 +3273,7 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
} else if (type == MDNS_TYPE_TXT) {
if (search_result) {
mdns_txt_item_t * txt = NULL;
uint8_t *txt_value_len = NULL;
size_t txt_count = 0;
mdns_result_t * result = NULL;
@ -3266,16 +3294,17 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
}
}
if (!result->txt) {
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_count);
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_value_len, &txt_count);
if (txt_count) {
result->txt = txt;
result->txt_count = txt_count;
result->txt_value_len = txt_value_len;
}
}
} else {
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_count);
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_value_len, &txt_count);
if (txt_count) {
_mdns_search_result_add_txt(search_result, txt, txt_count, packet->tcpip_if, packet->ip_protocol);
_mdns_search_result_add_txt(search_result, txt, txt_value_len, txt_count, packet->tcpip_if, packet->ip_protocol);
}
}
} else if (ours) {
@ -3824,7 +3853,7 @@ static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char
/**
* @brief Called from parser to add TXT data to search result
*/
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, uint8_t *txt_value_len, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_result_t * r = search->result;
while (r) {
@ -3833,6 +3862,7 @@ static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_it
goto free_txt;
}
r->txt = txt;
r->txt_value_len = txt_value_len;
r->txt_count = txt_count;
return;
}
@ -3847,6 +3877,7 @@ static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_it
memset(r, 0 , sizeof(mdns_result_t));
r->txt = txt;
r->txt_value_len = txt_value_len;
r->txt_count = txt_count;
r->tcpip_if = tcpip_if;
r->ip_protocol = ip_protocol;
@ -4225,6 +4256,7 @@ static void _mdns_execute_action(mdns_action_t * action)
free((char *)txt->value);
free(key);
txt->value = value;
txt->value_len = action->data.srv_txt_set.value_len;
break;
}
txt = txt->next;
@ -4238,6 +4270,7 @@ static void _mdns_execute_action(mdns_action_t * action)
}
txt->key = key;
txt->value = value;
txt->value_len = action->data.srv_txt_set.value_len;
txt->next = service->txt;
service->txt = txt;
}
@ -4860,8 +4893,8 @@ esp_err_t mdns_instance_name_set(const char * instance)
* MDNS SERVICES
* */
esp_err_t mdns_service_add_for_host(const char * instance, const char * service, const char * proto,
const char * hostname, uint16_t port, mdns_txt_item_t txt[], size_t num_items)
esp_err_t mdns_service_add_for_host(const char * instance, const char * service, const char * proto, const char * hostname,
uint16_t port, mdns_txt_item_t txt[], size_t num_items)
{
if (!_mdns_server || _str_null_or_empty(service) || _str_null_or_empty(proto) || _str_null_or_empty(hostname) ||
!port) {
@ -5013,17 +5046,19 @@ esp_err_t mdns_service_txt_set(const char * service, const char * proto, mdns_tx
return mdns_service_txt_set_for_host(service, proto, _mdns_server->hostname, txt, num_items);
}
esp_err_t mdns_service_txt_item_set_for_host(const char * service, const char * proto, const char * hostname,
const char * key, const char * value)
esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char *service, const char *proto,
const char *hostname, const char *key,
const char *value, uint8_t value_len)
{
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) || _str_null_or_empty(key) || !value) {
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) ||
_str_null_or_empty(key) || !value) {
return ESP_ERR_INVALID_ARG;
}
mdns_srv_item_t * s = _mdns_get_service_item(service, proto, hostname);
mdns_srv_item_t *s = _mdns_get_service_item(service, proto, hostname);
if (!s) {
return ESP_ERR_NOT_FOUND;
}
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
mdns_action_t *action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) {
HOOK_MALLOC_FAILED;
return ESP_ERR_NO_MEM;
@ -5036,12 +5071,14 @@ esp_err_t mdns_service_txt_item_set_for_host(const char * service, const char *
free(action);
return ESP_ERR_NO_MEM;
}
action->data.srv_txt_set.value = strdup(value);
action->data.srv_txt_set.value = (char *)malloc(value_len);
if (!action->data.srv_txt_set.value) {
free(action->data.srv_txt_set.key);
free(action);
return ESP_ERR_NO_MEM;
}
memcpy(action->data.srv_txt_set.value, value, value_len);
action->data.srv_txt_set.value_len = value_len;
if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) {
free(action->data.srv_txt_set.key);
free(action->data.srv_txt_set.value);
@ -5051,12 +5088,31 @@ esp_err_t mdns_service_txt_item_set_for_host(const char * service, const char *
return ESP_OK;
}
esp_err_t mdns_service_txt_item_set(const char * service, const char * proto, const char * key, const char * value)
esp_err_t mdns_service_txt_item_set_for_host(const char *service, const char *proto, const char *hostname,
const char *key, const char *value)
{
return mdns_service_txt_item_set_for_host_with_explicit_value_len(service, proto, hostname, key, value,
strlen(value));
}
esp_err_t mdns_service_txt_item_set(const char *service, const char *proto, const char *key, const char *value)
{
if (!_mdns_server) {
return ESP_ERR_INVALID_STATE;
}
return mdns_service_txt_item_set_for_host(service, proto, _mdns_server->hostname, key, value);
return mdns_service_txt_item_set_for_host_with_explicit_value_len(service, proto, _mdns_server->hostname, key,
value, strlen(value));
}
esp_err_t mdns_service_txt_item_set_with_explicit_value_len(const char *service, const char *proto, const char *key,
const char *value, uint8_t value_len)
{
if (!_mdns_server) {
return ESP_ERR_INVALID_STATE;
}
return mdns_service_txt_item_set_for_host_with_explicit_value_len(service, proto, _mdns_server->hostname, key,
value, value_len);
}
esp_err_t mdns_service_txt_item_remove_for_host(const char * service, const char * proto, const char * hostname,
@ -5215,6 +5271,7 @@ void mdns_query_results_free(mdns_result_t * results)
free((char *)(r->txt[i].value));
}
free(r->txt);
free(r->txt_value_len);
while (r->addr) {
a = r->addr;

Wyświetl plik

@ -277,7 +277,8 @@ typedef struct {
typedef struct mdns_txt_linked_item_s {
const char * key; /*!< item key name */
const char * value; /*!< item value string */
char * value; /*!< item value string */
uint8_t value_len; /*!< item value length */
struct mdns_txt_linked_item_s * next; /*!< next result, or NULL for the last result in the list */
} mdns_txt_linked_item_t;
@ -426,6 +427,7 @@ typedef struct {
mdns_srv_item_t * service;
char * key;
char * value;
uint8_t value_len;
} srv_txt_set;
struct {
mdns_srv_item_t * service;

Wyświetl plik

@ -75,7 +75,7 @@ static void initialise_mdns(void)
//add another TXT item
ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "path", "/foobar") );
//change TXT item value
ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "u", "admin") );
ESP_ERROR_CHECK( mdns_service_txt_item_set_with_explicit_value_len("_http", "_tcp", "u", "admin", strlen("admin")) );
free(hostname);
}
@ -98,9 +98,10 @@ static void mdns_print_results(mdns_result_t * results){
printf(" SRV : %s.local:%u\n", r->hostname, r->port);
}
if(r->txt_count){
printf(" TXT : [%u] ", r->txt_count);
printf(" TXT : [%zu] ", r->txt_count);
for(t=0; t<r->txt_count; t++){
printf("%s=%s; ", r->txt[t].key, r->txt[t].value?r->txt[t].value:"NULL");
printf("%s=%s(%d); ", r->txt[t].key, r->txt[t].value?r->txt[t].value:"NULL",
r->txt_value_len[t]);
}
printf("\n");
}