mdns: allow explicit txt value length

* Original commit: espressif/esp-idf@b4e0088b68
This commit is contained in:
Jiacheng Guo
2021-06-15 20:13:00 +08:00
committed by suren-gabrielyan-espressif
parent 73b1763029
commit 2ddaee2b6e
4 changed files with 140 additions and 31 deletions

View File

@ -79,6 +79,7 @@ typedef struct mdns_result_s {
uint16_t port; /*!< service port */ uint16_t port; /*!< service port */
// TXT // TXT
mdns_txt_item_t * txt; /*!< txt record */ 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 */ size_t txt_count; /*!< number of txt items */
// A and AAAA // A and AAAA
mdns_ip_addr_t * addr; /*!< linked list of IP addresses found */ 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 * @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, * @param instance_name instance name to set. If NULL,
* global instance name or hostname will be used * global instance name or hostname will be used
* @param service_type service type (_http, _ftp, etc) * @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); 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 * @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, * @param instance_name instance name to set. If NULL,
* global instance name or hostname will be used * global instance name or hostname will be used
* @param service_type service type (_http, _ftp, etc) * @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 * @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 service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp) * @param proto service protocol (_tcp, _udp)
* @param txt array of TXT data (eg. {{"var","val"},{"other","2"}}) * @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 * @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 service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp) * @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used. * @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 * @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 service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp) * @param proto service protocol (_tcp, _udp)
* @param key the key that you want to add/update * @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); 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 * @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 service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp) * @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used. * @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, 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); 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 * @brief Remove TXT item for service TXT record
* *

View File

