From b87bef52e5e94d9142d09b129c68a93228aa64f2 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 12 Jan 2023 19:59:06 +0100 Subject: [PATCH 1/3] feat(mdns): Add support for IPv4 reverse query Partially addresses https://github.com/espressif/esp-protocols/issues/101 --- components/mdns/mdns.c | 120 +++++++++++++++++++++++++++++++++++------ 1 file changed, 103 insertions(+), 17 deletions(-) diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 42bb4f5da..f7cefd8c0 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -434,8 +434,7 @@ static const uint8_t *_mdns_read_fqdn(const uint8_t *packet, const uint8_t *star if (name->parts == 1 && buf[0] != '_' && (strcasecmp(buf, MDNS_DEFAULT_DOMAIN) != 0) && (strcasecmp(buf, "arpa") != 0) - && (strcasecmp(buf, "ip6") != 0) - && (strcasecmp(buf, "in-addr") != 0)) { + && (strcasecmp(buf, "ip6") != 0)) { strlcat(name->host, ".", sizeof(name->host)); strlcat(name->host, buf, sizeof(name->host)); } else if (strcasecmp(buf, MDNS_SUB_STR) == 0) { @@ -680,7 +679,7 @@ search_next: const uint8_t *content = _mdns_read_fqdn(packet, len_location, &name, buf, packet_len); if (!content) { //not a readable fqdn? - return 0; + goto search_next; // could be our unfinished fqdn, continue searching } if (name.parts == count) { uint8_t i; @@ -1100,22 +1099,36 @@ static uint16_t _mdns_append_aaaa_record(uint8_t *packet, uint16_t *index, const */ static uint16_t _mdns_append_question(uint8_t *packet, uint16_t *index, mdns_out_question_t *q) { - const char *str[4]; + const char *str[6]; uint8_t str_index = 0; uint8_t part_length; - if (q->host) { - str[str_index++] = q->host; - } - if (q->service) { - str[str_index++] = q->service; - } - if (q->proto) { - str[str_index++] = q->proto; - } - if (q->domain) { - str[str_index++] = q->domain; + if (q->host && strstr(q->host, "in-addr")) { + char * host = strdup(q->host); + char *rest = NULL; + for (char *p = strtok_r(host,".", &rest); p != NULL; p = strtok_r(NULL, ".", &rest)) { + str[str_index++] = p; + } + if (q->domain) { + str[str_index++] = q->domain; + } + + } else { + if (q->host) { + str[str_index++] = q->host; + } + if (q->service) { + str[str_index++] = q->service; + } + if (q->proto) { + str[str_index++] = q->proto; + } + if (q->domain) { + str[str_index++] = q->domain; + } + } + part_length = _mdns_append_fqdn(packet, index, str, str_index, MDNS_MAX_PACKET_SIZE); if (!part_length) { return 0; @@ -1200,6 +1213,63 @@ static uint8_t _mdns_append_host_answer(uint8_t *packet, uint16_t *index, mdns_h return num_records; } +static uint16_t _mdns_append_rev_ptr_record(uint8_t * packet, uint16_t * index, const char* name, bool flush, bool bye) +{ + const char * str[6]; + int i = 0; + + if (strstr(name, "in-addr") == NULL) { + return 0; + } + char * host = strdup(name); + char *rest = NULL; + for (char *p = strtok_r(host,".", &rest); p != NULL; p = strtok_r(NULL, ".", &rest)) { + str[i++] = p; + } + str[i++] = "arpa"; + uint16_t record_length = 0; + uint8_t part_length; + + part_length = _mdns_append_fqdn(packet, index, str, i, MDNS_MAX_PACKET_SIZE); + if (!part_length) { + return 0; + } + record_length += part_length; + + part_length = _mdns_append_type(packet, index, MDNS_ANSWER_PTR, false, bye?0:MDNS_ANSWER_PTR_TTL); + if (!part_length) { + return 0; + } + record_length += part_length; + + uint16_t data_len_location = *index - 2; + str[0] = _mdns_self_host.hostname; + str[1] = MDNS_DEFAULT_DOMAIN; + + part_length = _mdns_append_fqdn(packet, index, str, 2, MDNS_MAX_PACKET_SIZE); + if (!part_length) { + return 0; + } + + _mdns_set_u16(packet, data_len_location, part_length); + record_length += part_length; + + return record_length; +} + + +static uint8_t _mdns_append_reverse_ptr_record(uint8_t *packet, uint16_t *index, const char* name, bool flush, bool bye) +{ + uint8_t appended_answers = 0; + + if (_mdns_append_rev_ptr_record(packet, index, name, flush, bye) <= 0) { + return appended_answers; + } + appended_answers++; + + return appended_answers; +} + /** * @brief Append PTR answers to packet * @@ -1238,6 +1308,8 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an if (answer->type == MDNS_TYPE_PTR) { if (answer->service) { return _mdns_append_service_ptr_answers(packet, index, answer->service, answer->flush, answer->bye); + } else if (answer->host && answer->host->hostname && strstr(answer->host->hostname, "in-addr")) { + return _mdns_append_reverse_ptr_record(packet, index, answer->host->hostname, answer->flush, answer->bye) > 0; } else { return _mdns_append_ptr_record(packet, index, answer->custom_instance, answer->custom_service, answer->custom_proto, @@ -1639,6 +1711,15 @@ static bool _mdns_create_answer_from_service(mdns_tx_packet_t *packet, mdns_serv return true; } +static bool _mdns_create_answer_from_reverse_query(mdns_tx_packet_t * packet, const char * hostname, bool send_flush) +{ + mdns_host_item_t * host = mdns_get_host_item(hostname); + if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, NULL, host, send_flush, false)) { + return false; + } + return true; +} + static bool _mdns_create_answer_from_hostname(mdns_tx_packet_t *packet, const char *hostname, bool send_flush) { mdns_host_item_t *host = mdns_get_host_item(hostname); @@ -1723,13 +1804,18 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_ _mdns_free_tx_packet(packet); return; } + } else if (q->type == MDNS_TYPE_PTR) { + if (!_mdns_create_answer_from_reverse_query(packet, q->host, send_flush)) { + _mdns_free_tx_packet(packet); + return; + } } else if (!_mdns_alloc_answer(&packet->answers, q->type, NULL, NULL, send_flush, false)) { _mdns_free_tx_packet(packet); return; } if (parsed_packet->src_port != MDNS_SERVICE_PORT && // Repeat the queries only for "One-Shot mDNS queries" - (q->type == MDNS_TYPE_ANY || q->type == MDNS_TYPE_A || q->type == MDNS_TYPE_AAAA)) { + (q->type == MDNS_TYPE_ANY || q->type == MDNS_TYPE_A || q->type == MDNS_TYPE_AAAA || q->type == MDNS_TYPE_PTR)) { mdns_out_question_t *out_question = malloc(sizeof(mdns_out_question_t)); if (out_question == NULL) { HOOK_MALLOC_FAILED; @@ -2948,7 +3034,7 @@ static bool _mdns_name_is_discovery(mdns_name_t *name, uint16_t type) static bool _mdns_name_is_ours(mdns_name_t *name) { //domain have to be "local" - if (_str_null_or_empty(name->domain) || strcasecmp(name->domain, MDNS_DEFAULT_DOMAIN)) { + if (_str_null_or_empty(name->domain) || ( strcasecmp(name->domain, MDNS_DEFAULT_DOMAIN) && strcasecmp(name->domain, "arpa")) ) { return false; } From fb8a2f01981cbf63d26db26281035799bf7d516a Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 13 Jan 2023 20:32:07 +0100 Subject: [PATCH 2/3] fix(mdns): Host test with IDFv5.1 --- .github/workflows/host-test.yml | 24 ++++++- components/mdns/CMakeLists.txt | 7 +- components/mdns/Kconfig | 14 ++++ components/mdns/mdns.c | 46 +++++++----- .../mdns/private_include/mdns_private.h | 6 +- .../mdns/tests/host_test/CMakeLists.txt | 4 +- components/mdns/tests/host_test/README.md | 8 +++ .../CMakeLists.txt | 2 +- .../esp_event_mock.c | 0 .../include/esp_event.h | 10 +-- .../include/esp_event_base.h | 6 ++ .../components/esp_netif_linux/CMakeLists.txt | 4 +- .../esp_netif_linux/esp_netif_linux.c | 2 - .../include/machine/endian.h | 0 .../esp_system_protocols_linux/CMakeLists.txt | 3 - .../esp_system_protocols_linux/esp_log_impl.c | 27 ------- .../include/bsd_strings.h | 8 --- .../esp_system_protocols_linux/strlcat.c | 70 ------------------- .../components/esp_timer_linux/CMakeLists.txt | 2 +- .../components/esp_timer_linux/timer_task.hpp | 3 +- .../CMakeLists.txt | 2 +- .../{freertos_linux => freertos}/Kconfig | 0 .../freertos_linux.c | 18 ++--- .../include/esp_task.h | 0 .../include/freertos/FreeRTOS.h | 1 + .../freertos/include/freertos/queue.h | 13 ++++ .../freertos/include/freertos/semphr.h | 13 ++++ .../include/freertos/task.h | 0 .../queue_unique_ptr.cpp | 0 .../queue_unique_ptr.hpp | 0 .../tests/host_test/main/Kconfig.projbuild | 15 ++++ components/mdns/tests/host_test/main/main.c | 39 ++++++----- .../mdns/tests/host_test/make_eth2_netif | 5 ++ .../mdns/tests/host_test/sdkconfig.defaults | 7 ++ 34 files changed, 187 insertions(+), 172 deletions(-) rename components/mdns/tests/host_test/components/{esp_event_mock => esp_event}/CMakeLists.txt (59%) rename components/mdns/tests/host_test/components/{esp_event_mock => esp_event}/esp_event_mock.c (100%) rename components/mdns/tests/host_test/components/{esp_event_mock => esp_event}/include/esp_event.h (68%) rename components/mdns/tests/host_test/components/{esp_event_mock => esp_event}/include/esp_event_base.h (77%) rename components/mdns/tests/host_test/components/{esp_system_protocols_linux => esp_netif_linux}/include/machine/endian.h (100%) delete mode 100644 components/mdns/tests/host_test/components/esp_system_protocols_linux/CMakeLists.txt delete mode 100644 components/mdns/tests/host_test/components/esp_system_protocols_linux/esp_log_impl.c delete mode 100644 components/mdns/tests/host_test/components/esp_system_protocols_linux/include/bsd_strings.h delete mode 100644 components/mdns/tests/host_test/components/esp_system_protocols_linux/strlcat.c rename components/mdns/tests/host_test/components/{freertos_linux => freertos}/CMakeLists.txt (85%) rename components/mdns/tests/host_test/components/{freertos_linux => freertos}/Kconfig (100%) rename components/mdns/tests/host_test/components/{freertos_linux => freertos}/freertos_linux.c (97%) rename components/mdns/tests/host_test/components/{freertos_linux => freertos}/include/esp_task.h (100%) rename components/mdns/tests/host_test/components/{freertos_linux => freertos}/include/freertos/FreeRTOS.h (96%) create mode 100644 components/mdns/tests/host_test/components/freertos/include/freertos/queue.h create mode 100644 components/mdns/tests/host_test/components/freertos/include/freertos/semphr.h rename components/mdns/tests/host_test/components/{freertos_linux => freertos}/include/freertos/task.h (100%) rename components/mdns/tests/host_test/components/{freertos_linux => freertos}/queue_unique_ptr.cpp (100%) rename components/mdns/tests/host_test/components/{freertos_linux => freertos}/queue_unique_ptr.hpp (100%) create mode 100644 components/mdns/tests/host_test/main/Kconfig.projbuild create mode 100755 components/mdns/tests/host_test/make_eth2_netif create mode 100644 components/mdns/tests/host_test/sdkconfig.defaults diff --git a/.github/workflows/host-test.yml b/.github/workflows/host-test.yml index 656c29079..91ef93536 100644 --- a/.github/workflows/host-test.yml +++ b/.github/workflows/host-test.yml @@ -3,8 +3,8 @@ name: Host test on: [push, pull_request] jobs: - host_test: - name: Build and Test on Host + host_test_esp_modem: + name: esp-modem Build and Test on Host runs-on: ubuntu-20.04 container: espressif/idf:release-v4.3 env: @@ -38,3 +38,23 @@ jobs: if: always() with: files: esp-protocols/components/esp_modem/test/host_test/junit.xml + + host_test_mdns: + name: mdns Build and Test on Host + runs-on: ubuntu-20.04 + container: espressif/idf:latest + + steps: + - name: Checkout esp-protocols + uses: actions/checkout@master + with: + path: esp-protocols + + - name: Build and Test + shell: bash + run: | + apt-get update && apt-get install -y dnsutils gcc g++ + . ${IDF_PATH}/export.sh + cd $GITHUB_WORKSPACE/esp-protocols/components/mdns/tests/host_test + idf.py build + ./build/mdns_host.elf & dig +short -p 5353 @224.0.0.251 myesp.local diff --git a/components/mdns/CMakeLists.txt b/components/mdns/CMakeLists.txt index 5feb3c812..2b5129098 100644 --- a/components/mdns/CMakeLists.txt +++ b/components/mdns/CMakeLists.txt @@ -6,7 +6,7 @@ endif() idf_build_get_property(target IDF_TARGET) if(${target} STREQUAL "linux") - set(dependencies esp_system_protocols_linux) + set(dependencies esp_event esp_netif_linux esp_timer_linux esp_system) set(srcs "mdns.c" ${MDNS_NETWORKING}) else() set(dependencies lwip console esp_netif) @@ -22,6 +22,11 @@ idf_component_register( PRIV_REQUIRES ${private_dependencies}) target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") +if(${target} STREQUAL "linux") + target_link_libraries(${COMPONENT_LIB} PRIVATE "-lbsd") +endif() + + if(CONFIG_ETH_ENABLED) idf_component_optional_requires(PRIVATE esp_eth) endif() diff --git a/components/mdns/Kconfig b/components/mdns/Kconfig index 50bab3ba1..37b046a8a 100644 --- a/components/mdns/Kconfig +++ b/components/mdns/Kconfig @@ -81,6 +81,20 @@ menu "mDNS" This option creates a new thread to serve receiving packets (TODO). This option uses additional N sockets, where N is number of interfaces. + config MDNS_SKIP_SUPPRESSING_OWN_QUERIES + bool "Skip suppressing our own packets" + default n + help + Enable only if the querier and the responder share the same IP address. + This usually happens in test mode, where we may run multiple instances of + responders/queriers on the same interface. + + config MDNS_ENABLE_DEBUG_PRINTS + bool "Enable debug prints of mDNS packets" + default n + help + Enable for the library to log received and sent mDNS packets to stdout. + config MDNS_MULTIPLE_INSTANCE bool "Multiple instances under the same service type" default y diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index f7cefd8c0..31408e63b 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -17,10 +17,15 @@ #include "mdns_networking.h" #include "esp_log.h" #include "esp_random.h" -#if CONFIG_ETH_ENABLED +#if __has_include("bsd/string.h") +#include "bsd/string.h" +#endif +#if CONFIG_ETH_ENABLED && CONFIG_MDNS_PREDEF_NETIF_ETH #include "esp_eth.h" #endif +#if CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP #include "esp_wifi.h" +#endif #ifdef MDNS_ENABLE_DEBUG @@ -1102,10 +1107,11 @@ static uint16_t _mdns_append_question(uint8_t *packet, uint16_t *index, mdns_out const char *str[6]; uint8_t str_index = 0; uint8_t part_length; + char *host_dup = NULL; // need to duplicate host-name for some cases if (q->host && strstr(q->host, "in-addr")) { - char * host = strdup(q->host); + host_dup = strdup(q->host); char *rest = NULL; - for (char *p = strtok_r(host,".", &rest); p != NULL; p = strtok_r(NULL, ".", &rest)) { + for (char *p = strtok_r(host_dup, ".", &rest); p != NULL; p = strtok_r(NULL, ".", &rest)) { str[str_index++] = p; } if (q->domain) { @@ -1131,11 +1137,13 @@ static uint16_t _mdns_append_question(uint8_t *packet, uint16_t *index, mdns_out part_length = _mdns_append_fqdn(packet, index, str, str_index, MDNS_MAX_PACKET_SIZE); if (!part_length) { + free(host_dup); return 0; } part_length += _mdns_append_u16(packet, index, q->type); part_length += _mdns_append_u16(packet, index, q->unicast ? 0x8001 : 0x0001); + free(host_dup); return part_length; } @@ -1213,17 +1221,17 @@ static uint8_t _mdns_append_host_answer(uint8_t *packet, uint16_t *index, mdns_h return num_records; } -static uint16_t _mdns_append_rev_ptr_record(uint8_t * packet, uint16_t * index, const char* name, bool flush, bool bye) +static uint16_t _mdns_append_rev_ptr_record(uint8_t *packet, uint16_t *index, const char *name, bool flush, bool bye) { - const char * str[6]; + const char *str[6]; int i = 0; if (strstr(name, "in-addr") == NULL) { return 0; } - char * host = strdup(name); + char *host = strdup(name); char *rest = NULL; - for (char *p = strtok_r(host,".", &rest); p != NULL; p = strtok_r(NULL, ".", &rest)) { + for (char *p = strtok_r(host, ".", &rest); p != NULL; p = strtok_r(NULL, ".", &rest)) { str[i++] = p; } str[i++] = "arpa"; @@ -1236,7 +1244,7 @@ static uint16_t _mdns_append_rev_ptr_record(uint8_t * packet, uint16_t * index, } record_length += part_length; - part_length = _mdns_append_type(packet, index, MDNS_ANSWER_PTR, false, bye?0:MDNS_ANSWER_PTR_TTL); + part_length = _mdns_append_type(packet, index, MDNS_ANSWER_PTR, false, bye ? 0 : MDNS_ANSWER_PTR_TTL); if (!part_length) { return 0; } @@ -1258,7 +1266,7 @@ static uint16_t _mdns_append_rev_ptr_record(uint8_t * packet, uint16_t * index, } -static uint8_t _mdns_append_reverse_ptr_record(uint8_t *packet, uint16_t *index, const char* name, bool flush, bool bye) +static uint8_t _mdns_append_reverse_ptr_record(uint8_t *packet, uint16_t *index, const char *name, bool flush, bool bye) { uint8_t appended_answers = 0; @@ -1711,9 +1719,9 @@ static bool _mdns_create_answer_from_service(mdns_tx_packet_t *packet, mdns_serv return true; } -static bool _mdns_create_answer_from_reverse_query(mdns_tx_packet_t * packet, const char * hostname, bool send_flush) +static bool _mdns_create_answer_from_reverse_query(mdns_tx_packet_t *packet, const char *hostname, bool send_flush) { - mdns_host_item_t * host = mdns_get_host_item(hostname); + mdns_host_item_t *host = mdns_get_host_item(hostname); if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, NULL, host, send_flush, false)) { return false; } @@ -3394,6 +3402,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet) mdns_debug_packet(data, len); #endif +#ifndef CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES // Check if the packet wasn't sent by us if (packet->ip_protocol == MDNS_IP_PROTOCOL_V4) { esp_netif_ip_info_t if_ip_info; @@ -3410,6 +3419,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet) } #endif } +#endif // Check for the minimum size of mdns packet if (len <= MDNS_HEAD_ADDITIONAL_OFFSET) { @@ -3977,6 +3987,7 @@ static inline void post_mdns_announce_pcb(mdns_predef_if_t preset_if, mdns_ip_pr mdns_post_custom_action_tcpip_if(mdns_if_from_preset_if(preset_if), protocol == MDNS_IP_PROTOCOL_V4 ? MDNS_EVENT_ANNOUNCE_IP4 : MDNS_EVENT_ANNOUNCE_IP6); } +#if CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP || CONFIG_MDNS_PREDEF_NETIF_ETH void mdns_preset_if_handle_system_event(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { @@ -4054,6 +4065,7 @@ void mdns_preset_if_handle_system_event(void *arg, esp_event_base_t event_base, } } } +#endif /* CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP || CONFIG_MDNS_PREDEF_NETIF_ETH */ /* * MDNS Search @@ -6151,19 +6163,19 @@ void mdns_debug_packet(const uint8_t *data, size_t len) _mdns_dbg_printf("Packet[%u]: ", t); header.id = _mdns_read_u16(data, MDNS_HEAD_ID_OFFSET); - header.flags.value = _mdns_read_u16(data, MDNS_HEAD_FLAGS_OFFSET); + header.flags = _mdns_read_u16(data, MDNS_HEAD_FLAGS_OFFSET); header.questions = _mdns_read_u16(data, MDNS_HEAD_QUESTIONS_OFFSET); header.answers = _mdns_read_u16(data, MDNS_HEAD_ANSWERS_OFFSET); header.servers = _mdns_read_u16(data, MDNS_HEAD_SERVERS_OFFSET); header.additional = _mdns_read_u16(data, MDNS_HEAD_ADDITIONAL_OFFSET); _mdns_dbg_printf("%s", - (header.flags.value == MDNS_FLAGS_QR_AUTHORITATIVE) ? "AUTHORITATIVE\n" : - (header.flags.value == MDNS_FLAGS_DISTRIBUTED) ? "DISTRIBUTED\n" : - (header.flags.value == 0) ? "\n" : " " + (header.flags == MDNS_FLAGS_QR_AUTHORITATIVE) ? "AUTHORITATIVE\n" : + (header.flags == MDNS_FLAGS_DISTRIBUTED) ? "DISTRIBUTED\n" : + (header.flags == 0) ? "\n" : " " ); - if (header.flags.value && header.flags.value != MDNS_FLAGS_QR_AUTHORITATIVE) { - _mdns_dbg_printf("0x%04X\n", header.flags.value); + if (header.flags && header.flags != MDNS_FLAGS_QR_AUTHORITATIVE) { + _mdns_dbg_printf("0x%04X\n", header.flags); } if (header.questions) { diff --git a/components/mdns/private_include/mdns_private.h b/components/mdns/private_include/mdns_private.h index 0f40110e8..4fc29a36b 100644 --- a/components/mdns/private_include/mdns_private.h +++ b/components/mdns/private_include/mdns_private.h @@ -14,10 +14,10 @@ #include "freertos/queue.h" #include "freertos/semphr.h" #include "esp_timer.h" +#include "esp_system.h" -//#define MDNS_ENABLE_DEBUG - -#ifdef MDNS_ENABLE_DEBUG +#ifdef CONFIG_MDNS_ENABLE_DEBUG_PRINTS +#define MDNS_ENABLE_DEBUG #define _mdns_dbg_printf(...) printf(__VA_ARGS__) #endif diff --git a/components/mdns/tests/host_test/CMakeLists.txt b/components/mdns/tests/host_test/CMakeLists.txt index 132e436ea..7a421d02f 100644 --- a/components/mdns/tests/host_test/CMakeLists.txt +++ b/components/mdns/tests/host_test/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required(VERSION 3.5) +set(EXTRA_COMPONENT_DIRS "../..") + include($ENV{IDF_PATH}/tools/cmake/project.cmake) -set(COMPONENTS main) +set(COMPONENTS main esp_netif_linux) project(mdns_host) diff --git a/components/mdns/tests/host_test/README.md b/components/mdns/tests/host_test/README.md index ab916520d..4953f0e28 100644 --- a/components/mdns/tests/host_test/README.md +++ b/components/mdns/tests/host_test/README.md @@ -1,7 +1,10 @@ # Setup dummy network interfaces + +Note: Set two addresses so we could use one as source and another as destination ``` sudo ip link add eth2 type dummy sudo ip addr add 192.168.1.200/24 dev eth2 +sudo ip addr add 192.168.1.201/24 dev eth2 sudo ip link set eth2 up sudo ifconfig eth2 multicast ``` @@ -12,6 +15,11 @@ sudo ifconfig eth2 multicast dig +short -b 192.168.1.200 -p 5353 @224.0.0.251 myesp.local ``` +or a reverse query: +``` +dig +short -b 192.168.2.200 -p 5353 @224.0.0.251 -x 192.168.1.200 +``` + # Run avahi to browse services Avahi needs the netif to have the "multicast" flag set diff --git a/components/mdns/tests/host_test/components/esp_event_mock/CMakeLists.txt b/components/mdns/tests/host_test/components/esp_event/CMakeLists.txt similarity index 59% rename from components/mdns/tests/host_test/components/esp_event_mock/CMakeLists.txt rename to components/mdns/tests/host_test/components/esp_event/CMakeLists.txt index 606c16f80..f7bfde341 100644 --- a/components/mdns/tests/host_test/components/esp_event_mock/CMakeLists.txt +++ b/components/mdns/tests/host_test/components/esp_event/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS esp_event_mock.c INCLUDE_DIRS include - REQUIRES esp_system_protocols_linux) + REQUIRES) diff --git a/components/mdns/tests/host_test/components/esp_event_mock/esp_event_mock.c b/components/mdns/tests/host_test/components/esp_event/esp_event_mock.c similarity index 100% rename from components/mdns/tests/host_test/components/esp_event_mock/esp_event_mock.c rename to components/mdns/tests/host_test/components/esp_event/esp_event_mock.c diff --git a/components/mdns/tests/host_test/components/esp_event_mock/include/esp_event.h b/components/mdns/tests/host_test/components/esp_event/include/esp_event.h similarity index 68% rename from components/mdns/tests/host_test/components/esp_event_mock/include/esp_event.h rename to components/mdns/tests/host_test/components/esp_event/include/esp_event.h index 872eba49e..bc408c7fb 100644 --- a/components/mdns/tests/host_test/components/esp_event_mock/include/esp_event.h +++ b/components/mdns/tests/host_test/components/esp_event/include/esp_event.h @@ -8,16 +8,12 @@ #include "stdbool.h" #include "esp_err.h" #include "esp_event_base.h" -#include "bsd_strings.h" +//#include "bsd_strings.h" -#define ESP_EVENT_DECLARE_BASE(x) -#define ESP_EVENT_ANY_ID (-1) -typedef void *esp_event_base_t; -typedef void *system_event_t; -const char *WIFI_EVENT; -const char *IP_EVENT; +//const char *WIFI_EVENT; +//const char *IP_EVENT; esp_err_t esp_event_handler_register(const char *event_base, int32_t event_id, void *event_handler, void *event_handler_arg); diff --git a/components/mdns/tests/host_test/components/esp_event_mock/include/esp_event_base.h b/components/mdns/tests/host_test/components/esp_event/include/esp_event_base.h similarity index 77% rename from components/mdns/tests/host_test/components/esp_event_mock/include/esp_event_base.h rename to components/mdns/tests/host_test/components/esp_event/include/esp_event_base.h index a9e117bcd..059805bbe 100644 --- a/components/mdns/tests/host_test/components/esp_event_mock/include/esp_event_base.h +++ b/components/mdns/tests/host_test/components/esp_event/include/esp_event_base.h @@ -11,3 +11,9 @@ typedef enum { WIFI_EVENT_AP_START, /**< ESP32 soft-AP start */ WIFI_EVENT_AP_STOP, /**< ESP32 soft-AP stop */ } mdns_used_event_t; + +#define ESP_EVENT_DECLARE_BASE(x) +#define ESP_EVENT_ANY_ID (-1) + +typedef void *esp_event_base_t; +typedef void *system_event_t; diff --git a/components/mdns/tests/host_test/components/esp_netif_linux/CMakeLists.txt b/components/mdns/tests/host_test/components/esp_netif_linux/CMakeLists.txt index 086034b08..b02c5fec0 100644 --- a/components/mdns/tests/host_test/components/esp_netif_linux/CMakeLists.txt +++ b/components/mdns/tests/host_test/components/esp_netif_linux/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS esp_netif_linux.c - INCLUDE_DIRS include - REQUIRES esp_system_protocols_linux) + INCLUDE_DIRS include $ENV{IDF_PATH}/components/esp_netif/include + REQUIRES esp_event) diff --git a/components/mdns/tests/host_test/components/esp_netif_linux/esp_netif_linux.c b/components/mdns/tests/host_test/components/esp_netif_linux/esp_netif_linux.c index e595ee03a..5c9aaadd1 100644 --- a/components/mdns/tests/host_test/components/esp_netif_linux/esp_netif_linux.c +++ b/components/mdns/tests/host_test/components/esp_netif_linux/esp_netif_linux.c @@ -50,9 +50,7 @@ esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_ struct sockaddr_in *pAddr = (struct sockaddr_in *) tmp->ifa_addr; inet_ntop(AF_INET, &pAddr->sin_addr, addr, sizeof(addr) ); if (strcmp(esp_netif->if_desc, tmp->ifa_name) == 0) { - printf("AF_INET: %s: %s\n", tmp->ifa_name, addr); memcpy(&ip_info->ip.addr, &pAddr->sin_addr, 4); - break; } } tmp = tmp->ifa_next; diff --git a/components/mdns/tests/host_test/components/esp_system_protocols_linux/include/machine/endian.h b/components/mdns/tests/host_test/components/esp_netif_linux/include/machine/endian.h similarity index 100% rename from components/mdns/tests/host_test/components/esp_system_protocols_linux/include/machine/endian.h rename to components/mdns/tests/host_test/components/esp_netif_linux/include/machine/endian.h diff --git a/components/mdns/tests/host_test/components/esp_system_protocols_linux/CMakeLists.txt b/components/mdns/tests/host_test/components/esp_system_protocols_linux/CMakeLists.txt deleted file mode 100644 index 6504024a4..000000000 --- a/components/mdns/tests/host_test/components/esp_system_protocols_linux/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -idf_component_register(SRCS esp_log_impl.c strlcat.c - INCLUDE_DIRS include - REQUIRES esp_netif_linux esp_timer_linux freertos_linux esp_event_mock esp_netif log esp_common) diff --git a/components/mdns/tests/host_test/components/esp_system_protocols_linux/esp_log_impl.c b/components/mdns/tests/host_test/components/esp_system_protocols_linux/esp_log_impl.c deleted file mode 100644 index bf9305aee..000000000 --- a/components/mdns/tests/host_test/components/esp_system_protocols_linux/esp_log_impl.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "esp_err.h" -#include "esp_log.h" -#include - -void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) -{ - ESP_LOGE("ESP_ERROR_CHECK", "Failed with esp_err_t: 0x%x", rc); - ESP_LOGE("ESP_ERROR_CHECK", "Expression: %s", expression); - ESP_LOGE("ESP_ERROR_CHECK", "Functions: %s %s(%d)", function, file, line); - abort(); -} - -void esp_log_buffer_hexdump_internal(const char *tag, const void *buffer, uint16_t buff_len, esp_log_level_t log_level) -{ - if ( LOG_LOCAL_LEVEL >= log_level ) { - ESP_LOG_LEVEL(log_level, tag, "Buffer:%p length:%d", buffer, buff_len); - for (int i = 0; i < buff_len; ++i) { - printf("%02x ", ((uint8_t *)buffer)[i]); - } - printf("\n"); - } -} diff --git a/components/mdns/tests/host_test/components/esp_system_protocols_linux/include/bsd_strings.h b/components/mdns/tests/host_test/components/esp_system_protocols_linux/include/bsd_strings.h deleted file mode 100644 index eee857f31..000000000 --- a/components/mdns/tests/host_test/components/esp_system_protocols_linux/include/bsd_strings.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once - -size_t strlcat(char *dest, const char *src, size_t size); diff --git a/components/mdns/tests/host_test/components/esp_system_protocols_linux/strlcat.c b/components/mdns/tests/host_test/components/esp_system_protocols_linux/strlcat.c deleted file mode 100644 index b5562df30..000000000 --- a/components/mdns/tests/host_test/components/esp_system_protocols_linux/strlcat.c +++ /dev/null @@ -1,70 +0,0 @@ -/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */ - -/*- - * Copyright (c) 1998 Todd C. Miller - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "string.h" - -/* - * Appends src to string dst of size siz (unlike strncat, siz is the - * full size of dst, not space left). At most siz-1 characters - * will be copied. Always NUL terminates (unless siz <= strlen(dst)). - * Returns strlen(src) + MIN(siz, strlen(initial dst)). - * If retval >= siz, truncation occurred. - */ -size_t -strlcat(dst, src, siz) -char *dst; -const char *src; -size_t siz; -{ - char *d = dst; - const char *s = src; - size_t n = siz; - size_t dlen; - - /* Find the end of dst and adjust bytes left but don't go past end */ - while (n-- != 0 && *d != '\0') { - d++; - } - dlen = d - dst; - n = siz - dlen; - - if (n == 0) { - return (dlen + strlen(s)); - } - while (*s != '\0') { - if (n != 1) { - *d++ = *s; - n--; - } - s++; - } - *d = '\0'; - - return (dlen + (s - src)); /* count does not include NUL */ -} diff --git a/components/mdns/tests/host_test/components/esp_timer_linux/CMakeLists.txt b/components/mdns/tests/host_test/components/esp_timer_linux/CMakeLists.txt index a2bec32aa..80bcd3e36 100644 --- a/components/mdns/tests/host_test/components/esp_timer_linux/CMakeLists.txt +++ b/components/mdns/tests/host_test/components/esp_timer_linux/CMakeLists.txt @@ -1,6 +1,6 @@ idf_component_register(SRCS esp_timer_linux.c timer_task.cpp INCLUDE_DIRS include - REQUIRES esp_system_protocols_linux freertos_linux) + REQUIRES esp_event) set_target_properties(${COMPONENT_LIB} PROPERTIES CXX_STANDARD 17 diff --git a/components/mdns/tests/host_test/components/esp_timer_linux/timer_task.hpp b/components/mdns/tests/host_test/components/esp_timer_linux/timer_task.hpp index be8bec5f5..9477a0ded 100644 --- a/components/mdns/tests/host_test/components/esp_timer_linux/timer_task.hpp +++ b/components/mdns/tests/host_test/components/esp_timer_linux/timer_task.hpp @@ -16,7 +16,7 @@ typedef void (*cb_t)(void *arg); class TimerTaskMock { public: - TimerTaskMock(cb_t cb): cb(cb), t(run_static, this), active(false), ms(INT32_MAX) {} + TimerTaskMock(cb_t cb): cb(cb), active(false), ms(INT32_MAX) {} ~TimerTaskMock(void) { active = false; @@ -27,6 +27,7 @@ public: { ms = m; active = true; + t = std::thread(run_static, this); } private: diff --git a/components/mdns/tests/host_test/components/freertos_linux/CMakeLists.txt b/components/mdns/tests/host_test/components/freertos/CMakeLists.txt similarity index 85% rename from components/mdns/tests/host_test/components/freertos_linux/CMakeLists.txt rename to components/mdns/tests/host_test/components/freertos/CMakeLists.txt index cd1686154..925b08732 100644 --- a/components/mdns/tests/host_test/components/freertos_linux/CMakeLists.txt +++ b/components/mdns/tests/host_test/components/freertos/CMakeLists.txt @@ -1,6 +1,6 @@ idf_component_register(SRCS freertos_linux.c queue_unique_ptr.cpp INCLUDE_DIRS include - REQUIRES esp_system_protocols_linux) + REQUIRES) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) diff --git a/components/mdns/tests/host_test/components/freertos_linux/Kconfig b/components/mdns/tests/host_test/components/freertos/Kconfig similarity index 100% rename from components/mdns/tests/host_test/components/freertos_linux/Kconfig rename to components/mdns/tests/host_test/components/freertos/Kconfig diff --git a/components/mdns/tests/host_test/components/freertos_linux/freertos_linux.c b/components/mdns/tests/host_test/components/freertos/freertos_linux.c similarity index 97% rename from components/mdns/tests/host_test/components/freertos_linux/freertos_linux.c rename to components/mdns/tests/host_test/components/freertos/freertos_linux.c index c34cf5cbd..d69dea54f 100644 --- a/components/mdns/tests/host_test/components/freertos_linux/freertos_linux.c +++ b/components/mdns/tests/host_test/components/freertos/freertos_linux.c @@ -158,15 +158,15 @@ void xTaskCreate(TaskFunction_t pvTaskCode, const char *const pcName, const uint } } -uint32_t esp_get_free_heap_size(void) -{ - return 0; -} - -uint32_t esp_random(void) -{ - return rand(); -} +//uint32_t esp_get_free_heap_size(void) +//{ +// return 0; +//} +// +//uint32_t esp_random(void) +//{ +// return rand(); +//} void xTaskNotifyGive(TaskHandle_t task) { diff --git a/components/mdns/tests/host_test/components/freertos_linux/include/esp_task.h b/components/mdns/tests/host_test/components/freertos/include/esp_task.h similarity index 100% rename from components/mdns/tests/host_test/components/freertos_linux/include/esp_task.h rename to components/mdns/tests/host_test/components/freertos/include/esp_task.h diff --git a/components/mdns/tests/host_test/components/freertos_linux/include/freertos/FreeRTOS.h b/components/mdns/tests/host_test/components/freertos/include/freertos/FreeRTOS.h similarity index 96% rename from components/mdns/tests/host_test/components/freertos_linux/include/freertos/FreeRTOS.h rename to components/mdns/tests/host_test/components/freertos/include/freertos/FreeRTOS.h index e087f8b3c..6febf24ad 100644 --- a/components/mdns/tests/host_test/components/freertos_linux/include/freertos/FreeRTOS.h +++ b/components/mdns/tests/host_test/components/freertos/include/freertos/FreeRTOS.h @@ -32,3 +32,4 @@ typedef int BaseType_t; uint32_t esp_get_free_heap_size(void); uint32_t esp_random(void); +void vTaskSuspendAll(void); diff --git a/components/mdns/tests/host_test/components/freertos/include/freertos/queue.h b/components/mdns/tests/host_test/components/freertos/include/freertos/queue.h new file mode 100644 index 000000000..38938e0c3 --- /dev/null +++ b/components/mdns/tests/host_test/components/freertos/include/freertos/queue.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +// +// Created by david on 1/13/23. +// + +#ifndef _QUEUE_H_ +#define _QUEUE_H_ + +#endif //_QUEUE_H_ diff --git a/components/mdns/tests/host_test/components/freertos/include/freertos/semphr.h b/components/mdns/tests/host_test/components/freertos/include/freertos/semphr.h new file mode 100644 index 000000000..175ee7e51 --- /dev/null +++ b/components/mdns/tests/host_test/components/freertos/include/freertos/semphr.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +// +// Created by david on 1/13/23. +// + +#ifndef _SEMAPHR_H_ +#define _SEMAPHR_H_ + +#endif //_SEMAPHR_H_ diff --git a/components/mdns/tests/host_test/components/freertos_linux/include/freertos/task.h b/components/mdns/tests/host_test/components/freertos/include/freertos/task.h similarity index 100% rename from components/mdns/tests/host_test/components/freertos_linux/include/freertos/task.h rename to components/mdns/tests/host_test/components/freertos/include/freertos/task.h diff --git a/components/mdns/tests/host_test/components/freertos_linux/queue_unique_ptr.cpp b/components/mdns/tests/host_test/components/freertos/queue_unique_ptr.cpp similarity index 100% rename from components/mdns/tests/host_test/components/freertos_linux/queue_unique_ptr.cpp rename to components/mdns/tests/host_test/components/freertos/queue_unique_ptr.cpp diff --git a/components/mdns/tests/host_test/components/freertos_linux/queue_unique_ptr.hpp b/components/mdns/tests/host_test/components/freertos/queue_unique_ptr.hpp similarity index 100% rename from components/mdns/tests/host_test/components/freertos_linux/queue_unique_ptr.hpp rename to components/mdns/tests/host_test/components/freertos/queue_unique_ptr.hpp diff --git a/components/mdns/tests/host_test/main/Kconfig.projbuild b/components/mdns/tests/host_test/main/Kconfig.projbuild new file mode 100644 index 000000000..f19001f87 --- /dev/null +++ b/components/mdns/tests/host_test/main/Kconfig.projbuild @@ -0,0 +1,15 @@ +menu "Test Configuration" + + config TEST_HOSTNAME + string "mDNS Hostname" + default "esp32-mdns" + help + mDNS Hostname for example to use + + config TEST_NETIF_NAME + string "Network interface name" + default "eth2" + help + Name/ID if the network interface on which we run the mDNS host test + +endmenu diff --git a/components/mdns/tests/host_test/main/main.c b/components/mdns/tests/host_test/main/main.c index 51ca92a52..47de777f9 100644 --- a/components/mdns/tests/host_test/main/main.c +++ b/components/mdns/tests/host_test/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -35,27 +35,34 @@ int main(int argc, char *argv[]) { setvbuf(stdout, NULL, _IONBF, 0); - const esp_netif_inherent_config_t base_cg = { .if_key = "WIFI_STA_DEF", .if_desc = "eth2" }; + const esp_netif_inherent_config_t base_cg = { .if_key = "WIFI_STA_DEF", .if_desc = CONFIG_TEST_NETIF_NAME }; esp_netif_config_t cfg = { .base = &base_cg }; esp_netif_t *sta = esp_netif_new(&cfg); + ESP_ERROR_CHECK(mdns_init()); + ESP_ERROR_CHECK(mdns_register_netif(sta)); + ESP_ERROR_CHECK(mdns_netif_action(sta, MDNS_EVENT_ENABLE_IP4)); - mdns_init(); + mdns_hostname_set(CONFIG_TEST_HOSTNAME); + ESP_LOGI(TAG, "mdns hostname set to: [%s]", CONFIG_TEST_HOSTNAME); + mdns_ip_addr_t addr4 = { .addr.u_addr.ip4.addr = 0x1020304 }; + addr4.addr.type = ESP_IPADDR_TYPE_V4; + const char *delegated_hostname = "200.0.168.192.in-addr"; + addr4.addr.type = ESP_IPADDR_TYPE_V4; + ESP_ERROR_CHECK( mdns_delegate_hostname_add(delegated_hostname, &addr4) ); - mdns_hostname_set("myesp"); - ESP_LOGI(TAG, "mdns hostname set to: [%s]", "myesp"); //set default mDNS instance name - mdns_instance_name_set("myesp-inst"); + //mdns_instance_name_set("myesp-inst"); //structure with TXT records - mdns_txt_item_t serviceTxtData[3] = { - {"board", "esp32"}, - {"u", "user"}, - {"p", "password"} - }; - vTaskDelay(1000); - ESP_ERROR_CHECK(mdns_service_add("myesp-service2", "_http", "_tcp", 80, serviceTxtData, 3)); - vTaskDelay(2000); - - query_mdns_host("david-comp"); +// mdns_txt_item_t serviceTxtData[3] = { +// {"board", "esp32"}, +// {"u", "user"}, +// {"p", "password"} +// }; +// vTaskDelay(pdMS_TO_TICKS(1000)); + vTaskDelay(pdMS_TO_TICKS(10000)); + // ESP_ERROR_CHECK(mdns_service_add("myesp-service2", "_http", "_tcp", 80, serviceTxtData, 3)); + // vTaskDelay(2000); + query_mdns_host("david-work"); vTaskDelay(2000); esp_netif_destroy(sta); mdns_free(); diff --git a/components/mdns/tests/host_test/make_eth2_netif b/components/mdns/tests/host_test/make_eth2_netif new file mode 100755 index 000000000..2436125b7 --- /dev/null +++ b/components/mdns/tests/host_test/make_eth2_netif @@ -0,0 +1,5 @@ +sudo ip link add eth2 type dummy +sudo ip addr add 192.168.1.200/24 dev eth2 +sudo ip addr add 192.168.1.201/24 dev eth2 +sudo ip link set eth2 up +sudo ifconfig eth2 multicast diff --git a/components/mdns/tests/host_test/sdkconfig.defaults b/components/mdns/tests/host_test/sdkconfig.defaults new file mode 100644 index 000000000..7c7663f3f --- /dev/null +++ b/components/mdns/tests/host_test/sdkconfig.defaults @@ -0,0 +1,7 @@ +CONFIG_IDF_TARGET="linux" +CONFIG_MDNS_NETWORKING_SOCKET=y +CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES=y +CONFIG_TEST_NETIF_NAME="eth0" +CONFIG_TEST_HOSTNAME="myesp" +# CONFIG_MDNS_PREDEF_NETIF_STA is not set +# CONFIG_MDNS_PREDEF_NETIF_AP is not set From 91134f10ffd9f8bc5f252e5f2ac0ced71ab0d7a5 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Mon, 16 Jan 2023 23:13:11 +0100 Subject: [PATCH 3/3] mdns: Make reverse query conditional per Kconfig and auto-register reverse logical names --- .github/workflows/host-test.yml | 5 +- components/mdns/Kconfig | 7 + .../mdns/examples/main/mdns_example_main.c | 9 +- components/mdns/include/mdns.h | 2 + components/mdns/mdns.c | 195 +++++++++++------- .../components/esp_event/CMakeLists.txt | 3 +- .../components/esp_event/include/esp_event.h | 7 +- .../components/freertos/CMakeLists.txt | 3 +- .../components/freertos/freertos_linux.c | 10 - components/mdns/tests/host_test/main/main.c | 33 ++- .../mdns/tests/host_test/make_eth2_netif | 5 - .../mdns/tests/host_test/sdkconfig.defaults | 6 +- 12 files changed, 160 insertions(+), 125 deletions(-) delete mode 100755 components/mdns/tests/host_test/make_eth2_netif diff --git a/.github/workflows/host-test.yml b/.github/workflows/host-test.yml index 91ef93536..d823d38b8 100644 --- a/.github/workflows/host-test.yml +++ b/.github/workflows/host-test.yml @@ -57,4 +57,7 @@ jobs: . ${IDF_PATH}/export.sh cd $GITHUB_WORKSPACE/esp-protocols/components/mdns/tests/host_test idf.py build - ./build/mdns_host.elf & dig +short -p 5353 @224.0.0.251 myesp.local + ./build/mdns_host.elf & + dig +short -p 5353 @224.0.0.251 myesp.local > ip.txt + cat ip.txt | xargs dig +short -p 5353 @224.0.0.251 -x + cat ip.txt diff --git a/components/mdns/Kconfig b/components/mdns/Kconfig index 37b046a8a..53fb79ee5 100644 --- a/components/mdns/Kconfig +++ b/components/mdns/Kconfig @@ -95,6 +95,13 @@ menu "mDNS" help Enable for the library to log received and sent mDNS packets to stdout. + config MDNS_RESPOND_REVERSE_QUERIES + bool "Enable responding to IPv4 reverse queries" + default n + help + Enables support for IPv4 reverse lookup. If enabled, the mDNS library + response to PTR queries of "A.B.C.D.in-addr.arpa" type. + config MDNS_MULTIPLE_INSTANCE bool "Multiple instances under the same service type" default y diff --git a/components/mdns/examples/main/mdns_example_main.c b/components/mdns/examples/main/mdns_example_main.c index d0a393c9a..bd2cfe147 100644 --- a/components/mdns/examples/main/mdns_example_main.c +++ b/components/mdns/examples/main/mdns_example_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -279,6 +279,13 @@ void app_main(void) ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ENABLE_IP4)); ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ANNOUNCE_IP4)); #endif + +#if defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES) + while (mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_IP4_REVERSE_LOOKUP) != ESP_OK) { + vTaskDelay(50 / portTICK_PERIOD_MS); + } +#endif + initialise_button(); xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL); } diff --git a/components/mdns/include/mdns.h b/components/mdns/include/mdns.h index fd6186276..d6a3f150b 100644 --- a/components/mdns/include/mdns.h +++ b/components/mdns/include/mdns.h @@ -34,6 +34,8 @@ typedef enum { MDNS_EVENT_ANNOUNCE_IP6 = 1 << 4, MDNS_EVENT_DISABLE_IP4 = 1 << 5, MDNS_EVENT_DISABLE_IP6 = 1 << 6, + MDNS_EVENT_IP4_REVERSE_LOOKUP = 1 << 7, + MDNS_EVENT_IP6_REVERSE_LOOKUP = 1 << 8, } mdns_event_actions_t; /** diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 31408e63b..8c10cb1a3 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -17,9 +17,7 @@ #include "mdns_networking.h" #include "esp_log.h" #include "esp_random.h" -#if __has_include("bsd/string.h") -#include "bsd/string.h" -#endif + #if CONFIG_ETH_ENABLED && CONFIG_MDNS_PREDEF_NETIF_ETH #include "esp_eth.h" #endif @@ -439,7 +437,11 @@ static const uint8_t *_mdns_read_fqdn(const uint8_t *packet, const uint8_t *star if (name->parts == 1 && buf[0] != '_' && (strcasecmp(buf, MDNS_DEFAULT_DOMAIN) != 0) && (strcasecmp(buf, "arpa") != 0) - && (strcasecmp(buf, "ip6") != 0)) { + && (strcasecmp(buf, "ip6") != 0) +#ifndef CONFIG_MDNS_RESPOND_REVERSE_QUERIES + && (strcasecmp(buf, "in-addr") != 0) +#endif + ) { strlcat(name->host, ".", sizeof(name->host)); strlcat(name->host, buf, sizeof(name->host)); } else if (strcasecmp(buf, MDNS_SUB_STR) == 0) { @@ -643,6 +645,60 @@ static inline int append_one_txt_record_entry(uint8_t *packet, uint16_t *index, return len + 1; } +#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES +static inline int append_single_str(uint8_t *packet, uint16_t *index, const char *str, int len) +{ + if ((*index + len + 1) >= MDNS_MAX_PACKET_SIZE) { + return 0; + } + if (!_mdns_append_u8(packet, index, len)) { + return 0; + } + memcpy(packet + *index, str, len); + *index += len; + return *index; +} + +/** + * @brief appends FQDN to a packet from hostname separated by dots. This API works the same way as + * _mdns_append_fqdn(), but refrains from DNS compression (as it's mainly used for IP addresses (many short items), + * where we gain very little (or compression even gets counter-productive mainly for IPv6 addresses) + * + * @param packet MDNS packet + * @param index offset in the packet + * @param name name representing FQDN in '.' separated parts + * @param last true if appending the last part (domain, typically "arpa") + * + * @return length of added data: 0 on error or length on success + */ +static uint16_t append_fqdn_dots(uint8_t *packet, uint16_t *index, const char *name, bool last) +{ + int len = strlen(name); + char *host = (char *)name; + char *end = host; + char *start = host; + do { + end = memchr(start, '.', len); + end = end ? end : host + len; + int part_len = end - start; + if (!append_single_str(packet, index, start, part_len)) { + return 0; + } + start = ++end; + } while (end < name + len); + + if (!append_single_str(packet, index, "arpa", sizeof("arpa") - 1)) { + return 0; + } + + //empty string so terminate + if (!_mdns_append_u8(packet, index, 0)) { + return 0; + } + return *index; +} +#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */ + /** * @brief appends FQDN to a packet, incrementing the index and * compressing the output if previous occurrence of the string (or part of it) has been found @@ -1104,21 +1160,18 @@ static uint16_t _mdns_append_aaaa_record(uint8_t *packet, uint16_t *index, const */ static uint16_t _mdns_append_question(uint8_t *packet, uint16_t *index, mdns_out_question_t *q) { - const char *str[6]; - uint8_t str_index = 0; uint8_t part_length; - char *host_dup = NULL; // need to duplicate host-name for some cases +#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES if (q->host && strstr(q->host, "in-addr")) { - host_dup = strdup(q->host); - char *rest = NULL; - for (char *p = strtok_r(host_dup, ".", &rest); p != NULL; p = strtok_r(NULL, ".", &rest)) { - str[str_index++] = p; + part_length = append_fqdn_dots(packet, index, q->host, false); + if (!part_length) { + return 0; } - if (q->domain) { - str[str_index++] = q->domain; - } - - } else { + } else +#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */ + { + const char *str[4]; + uint8_t str_index = 0; if (q->host) { str[str_index++] = q->host; } @@ -1131,19 +1184,14 @@ static uint16_t _mdns_append_question(uint8_t *packet, uint16_t *index, mdns_out if (q->domain) { str[str_index++] = q->domain; } - - } - - - part_length = _mdns_append_fqdn(packet, index, str, str_index, MDNS_MAX_PACKET_SIZE); - if (!part_length) { - free(host_dup); - return 0; + part_length = _mdns_append_fqdn(packet, index, str, str_index, MDNS_MAX_PACKET_SIZE); + if (!part_length) { + return 0; + } } part_length += _mdns_append_u16(packet, index, q->type); part_length += _mdns_append_u16(packet, index, q->unicast ? 0x8001 : 0x0001); - free(host_dup); return part_length; } @@ -1221,62 +1269,36 @@ static uint8_t _mdns_append_host_answer(uint8_t *packet, uint16_t *index, mdns_h return num_records; } -static uint16_t _mdns_append_rev_ptr_record(uint8_t *packet, uint16_t *index, const char *name, bool flush, bool bye) +#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES +/** + * @brief Appends reverse lookup PTR record + */ +static uint8_t _mdns_append_reverse_ptr_record(uint8_t *packet, uint16_t *index, const char *name) { - const char *str[6]; - int i = 0; - if (strstr(name, "in-addr") == NULL) { return 0; } - char *host = strdup(name); - char *rest = NULL; - for (char *p = strtok_r(host, ".", &rest); p != NULL; p = strtok_r(NULL, ".", &rest)) { - str[i++] = p; - } - str[i++] = "arpa"; - uint16_t record_length = 0; - uint8_t part_length; - part_length = _mdns_append_fqdn(packet, index, str, i, MDNS_MAX_PACKET_SIZE); - if (!part_length) { + if (!append_fqdn_dots(packet, index, name, false)) { return 0; } - record_length += part_length; - part_length = _mdns_append_type(packet, index, MDNS_ANSWER_PTR, false, bye ? 0 : MDNS_ANSWER_PTR_TTL); - if (!part_length) { + if (!_mdns_append_type(packet, index, MDNS_ANSWER_PTR, false, 10 /* TTL set to 10s*/ )) { return 0; } - record_length += part_length; - uint16_t data_len_location = *index - 2; - str[0] = _mdns_self_host.hostname; - str[1] = MDNS_DEFAULT_DOMAIN; + uint16_t data_len_location = *index - 2; /* store the position of size (2=16bis) of this record */ + const char *str[2] = { _mdns_self_host.hostname, MDNS_DEFAULT_DOMAIN }; - part_length = _mdns_append_fqdn(packet, index, str, 2, MDNS_MAX_PACKET_SIZE); + int part_length = _mdns_append_fqdn(packet, index, str, 2, MDNS_MAX_PACKET_SIZE); if (!part_length) { return 0; } _mdns_set_u16(packet, data_len_location, part_length); - record_length += part_length; - - return record_length; -} - - -static uint8_t _mdns_append_reverse_ptr_record(uint8_t *packet, uint16_t *index, const char *name, bool flush, bool bye) -{ - uint8_t appended_answers = 0; - - if (_mdns_append_rev_ptr_record(packet, index, name, flush, bye) <= 0) { - return appended_answers; - } - appended_answers++; - - return appended_answers; + return 1; /* appending only 1 record */ } +#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */ /** * @brief Append PTR answers to packet @@ -1316,8 +1338,10 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an if (answer->type == MDNS_TYPE_PTR) { if (answer->service) { return _mdns_append_service_ptr_answers(packet, index, answer->service, answer->flush, answer->bye); +#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES } else if (answer->host && answer->host->hostname && strstr(answer->host->hostname, "in-addr")) { - return _mdns_append_reverse_ptr_record(packet, index, answer->host->hostname, answer->flush, answer->bye) > 0; + return _mdns_append_reverse_ptr_record(packet, index, answer->host->hostname) > 0; +#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */ } else { return _mdns_append_ptr_record(packet, index, answer->custom_instance, answer->custom_service, answer->custom_proto, @@ -1719,15 +1743,6 @@ static bool _mdns_create_answer_from_service(mdns_tx_packet_t *packet, mdns_serv return true; } -static bool _mdns_create_answer_from_reverse_query(mdns_tx_packet_t *packet, const char *hostname, bool send_flush) -{ - mdns_host_item_t *host = mdns_get_host_item(hostname); - if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, NULL, host, send_flush, false)) { - return false; - } - return true; -} - static bool _mdns_create_answer_from_hostname(mdns_tx_packet_t *packet, const char *hostname, bool send_flush) { mdns_host_item_t *host = mdns_get_host_item(hostname); @@ -1812,18 +1827,24 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_ _mdns_free_tx_packet(packet); return; } +#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES } else if (q->type == MDNS_TYPE_PTR) { - if (!_mdns_create_answer_from_reverse_query(packet, q->host, send_flush)) { - _mdns_free_tx_packet(packet); + mdns_host_item_t *host = mdns_get_host_item(q->host); + if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, NULL, host, send_flush, false)) { return; } +#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */ } else if (!_mdns_alloc_answer(&packet->answers, q->type, NULL, NULL, send_flush, false)) { _mdns_free_tx_packet(packet); return; } if (parsed_packet->src_port != MDNS_SERVICE_PORT && // Repeat the queries only for "One-Shot mDNS queries" - (q->type == MDNS_TYPE_ANY || q->type == MDNS_TYPE_A || q->type == MDNS_TYPE_AAAA || q->type == MDNS_TYPE_PTR)) { + (q->type == MDNS_TYPE_ANY || q->type == MDNS_TYPE_A || q->type == MDNS_TYPE_AAAA +#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES + || q->type == MDNS_TYPE_PTR +#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */ + )) { mdns_out_question_t *out_question = malloc(sizeof(mdns_out_question_t)); if (out_question == NULL) { HOOK_MALLOC_FAILED; @@ -3042,7 +3063,11 @@ static bool _mdns_name_is_discovery(mdns_name_t *name, uint16_t type) static bool _mdns_name_is_ours(mdns_name_t *name) { //domain have to be "local" - if (_str_null_or_empty(name->domain) || ( strcasecmp(name->domain, MDNS_DEFAULT_DOMAIN) && strcasecmp(name->domain, "arpa")) ) { + if (_str_null_or_empty(name->domain) || ( strcasecmp(name->domain, MDNS_DEFAULT_DOMAIN) +#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES + && strcasecmp(name->domain, "arpa") +#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */ + ) ) { return false; } @@ -3967,6 +3992,22 @@ static void perform_event_action(mdns_if_t mdns_if, mdns_event_actions_t action) if (action & MDNS_EVENT_ANNOUNCE_IP6) { _mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V6, NULL, 0, true); } + +#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES + if (action & MDNS_EVENT_IP4_REVERSE_LOOKUP) { + esp_netif_ip_info_t if_ip_info; + if (esp_netif_get_ip_info(_mdns_get_esp_netif(mdns_if), &if_ip_info) == ESP_OK) { + esp_ip4_addr_t *ip = &if_ip_info.ip; + char *reverse_query_name = NULL; + if (asprintf(&reverse_query_name, "%d.%d.%d.%d.in-addr", + esp_ip4_addr4_16(ip), esp_ip4_addr3_16(ip), + esp_ip4_addr2_16(ip), esp_ip4_addr1_16(ip)) > 0 && reverse_query_name) { + ESP_LOGD(TAG, "Registered reverse query: %s.arpa", reverse_query_name); + _mdns_delegate_hostname_add(reverse_query_name, NULL); + } + } + } +#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */ } /** diff --git a/components/mdns/tests/host_test/components/esp_event/CMakeLists.txt b/components/mdns/tests/host_test/components/esp_event/CMakeLists.txt index f7bfde341..2fd6198bd 100644 --- a/components/mdns/tests/host_test/components/esp_event/CMakeLists.txt +++ b/components/mdns/tests/host_test/components/esp_event/CMakeLists.txt @@ -1,3 +1,2 @@ idf_component_register(SRCS esp_event_mock.c - INCLUDE_DIRS include - REQUIRES) + INCLUDE_DIRS include) diff --git a/components/mdns/tests/host_test/components/esp_event/include/esp_event.h b/components/mdns/tests/host_test/components/esp_event/include/esp_event.h index bc408c7fb..0b8b69ee8 100644 --- a/components/mdns/tests/host_test/components/esp_event/include/esp_event.h +++ b/components/mdns/tests/host_test/components/esp_event/include/esp_event.h @@ -8,12 +8,7 @@ #include "stdbool.h" #include "esp_err.h" #include "esp_event_base.h" -//#include "bsd_strings.h" - - - -//const char *WIFI_EVENT; -//const char *IP_EVENT; +#include "bsd/string.h" esp_err_t esp_event_handler_register(const char *event_base, int32_t event_id, void *event_handler, void *event_handler_arg); diff --git a/components/mdns/tests/host_test/components/freertos/CMakeLists.txt b/components/mdns/tests/host_test/components/freertos/CMakeLists.txt index 925b08732..9180dbce1 100644 --- a/components/mdns/tests/host_test/components/freertos/CMakeLists.txt +++ b/components/mdns/tests/host_test/components/freertos/CMakeLists.txt @@ -1,6 +1,5 @@ idf_component_register(SRCS freertos_linux.c queue_unique_ptr.cpp - INCLUDE_DIRS include - REQUIRES) + INCLUDE_DIRS include) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) diff --git a/components/mdns/tests/host_test/components/freertos/freertos_linux.c b/components/mdns/tests/host_test/components/freertos/freertos_linux.c index d69dea54f..fcba4416e 100644 --- a/components/mdns/tests/host_test/components/freertos/freertos_linux.c +++ b/components/mdns/tests/host_test/components/freertos/freertos_linux.c @@ -158,16 +158,6 @@ void xTaskCreate(TaskFunction_t pvTaskCode, const char *const pcName, const uint } } -//uint32_t esp_get_free_heap_size(void) -//{ -// return 0; -//} -// -//uint32_t esp_random(void) -//{ -// return rand(); -//} - void xTaskNotifyGive(TaskHandle_t task) { diff --git a/components/mdns/tests/host_test/main/main.c b/components/mdns/tests/host_test/main/main.c index 47de777f9..5b3930743 100644 --- a/components/mdns/tests/host_test/main/main.c +++ b/components/mdns/tests/host_test/main/main.c @@ -39,31 +39,26 @@ int main(int argc, char *argv[]) esp_netif_config_t cfg = { .base = &base_cg }; esp_netif_t *sta = esp_netif_new(&cfg); ESP_ERROR_CHECK(mdns_init()); - ESP_ERROR_CHECK(mdns_register_netif(sta)); - ESP_ERROR_CHECK(mdns_netif_action(sta, MDNS_EVENT_ENABLE_IP4)); - - mdns_hostname_set(CONFIG_TEST_HOSTNAME); + ESP_ERROR_CHECK(mdns_hostname_set(CONFIG_TEST_HOSTNAME)); ESP_LOGI(TAG, "mdns hostname set to: [%s]", CONFIG_TEST_HOSTNAME); - mdns_ip_addr_t addr4 = { .addr.u_addr.ip4.addr = 0x1020304 }; - addr4.addr.type = ESP_IPADDR_TYPE_V4; - const char *delegated_hostname = "200.0.168.192.in-addr"; - addr4.addr.type = ESP_IPADDR_TYPE_V4; - ESP_ERROR_CHECK( mdns_delegate_hostname_add(delegated_hostname, &addr4) ); + ESP_ERROR_CHECK(mdns_register_netif(sta)); + ESP_ERROR_CHECK(mdns_netif_action(sta, MDNS_EVENT_ENABLE_IP4 | MDNS_EVENT_IP4_REVERSE_LOOKUP)); +#ifdef REGISTER_SERVICE //set default mDNS instance name - //mdns_instance_name_set("myesp-inst"); + mdns_instance_name_set("myesp-inst"); //structure with TXT records -// mdns_txt_item_t serviceTxtData[3] = { -// {"board", "esp32"}, -// {"u", "user"}, -// {"p", "password"} -// }; -// vTaskDelay(pdMS_TO_TICKS(1000)); + mdns_txt_item_t serviceTxtData[3] = { + {"board", "esp32"}, + {"u", "user"}, + {"p", "password"} + }; + vTaskDelay(pdMS_TO_TICKS(10000)); + ESP_ERROR_CHECK(mdns_service_add("myesp-service2", "_http", "_tcp", 80, serviceTxtData, 3)); +#endif vTaskDelay(pdMS_TO_TICKS(10000)); - // ESP_ERROR_CHECK(mdns_service_add("myesp-service2", "_http", "_tcp", 80, serviceTxtData, 3)); - // vTaskDelay(2000); query_mdns_host("david-work"); - vTaskDelay(2000); + vTaskDelay(pdMS_TO_TICKS(1000)); esp_netif_destroy(sta); mdns_free(); ESP_LOGI(TAG, "Exit"); diff --git a/components/mdns/tests/host_test/make_eth2_netif b/components/mdns/tests/host_test/make_eth2_netif deleted file mode 100755 index 2436125b7..000000000 --- a/components/mdns/tests/host_test/make_eth2_netif +++ /dev/null @@ -1,5 +0,0 @@ -sudo ip link add eth2 type dummy -sudo ip addr add 192.168.1.200/24 dev eth2 -sudo ip addr add 192.168.1.201/24 dev eth2 -sudo ip link set eth2 up -sudo ifconfig eth2 multicast diff --git a/components/mdns/tests/host_test/sdkconfig.defaults b/components/mdns/tests/host_test/sdkconfig.defaults index 7c7663f3f..621659fac 100644 --- a/components/mdns/tests/host_test/sdkconfig.defaults +++ b/components/mdns/tests/host_test/sdkconfig.defaults @@ -3,5 +3,7 @@ CONFIG_MDNS_NETWORKING_SOCKET=y CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES=y CONFIG_TEST_NETIF_NAME="eth0" CONFIG_TEST_HOSTNAME="myesp" -# CONFIG_MDNS_PREDEF_NETIF_STA is not set -# CONFIG_MDNS_PREDEF_NETIF_AP is not set +CONFIG_MDNS_PREDEF_NETIF_STA=n +CONFIG_MDNS_PREDEF_NETIF_AP=n +CONFIG_MDNS_ENABLE_DEBUG_PRINTS=y +CONFIG_MDNS_RESPOND_REVERSE_QUERIES=y