mdns: added support for searching services

Two new API:
err_t mdns_search_service(const char *name, const char *service, enum mdns_sd_proto proto,
                          struct netif *netif, search_result_fn_t result_fn, void *arg,
                          s8_t *request_id);
void mdns_search_stop(s8_t request_id);

One compilation flags:
LWIP_MDNS_SEARCH

One options flags:
MDNS_MAX_REQUESTS

Some structure declarations moved to allow use by callback result function.

Result domain names are early uncompress before calling application callback
because it cannot be made by application itself.

Allow search services with multiples labels included, like '_services._dns-sd'.

Search for `_services._dns-sd._udp.local.` is handled in a special way.
Only `PTR` answers are send back to the application.

The `mdns_search_service()` function won't assert if no more space in `mdns_request`
table, just return an error if too many simultanous requests.
This commit is contained in:
David Girault
2017-04-21 12:05:47 +02:00
committed by Simon Goldschmidt
parent 9263d44847
commit b4be0d8808
8 changed files with 438 additions and 31 deletions

View File

@@ -57,10 +57,42 @@ enum mdns_sd_proto {
#define MDNS_PROBING_SUCCESSFUL 1
#define MDNS_LABEL_MAXLEN 63
#define MDNS_DOMAIN_MAXLEN 256
struct mdns_host;
struct mdns_service;
/* Domain structs - also visible for unit tests */
struct mdns_domain {
/* Encoded domain name */
u8_t name[MDNS_DOMAIN_MAXLEN];
/* Total length of domain name, including zero */
u16_t length;
/* Set if compression of this domain is not allowed */
u8_t skip_compression;
};
/** Domain, type and class.
* Shared between questions and answers */
struct mdns_rr_info {
struct mdns_domain domain;
u16_t type;
u16_t klass;
};
struct mdns_answer {
struct mdns_rr_info info;
/** cache flush command bit */
u16_t cache_flush;
/* Validity time in seconds */
u32_t ttl;
/** Length of variable answer */
u16_t rd_length;
/** Offset of start of variable answer in packet */
u16_t rd_offset;
};
/** Callback function to add text to a reply, called when generating the reply */
typedef void (*service_get_txt_fn_t)(struct mdns_service *service, void *txt_userdata);
@@ -97,6 +129,19 @@ void mdns_resp_announce(struct netif *netif);
*/
#define mdns_resp_netif_settings_changed(netif) mdns_resp_announce(netif)
#if LWIP_MDNS_SEARCH
typedef void (*search_result_fn_t)(struct mdns_answer *answer, const char *varpart, int varlen, int flags, void *arg);
/* flags bits, both can be set! */
#define MDNS_SEARCH_RESULT_FIRST 1 /* First answer in received frame. */
#define MDNS_SEARCH_RESULT_LAST 2 /* Last answer. */
err_t mdns_search_service(const char *name, const char *service, enum mdns_sd_proto proto,
struct netif *netif, search_result_fn_t result_fn, void *arg,
s8_t *request_id);
void mdns_search_stop(s8_t request_id);
#endif /* LWIP_MDNS_SEARCH */
#endif /* LWIP_MDNS_RESPONDER */
#ifdef __cplusplus

View File

@@ -51,6 +51,8 @@ extern "C" {
/* Domain methods - also visible for unit tests */
err_t mdns_domain_add_label(struct mdns_domain *domain, const char *label, u8_t len);
err_t mdns_domain_add_domain(struct mdns_domain *domain, struct mdns_domain *source);
err_t mdns_domain_add_string(struct mdns_domain *domain, const char *source);
u16_t mdns_readname(struct pbuf *p, u16_t offset, struct mdns_domain *domain);
void mdns_domain_debug_print(struct mdns_domain *domain);
int mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b);
@@ -63,6 +65,9 @@ err_t mdns_build_reverse_v6_domain(struct mdns_domain *domain, const ip6_addr_t
err_t mdns_build_host_domain(struct mdns_domain *domain, struct mdns_host *mdns);
err_t mdns_build_dnssd_domain(struct mdns_domain *domain);
err_t mdns_build_service_domain(struct mdns_domain *domain, struct mdns_service *service, int include_name);
#if LWIP_MDNS_SEARCH
err_t mdns_build_request_domain(struct mdns_domain *domain, struct mdns_request *request, int include_name);
#endif
u16_t mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain);
err_t mdns_write_domain(struct mdns_outpacket *outpkt, struct mdns_domain *domain);

View File

@@ -67,6 +67,18 @@
#define MDNS_RESP_USENETIF_EXTCALLBACK LWIP_NETIF_EXT_STATUS_CALLBACK
#endif
/**
* LWIP_MDNS_SEARCH==1: Turn on search over multicast DNS module.
*/
#ifndef LWIP_MDNS_SEARCH
#define LWIP_MDNS_SEARCH 1
#endif
/** The maximum number of running requests */
#ifndef MDNS_MAX_REQUESTS
#define MDNS_MAX_REQUESTS 2
#endif
/**
* MDNS_DEBUG: Enable debugging for multicast DNS.
*/

View File

@@ -125,6 +125,9 @@ void mdns_send_unicast_msg_delayed_ipv6(void *arg);
void mdns_start_multicast_timeouts_ipv6(struct netif *netif);
#endif
void mdns_prepare_txtdata(struct mdns_service *service);
#ifdef LWIP_MDNS_SEARCH
err_t mdns_send_request(struct mdns_request *req, struct netif *netif, const ip_addr_t *destination);
#endif
#endif /* LWIP_MDNS_RESPONDER */

View File

@@ -48,7 +48,6 @@ extern "C" {
#if LWIP_MDNS_RESPONDER
#define MDNS_DOMAIN_MAXLEN 256
#define MDNS_READNAME_ERROR 0xFFFF
#define NUM_DOMAIN_OFFSETS 10
@@ -72,16 +71,24 @@ extern "C" {
#define MDNS_PROBE_MAX_CONFLICTS_TIME_WINDOW 10000
#define MDNS_PROBE_MAX_CONFLICTS_TIMEOUT 5000
/* Domain structs - also visible for unit tests */
struct mdns_domain {
/* Encoded domain name */
u8_t name[MDNS_DOMAIN_MAXLEN];
/* Total length of domain name, including zero */
u16_t length;
/* Set if compression of this domain is not allowed */
u8_t skip_compression;
#if LWIP_MDNS_SEARCH
/** Description of a search request */
struct mdns_request {
/** Name of service, like 'myweb' */
char name[MDNS_LABEL_MAXLEN + 1];
/** Type of service, like '_http' or '_services._dns-sd' */
struct mdns_domain service;
/** Callback function called for each response */
search_result_fn_t result_fn;
void *arg;
/** Protocol, TCP or UDP */
u16_t proto;
/** Query type (PTR, SRV, ...) */
u8_t qtype;
/** PTR only request. */
u16_t only_ptr;
};
#endif
/** Description of a service */
struct mdns_service {
@@ -149,6 +156,10 @@ struct mdns_outmsg {
u8_t host_reverse_v6_replies;
/* Reply bitmask per service */
u8_t serv_replies[MDNS_MAX_SERVICES];
#ifdef LWIP_MDNS_SEARCH
/** Search query to send */
struct mdns_request *query;
#endif
};
/** Delayed msg info */