mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-02-05 15:39:54 +00:00
mDNS fix TTL bug
MDNS_TTL changed to MDNS_IP_TTL for clarity. The mDNS RR ttl does not need to be settalbe, this is against the RFC. RFC6762 states that for rr's with the hostname in them somewhere, the ttl should be 120s. If it's not in their it should be 75 minutes and if the answer is send to a legacy dns querier, it should be no more then 10s. This patch corrects the ttl behavior to the RFC.
This commit is contained in:
parent
c4321330d0
commit
62fb2fd749
@ -93,7 +93,7 @@ static const ip_addr_t v4group = DNS_MQUERY_IPV4_GROUP_INIT;
|
|||||||
static const ip_addr_t v6group = DNS_MQUERY_IPV6_GROUP_INIT;
|
static const ip_addr_t v6group = DNS_MQUERY_IPV6_GROUP_INIT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MDNS_TTL 255
|
#define MDNS_IP_TTL 255
|
||||||
|
|
||||||
|
|
||||||
static u8_t mdns_netif_client_id;
|
static u8_t mdns_netif_client_id;
|
||||||
@ -558,6 +558,7 @@ mdns_handle_question(struct mdns_packet *pkt)
|
|||||||
struct mdns_answer ans;
|
struct mdns_answer ans;
|
||||||
u8_t rev_v6;
|
u8_t rev_v6;
|
||||||
int match;
|
int match;
|
||||||
|
u32_t rr_ttl = MDNS_TTL_120;
|
||||||
|
|
||||||
res = mdns_read_answer(pkt, &ans);
|
res = mdns_read_answer(pkt, &ans);
|
||||||
if (res != ERR_OK) {
|
if (res != ERR_OK) {
|
||||||
@ -577,7 +578,7 @@ mdns_handle_question(struct mdns_packet *pkt)
|
|||||||
|
|
||||||
rev_v6 = 0;
|
rev_v6 = 0;
|
||||||
match = reply.host_replies & check_host(pkt->netif, &ans.info, &rev_v6);
|
match = reply.host_replies & check_host(pkt->netif, &ans.info, &rev_v6);
|
||||||
if (match && (ans.ttl > (mdns->dns_ttl / 2))) {
|
if (match && (ans.ttl > (rr_ttl / 2))) {
|
||||||
/* The RR in the known answer matches an RR we are planning to send,
|
/* The RR in the known answer matches an RR we are planning to send,
|
||||||
* and the TTL is less than half gone.
|
* and the TTL is less than half gone.
|
||||||
* If the payload matches we should not send that answer.
|
* If the payload matches we should not send that answer.
|
||||||
@ -631,7 +632,10 @@ mdns_handle_question(struct mdns_packet *pkt)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match = reply.serv_replies[i] & check_service(service, &ans.info);
|
match = reply.serv_replies[i] & check_service(service, &ans.info);
|
||||||
if (match && (ans.ttl > (service->dns_ttl / 2))) {
|
if (match & REPLY_SERVICE_TYPE_PTR) {
|
||||||
|
rr_ttl = MDNS_TTL_4500;
|
||||||
|
}
|
||||||
|
if (match && (ans.ttl > (rr_ttl / 2))) {
|
||||||
/* The RR in the known answer matches an RR we are planning to send,
|
/* The RR in the known answer matches an RR we are planning to send,
|
||||||
* and the TTL is less than half gone.
|
* and the TTL is less than half gone.
|
||||||
* If the payload matches we should not send that answer.
|
* If the payload matches we should not send that answer.
|
||||||
@ -986,11 +990,10 @@ mdns_probe(void* arg)
|
|||||||
* @param hostname Name to use. Queries for <hostname>.local will be answered
|
* @param hostname Name to use. Queries for <hostname>.local will be answered
|
||||||
* with the IP addresses of the netif. The hostname will be copied, the
|
* with the IP addresses of the netif. The hostname will be copied, the
|
||||||
* given pointer can be on the stack.
|
* given pointer can be on the stack.
|
||||||
* @param dns_ttl Validity time in seconds to send out for IP address data in DNS replies
|
|
||||||
* @return ERR_OK if netif was added, an err_t otherwise
|
* @return ERR_OK if netif was added, an err_t otherwise
|
||||||
*/
|
*/
|
||||||
err_t
|
err_t
|
||||||
mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl)
|
mdns_resp_add_netif(struct netif *netif, const char *hostname)
|
||||||
{
|
{
|
||||||
err_t res;
|
err_t res;
|
||||||
struct mdns_host *mdns;
|
struct mdns_host *mdns;
|
||||||
@ -1006,7 +1009,6 @@ mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl)
|
|||||||
netif_set_client_data(netif, mdns_netif_client_id, mdns);
|
netif_set_client_data(netif, mdns_netif_client_id, mdns);
|
||||||
|
|
||||||
MEMCPY(&mdns->name, hostname, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(hostname)));
|
MEMCPY(&mdns->name, hostname, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(hostname)));
|
||||||
mdns->dns_ttl = dns_ttl;
|
|
||||||
mdns->probes_sent = 0;
|
mdns->probes_sent = 0;
|
||||||
mdns->probing_state = MDNS_PROBING_NOT_STARTED;
|
mdns->probing_state = MDNS_PROBING_NOT_STARTED;
|
||||||
|
|
||||||
@ -1115,14 +1117,13 @@ mdns_resp_rename_netif(struct netif *netif, const char *hostname)
|
|||||||
* @param proto The service protocol, DNSSD_PROTO_TCP for TCP ("_tcp") and DNSSD_PROTO_UDP
|
* @param proto The service protocol, DNSSD_PROTO_TCP for TCP ("_tcp") and DNSSD_PROTO_UDP
|
||||||
* for others ("_udp")
|
* for others ("_udp")
|
||||||
* @param port The port the service listens to
|
* @param port The port the service listens to
|
||||||
* @param dns_ttl Validity time in seconds to send out for service data in DNS replies
|
|
||||||
* @param txt_fn Callback to get TXT data. Will be called each time a TXT reply is created to
|
* @param txt_fn Callback to get TXT data. Will be called each time a TXT reply is created to
|
||||||
* allow dynamic replies.
|
* allow dynamic replies.
|
||||||
* @param txt_data Userdata pointer for txt_fn
|
* @param txt_data Userdata pointer for txt_fn
|
||||||
* @return service_id if the service was added to the netif, an err_t otherwise
|
* @return service_id if the service was added to the netif, an err_t otherwise
|
||||||
*/
|
*/
|
||||||
s8_t
|
s8_t
|
||||||
mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_data)
|
mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, service_get_txt_fn_t txt_fn, void *txt_data)
|
||||||
{
|
{
|
||||||
s8_t i;
|
s8_t i;
|
||||||
s8_t slot = -1;
|
s8_t slot = -1;
|
||||||
@ -1155,7 +1156,6 @@ mdns_resp_add_service(struct netif *netif, const char *name, const char *service
|
|||||||
srv->txt_userdata = txt_data;
|
srv->txt_userdata = txt_data;
|
||||||
srv->proto = (u16_t)proto;
|
srv->proto = (u16_t)proto;
|
||||||
srv->port = port;
|
srv->port = port;
|
||||||
srv->dns_ttl = dns_ttl;
|
|
||||||
|
|
||||||
mdns->services[slot] = srv;
|
mdns->services[slot] = srv;
|
||||||
|
|
||||||
@ -1320,9 +1320,9 @@ mdns_resp_init(void)
|
|||||||
mdns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
|
mdns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
|
||||||
LWIP_ASSERT("Failed to allocate pcb", mdns_pcb != NULL);
|
LWIP_ASSERT("Failed to allocate pcb", mdns_pcb != NULL);
|
||||||
#if LWIP_MULTICAST_TX_OPTIONS
|
#if LWIP_MULTICAST_TX_OPTIONS
|
||||||
udp_set_multicast_ttl(mdns_pcb, MDNS_TTL);
|
udp_set_multicast_ttl(mdns_pcb, MDNS_IP_TTL);
|
||||||
#else
|
#else
|
||||||
mdns_pcb->ttl = MDNS_TTL;
|
mdns_pcb->ttl = MDNS_IP_TTL;
|
||||||
#endif
|
#endif
|
||||||
res = udp_bind(mdns_pcb, IP_ANY_TYPE, LWIP_IANA_PORT_MDNS);
|
res = udp_bind(mdns_pcb, IP_ANY_TYPE, LWIP_IANA_PORT_MDNS);
|
||||||
LWIP_UNUSED_ARG(res); /* in case of LWIP_NOASSERT */
|
LWIP_UNUSED_ARG(res); /* in case of LWIP_NOASSERT */
|
||||||
|
@ -254,23 +254,29 @@ static err_t
|
|||||||
mdns_add_a_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg)
|
mdns_add_a_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg)
|
||||||
{
|
{
|
||||||
err_t res;
|
err_t res;
|
||||||
|
u32_t ttl = MDNS_TTL_120;
|
||||||
struct mdns_domain host;
|
struct mdns_domain host;
|
||||||
mdns_build_host_domain(&host, netif_mdns_data(msg->netif));
|
mdns_build_host_domain(&host, netif_mdns_data(msg->netif));
|
||||||
/* When answering to a legacy querier, we need to repeat the question.
|
/* When answering to a legacy querier, we need to repeat the question and
|
||||||
* But this only needs to be done for the question asked (max one question),
|
* limit the ttl to the short legacy ttl */
|
||||||
* not for the additional records. */
|
if(msg->legacy_query) {
|
||||||
if(msg->legacy_query && reply->questions < 1) {
|
/* Repeating the question only needs to be done for the question asked
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
* (max one question), not for the additional records. */
|
||||||
res = mdns_add_question(reply, &host, DNS_RRTYPE_A, DNS_RRCLASS_IN, 0);
|
if(reply->questions < 1) {
|
||||||
if (res != ERR_OK) {
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
||||||
return res;
|
res = mdns_add_question(reply, &host, DNS_RRTYPE_A, DNS_RRCLASS_IN, 0);
|
||||||
|
if (res != ERR_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
reply->questions = 1;
|
||||||
}
|
}
|
||||||
reply->questions = 1;
|
/* ttl of legacy answer may not be greater then 10 seconds */
|
||||||
|
ttl = MDNS_TTL_10;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with A record\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with A record\n"));
|
||||||
return mdns_add_answer(reply, &host, DNS_RRTYPE_A, DNS_RRCLASS_IN, msg->cache_flush,
|
return mdns_add_answer(reply, &host, DNS_RRTYPE_A, DNS_RRCLASS_IN, msg->cache_flush,
|
||||||
(netif_mdns_data(msg->netif))->dns_ttl,
|
ttl, (const u8_t *) netif_ip4_addr(msg->netif),
|
||||||
(const u8_t *) netif_ip4_addr(msg->netif), sizeof(ip4_addr_t), NULL);
|
sizeof(ip4_addr_t), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a 4.3.2.1.in-addr.arpa -> hostname.local PTR RR to outpacket */
|
/** Write a 4.3.2.1.in-addr.arpa -> hostname.local PTR RR to outpacket */
|
||||||
@ -278,23 +284,29 @@ static err_t
|
|||||||
mdns_add_hostv4_ptr_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg)
|
mdns_add_hostv4_ptr_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg)
|
||||||
{
|
{
|
||||||
err_t res;
|
err_t res;
|
||||||
|
u32_t ttl = MDNS_TTL_120;
|
||||||
struct mdns_domain host, revhost;
|
struct mdns_domain host, revhost;
|
||||||
mdns_build_host_domain(&host, netif_mdns_data(msg->netif));
|
mdns_build_host_domain(&host, netif_mdns_data(msg->netif));
|
||||||
mdns_build_reverse_v4_domain(&revhost, netif_ip4_addr(msg->netif));
|
mdns_build_reverse_v4_domain(&revhost, netif_ip4_addr(msg->netif));
|
||||||
/* When answering to a legacy querier, we need to repeat the question.
|
/* When answering to a legacy querier, we need to repeat the question and
|
||||||
* But this only needs to be done for the question asked (max one question),
|
* limit the ttl to the short legacy ttl */
|
||||||
* not for the additional records. */
|
if(msg->legacy_query) {
|
||||||
if(msg->legacy_query && reply->questions < 1) {
|
/* Repeating the question only needs to be done for the question asked
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
* (max one question), not for the additional records. */
|
||||||
res = mdns_add_question(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0);
|
if(reply->questions < 1) {
|
||||||
if (res != ERR_OK) {
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
||||||
return res;
|
res = mdns_add_question(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0);
|
||||||
|
if (res != ERR_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
reply->questions = 1;
|
||||||
}
|
}
|
||||||
reply->questions = 1;
|
/* ttl of legacy answer may not be greater then 10 seconds */
|
||||||
|
ttl = MDNS_TTL_10;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with v4 PTR record\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with v4 PTR record\n"));
|
||||||
return mdns_add_answer(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, msg->cache_flush,
|
return mdns_add_answer(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN,
|
||||||
(netif_mdns_data(msg->netif))->dns_ttl, NULL, 0, &host);
|
msg->cache_flush, ttl, NULL, 0, &host);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -304,23 +316,29 @@ static err_t
|
|||||||
mdns_add_aaaa_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg, int addrindex)
|
mdns_add_aaaa_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg, int addrindex)
|
||||||
{
|
{
|
||||||
err_t res;
|
err_t res;
|
||||||
|
u32_t ttl = MDNS_TTL_120;
|
||||||
struct mdns_domain host;
|
struct mdns_domain host;
|
||||||
mdns_build_host_domain(&host, netif_mdns_data(msg->netif));
|
mdns_build_host_domain(&host, netif_mdns_data(msg->netif));
|
||||||
/* When answering to a legacy querier, we need to repeat the question.
|
/* When answering to a legacy querier, we need to repeat the question and
|
||||||
* But this only needs to be done for the question asked (max one question),
|
* limit the ttl to the short legacy ttl */
|
||||||
* not for the additional records. */
|
if(msg->legacy_query) {
|
||||||
if(msg->legacy_query && reply->questions < 1) {
|
/* Repeating the question only needs to be done for the question asked
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
* (max one question), not for the additional records. */
|
||||||
res = mdns_add_question(reply, &host, DNS_RRTYPE_AAAA, DNS_RRCLASS_IN, 0);
|
if(reply->questions < 1) {
|
||||||
if (res != ERR_OK) {
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
||||||
return res;
|
res = mdns_add_question(reply, &host, DNS_RRTYPE_AAAA, DNS_RRCLASS_IN, 0);
|
||||||
|
if (res != ERR_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
reply->questions = 1;
|
||||||
}
|
}
|
||||||
reply->questions = 1;
|
/* ttl of legacy answer may not be greater then 10 seconds */
|
||||||
|
ttl = MDNS_TTL_10;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with AAAA record\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with AAAA record\n"));
|
||||||
return mdns_add_answer(reply, &host, DNS_RRTYPE_AAAA, DNS_RRCLASS_IN, msg->cache_flush,
|
return mdns_add_answer(reply, &host, DNS_RRTYPE_AAAA, DNS_RRCLASS_IN, msg->cache_flush,
|
||||||
(netif_mdns_data(msg->netif))->dns_ttl,
|
ttl, (const u8_t *) netif_ip6_addr(msg->netif, addrindex),
|
||||||
(const u8_t *) netif_ip6_addr(msg->netif, addrindex), sizeof(ip6_addr_p_t), NULL);
|
sizeof(ip6_addr_p_t), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a x.y.z.ip6.arpa -> hostname.local PTR RR to outpacket */
|
/** Write a x.y.z.ip6.arpa -> hostname.local PTR RR to outpacket */
|
||||||
@ -328,23 +346,29 @@ static err_t
|
|||||||
mdns_add_hostv6_ptr_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg, int addrindex)
|
mdns_add_hostv6_ptr_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg, int addrindex)
|
||||||
{
|
{
|
||||||
err_t res;
|
err_t res;
|
||||||
|
u32_t ttl = MDNS_TTL_120;
|
||||||
struct mdns_domain host, revhost;
|
struct mdns_domain host, revhost;
|
||||||
mdns_build_host_domain(&host, netif_mdns_data(msg->netif));
|
mdns_build_host_domain(&host, netif_mdns_data(msg->netif));
|
||||||
mdns_build_reverse_v6_domain(&revhost, netif_ip6_addr(msg->netif, addrindex));
|
mdns_build_reverse_v6_domain(&revhost, netif_ip6_addr(msg->netif, addrindex));
|
||||||
/* When answering to a legacy querier, we need to repeat the question.
|
/* When answering to a legacy querier, we need to repeat the question and
|
||||||
* But this only needs to be done for the question asked (max one question),
|
* limit the ttl to the short legacy ttl */
|
||||||
* not for the additional records. */
|
if(msg->legacy_query) {
|
||||||
if(msg->legacy_query && reply->questions < 1) {
|
/* Repeating the question only needs to be done for the question asked
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
* (max one question), not for the additional records. */
|
||||||
res = mdns_add_question(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0);
|
if(reply->questions < 1) {
|
||||||
if (res != ERR_OK) {
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
||||||
return res;
|
res = mdns_add_question(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0);
|
||||||
|
if (res != ERR_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
reply->questions = 1;
|
||||||
}
|
}
|
||||||
reply->questions = 1;
|
/* ttl of legacy answer may not be greater then 10 seconds */
|
||||||
|
ttl = MDNS_TTL_10;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with v6 PTR record\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with v6 PTR record\n"));
|
||||||
return mdns_add_answer(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, msg->cache_flush,
|
return mdns_add_answer(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN,
|
||||||
(netif_mdns_data(msg->netif))->dns_ttl, NULL, 0, &host);
|
msg->cache_flush, ttl, NULL, 0, &host);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -354,23 +378,29 @@ mdns_add_servicetype_ptr_answer(struct mdns_outpacket *reply, struct mdns_outmsg
|
|||||||
struct mdns_service *service)
|
struct mdns_service *service)
|
||||||
{
|
{
|
||||||
err_t res;
|
err_t res;
|
||||||
|
u32_t ttl = MDNS_TTL_4500;
|
||||||
struct mdns_domain service_type, service_dnssd;
|
struct mdns_domain service_type, service_dnssd;
|
||||||
mdns_build_service_domain(&service_type, service, 0);
|
mdns_build_service_domain(&service_type, service, 0);
|
||||||
mdns_build_dnssd_domain(&service_dnssd);
|
mdns_build_dnssd_domain(&service_dnssd);
|
||||||
/* When answering to a legacy querier, we need to repeat the question.
|
/* When answering to a legacy querier, we need to repeat the question and
|
||||||
* But this only needs to be done for the question asked (max one question),
|
* limit the ttl to the short legacy ttl */
|
||||||
* not for the additional records. */
|
if(msg->legacy_query) {
|
||||||
if(msg->legacy_query && reply->questions < 1) {
|
/* Repeating the question only needs to be done for the question asked
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
* (max one question), not for the additional records. */
|
||||||
res = mdns_add_question(reply, &service_dnssd, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0);
|
if(reply->questions < 1) {
|
||||||
if (res != ERR_OK) {
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
||||||
return res;
|
res = mdns_add_question(reply, &service_dnssd, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0);
|
||||||
|
if (res != ERR_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
reply->questions = 1;
|
||||||
}
|
}
|
||||||
reply->questions = 1;
|
/* ttl of legacy answer may not be greater then 10 seconds */
|
||||||
|
ttl = MDNS_TTL_10;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service type PTR record\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service type PTR record\n"));
|
||||||
return mdns_add_answer(reply, &service_dnssd, DNS_RRTYPE_PTR, DNS_RRCLASS_IN,
|
return mdns_add_answer(reply, &service_dnssd, DNS_RRTYPE_PTR, DNS_RRCLASS_IN,
|
||||||
0, service->dns_ttl, NULL, 0, &service_type);
|
0, ttl, NULL, 0, &service_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a servicetype -> servicename PTR RR to outpacket */
|
/** Write a servicetype -> servicename PTR RR to outpacket */
|
||||||
@ -379,23 +409,29 @@ mdns_add_servicename_ptr_answer(struct mdns_outpacket *reply, struct mdns_outmsg
|
|||||||
struct mdns_service *service)
|
struct mdns_service *service)
|
||||||
{
|
{
|
||||||
err_t res;
|
err_t res;
|
||||||
|
u32_t ttl = MDNS_TTL_120;
|
||||||
struct mdns_domain service_type, service_instance;
|
struct mdns_domain service_type, service_instance;
|
||||||
mdns_build_service_domain(&service_type, service, 0);
|
mdns_build_service_domain(&service_type, service, 0);
|
||||||
mdns_build_service_domain(&service_instance, service, 1);
|
mdns_build_service_domain(&service_instance, service, 1);
|
||||||
/* When answering to a legacy querier, we need to repeat the question.
|
/* When answering to a legacy querier, we need to repeat the question and
|
||||||
* But this only needs to be done for the question asked (max one question),
|
* limit the ttl to the short legacy ttl */
|
||||||
* not for the additional records. */
|
if(msg->legacy_query) {
|
||||||
if(msg->legacy_query && reply->questions < 1) {
|
/* Repeating the question only needs to be done for the question asked
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
* (max one question), not for the additional records. */
|
||||||
res = mdns_add_question(reply, &service_type, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0);
|
if(reply->questions < 1) {
|
||||||
if (res != ERR_OK) {
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
||||||
return res;
|
res = mdns_add_question(reply, &service_type, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0);
|
||||||
|
if (res != ERR_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
reply->questions = 1;
|
||||||
}
|
}
|
||||||
reply->questions = 1;
|
/* ttl of legacy answer may not be greater then 10 seconds */
|
||||||
|
ttl = MDNS_TTL_10;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service name PTR record\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service name PTR record\n"));
|
||||||
return mdns_add_answer(reply, &service_type, DNS_RRTYPE_PTR, DNS_RRCLASS_IN,
|
return mdns_add_answer(reply, &service_type, DNS_RRTYPE_PTR, DNS_RRCLASS_IN,
|
||||||
0, service->dns_ttl, NULL, 0, &service_instance);
|
0, ttl, NULL, 0, &service_instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a SRV RR to outpacket */
|
/** Write a SRV RR to outpacket */
|
||||||
@ -404,6 +440,7 @@ mdns_add_srv_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg,
|
|||||||
struct mdns_host *mdns, struct mdns_service *service)
|
struct mdns_host *mdns, struct mdns_service *service)
|
||||||
{
|
{
|
||||||
err_t res;
|
err_t res;
|
||||||
|
u32_t ttl = MDNS_TTL_120;
|
||||||
struct mdns_domain service_instance, srvhost;
|
struct mdns_domain service_instance, srvhost;
|
||||||
u16_t srvdata[3];
|
u16_t srvdata[3];
|
||||||
mdns_build_service_domain(&service_instance, service, 1);
|
mdns_build_service_domain(&service_instance, service, 1);
|
||||||
@ -414,9 +451,10 @@ mdns_add_srv_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg,
|
|||||||
* name compression MUST NOT be performed on SRV records.
|
* name compression MUST NOT be performed on SRV records.
|
||||||
*/
|
*/
|
||||||
srvhost.skip_compression = 1;
|
srvhost.skip_compression = 1;
|
||||||
/* When answering to a legacy querier, we need to repeat the question.
|
/* When answering to a legacy querier, we need to repeat the question and
|
||||||
* But this only needs to be done for the question asked (max one question),
|
* limit the ttl to the short legacy ttl.
|
||||||
* not for the additional records. */
|
* Repeating the question only needs to be done for the question asked
|
||||||
|
* (max one question), not for the additional records. */
|
||||||
if(reply->questions < 1) {
|
if(reply->questions < 1) {
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
||||||
res = mdns_add_question(reply, &service_instance, DNS_RRTYPE_SRV, DNS_RRCLASS_IN, 0);
|
res = mdns_add_question(reply, &service_instance, DNS_RRTYPE_SRV, DNS_RRCLASS_IN, 0);
|
||||||
@ -425,13 +463,15 @@ mdns_add_srv_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg,
|
|||||||
}
|
}
|
||||||
reply->questions = 1;
|
reply->questions = 1;
|
||||||
}
|
}
|
||||||
|
/* ttl of legacy answer may not be greater then 10 seconds */
|
||||||
|
ttl = MDNS_TTL_10;
|
||||||
}
|
}
|
||||||
srvdata[0] = lwip_htons(SRV_PRIORITY);
|
srvdata[0] = lwip_htons(SRV_PRIORITY);
|
||||||
srvdata[1] = lwip_htons(SRV_WEIGHT);
|
srvdata[1] = lwip_htons(SRV_WEIGHT);
|
||||||
srvdata[2] = lwip_htons(service->port);
|
srvdata[2] = lwip_htons(service->port);
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with SRV record\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with SRV record\n"));
|
||||||
return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_SRV, DNS_RRCLASS_IN,
|
return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_SRV, DNS_RRCLASS_IN,
|
||||||
msg->cache_flush, service->dns_ttl,
|
msg->cache_flush, ttl,
|
||||||
(const u8_t *) &srvdata, sizeof(srvdata), &srvhost);
|
(const u8_t *) &srvdata, sizeof(srvdata), &srvhost);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,24 +481,30 @@ mdns_add_txt_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg,
|
|||||||
struct mdns_service *service)
|
struct mdns_service *service)
|
||||||
{
|
{
|
||||||
err_t res;
|
err_t res;
|
||||||
|
u32_t ttl = MDNS_TTL_120;
|
||||||
struct mdns_domain service_instance;
|
struct mdns_domain service_instance;
|
||||||
mdns_build_service_domain(&service_instance, service, 1);
|
mdns_build_service_domain(&service_instance, service, 1);
|
||||||
mdns_prepare_txtdata(service);
|
mdns_prepare_txtdata(service);
|
||||||
/* When answering to a legacy querier, we need to repeat the question.
|
/* When answering to a legacy querier, we need to repeat the question and
|
||||||
* But this only needs to be done for the question asked (max one question),
|
* limit the ttl to the short legacy ttl */
|
||||||
* not for the additional records. */
|
if(msg->legacy_query) {
|
||||||
if(msg->legacy_query && reply->questions < 1) {
|
/* Repeating the question only needs to be done for the question asked
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
* (max one question), not for the additional records. */
|
||||||
res = mdns_add_question(reply, &service_instance, DNS_RRTYPE_TXT, DNS_RRCLASS_IN, 0);
|
if(reply->questions < 1) {
|
||||||
if (res != ERR_OK) {
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
|
||||||
return res;
|
res = mdns_add_question(reply, &service_instance, DNS_RRTYPE_TXT, DNS_RRCLASS_IN, 0);
|
||||||
|
if (res != ERR_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
reply->questions = 1;
|
||||||
}
|
}
|
||||||
reply->questions = 1;
|
/* ttl of legacy answer may not be greater then 10 seconds */
|
||||||
|
ttl = MDNS_TTL_10;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with TXT record\n"));
|
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with TXT record\n"));
|
||||||
return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_TXT, DNS_RRCLASS_IN,
|
return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_TXT, DNS_RRCLASS_IN,
|
||||||
msg->cache_flush, service->dns_ttl,
|
msg->cache_flush, ttl, (u8_t *) &service->txtdata.name,
|
||||||
(u8_t *) &service->txtdata.name, service->txtdata.length, NULL);
|
service->txtdata.length, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,11 +73,11 @@ void mdns_resp_init(void);
|
|||||||
|
|
||||||
void mdns_resp_register_name_result_cb(mdns_name_result_cb_t cb);
|
void mdns_resp_register_name_result_cb(mdns_name_result_cb_t cb);
|
||||||
|
|
||||||
err_t mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl);
|
err_t mdns_resp_add_netif(struct netif *netif, const char *hostname);
|
||||||
err_t mdns_resp_remove_netif(struct netif *netif);
|
err_t mdns_resp_remove_netif(struct netif *netif);
|
||||||
err_t mdns_resp_rename_netif(struct netif *netif, const char *hostname);
|
err_t mdns_resp_rename_netif(struct netif *netif, const char *hostname);
|
||||||
|
|
||||||
s8_t mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_userdata);
|
s8_t mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, service_get_txt_fn_t txt_fn, void *txt_userdata);
|
||||||
err_t mdns_resp_del_service(struct netif *netif, s8_t slot);
|
err_t mdns_resp_del_service(struct netif *netif, s8_t slot);
|
||||||
err_t mdns_resp_rename_service(struct netif *netif, s8_t slot, const char *name);
|
err_t mdns_resp_rename_service(struct netif *netif, s8_t slot, const char *name);
|
||||||
|
|
||||||
|
@ -54,6 +54,15 @@ extern "C" {
|
|||||||
#define SRV_PRIORITY 0
|
#define SRV_PRIORITY 0
|
||||||
#define SRV_WEIGHT 0
|
#define SRV_WEIGHT 0
|
||||||
|
|
||||||
|
/* mDNS TTL: (RFC6762 section 10)
|
||||||
|
* - 120 seconds if the hostname appears somewhere in the RR
|
||||||
|
* - 75 minutes if not (4500 seconds)
|
||||||
|
* - 10 seconds if responding to a legacy query
|
||||||
|
*/
|
||||||
|
#define MDNS_TTL_10 10
|
||||||
|
#define MDNS_TTL_120 120
|
||||||
|
#define MDNS_TTL_4500 4500
|
||||||
|
|
||||||
/* Domain structs - also visible for unit tests */
|
/* Domain structs - also visible for unit tests */
|
||||||
|
|
||||||
struct mdns_domain {
|
struct mdns_domain {
|
||||||
@ -77,8 +86,6 @@ struct mdns_service {
|
|||||||
* to update txtdata buffer */
|
* to update txtdata buffer */
|
||||||
service_get_txt_fn_t txt_fn;
|
service_get_txt_fn_t txt_fn;
|
||||||
void *txt_userdata;
|
void *txt_userdata;
|
||||||
/** TTL in seconds of SRV/TXT replies */
|
|
||||||
u32_t dns_ttl;
|
|
||||||
/** Protocol, TCP or UDP */
|
/** Protocol, TCP or UDP */
|
||||||
u16_t proto;
|
u16_t proto;
|
||||||
/** Port of the service */
|
/** Port of the service */
|
||||||
@ -91,8 +98,6 @@ struct mdns_host {
|
|||||||
char name[MDNS_LABEL_MAXLEN + 1];
|
char name[MDNS_LABEL_MAXLEN + 1];
|
||||||
/** Pointer to services */
|
/** Pointer to services */
|
||||||
struct mdns_service *services[MDNS_MAX_SERVICES];
|
struct mdns_service *services[MDNS_MAX_SERVICES];
|
||||||
/** TTL in seconds of A/AAAA/PTR replies */
|
|
||||||
u32_t dns_ttl;
|
|
||||||
/** Number of probes sent for the current name */
|
/** Number of probes sent for the current name */
|
||||||
u8_t probes_sent;
|
u8_t probes_sent;
|
||||||
/** State in probing sequence */
|
/** State in probing sequence */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user