mdns: Allow TXT entries larger than 63 bytes; add configurable maximum TXT RDATA length
This commit is contained in:
@@ -92,9 +92,9 @@ If this call returns successfully, the following queries will be answered:
|
|||||||
LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return);
|
LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return);
|
||||||
}
|
}
|
||||||
|
|
||||||
Since a hostname struct is used for TXT storage each single item can be max
|
Each item is encoded as a length byte followed by the data, so each single
|
||||||
63 bytes long, and the total max length (including length bytes for each
|
item can be max 255 bytes long, and the total max length (including length
|
||||||
item) is 255 bytes.
|
bytes for each item) is defined by MDNS_TXT_RDATA_MAXLEN (default 255).
|
||||||
|
|
||||||
If your device runs a webserver on port 80, an example call might be:
|
If your device runs a webserver on port 80, an example call might be:
|
||||||
|
|
||||||
|
|||||||
@@ -1272,7 +1272,7 @@ mdns_parse_pkt_known_answers(struct netif *netif, struct mdns_packet *pkt,
|
|||||||
} else if (match & REPLY_SERVICE_TXT) {
|
} else if (match & REPLY_SERVICE_TXT) {
|
||||||
mdns_prepare_txtdata(service);
|
mdns_prepare_txtdata(service);
|
||||||
if (service->txtdata.length == ans.rd_length &&
|
if (service->txtdata.length == ans.rd_length &&
|
||||||
pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.name, ans.rd_length) == 0) {
|
pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.rdata, ans.rd_length) == 0) {
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: TXT\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: TXT\n"));
|
||||||
reply->serv_replies[i] &= ~REPLY_SERVICE_TXT;
|
reply->serv_replies[i] &= ~REPLY_SERVICE_TXT;
|
||||||
}
|
}
|
||||||
@@ -2050,7 +2050,7 @@ mdns_handle_response(struct mdns_packet *pkt, struct netif *netif)
|
|||||||
} else if (ans.info.type == DNS_RRTYPE_TXT) {
|
} else if (ans.info.type == DNS_RRTYPE_TXT) {
|
||||||
mdns_prepare_txtdata(service);
|
mdns_prepare_txtdata(service);
|
||||||
if (service->txtdata.length == ans.rd_length &&
|
if (service->txtdata.length == ans.rd_length &&
|
||||||
pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.name, ans.rd_length) == 0) {
|
pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.rdata, ans.rd_length) == 0) {
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("mDNS: response equals our own TXT record -> no conflict\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("mDNS: response equals our own TXT record -> no conflict\n"));
|
||||||
conflict = 0;
|
conflict = 0;
|
||||||
}
|
}
|
||||||
@@ -2613,10 +2613,29 @@ mdns_resp_rename_service(struct netif *netif, u8_t slot, const char *name)
|
|||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Adds an RFC 1035 character-string to TXT RDATA. */
|
||||||
|
static err_t
|
||||||
|
mdns_txt_add_charstr(struct mdns_txtdata *txtdata, const char *value, u8_t len)
|
||||||
|
{
|
||||||
|
if (1 + len + txtdata->length > MDNS_TXT_RDATA_MAXLEN) {
|
||||||
|
LWIP_DEBUGF(MDNS_DEBUG, ("mdns_txt_add_charstr: adding string would exceed buffer (1+%d+%d > %d). Consider increasing MDNS_TXT_RDATA_MAXLEN.\n",
|
||||||
|
len, txtdata->length, MDNS_TXT_RDATA_MAXLEN));
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
txtdata->rdata[txtdata->length] = len;
|
||||||
|
txtdata->length++;
|
||||||
|
if (len) {
|
||||||
|
MEMCPY(&txtdata->rdata[txtdata->length], value, len);
|
||||||
|
txtdata->length += len;
|
||||||
|
}
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup mdns
|
* @ingroup mdns
|
||||||
* Call this function from inside the service_get_txt_fn_t callback to add text data.
|
* Call this function from inside the service_get_txt_fn_t callback to add text data.
|
||||||
* Buffer for TXT data is 256 bytes, and each field is prefixed with a length byte.
|
* Buffer for TXT data is MDNS_TXT_RDATA_MAXLEN (default 256) bytes, and each
|
||||||
|
* field is prefixed with a length byte.
|
||||||
* @param service The service provided to the get_txt callback
|
* @param service The service provided to the get_txt callback
|
||||||
* @param txt String to add to the TXT field.
|
* @param txt String to add to the TXT field.
|
||||||
* @param txt_len Length of string
|
* @param txt_len Length of string
|
||||||
@@ -2629,7 +2648,7 @@ mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_
|
|||||||
LWIP_ASSERT("mdns_resp_add_service_txtitem: service != NULL", service);
|
LWIP_ASSERT("mdns_resp_add_service_txtitem: service != NULL", service);
|
||||||
|
|
||||||
/* Use a mdns_domain struct to store txt chunks since it is the same encoding */
|
/* Use a mdns_domain struct to store txt chunks since it is the same encoding */
|
||||||
return mdns_domain_add_label(&service->txtdata, txt, txt_len);
|
return mdns_txt_add_charstr(&service->txtdata, txt, txt_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LWIP_MDNS_SEARCH
|
#if LWIP_MDNS_SEARCH
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ static void mdns_clear_outmsg(struct mdns_outmsg *outmsg);
|
|||||||
void
|
void
|
||||||
mdns_prepare_txtdata(struct mdns_service *service)
|
mdns_prepare_txtdata(struct mdns_service *service)
|
||||||
{
|
{
|
||||||
memset(&service->txtdata, 0, sizeof(struct mdns_domain));
|
memset(&service->txtdata, 0, sizeof(struct mdns_txtdata));
|
||||||
if (service->txt_fn) {
|
if (service->txt_fn) {
|
||||||
service->txt_fn(service, service->txt_userdata);
|
service->txt_fn(service, service->txt_userdata);
|
||||||
}
|
}
|
||||||
@@ -508,7 +508,7 @@ mdns_add_txt_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg,
|
|||||||
}
|
}
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with TXT record\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with TXT record\n"));
|
||||||
return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_TXT, DNS_RRCLASS_IN,
|
return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_TXT, DNS_RRCLASS_IN,
|
||||||
msg->cache_flush, ttl, (u8_t *) &service->txtdata.name,
|
msg->cache_flush, ttl, service->txtdata.rdata,
|
||||||
service->txtdata.length, NULL);
|
service->txtdata.length, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,12 @@
|
|||||||
#define MDNS_OUTPUT_PACKET_SIZE ((MDNS_MAX_SERVICES == 1) ? 512 : 1450)
|
#define MDNS_OUTPUT_PACKET_SIZE ((MDNS_MAX_SERVICES == 1) ? 512 : 1450)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** The maximum size of TXT RDATA allocated for each service record.
|
||||||
|
*/
|
||||||
|
#ifndef MDNS_TXT_RDATA_MAXLEN
|
||||||
|
# define MDNS_TXT_RDATA_MAXLEN 256
|
||||||
|
#endif
|
||||||
|
|
||||||
/** MDNS_RESP_USENETIF_EXTCALLBACK==1: register an ext_callback on the netif
|
/** MDNS_RESP_USENETIF_EXTCALLBACK==1: register an ext_callback on the netif
|
||||||
* to automatically restart probing/announcing on status or address change.
|
* to automatically restart probing/announcing on status or address change.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -90,10 +90,16 @@ struct mdns_request {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** TXT record data */
|
||||||
|
struct mdns_txtdata {
|
||||||
|
u8_t rdata[MDNS_TXT_RDATA_MAXLEN];
|
||||||
|
u16_t length;
|
||||||
|
};
|
||||||
|
|
||||||
/** Description of a service */
|
/** Description of a service */
|
||||||
struct mdns_service {
|
struct mdns_service {
|
||||||
/** TXT record to answer with */
|
/** TXT record to answer with */
|
||||||
struct mdns_domain txtdata;
|
struct mdns_txtdata txtdata;
|
||||||
/** Name of service, like 'myweb' */
|
/** Name of service, like 'myweb' */
|
||||||
char name[MDNS_LABEL_MAXLEN + 1];
|
char name[MDNS_LABEL_MAXLEN + 1];
|
||||||
/** Type of service, like '_http' */
|
/** Type of service, like '_http' */
|
||||||
|
|||||||
Reference in New Issue
Block a user