mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-01-27 12:35:26 +00:00
dns: added one-shot multicast DNS queries
This commit is contained in:
parent
85817e7611
commit
5774fdfe75
@ -6,6 +6,9 @@ HISTORY
|
|||||||
|
|
||||||
++ New features:
|
++ New features:
|
||||||
|
|
||||||
|
2016-12-09: Simon Goldschmidt
|
||||||
|
* dns.c: added one-shot multicast DNS queries
|
||||||
|
|
||||||
2016-11-24: Ambroz Bizjak, David van Moolenbroek
|
2016-11-24: Ambroz Bizjak, David van Moolenbroek
|
||||||
* tcp_out.c: Optimize passing contiguous nocopy buffers to tcp_write (bug #46290)
|
* tcp_out.c: Optimize passing contiguous nocopy buffers to tcp_write (bug #46290)
|
||||||
|
|
||||||
|
103
src/core/dns.c
103
src/core/dns.c
@ -24,6 +24,11 @@
|
|||||||
* the resolver code calls a specified callback function (which
|
* the resolver code calls a specified callback function (which
|
||||||
* must be implemented by the module that uses the resolver).
|
* must be implemented by the module that uses the resolver).
|
||||||
*
|
*
|
||||||
|
* Multicast DNS queries are supported for names ending on ".local".
|
||||||
|
* However, only "One-Shot Multicast DNS Queries" are supported (RFC 6762
|
||||||
|
* chapter 5.1), this is not a fully compliant implementation of continuous
|
||||||
|
* mDNS querying!
|
||||||
|
*
|
||||||
* All functions must be called from TCPIP thread.
|
* All functions must be called from TCPIP thread.
|
||||||
*
|
*
|
||||||
* @see @ref netconn_common for thread-safe access.
|
* @see @ref netconn_common for thread-safe access.
|
||||||
@ -71,6 +76,7 @@
|
|||||||
/** @todo: define good default values (rfc compliance) */
|
/** @todo: define good default values (rfc compliance) */
|
||||||
/** @todo: improve answer parsing, more checkings... */
|
/** @todo: improve answer parsing, more checkings... */
|
||||||
/** @todo: check RFC1035 - 7.3. Processing responses */
|
/** @todo: check RFC1035 - 7.3. Processing responses */
|
||||||
|
/** @todo: one-shot mDNS: dual-stack fallback to another IP version */
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
* Includes
|
* Includes
|
||||||
@ -175,6 +181,12 @@ static u16_t dns_txid;
|
|||||||
#define LWIP_DNS_SET_ADDRTYPE(x, y)
|
#define LWIP_DNS_SET_ADDRTYPE(x, y)
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
|
|
||||||
|
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||||
|
#define LWIP_DNS_ISMDNS_ARG(x) , x
|
||||||
|
#else
|
||||||
|
#define LWIP_DNS_ISMDNS_ARG(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
/** DNS query message structure.
|
/** DNS query message structure.
|
||||||
No packing needed: only used locally on the stack. */
|
No packing needed: only used locally on the stack. */
|
||||||
struct dns_query {
|
struct dns_query {
|
||||||
@ -224,6 +236,9 @@ struct dns_table_entry {
|
|||||||
#if LWIP_IPV4 && LWIP_IPV6
|
#if LWIP_IPV4 && LWIP_IPV6
|
||||||
u8_t reqaddrtype;
|
u8_t reqaddrtype;
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
|
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||||
|
u8_t is_mdns;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/** DNS request table entry: used when dns_gehostbyname cannot answer the
|
/** DNS request table entry: used when dns_gehostbyname cannot answer the
|
||||||
@ -287,6 +302,13 @@ static struct dns_table_entry dns_table[DNS_TABLE_SIZE];
|
|||||||
static struct dns_req_entry dns_requests[DNS_MAX_REQUESTS];
|
static struct dns_req_entry dns_requests[DNS_MAX_REQUESTS];
|
||||||
static ip_addr_t dns_servers[DNS_MAX_SERVERS];
|
static ip_addr_t dns_servers[DNS_MAX_SERVERS];
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
const ip_addr_t dns_mquery_v4group = DNS_MQUERY_IPV4_GROUP_INIT;
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
#if LWIP_IPV6
|
||||||
|
const ip_addr_t dns_mquery_v6group = DNS_MQUERY_IPV6_GROUP_INIT;
|
||||||
|
#endif /* LWIP_IPV6 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the resolver: set up the UDP pcb and configure the default server
|
* Initialize the resolver: set up the UDP pcb and configure the default server
|
||||||
* (if DNS_SERVER_ADDRESS is set).
|
* (if DNS_SERVER_ADDRESS is set).
|
||||||
@ -680,7 +702,11 @@ dns_send(u8_t idx)
|
|||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",
|
||||||
(u16_t)(entry->server_idx), entry->name));
|
(u16_t)(entry->server_idx), entry->name));
|
||||||
LWIP_ASSERT("dns server out of array", entry->server_idx < DNS_MAX_SERVERS);
|
LWIP_ASSERT("dns server out of array", entry->server_idx < DNS_MAX_SERVERS);
|
||||||
if (ip_addr_isany_val(dns_servers[entry->server_idx])) {
|
if (ip_addr_isany_val(dns_servers[entry->server_idx])
|
||||||
|
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||||
|
&& !entry->is_mdns
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
/* DNS server not valid anymore, e.g. PPP netif has been shut down */
|
/* DNS server not valid anymore, e.g. PPP netif has been shut down */
|
||||||
/* call specified callback function if provided */
|
/* call specified callback function if provided */
|
||||||
dns_call_found(idx, NULL);
|
dns_call_found(idx, NULL);
|
||||||
@ -693,6 +719,8 @@ dns_send(u8_t idx)
|
|||||||
p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(SIZEOF_DNS_HDR + strlen(entry->name) + 2 +
|
p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(SIZEOF_DNS_HDR + strlen(entry->name) + 2 +
|
||||||
SIZEOF_DNS_QUERY), PBUF_RAM);
|
SIZEOF_DNS_QUERY), PBUF_RAM);
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
|
const ip_addr_t* dst;
|
||||||
|
u16_t dst_port;
|
||||||
/* fill dns header */
|
/* fill dns header */
|
||||||
memset(&hdr, 0, SIZEOF_DNS_HDR);
|
memset(&hdr, 0, SIZEOF_DNS_HDR);
|
||||||
hdr.id = lwip_htons(entry->txid);
|
hdr.id = lwip_htons(entry->txid);
|
||||||
@ -735,7 +763,30 @@ dns_send(u8_t idx)
|
|||||||
/* send dns packet */
|
/* send dns packet */
|
||||||
LWIP_DEBUGF(DNS_DEBUG, ("sending DNS request ID %d for name \"%s\" to server %d\r\n",
|
LWIP_DEBUGF(DNS_DEBUG, ("sending DNS request ID %d for name \"%s\" to server %d\r\n",
|
||||||
entry->txid, entry->name, entry->server_idx));
|
entry->txid, entry->name, entry->server_idx));
|
||||||
err = udp_sendto(dns_pcbs[pcb_idx], p, &dns_servers[entry->server_idx], DNS_SERVER_PORT);
|
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||||
|
if (entry->is_mdns) {
|
||||||
|
dst_port = DNS_MQUERY_PORT;
|
||||||
|
#if LWIP_IPV6
|
||||||
|
if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype))
|
||||||
|
{
|
||||||
|
dst = &dns_mquery_v6group;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if LWIP_IPV4 && LWIP_IPV6
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#if LWIP_IPV4
|
||||||
|
{
|
||||||
|
dst = &dns_mquery_v4group;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else
|
||||||
|
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
||||||
|
{
|
||||||
|
dst_port = DNS_SERVER_PORT;
|
||||||
|
dst = &dns_servers[entry->server_idx];
|
||||||
|
}
|
||||||
|
err = udp_sendto(dns_pcbs[pcb_idx], p, dst, dst_port);
|
||||||
|
|
||||||
/* free pbuf */
|
/* free pbuf */
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
@ -938,7 +989,11 @@ dns_check_entry(u8_t i)
|
|||||||
case DNS_STATE_ASKING:
|
case DNS_STATE_ASKING:
|
||||||
if (--entry->tmr == 0) {
|
if (--entry->tmr == 0) {
|
||||||
if (++entry->retries == DNS_MAX_RETRIES) {
|
if (++entry->retries == DNS_MAX_RETRIES) {
|
||||||
if ((entry->server_idx + 1 < DNS_MAX_SERVERS) && !ip_addr_isany_val(dns_servers[entry->server_idx + 1])) {
|
if ((entry->server_idx + 1 < DNS_MAX_SERVERS) && !ip_addr_isany_val(dns_servers[entry->server_idx + 1])
|
||||||
|
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||||
|
&& !entry->is_mdns
|
||||||
|
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
||||||
|
) {
|
||||||
/* change of server */
|
/* change of server */
|
||||||
entry->server_idx++;
|
entry->server_idx++;
|
||||||
entry->tmr = 1;
|
entry->tmr = 1;
|
||||||
@ -1075,10 +1130,15 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr,
|
|||||||
goto memerr; /* ignore this packet */
|
goto memerr; /* ignore this packet */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether response comes from the same network address to which the
|
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||||
question was sent. (RFC 5452) */
|
if (!entry->is_mdns)
|
||||||
if (!ip_addr_cmp(addr, &dns_servers[entry->server_idx])) {
|
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
||||||
goto memerr; /* ignore this packet */
|
{
|
||||||
|
/* Check whether response comes from the same network address to which the
|
||||||
|
question was sent. (RFC 5452) */
|
||||||
|
if (!ip_addr_cmp(addr, &dns_servers[entry->server_idx])) {
|
||||||
|
goto memerr; /* ignore this packet */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the name in the "question" part match with the name in the entry and
|
/* Check if the name in the "question" part match with the name in the entry and
|
||||||
@ -1210,7 +1270,7 @@ memerr:
|
|||||||
*/
|
*/
|
||||||
static err_t
|
static err_t
|
||||||
dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found,
|
dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found,
|
||||||
void *callback_arg LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype))
|
void *callback_arg LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype) LWIP_DNS_ISMDNS_ARG(u8_t is_mdns))
|
||||||
{
|
{
|
||||||
u8_t i;
|
u8_t i;
|
||||||
u8_t lseq, lseqi;
|
u8_t lseq, lseqi;
|
||||||
@ -1326,6 +1386,10 @@ dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found,
|
|||||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS pcb %"U16_F"\n", name, (u16_t)(entry->pcb_idx)));
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS pcb %"U16_F"\n", name, (u16_t)(entry->pcb_idx)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||||
|
entry->is_mdns = is_mdns;
|
||||||
|
#endif
|
||||||
|
|
||||||
dns_seqno++;
|
dns_seqno++;
|
||||||
|
|
||||||
/* force to send query without waiting timer */
|
/* force to send query without waiting timer */
|
||||||
@ -1381,6 +1445,9 @@ dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_call
|
|||||||
void *callback_arg, u8_t dns_addrtype)
|
void *callback_arg, u8_t dns_addrtype)
|
||||||
{
|
{
|
||||||
size_t hostnamelen;
|
size_t hostnamelen;
|
||||||
|
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||||
|
u8_t is_mdns;
|
||||||
|
#endif
|
||||||
/* not initialized or no valid server yet, or invalid addr pointer
|
/* not initialized or no valid server yet, or invalid addr pointer
|
||||||
* or invalid hostname or invalid hostname length */
|
* or invalid hostname or invalid hostname length */
|
||||||
if ((addr == NULL) ||
|
if ((addr == NULL) ||
|
||||||
@ -1437,13 +1504,25 @@ dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_call
|
|||||||
LWIP_UNUSED_ARG(dns_addrtype);
|
LWIP_UNUSED_ARG(dns_addrtype);
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
|
|
||||||
/* prevent calling found callback if no server is set, return error instead */
|
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||||
if (ip_addr_isany_val(dns_servers[0])) {
|
if (strstr(hostname, ".local") == &hostname[hostnamelen] - 6) {
|
||||||
return ERR_VAL;
|
is_mdns = 1;
|
||||||
|
} else {
|
||||||
|
is_mdns = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_mdns)
|
||||||
|
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
||||||
|
{
|
||||||
|
/* prevent calling found callback if no server is set, return error instead */
|
||||||
|
if (ip_addr_isany_val(dns_servers[0])) {
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* queue query with specified callback */
|
/* queue query with specified callback */
|
||||||
return dns_enqueue(hostname, hostnamelen, found, callback_arg LWIP_DNS_ADDRTYPE_ARG(dns_addrtype));
|
return dns_enqueue(hostname, hostnamelen, found, callback_arg LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)
|
||||||
|
LWIP_DNS_ISMDNS_ARG(is_mdns));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* LWIP_DNS */
|
#endif /* LWIP_DNS */
|
||||||
|
@ -84,6 +84,13 @@ struct local_hostlist_entry {
|
|||||||
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
||||||
#endif /* DNS_LOCAL_HOSTLIST */
|
#endif /* DNS_LOCAL_HOSTLIST */
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
extern const ip_addr_t dns_mquery_v4group;
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
#if LWIP_IPV6
|
||||||
|
extern const ip_addr_t dns_mquery_v6group;
|
||||||
|
#endif /* LWIP_IPV6 */
|
||||||
|
|
||||||
/** Callback which is invoked when a hostname is found.
|
/** Callback which is invoked when a hostname is found.
|
||||||
* A function of this type must be implemented by the application using the DNS resolver.
|
* A function of this type must be implemented by the application using the DNS resolver.
|
||||||
* @param name pointer to the name that was looked up.
|
* @param name pointer to the name that was looked up.
|
||||||
|
@ -1057,6 +1057,12 @@
|
|||||||
#if !defined DNS_LOCAL_HOSTLIST_IS_DYNAMIC || defined __DOXYGEN__
|
#if !defined DNS_LOCAL_HOSTLIST_IS_DYNAMIC || defined __DOXYGEN__
|
||||||
#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0
|
#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0
|
||||||
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
||||||
|
|
||||||
|
/** Set this to 1 to enable querying ".local" names via mDNS
|
||||||
|
* using a One-Shot Multicast DNS Query */
|
||||||
|
#if !defined LWIP_DNS_SUPPORT_MDNS_QUERIES || defined __DOXYGEN__
|
||||||
|
#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
@ -115,6 +115,24 @@ PACK_STRUCT_END
|
|||||||
#endif
|
#endif
|
||||||
#define SIZEOF_DNS_HDR 12
|
#define SIZEOF_DNS_HDR 12
|
||||||
|
|
||||||
|
|
||||||
|
/* Multicast DNS definitions */
|
||||||
|
|
||||||
|
/** UDP port for multicast DNS queries */
|
||||||
|
#ifndef DNS_MQUERY_PORT
|
||||||
|
#define DNS_MQUERY_PORT 5353
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IPv4 group for multicast DNS queries: 224.0.0.251 */
|
||||||
|
#ifndef DNS_MQUERY_IPV4_GROUP_INIT
|
||||||
|
#define DNS_MQUERY_IPV4_GROUP_INIT IPADDR4_INIT_BYTES(224,0,0,251)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IPv6 group for multicast DNS queries: FF02::FB */
|
||||||
|
#ifndef DNS_MQUERY_IPV6_GROUP_INIT
|
||||||
|
#define DNS_MQUERY_IPV6_GROUP_INIT IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user