Compare commits

..

3 Commits

Author SHA1 Message Date
703419ac31 Merge branch 'mdns-big-txt' into mdns-big-txt_bdk 2026-01-02 01:03:36 -07:00
3d5c99570f 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.
2026-01-02 00:44:16 -07:00
c01c655c5f mdns: add some txtdata unit tests 2026-01-02 00:09:35 -07:00

View File

@@ -35,6 +35,7 @@
#include "lwip/pbuf.h"
#include "lwip/apps/mdns.h"
#include "lwip/apps/mdns_domain.h"
#include "lwip/apps/mdns_out.h"
#include "lwip/apps/mdns_priv.h"
START_TEST(readname_basic)
@@ -876,6 +877,155 @@ START_TEST(compress_long_match)
}
END_TEST
#define TXT_STRING_1 "path=/"
#define TXT_LENGTH_1 6
#define TXT_LENSTR_1 "\006"
#define TXT_STRING_2 ""
#define TXT_LENGTH_2 0
#define TXT_LENSTR_2 "\000"
#define TXT_STRING_3 "This sentence is sixty-three bytes long, including punctuation."
#define TXT_LENGTH_3 63
#define TXT_LENSTR_3 "\077"
#define TXT_STRING_4 "This tests whether mdns_resp_add_service_txtitem can properly handle strings longer than 63 characters."
#define TXT_LENGTH_4 103
#define TXT_LENSTR_4 "\147"
START_TEST(txt_short_item)
{
const char *expected_txtdata = TXT_LENSTR_1 TXT_STRING_1;
const size_t expected_txtdata_length = 1 + TXT_LENGTH_1;
struct mdns_service service;
err_t res;
memset(&service, 0, sizeof(struct mdns_service));
mdns_prepare_txtdata(&service);
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_1, TXT_LENGTH_1);
fail_unless(res == ERR_OK);
fail_unless(service.txtdata.length == expected_txtdata_length);
fail_if(memcmp(service.txtdata.rdata, expected_txtdata, expected_txtdata_length));
}
END_TEST
START_TEST(txt_empty_item)
{
const char *expected_txtdata = TXT_LENSTR_2 TXT_STRING_2;
const size_t expected_txtdata_length = 1 + TXT_LENGTH_2;
struct mdns_service service;
err_t res;
memset(&service, 0, sizeof(struct mdns_service));
mdns_prepare_txtdata(&service);
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_2, TXT_LENGTH_2);
fail_unless(res == ERR_OK);
fail_unless(service.txtdata.length == expected_txtdata_length);
fail_if(memcmp(service.txtdata.rdata, expected_txtdata, expected_txtdata_length));
}
END_TEST
START_TEST(txt_long_item)
{
const char *expected_txtdata = TXT_LENSTR_4 TXT_STRING_4;
const size_t expected_txtdata_length = 1 + TXT_LENGTH_4;
struct mdns_service service;
err_t res;
memset(&service, 0, sizeof(struct mdns_service));
mdns_prepare_txtdata(&service);
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_4, TXT_LENGTH_4);
fail_unless(res == ERR_OK);
fail_unless(service.txtdata.length == expected_txtdata_length);
fail_if(memcmp(service.txtdata.rdata, expected_txtdata, expected_txtdata_length));
}
END_TEST
START_TEST(txt_multiple_items)
{
const char *expected_txtdata = (
TXT_LENSTR_1
TXT_STRING_1
TXT_LENSTR_2
TXT_STRING_2
TXT_LENSTR_3
TXT_STRING_3
TXT_LENSTR_4
TXT_STRING_4
);
const size_t expected_txtdata_length = (
1 + TXT_LENGTH_1
+ 1 + TXT_LENGTH_2
+ 1 + TXT_LENGTH_3
+ 1 + TXT_LENGTH_4
);
struct mdns_service service;
err_t res;
memset(&service, 0, sizeof(struct mdns_service));
mdns_prepare_txtdata(&service);
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_1, TXT_LENGTH_1);
fail_unless(res == ERR_OK); /* TXT_STRING_1 */
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_2, TXT_LENGTH_2);
fail_unless(res == ERR_OK); /* TXT_STRING_1 */
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_3, TXT_LENGTH_3);
fail_unless(res == ERR_OK); /* TXT_STRING_3 */
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_4, TXT_LENGTH_4);
fail_unless(res == ERR_OK); /* TXT_STRING_4 */
fail_unless(service.txtdata.length == expected_txtdata_length);
fail_if(memcmp(service.txtdata.rdata, expected_txtdata, expected_txtdata_length));
}
END_TEST
START_TEST(txt_buffer_full)
{
const char *expected_txtdata = (
TXT_LENSTR_3 TXT_STRING_3
TXT_LENSTR_3 TXT_STRING_3
TXT_LENSTR_3 TXT_STRING_3
TXT_LENSTR_3 TXT_STRING_3
);
const size_t expected_txtdata_length = 256;
struct mdns_service service;
err_t res;
int i;
memset(&service, 0, sizeof(struct mdns_service));
mdns_prepare_txtdata(&service);
/* add a 64-byte string 4 times = 256 bytes */
for (i = 0; i < 4; i++) {
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_3, TXT_LENGTH_3);
ck_assert_msg(res == ERR_OK,
"adding text item failed with error %d (i=%d, txtdata.length=%d)",
res, i, service.txtdata.length);
}
/* Try to add a few more strings while the buffer is full. This should fail. */
res = mdns_resp_add_service_txtitem(&service, "", 0);
fail_unless(res != ERR_OK); /* empty string */
res = mdns_resp_add_service_txtitem(&service, "path=/", 6);
fail_unless(res != ERR_OK); /* short string */
fail_unless(service.txtdata.length == expected_txtdata_length);
fail_if(memcmp(service.txtdata.rdata, expected_txtdata, expected_txtdata_length));
}
END_TEST
Suite* mdns_suite(void)
{
testfunc tests[] = {
@@ -911,6 +1061,12 @@ Suite* mdns_suite(void)
TESTFUNC(compress_2nd_label_short),
TESTFUNC(compress_jump_to_jump),
TESTFUNC(compress_long_match),
TESTFUNC(txt_short_item),
TESTFUNC(txt_empty_item),
TESTFUNC(txt_long_item),
TESTFUNC(txt_multiple_items),
TESTFUNC(txt_buffer_full),
};
return create_suite("MDNS", tests, sizeof(tests)/sizeof(testfunc), NULL, NULL);
}