Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/mdns/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ endif()
set(MDNS_MEMORY "mdns_mem_caps.c")

set(MDNS_CORE "mdns_responder.c" "mdns_receive.c" "mdns_utils.c" "mdns_debug.c" "mdns_browser.c" "mdns_send.c" "mdns_netif.c"
"mdns_querier.c" "mdns_pcb.c" "mdns_service.c")
"mdns_querier.c" "mdns_pcb.c" "mdns_service.c" "mdns_cache.c")

idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "linux")
Expand Down
78 changes: 51 additions & 27 deletions components/mdns/include/mdns.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,35 +134,30 @@ typedef struct mdns_result_s {
size_t txt_count; /*!< number of txt items */
// A and AAAA
mdns_ip_addr_t *addr; /*!< linked list of IP addresses found */
// Browse only
char *subtype; /*!< browse subtype, or NULL for normal browse */
} mdns_result_t;

typedef void (*mdns_query_notify_t)(mdns_search_once_t *search);

/**
* @brief Browse result change notifier
*
* Called once per browse result that changed in a given response packet (not
* once per packet). The @p result argument points at the changed entry, but it
* remains a live node in the internal browse cache until the callback returns.
* Called once for every matching browse result changed by a received response,
* or once for every currently cached result when a new browse is registered.
*
* @warning @p result->next links other cached instances for this browse, not
* necessarily other results that changed in the same packet. For
* ordinary add/update notifications, use only @p result; do not walk
* @c next, because unchanged instances may appear there.
* The @p result is a temporary projection of the internal mDNS cache, which is only valid
* during the lifetime of this callback and is freed immediately after the callback returns.
*
* @warning Batch PTR TTL=0 ("goodbye") responses (for example when a peer
* exits and Bonjour sends many removals in one packet) may invoke the
* notifier once while several instances in the cache are updated.
* Until this is improved, applications may walk @c next and treat
* entries with @c ttl == 0 as removals. Do not assume every node on
* @c next changed in the current packet.
* @warning @p result->next is always NULL. Other instances cannot be obtained from @p result.
*
* @warning If handling is deferred outside this callback, copy @p result first
* (including strings and addresses). Goodbye entries may be freed when
* the callback returns.
* @warning If handling is deferred outside this callback, applications must make a deep copy
* of @p result with all components, including strings, TXT entries, address list, and subtype.
*
* @param result The browse result that changed. See the warnings above for
* use of @c result->next.
* @warning `mdns_browse_new*` APIs will acquire mDNS service lock, and `mdns_browse_notify_t` runs
* in the mDNS service task. Users must not call `mdns_service_new*` APIs from `mdns_browse_notify_t`.
*
* @param result Temporary result of the browse that changed.
*/
typedef void (*mdns_browse_notify_t)(mdns_result_t *result);

Expand Down Expand Up @@ -1053,19 +1048,35 @@ esp_err_t mdns_netif_action(esp_netif_t *esp_netif, mdns_event_actions_t event_a
* @return mdns_browse_t pointer to new browse object if initiated successfully.
* NULL otherwise.
*
* @note When several service instances share the same SRV target hostname, A/AAAA
* addresses from a response are attached only to the first matching browse
* result for that hostname (per interface and IP protocol). Other instances
* with the same target host are not populated automatically; applications
* that need host-level addresses for every instance must resolve or cache
* them separately until this behavior is improved.
* @note If matching services already present in the internal mDNS cache,
* the notifier will be called once for each cached service after this browse
* is registered.
*
* @note If one response packet contains answers for multiple active browses,
* only one browse is synchronized for that packet. This should not affect
* typical browse traffic, where packets answer one service type.
* @note The notifier receives a temporary result that is valid only during the callback.
* See @ref mdns_browse_notify_t for ownership and lifetime details.
*/
mdns_browse_t *mdns_browse_new(const char *service, const char *proto, mdns_browse_notify_t notifier);

/**
* @brief Browse mDNS for a service subtype `_subtype._sub._service._proto`
* (Selective Instance Enumeration per RFC 6763 Section 7.1).
*
* @param service Pointer to the `_service` which will be browsed.
* @param proto Pointer to the `_proto` which will be browsed.
* @param subtype Pointer to the `_subtype` to restrict browsing to. Can be NULL for standard browse.
* @param notifier The callback which will be called when the browsing service changed.
* @return mdns_browse_t pointer to new browse object if initiated successfully.
* NULL otherwise.
*
* @note If matching services already present in the internal mDNS cache,
* the notifier will be called once for each cached service after this browse
* is registered.
*
* @note The notifier receives a temporary result that is valid only during the callback.
* See @ref mdns_browse_notify_t for ownership and lifetime details.
*/
mdns_browse_t *mdns_browse_new_with_subtype(const char *service, const char *proto, const char *subtype, mdns_browse_notify_t notifier);

/**
* @brief Stop the `_service._proto` browse.
* @param service Pointer to the `_service` which will be browsed.
Expand All @@ -1077,6 +1088,19 @@ mdns_browse_t *mdns_browse_new(const char *service, const char *proto, mdns_brow
*/
esp_err_t mdns_browse_delete(const char *service, const char *proto);


/**
* @brief Stop the `_subtype._sub._service._proto` browse.
* @param service Pointer to the `_service` which will be browsed.
* @param proto Pointer to the `_proto` which will be browsed.
* @param subtype Pointer to the `_subtype`. Can be NULL to match a browse without subtype.
* @return
* - ESP_OK success.
* - ESP_ERR_FAIL mDNS is not running or the browsing was never started.
* - ESP_ERR_NO_MEM memory error.
*/
esp_err_t mdns_browse_delete_with_subtype(const char *service, const char *proto, const char *subtype);

#ifdef __cplusplus
}
#endif
Expand Down
Loading
Loading