From f0df12dad3223c601368dd67562079ed5027edef Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Thu, 18 May 2023 12:22:21 +0800 Subject: [PATCH] feat(mdns): Add APIs for looking up self hosted services and getting the self hostname --- .../mdns/examples/main/mdns_example_main.c | 18 +++++++ components/mdns/include/mdns.h | 31 +++++++++++ components/mdns/mdns.c | 51 ++++++++++++++++--- 3 files changed, 93 insertions(+), 7 deletions(-) diff --git a/components/mdns/examples/main/mdns_example_main.c b/components/mdns/examples/main/mdns_example_main.c index adb09be14..e08c08fc9 100644 --- a/components/mdns/examples/main/mdns_example_main.c +++ b/components/mdns/examples/main/mdns_example_main.c @@ -163,6 +163,23 @@ static void lookup_mdns_delegated_service(const char *service_name, const char * } #endif // CONFIG_MDNS_PUBLISH_DELEGATE_HOST +static void lookup_mdns_selfhosted_service(const char *service_name, const char *proto) +{ + ESP_LOGI(TAG, "Lookup selfhosted service: %s.%s.local", service_name, proto); + mdns_result_t *results = NULL; + esp_err_t err = mdns_lookup_selfhosted_service(NULL, service_name, proto, 20, &results); + if (err) { + ESP_LOGE(TAG, "Lookup Failed: %s", esp_err_to_name(err)); + return; + } + if (!results) { + ESP_LOGW(TAG, "No results found!"); + return; + } + mdns_print_results(results); + mdns_query_results_free(results); +} + static bool check_and_print_result(mdns_search_once_t *search) { // Check if any result is available @@ -260,6 +277,7 @@ static void check_button(void) #if CONFIG_MDNS_PUBLISH_DELEGATE_HOST lookup_mdns_delegated_service("_http", "_tcp"); #endif // CONFIG_MDNS_PUBLISH_DELEGATE_HOST + lookup_mdns_selfhosted_service("_http", "_tcp"); } old_level = new_level; } diff --git a/components/mdns/include/mdns.h b/components/mdns/include/mdns.h index 590773ef0..26761c887 100644 --- a/components/mdns/include/mdns.h +++ b/components/mdns/include/mdns.h @@ -128,6 +128,19 @@ void mdns_free(void); */ esp_err_t mdns_hostname_set(const char *hostname); +/** + * @brief Get the hostname for mDNS server + * + * @param hostname pointer to the hostname, it should be allocated + * and hold at least MDNS_NAME_BUF_LEN chars + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_ERR_INVALID_STATE when mdns is not initialized + */ +esp_err_t mdns_hostname_get(char *hostname); + /** * @brief Adds a hostname and address to be delegated * A/AAAA queries will be replied for the hostname and @@ -703,6 +716,24 @@ esp_err_t mdns_query_txt(const char *instance_name, const char *service_type, co esp_err_t mdns_lookup_delegated_service(const char *instance, const char *service_type, const char *proto, size_t max_results, mdns_result_t **result); +/** + * @brief Look up self hosted services. + * + * @param instance instance name (NULL for uncertain instance) + * @param service_type service type (_http, _ftp, etc) + * @param proto service protocol (_tcp, _udp) + * @param max_results maximum results to be collected + * @param result pointer to the result of the search + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_STATE mDNS is not running + * - ESP_ERR_NO_MEM memory error + * - ESP_ERR_INVALID_ARG parameter error + */ +esp_err_t mdns_lookup_selfhosted_service(const char *instance, const char *service_type, const char *proto, size_t max_results, + mdns_result_t **result); + /** * @brief Query mDNS for A record * diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 700d4813d..4103b91fd 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -5561,6 +5561,17 @@ esp_err_t mdns_hostname_set(const char *hostname) return ESP_OK; } +esp_err_t mdns_hostname_get(char *hostname) +{ + if (!_mdns_server || !hostname) { + return ESP_ERR_INVALID_ARG; + } + MDNS_SERVICE_LOCK(); + strncpy(hostname, _mdns_server->hostname, strnlen(_mdns_server->hostname, MDNS_NAME_BUF_LEN)); + MDNS_SERVICE_UNLOCK(); + return ESP_OK; +} + esp_err_t mdns_delegate_hostname_add(const char *hostname, const mdns_ip_addr_t *address_list) { if (!_mdns_server) { @@ -5798,7 +5809,7 @@ static mdns_ip_addr_t *_copy_delegated_host_address_list(char *hostname) return NULL; } -static mdns_result_t *_mdns_lookup_delegated_service(const char *instance, const char *service, const char *proto, size_t max_results) +static mdns_result_t *_mdns_lookup_service(const char *instance, const char *service, const char *proto, size_t max_results, bool selfhost) { if (_str_null_or_empty(service) || _str_null_or_empty(proto)) { return NULL; @@ -5808,7 +5819,13 @@ static mdns_result_t *_mdns_lookup_delegated_service(const char *instance, const mdns_srv_item_t *s = _mdns_server->services; while (s) { mdns_service_t *srv = s->service; - if (srv && srv->hostname && (_str_null_or_empty(_mdns_server->hostname) || strcmp(_mdns_server->hostname, srv->hostname) != 0)) { + if (!srv || !srv->hostname) { + s = s->next; + continue; + } + bool is_service_selfhosted = !_str_null_or_empty(_mdns_server->hostname) && !strcasecmp(_mdns_server->hostname, srv->hostname); + bool is_service_delegated = _str_null_or_empty(_mdns_server->hostname) || strcasecmp(_mdns_server->hostname, srv->hostname); + if ((selfhost && is_service_selfhosted) || (!selfhost && is_service_delegated)) { if (!strcasecmp(srv->service, service) && !strcasecmp(srv->proto, proto) && (_str_null_or_empty(instance) || _mdns_instance_name_match(srv->instance, instance))) { mdns_result_t *item = (mdns_result_t *)malloc(sizeof(mdns_result_t)); @@ -5819,7 +5836,7 @@ static mdns_result_t *_mdns_lookup_delegated_service(const char *instance, const item->next = results; results = item; item->esp_netif = NULL; - item->ttl = UINT32_MAX; + item->ttl = _str_null_or_empty(instance) ? MDNS_ANSWER_PTR_TTL : MDNS_ANSWER_SRV_TTL; item->ip_protocol = MDNS_IP_PROTOCOL_MAX; item->instance_name = strndup(srv->instance, MDNS_NAME_BUF_LEN - 1); if (!item->instance_name) { @@ -5843,9 +5860,14 @@ static mdns_result_t *_mdns_lookup_delegated_service(const char *instance, const } item->port = srv->port; item->txt = _copy_mdns_txt_items(srv->txt, &(item->txt_value_len), &(item->txt_count)); - item->addr = _copy_delegated_host_address_list(item->hostname); - if (!item->addr) { - goto handle_error; + // We should not append addresses for selfhost lookup result as we don't know which interface's address to append. + if (selfhost) { + item->addr = NULL; + } else { + item->addr = _copy_delegated_host_address_list(item->hostname); + if (!item->addr) { + goto handle_error; + } } if (num_results < max_results) { num_results++; @@ -6344,7 +6366,22 @@ esp_err_t mdns_lookup_delegated_service(const char *instance, const char *servic return ESP_ERR_INVALID_ARG; } MDNS_SERVICE_LOCK(); - *result = _mdns_lookup_delegated_service(instance, service, proto, max_results); + *result = _mdns_lookup_service(instance, service, proto, max_results, false); + MDNS_SERVICE_UNLOCK(); + return ESP_OK; +} + +esp_err_t mdns_lookup_selfhosted_service(const char *instance, const char *service, const char *proto, size_t max_results, + mdns_result_t **result) +{ + if (!_mdns_server) { + return ESP_ERR_INVALID_STATE; + } + if (!result || _str_null_or_empty(service) || _str_null_or_empty(proto)) { + return ESP_ERR_INVALID_ARG; + } + MDNS_SERVICE_LOCK(); + *result = _mdns_lookup_service(instance, service, proto, max_results, true); MDNS_SERVICE_UNLOCK(); return ESP_OK; }