blob: e0514d0d32aeb08e835cc96e2dc8a708b5ed464c [file] [log] [blame]
/*
*
* Copyright (c) 2013-2017 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* This file defines DNSResolver, the object that abstracts
* Domain Name System (DNS) resolution in InetLayer.
*
*/
#ifndef DNSRESOLVER_H
#define DNSRESOLVER_H
#include <InetLayer/IPAddress.h>
#include <InetLayer/InetError.h>
#include <InetLayer/InetLayerBasis.h>
#define NL_DNS_HOSTNAME_MAX_LEN (253)
struct addrinfo;
namespace nl {
namespace Inet {
class InetLayer;
/**
* Options controlling how IP address resolution is performed.
*/
enum DNSOptions
{
kDNSOption_AddrFamily_Mask = 0x07, ///< Bits within a DNSOptions integer value representing the desired address family.
kDNSOption_Flags_Mask = 0xF8, ///< Bits within a DNSOptions integer value reserved for flags.
// Address Family Choices
kDNSOption_AddrFamily_Any = 0x00, ///< Return IPv4 and/or IPv6 addresses in the order returned by the nameserver.
#if INET_CONFIG_ENABLE_IPV4
kDNSOption_AddrFamily_IPv4Only = 0x01, ///< Return only IPv4 addresses.
kDNSOption_AddrFamily_IPv4Preferred = 0x02, ///< Return IPv4 and/or IPv6 addresses, with IPv4 addresses listed first.
#endif
kDNSOption_AddrFamily_IPv6Only = 0x03, ///< Return only IPv6 addresses.
kDNSOption_AddrFamily_IPv6Preferred = 0x04, ///< Return IPv4 and/or IPv6 addresses, with IPv6 addresses listed first.
// NOTE: At present there are no DNSOption flags define.
kDNSOption_ValidFlags = 0, ///< Set of all valid DNSOption flags.
kDNSOption_Default = kDNSOption_AddrFamily_Any
};
/**
* @class DNSResolver
*
* @brief
* This is an internal class to InetLayer that provides the abstraction of
* Domain Name System (DNS) resolution in InetLayer. There is no public
* interface available for the application layer.
*
*/
class DNSResolver: public InetLayerBasis
{
private:
friend class InetLayer;
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
#if INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
friend class AsyncDNSResolverSockets;
/// States of the DNSResolver object with respect to hostname resolution.
typedef enum DNSResolverState
{
kState_Unused = 0, ///<Used to indicate that the DNSResolver object is not used.
kState_Active = 2, ///<Used to indicate that a DNS resolution is being performed on the DNSResolver object.
kState_Complete = 3, ///<Used to indicate that the DNS resolution on the DNSResolver object is complete.
kState_Canceled = 4, ///<Used to indicate that the DNS resolution on the DNSResolver has been canceled.
} DNSResolverState;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
#endif // INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
/**
* @brief Type of event handling function called when a DNS request completes.
*
* @param[in] appState Application state pointer.
* @param[in] err Error code.
* @param[in] addrCount Number of IP addresses in the \c addrArray list.
* @param[in] addrArray List of addresses in the answer.
*
* @details
* Provide a function of this type to the \c Resolve method to process
* completion events.
*/
typedef void (*OnResolveCompleteFunct)(void *appState, INET_ERROR err, uint8_t addrCount, IPAddress *addrArray);
static Weave::System::ObjectPool<DNSResolver, INET_CONFIG_NUM_DNS_RESOLVERS> sPool;
/**
* A pointer to the callback function when a DNS request is complete.
*/
OnResolveCompleteFunct OnComplete;
/**
* A pointer to the DNS table that stores a list of resolved addresses.
*/
IPAddress *AddrArray;
/**
* The maximum number of addresses that could be stored in the DNS table.
*/
uint8_t MaxAddrs;
/**
* The actual number of addresses that are stored in the DNS table.
*/
uint8_t NumAddrs;
/**
* DNS options for the current request.
*/
uint8_t DNSOptions;
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
void InitAddrInfoHints(struct addrinfo & hints);
INET_ERROR ProcessGetAddrInfoResult(int returnCode, struct addrinfo * results);
void CopyAddresses(int family, uint8_t maxAddrs, const struct addrinfo * addrs);
uint8_t CountAddresses(int family, const struct addrinfo * addrs);
#if INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
/* Hostname that requires resolution */
char asyncHostNameBuf[NL_DNS_HOSTNAME_MAX_LEN + 1]; // DNS limits hostnames to 253 max characters.
INET_ERROR asyncDNSResolveResult;
/* The next DNSResolver object in the asynchronous DNS resolution queue. */
DNSResolver *pNextAsyncDNSResolver;
DNSResolverState mState;
void HandleAsyncResolveComplete(void);
#endif // INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
INET_ERROR Resolve(const char *hostName, uint16_t hostNameLen, uint8_t options,
uint8_t maxAddrs, IPAddress *addrArray,
OnResolveCompleteFunct onComplete, void *appState);
INET_ERROR Cancel(void);
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
void HandleResolveComplete(void);
#if LWIP_VERSION_MAJOR > 1
static void LwIPHandleResolveComplete(const char *name, const ip_addr_t *ipaddr, void *callback_arg);
#else // LWIP_VERSION_MAJOR <= 1
static void LwIPHandleResolveComplete(const char *name, ip_addr_t *ipaddr, void *callback_arg);
#endif // LWIP_VERSION_MAJOR <= 1
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
};
} // namespace Inet
} // namespace nl
#endif // !defined(DNSRESOLVER_H_)