@ -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 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_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_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 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_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); 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; 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 * @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; char * tmp;
mdns_txt_linked_item_t * txt = service->txt; mdns_txt_linked_item_t * txt = service->txt;
while (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) { if (tmp) {
sprintf(tmp, "%s=%s", txt->key, txt->value); int offset = sprintf(tmp, "%s=", txt->key);
uint8_t l = _mdns_append_string(packet, index, tmp); memcpy(tmp + offset, txt->value, txt->value_len);
uint8_t l = _mdns_append_string_with_len(packet, index, tmp, txt_data_len);
free(tmp); free(tmp);
if (!l) { if (!l) {
return 0; 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); free(new_item);
break; break;
} }
new_item->value_len = strlen(new_item->value);
new_item->next = new_txt; new_item->next = new_txt;
new_txt = new_item; 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 * @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_txt = NULL;
*out_count = 0; *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; HOOK_MALLOC_FAILED;
return; 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, 0, sizeof(mdns_txt_item_t) * num_items);
memset(txt_value_len, 0, num_items);
size_t txt_num = 0; size_t txt_num = 0;
while (i < len) { 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 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); memcpy(key, data + i, name_len);
key[name_len] = 0; key[name_len] = 0;
i += name_len + 1; i += name_len + 1;
t->key = key; t->key = key;
int value_len = partLen - name_len - 1; int new_value_len = partLen - name_len - 1;
if (value_len > 0) { if (new_value_len > 0) {
char * value = (char *)malloc(value_len + 1); char * value = (char *)malloc(new_value_len + 1);
if (!value) { if (!value) {
HOOK_MALLOC_FAILED; HOOK_MALLOC_FAILED;
goto handle_error;//error goto handle_error;//error
} }
memcpy(value, data + i, value_len); memcpy(value, data + i, new_value_len);
value[value_len] = 0; value[new_value_len] = 0;
i += value_len; *value_len = new_value_len;
i += new_value_len;
t->value = value; t->value = value;
} }
} }
*out_txt = txt; *out_txt = txt;
*out_count = txt_num; *out_count = txt_num;
*out_value_len = txt_value_len;
return; return;
handle_error : handle_error :
@ -2917,6 +2943,7 @@ handle_error :
free((char *)t->key); free((char *)t->key);
free((char *)t->value); free((char *)t->value);
} }
free(txt_value_len);
free(txt); free(txt);
} }
@ -3246,6 +3273,7 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
} else if (type == MDNS_TYPE_TXT) { } else if (type == MDNS_TYPE_TXT) {
if (search_result) { if (search_result) {
mdns_txt_item_t * txt = NULL; mdns_txt_item_t * txt = NULL;
uint8_t *txt_value_len = NULL;
size_t txt_count = 0; size_t txt_count = 0;
mdns_result_t * result = NULL; mdns_result_t * result = NULL;
@ -3266,16 +3294,17 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
} }
} }
if (!result->txt) { 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) { if (txt_count) {
result->txt = txt; result->txt = txt;
result->txt_count = txt_count; result->txt_count = txt_count;
result->txt_value_len = txt_value_len;
} }
} }
} else { } 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) { 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) { } 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 * @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; mdns_result_t * r = search->result;
while (r) { while (r) {
@ -3833,6 +3862,7 @@ static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_it
goto free_txt; goto free_txt;
} }
r->txt = txt; r->txt = txt;
r->txt_value_len = txt_value_len;
r->txt_count = txt_count; r->txt_count = txt_count;
return; 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)); memset(r, 0 , sizeof(mdns_result_t));
r->txt = txt; r->txt = txt;
r->txt_value_len = txt_value_len;
r->txt_count = txt_count; r->txt_count = txt_count;
r->tcpip_if = tcpip_if; r->tcpip_if = tcpip_if;
r->ip_protocol = ip_protocol; r->ip_protocol = ip_protocol;
@ -4225,6 +4256,7 @@ static void _mdns_execute_action(mdns_action_t * action)
free((char *)txt->value); free((char *)txt->value);
free(key); free(key);
txt->value = value; txt->value = value;
txt->value_len = action->data.srv_txt_set.value_len;
break; break;
} }
txt = txt->next; txt = txt->next;
@ -4238,6 +4270,7 @@ static void _mdns_execute_action(mdns_action_t * action)
} }
txt->key = key; txt->key = key;
txt->value = value; txt->value = value;
txt->value_len = action->data.srv_txt_set.value_len;
txt->next = service->txt; txt->next = service->txt;
service->txt = txt; service->txt = txt;
} }
@ -4860,8 +4893,8 @@ esp_err_t mdns_instance_name_set(const char * instance)
* MDNS SERVICES * MDNS SERVICES
* */ * */
esp_err_t mdns_service_add_for_host(const char * instance, const char * service, const char * proto, esp_err_t mdns_service_add_for_host(const char * instance, const char * service, const char * proto, const char * hostname,
const char * hostname, uint16_t port, mdns_txt_item_t txt[], size_t num_items) 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) || if (!_mdns_server || _str_null_or_empty(service) || _str_null_or_empty(proto) || _str_null_or_empty(hostname) ||
!port) { !port) {
@ -5013,10 +5046,12 @@ 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); 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, esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char *service, const char *proto,
const char * key, const char * value) 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; 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);
@ -5036,12 +5071,14 @@ esp_err_t mdns_service_txt_item_set_for_host(const char * service, const char *
free(action); free(action);
return ESP_ERR_NO_MEM; 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) { if (!action->data.srv_txt_set.value) {
free(action->data.srv_txt_set.key); free(action->data.srv_txt_set.key);
free(action); free(action);
return ESP_ERR_NO_MEM; 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) { if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) {
free(action->data.srv_txt_set.key); free(action->data.srv_txt_set.key);
free(action->data.srv_txt_set.value); 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; return ESP_OK;
} }
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) esp_err_t mdns_service_txt_item_set(const char *service, const char *proto, const char *key, const char *value)
{ {
if (!_mdns_server) { if (!_mdns_server) {
return ESP_ERR_INVALID_STATE; 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, 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((char *)(r->txt[i].value));
} }
free(r->txt); free(r->txt);
free(r->txt_value_len);
while (r->addr) { while (r->addr) {
a = r->addr; a = r->addr;

View File

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

View File

@ -75,7 +75,7 @@ static void initialise_mdns(void)
//add another TXT item //add another TXT item
ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "path", "/foobar") ); ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "path", "/foobar") );
//change TXT item value //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); 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); printf(" SRV : %s.local:%u\n", r->hostname, r->port);
} }
if(r->txt_count){ if(r->txt_count){
printf(" TXT : [%u] ", r->txt_count); printf(" TXT : [%zu] ", r->txt_count);
for(t=0; t<r->txt_count; t++){ 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"); printf("\n");
} }