mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-05-19 06:36:51 +08:00
mDNS: add support for output delaying
See below commit messages for more information mDNS: support for direct and delayed sends There are two ways to send a response, directly and after a delay. A probe or an announce msg are now send via the direct way and all responses are send via the delayed way. mDNS improved delay vs direct send behavior on questions All multicast answers are delayed at the moment. While all unicast answers are send out directly. A unicast answer is send when this is requested by the QU bit, when a unicast question was send or when the question originated from a legacy querier. mDNS: add probe query detection. If a probe query is detected a direct unicast respond is send. Independent of the QU/QM bit. mDNS split delayed multicast msgs into ipv4 and ipv6 buffers. We are implementing a two resolvers in one (IPv6 and IPv4 together). For directly send answers, this does not matter. But for delayed answers, we need to make a separate buffer for both. mDNS: addr bug, we should not clear full outmsg memset deleted also the dest_addr and dest_port, which should remain and is constant. This commit contains a function that resets only the needed parts of the outmsg struct. mDNS: do not multicast a rr within one second. RFC6762 section 6: prevent network flooding. When a multicast packet is send out, we start a timeout of 1s within this 1 second all multicast requests are ignored. We do not make a difference between the records, we set the delay for all records. mDNS: improved split for unicast vs multicast and direct vs delayed unicast delayed message are now possible and multicast direct msgs to. MDNS: changed printfs to lwip debug messages MDNS: change timeouts from max time to random time mDNS: send multicast response on QU questions if not multicasted recently. If a QU question is received, the responder should multicast the answer if it did not multicast that record within 25% of it's ttl. we implemented a stripped down version, meaning that we look at the records as one set and use one timer for all records. So if the responder multicasted a record within 30s of the QU question it will respond with a unicast answer. if not, it will respond multicast. mDNS: timeouts -> create function for mdns timeout handling mdns_set_timeout will check if the timer is running or not and will update the flag to running after starting the timer. Multicast timeouts were not set everywhere they needed to be. This is solved. mulit <-> multi typo fixed. mDNS: solve commenting and style issues mDNS: add #if LWIP_IPVx to new code LWIP_IPV4/6 can be enabled or disabled, all combination should work.
This commit is contained in:
committed by
Dirk Ziegelmeier
parent
4ea5110662
commit
4289293061
@@ -54,8 +54,12 @@ err_t mdns_domain_add_label(struct mdns_domain *domain, const char *label, u8_t
|
||||
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);
|
||||
#if LWIP_IPV4
|
||||
err_t mdns_build_reverse_v4_domain(struct mdns_domain *domain, const ip4_addr_t *addr);
|
||||
#endif
|
||||
#if LWIP_IPV6
|
||||
err_t mdns_build_reverse_v6_domain(struct mdns_domain *domain, const ip6_addr_t *addr);
|
||||
#endif
|
||||
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);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "lwip/apps/mdns_opts.h"
|
||||
#include "lwip/apps/mdns_priv.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/timeouts.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -73,7 +74,42 @@ extern "C" {
|
||||
/* Lookup for text info on service instance */
|
||||
#define REPLY_SERVICE_TXT 0x80
|
||||
|
||||
/* RFC6762 section 6:
|
||||
* To protect the network against excessive packet flooding due to software bugs
|
||||
* or malicious attack, a Multicast DNS responder MUST NOT (except in the one
|
||||
* special case of answering probe queries) multicast a record on a given
|
||||
* interface until at least one second has elapsed since the last time that
|
||||
* record was multicast on that particular interface.
|
||||
*/
|
||||
#define MDNS_MULTICAST_TIMEOUT 1000
|
||||
|
||||
/* RFC6762 section 5.4:
|
||||
* When receiving a question with the unicast-response bit set, a responder
|
||||
* SHOULD usually respond with a unicast packet directed back to the querier.
|
||||
* However, if the responder has not multicast that record recently (within one
|
||||
* quarter of its TTL), then the responder SHOULD instead multicast the response
|
||||
* so as to keep all the peer caches up to date, and to permit passive conflict
|
||||
* detection.
|
||||
* -> we implement a stripped down version. Depending on a timeout of 30s
|
||||
* (25% of 120s) all QU questions are send via multicast or unicast.
|
||||
*/
|
||||
#define MDNS_MULTICAST_TIMEOUT_25TTL 30000
|
||||
|
||||
err_t mdns_send_outpacket(struct mdns_outmsg *msg, struct netif *netif);
|
||||
void mdns_set_timeout(struct netif *netif, u32_t msecs,
|
||||
sys_timeout_handler handler, u8_t *busy_flag);
|
||||
#if LWIP_IPV4
|
||||
void mdns_multicast_timeout_reset_ipv4(void *arg);
|
||||
void mdns_multicast_timeout_25ttl_reset_ipv4(void *arg);
|
||||
void mdns_send_multicast_msg_delayed_ipv4(void *arg);
|
||||
void mdns_send_unicast_msg_delayed_ipv4(void *arg);
|
||||
#endif
|
||||
#if LWIP_IPV6
|
||||
void mdns_multicast_timeout_reset_ipv6(void *arg);
|
||||
void mdns_multicast_timeout_25ttl_reset_ipv6(void *arg);
|
||||
void mdns_send_multicast_msg_delayed_ipv6(void *arg);
|
||||
void mdns_send_unicast_msg_delayed_ipv6(void *arg);
|
||||
#endif
|
||||
void mdns_prepare_txtdata(struct mdns_service *service);
|
||||
|
||||
#endif /* LWIP_MDNS_RESPONDER */
|
||||
|
||||
@@ -92,18 +92,6 @@ struct mdns_service {
|
||||
u16_t port;
|
||||
};
|
||||
|
||||
/** Description of a host/netif */
|
||||
struct mdns_host {
|
||||
/** Hostname */
|
||||
char name[MDNS_LABEL_MAXLEN + 1];
|
||||
/** Pointer to services */
|
||||
struct mdns_service *services[MDNS_MAX_SERVICES];
|
||||
/** Number of probes sent for the current name */
|
||||
u8_t probes_sent;
|
||||
/** State in probing sequence */
|
||||
u8_t probing_state;
|
||||
};
|
||||
|
||||
/** mDNS output packet */
|
||||
struct mdns_outpacket {
|
||||
/** Packet data */
|
||||
@@ -134,11 +122,14 @@ struct mdns_outmsg {
|
||||
u16_t dest_port;
|
||||
/** If all answers in packet should set cache_flush bit */
|
||||
u8_t cache_flush;
|
||||
/** If reply should be sent unicast */
|
||||
u8_t unicast_reply;
|
||||
/** If reply should be sent unicast (as requested) */
|
||||
u8_t unicast_reply_requested;
|
||||
/** If legacy query. (tx_id needed, and write
|
||||
* question again in reply before answer) */
|
||||
u8_t legacy_query;
|
||||
/** If the query is a probe msg we need to respond immediatly. Independent of
|
||||
* the QU or QM flag. */
|
||||
u8_t probe_query_recv;
|
||||
/* Question bitmask for host information */
|
||||
u8_t host_questions;
|
||||
/* Questions bitmask per service */
|
||||
@@ -151,6 +142,43 @@ struct mdns_outmsg {
|
||||
u8_t serv_replies[MDNS_MAX_SERVICES];
|
||||
};
|
||||
|
||||
/** Delayed msg info */
|
||||
struct mdns_delayed_msg {
|
||||
/** Timer state multicast */
|
||||
u8_t multicast_msg_waiting;
|
||||
/** Multicast timeout on */
|
||||
u8_t multicast_timeout;
|
||||
/** Output msg used for delayed multicast responses */
|
||||
struct mdns_outmsg delayed_msg_multicast;
|
||||
/** Prefer multicast over unicast timeout -> 25% of TTL = we take 30s as
|
||||
general delay. */
|
||||
u8_t multicast_timeout_25TTL;
|
||||
/** Only send out new unicast message if previous was send */
|
||||
u8_t unicast_msg_in_use;
|
||||
/** Output msg used for delayed unicast responses */
|
||||
struct mdns_outmsg delayed_msg_unicast;
|
||||
};
|
||||
|
||||
/** Description of a host/netif */
|
||||
struct mdns_host {
|
||||
/** Hostname */
|
||||
char name[MDNS_LABEL_MAXLEN + 1];
|
||||
/** Pointer to services */
|
||||
struct mdns_service *services[MDNS_MAX_SERVICES];
|
||||
/** Number of probes sent for the current name */
|
||||
u8_t probes_sent;
|
||||
/** State in probing sequence */
|
||||
u8_t probing_state;
|
||||
#if LWIP_IPV4
|
||||
/** delayed msg struct for IPv4 */
|
||||
struct mdns_delayed_msg ipv4;
|
||||
#endif
|
||||
#if LWIP_IPV6
|
||||
/** delayed msg struct for IPv6 */
|
||||
struct mdns_delayed_msg ipv6;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* LWIP_MDNS_RESPONDER */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user