mdns: Allow TXT entries larger than 63 bytes; add configurable maximum TXT RDATA size
This can be used to fix device adoption in ESPHome, which uses a long "package_import_url" string to advertise the location of the sourcecode for the device's configuration.
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);
|
||||
}
|
||||
|
||||
Since a hostname struct is used for TXT storage each single item can be max
|
||||
63 bytes long, and the total max length (including length bytes for each
|
||||
item) is 255 bytes.
|
||||
Each item is encoded as a length byte followed by the data, so each single
|
||||
item can be max 255 bytes long, and the total max length (including length
|
||||
bytes for each item) is defined by MDNS_TXT_RDATA_SIZE (default 255).
|
||||
|
||||
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) {
|
||||
mdns_prepare_txtdata(service);
|
||||
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"));
|
||||
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) {
|
||||
mdns_prepare_txtdata(service);
|
||||
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"));
|
||||
conflict = 0;
|
||||
}
|
||||
@@ -2613,10 +2613,29 @@ mdns_resp_rename_service(struct netif *netif, u8_t slot, const char *name)
|
||||
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_SIZE) {
|
||||
LWIP_DEBUGF(MDNS_DEBUG, ("mdns_txt_add_charstr: adding string would exceed buffer (1+%d+%d > %d). Consider increasing MDNS_TXT_RDATA_SIZE.\n",
|
||||
len, txtdata->length, MDNS_TXT_RDATA_SIZE));
|
||||
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
|
||||
* 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_SIZE (default 256) bytes, and each
|
||||
* field is prefixed with a length byte.
|
||||
* @param service The service provided to the get_txt callback
|
||||
* @param txt String to add to the TXT field.
|
||||
* @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);
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -62,7 +62,7 @@ static void mdns_clear_outmsg(struct mdns_outmsg *outmsg);
|
||||
void
|
||||
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) {
|
||||
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"));
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,12 @@
|
||||
#define MDNS_OUTPUT_PACKET_SIZE ((MDNS_MAX_SERVICES == 1) ? 512 : 1450)
|
||||
#endif
|
||||
|
||||
/** The maximum size of TXT RDATA allocated for each service.
|
||||
*/
|
||||
#ifndef MDNS_TXT_RDATA_SIZE
|
||||
# define MDNS_TXT_RDATA_SIZE 256
|
||||
#endif
|
||||
|
||||
/** MDNS_RESP_USENETIF_EXTCALLBACK==1: register an ext_callback on the netif
|
||||
* to automatically restart probing/announcing on status or address change.
|
||||
*/
|
||||
|
||||
@@ -90,10 +90,16 @@ struct mdns_request {
|
||||
};
|
||||
#endif
|
||||
|
||||
/** TXT record data */
|
||||
struct mdns_txtdata {
|
||||
u8_t rdata[MDNS_TXT_RDATA_SIZE];
|
||||
u16_t length;
|
||||
};
|
||||
|
||||
/** Description of a service */
|
||||
struct mdns_service {
|
||||
/** TXT record to answer with */
|
||||
struct mdns_domain txtdata;
|
||||
struct mdns_txtdata txtdata;
|
||||
/** Name of service, like 'myweb' */
|
||||
char name[MDNS_LABEL_MAXLEN + 1];
|
||||
/** Type of service, like '_http' */
|
||||
|
||||
Reference in New Issue
Block a user