aboutsummaryrefslogtreecommitdiff
path: root/src/resolv.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolv.h')
-rw-r--r--src/resolv.h250
1 files changed, 203 insertions, 47 deletions
diff --git a/src/resolv.h b/src/resolv.h
index 352da48..f823410 100644
--- a/src/resolv.h
+++ b/src/resolv.h
@@ -1,3 +1,7 @@
+/** \file
+ * \brief The resolv worker
+ * \note Open RFC 1035 now!
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -26,8 +30,9 @@
#include <mbedtls/ctr_drbg.h>
+/* Alias and forward declarations */
struct prne_resolv;
-typedef struct prne_resolv prne_resolv_t;
+typedef struct prne_resolv prne_resolv_t; // The instance handle type (opaque)
typedef struct prne_resolv_ns_pool prne_resolv_ns_pool_t;
struct prne_resolv_prm;
@@ -36,59 +41,88 @@ struct prne_resolv_rr;
typedef struct prne_resolv_prm prne_resolv_prm_t;
typedef struct prne_resolv_fut prne_resolv_fut_t;
typedef struct prne_resolv_rr prne_resolv_rr_t;
-typedef uint16_t prne_resolv_rcode_t;
+typedef uint16_t prne_resolv_rcode_t; // The type for DNS return codes
+// The query operation result
typedef enum {
- PRNE_RESOLV_QR_NONE = -1,
+ PRNE_RESOLV_QR_NONE = -1, // Null value
- PRNE_RESOLV_QR_OK,
- PRNE_RESOLV_QR_ERR,
- PRNE_RESOLV_QR_PRO_ERR,
- PRNE_RESOLV_QR_FIN,
- PRNE_RESOLV_QR_IMPL,
- PRNE_RESOLV_QR_TIMEOUT,
- PRNE_RESOLV_QR_STATUS,
+ PRNE_RESOLV_QR_OK, // Operation successful
+ PRNE_RESOLV_QR_ERR, // Error occurred (errno set)
+ PRNE_RESOLV_QR_PRO_ERR, // Protocol error
+ PRNE_RESOLV_QR_FIN, // prne_fin_worker() called whilst processing query
+ PRNE_RESOLV_QR_IMPL, // Failed due to implementation's limitation
+ PRNE_RESOLV_QR_TIMEOUT, // Query timed out
+ PRNE_RESOLV_QR_STATUS, // RCODE other than zero returned
- NB_PRNE_RESOLV
+ NB_PRNE_RESOLV // Meta value: the number of enums excluding the null value
} prne_resolv_qr_t;
+// The record type
typedef enum {
- PRNE_RESOLV_QT_NONE = -1,
+ PRNE_RESOLV_QT_NONE = -1, // Null value
- PRNE_RESOLV_QT_A,
- PRNE_RESOLV_QT_AAAA,
- PRNE_RESOLV_QT_TXT,
+ PRNE_RESOLV_QT_A, // A record
+ PRNE_RESOLV_QT_AAAA, // AAAA record
+ PRNE_RESOLV_QT_TXT, // TXT record
+ // Meta value: the number of enums excluding the null value
NB_PRNE_RESOLV_QT
} prne_resolv_query_type_t;
+// The name server pool object
struct prne_resolv_ns_pool {
- prne_net_endpoint_t *arr;
- size_t cnt;
+ prne_net_endpoint_t *arr; // The pointer to the array of name servers
+ size_t cnt; // The number of elements in the array
+ /*
+ * True if the object has the responsibility of freeing the dynamically
+ * allocated members
+ */
bool ownership;
};
+// The query operation promise object
struct prne_resolv_prm {
- void *ctx;
- prne_resolv_fut_t *fut;
+ void *ctx; // The opaque context
+ prne_resolv_fut_t *fut; // The future object
};
+/**
+ * \brief The query operation future object
+ * \note The life span of the future object is independent of the life span of
+ * the promise object
+ */
struct prne_resolv_fut {
- size_t rr_cnt;
- prne_resolv_rr_t *rr;
- int err;
- prne_resolv_qr_t qr;
- prne_resolv_rcode_t status;
+ size_t rr_cnt; // The number of resource records
+ prne_resolv_rr_t *rr; // The pointer to the array of resource records
+ int err; // errno occurred whilst processing the query
+ prne_resolv_qr_t qr; // The query result code
+ prne_resolv_rcode_t status; // The returned query status code
};
+// The query resource record
struct prne_resolv_rr {
+ /*
+ * The name of the record, the lengths of the labels replaced with the
+ * character '.'. This means that the names will look like this:
+ * "www.example.com."
+ */
char *name;
- uint16_t rr_class, rr_type;
- uint32_t rr_ttl;
+ uint16_t
+ rr_class, // The resource record class (1, the internet)
+ rr_type; // The resource type (not prne_resolv_query_type_t)
+ uint32_t rr_ttl; // The TTL value of the record
+ // The pointer to the binary data, including the preceeding length byte
uint8_t *rd_data;
- uint16_t rd_len;
+ uint16_t rd_len; // The byte length of the binary data
};
+/* The IPv4 addresses of the popular public name servers for use in array
+ * initialiser lists.
+ * Note that the byte length of these addresses are 16 bytes so that they can be
+ * used to initialise prne_ip_addr_t. You may to ignore the last 12 bytes by
+ * explicitly declaring the size of the array.
+ */
#define PRNE_RESOLV_NS_IPV4_GOOGLE_A \
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
@@ -113,6 +147,7 @@ struct prne_resolv_rr {
#define PRNE_RESOLV_NS_IPV4_CLEANBROWSING_B \
0xb9, 0xe4, 0xa9, 0x09, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+// The concatenated byte array of the name servers above
#define PRNE_RESOLV_NS_POOL_IPV4 {\
PRNE_RESOLV_NS_IPV4_GOOGLE_A,\
PRNE_RESOLV_NS_IPV4_GOOGLE_B,\
@@ -124,6 +159,9 @@ struct prne_resolv_rr {
PRNE_RESOLV_NS_IPV4_CLEANBROWSING_B\
}
+/* The IPv6 addresses of the popular public name servers for use in array
+ * initialiser lists.
+ */
#define PRNE_RESOLV_NS_IPV6_GOOGLE_A \
0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88
@@ -148,6 +186,7 @@ struct prne_resolv_rr {
#define PRNE_RESOLV_NS_IPV6_CLEANBROWSING_B \
0x2a, 0x0d, 0x2a, 0x00, 0x00, 0x02, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02
+// The concatenated byte array of the name servers above
#define PRNE_RESOLV_NS_POOL_IPV6 {\
PRNE_RESOLV_NS_IPV6_GOOGLE_A,\
PRNE_RESOLV_NS_IPV6_GOOGLE_B,\
@@ -159,60 +198,177 @@ struct prne_resolv_rr {
PRNE_RESOLV_NS_IPV6_CLEANBROWSING_B\
}
-/* Default Nameserver Pools
-*
-* For testing only. Referencing these will increase the size of the binary.
-*/
+/* The default name server pools
+ * These are for testing purposes only. Referencing these variables will
+ * increase the size of the binary significantly as IPv4 addresses are not
+ * stored as a series of 4-byte-elements.
+ */
extern const prne_resolv_ns_pool_t PRNE_RESOLV_DEF_IPV4_POOL;
extern const prne_resolv_ns_pool_t PRNE_RESOLV_DEF_IPV6_POOL;
-// honor bind-utils' choice of words
-#define PRNE_RESOLV_RCODE_NOERROR 0
-#define PRNE_RESOLV_RCODE_FORMERR 1
-#define PRNE_RESOLV_RCODE_SERVFAIL 2
-#define PRNE_RESOLV_RCODE_NXDOMAIN 3
-#define PRNE_RESOLV_RCODE_NOTIMP 4
-#define PRNE_RESOLV_RCODE_REFUSED 5
-
-#define PRNE_RESOLV_RTYPE_A 1
-#define PRNE_RESOLV_RTYPE_NS 2
-#define PRNE_RESOLV_RTYPE_CNAME 5
-#define PRNE_RESOLV_RTYPE_SOA 6
-#define PRNE_RESOLV_RTYPE_PTR 12
-#define PRNE_RESOLV_RTYPE_MX 15
-#define PRNE_RESOLV_RTYPE_TXT 16
-#define PRNE_RESOLV_RTYPE_AAAA 28
+/* The response codes as per RFC 1035 4.1.1
+ * bind-utils' choice of words are honoured.
+ */
+#define PRNE_RESOLV_RCODE_NOERROR 0 // No error condition
+#define PRNE_RESOLV_RCODE_FORMERR 1 // Format error
+#define PRNE_RESOLV_RCODE_SERVFAIL 2 // Server failure
+#define PRNE_RESOLV_RCODE_NXDOMAIN 3 // Name Error
+#define PRNE_RESOLV_RCODE_NOTIMP 4 // Not Implemented
+#define PRNE_RESOLV_RCODE_REFUSED 5 // Refused
+// The DNS record types as per RFC 1035 3.2.2 and RFC 3596
+#define PRNE_RESOLV_RTYPE_A 1 // A host address
+#define PRNE_RESOLV_RTYPE_NS 2 // An authoritive name server
+#define PRNE_RESOLV_RTYPE_CNAME 5 // The canonical name for an alias
+// Marks the start of a zone of authority
+#define PRNE_RESOLV_RTYPE_SOA 6
+#define PRNE_RESOLV_RTYPE_PTR 12 // A domain name pointer
+#define PRNE_RESOLV_RTYPE_MX 15 // Mail exchange
+#define PRNE_RESOLV_RTYPE_TXT 16 // text strings
+#define PRNE_RESOLV_RTYPE_AAAA 28 // A host address (IPv6)
+/**
+ * \brief Allocate resources and start an instance of the resolv worker
+ * \param wkr The initialised worker object
+ * \param ctr_drbg The CTR DRBG object for SSL connections. The object has to be
+ * valid until the worker is freed.
+ * \param pool_v4 The IPv4 name server pool
+ * \param pool_v6 The IPv6 name server pool
+ * \return A handle to the instasnce
+ * \retval NULL with \c errno set to \c EINVAL if \p wkr or \p ctr_drbg is
+ * passed NULL, or one of the name server pools is empty
+ * \retval NULL with \c errno set to \c ENOMEM on memory allocation error
+ */
prne_resolv_t *prne_alloc_resolv (
prne_worker_t *wkr,
mbedtls_ctr_drbg_context *ctr_drbg,
const prne_resolv_ns_pool_t pool_v4,
const prne_resolv_ns_pool_t pool_v6);
+/**
+ * \brief Queue A or AAAA query
+ * \param ctx The worker handle
+ * \param name The domain name of the host
+ * \param ipv The Internet Protocol version. \c PRNE_IPV_4 for A and
+ * \c PRNE_IPV_6 for AAAA.
+ * \param cv The condition variable for result notification. The objects must be
+ * valid until \p out is freed (optional)
+ * \param out The poiner to an instance of the query operation promise object
+ * \retval true on success
+ * \retval false with \c errno set to \c ECANCELED if the worker is finalising
+ * \retval false with \c errno set to \c ENOMEM on memory allocation error
+ * \note \p out is freed using \c prne_resolv_free_prm() before being set up by
+ * the function. Therefore, the object has to be initialised using
+ * \c prne_resolv_init_prm()
+ */
bool prne_resolv_prm_gethostbyname (
prne_resolv_t *ctx,
const char *name,
const prne_ipv_t ipv,
prne_pth_cv_t *cv,
prne_resolv_prm_t *out);
+/**
+ * \brief Queue TXT query
+ * \param ctx The worker handle
+ * \param name The domain name of the host
+ * \param cv The condition variable for result notification. The objects must be
+ * valid until \p out is freed (optional)
+ * \param out The poiner to an instance of the query operation promise object
+ * \retval true on success
+ * \retval false with \c errno set to \c ECANCELED if the worker is finalising
+ * \retval false with \c errno set to \c ENOMEM on memory allocation error
+ * \note \p out is freed using \c prne_resolv_free_prm() before being set up by
+ * the function. Therefore, the object has to be initialised using
+ * \c prne_resolv_init_prm()
+ */
bool prne_resolv_prm_gettxtrec (
prne_resolv_t *ctx,
const char *name,
prne_pth_cv_t *cv,
prne_resolv_prm_t *out);
+/**
+ * \brief Initialise the name server pool object
+ * \note Initialises the members of \p pool to initial values. Prepares \p pool
+ * so that it can be freed using \c prne_resolv_free_ns_pool()
+ */
void prne_resolv_init_ns_pool (prne_resolv_ns_pool_t *pool);
+/**
+ * \brief Free the resources allocated for the name server pool object
+ * \param pool The pointer to the object that has been initialised using
+ * \c prne_resolv_init_ns_pool()
+ */
void prne_resolv_free_ns_pool (prne_resolv_ns_pool_t *pool);
+/**
+ * \brief Allocate memory for the name server pool object
+ * \param pool The pointer to the object
+ * \param cnt The new number of elements
+ * \return true on successful allocation
+ * \return false on failure and \c errno set to \c ENOMEM
+ */
bool prne_resolv_alloc_ns_pool (prne_resolv_ns_pool_t *pool, const size_t cnt);
+/**
+ * \brief Make a shallow copy of the name server pool object with the specified
+ * ownership flag. This is a convenience function for making shallow copy of
+ * the object that is shared with the multiple instances of the resolv worker
+ * \param pool The source object
+ * \param ownership The ownership flag of the new copy
+ * \return The new shallow copy
+ */
prne_resolv_ns_pool_t prne_resolv_own_ns_pool(
const prne_resolv_ns_pool_t *pool,
const bool ownership);
+/**
+ * \brief Initialise the query operation promise object
+ * \note Initialises the members of \p prm to initial values. Prepares \p prm so
+ * that it can be freed using \c prne_resolv_free_prm()
+ */
void prne_resolv_init_prm (prne_resolv_prm_t *prm);
+/**
+ * \brief Free the resources allocated for the query operation promise object
+ * \param prm The pointer to the object that has been initialised using
+ * \c prne_resolv_init_prm()
+ */
void prne_resolv_free_prm (prne_resolv_prm_t *prm);
+/**
+ * \brief Initialise the query operation future object
+ * \note Initialises the members of \p fut to initial values. Prepares \p fut so
+ * that it can be freed using \c prne_free_resolv_fut()
+ */
void prne_init_resolv_fut (prne_resolv_fut_t *fut);
+/**
+ * \brief Free the resources allocated for the query operation future object
+ * \param fut The pointer to the object that has been initialised using
+ * \c prne_init_resolv_fut()
+ */
void prne_free_resolv_fut (prne_resolv_fut_t *fut);
+/**
+ * \brief Initialise the query resource record
+ * \note Initialises the members of \p rr to initial values. Prepares \p rr so
+ * that it can be freed using \c prne_free_resolv_rr()
+ */
void prne_init_resolv_rr (prne_resolv_rr_t *rr);
+/**
+ * \brief Free the resources allocated for the query resource record
+ * \param rr The pointer to the object that has been initialised using
+ * \c prne_init_resolv_rr()
+ */
void prne_free_resolv_rr (prne_resolv_rr_t *rr);
+
+/**
+ * \brief Convert the enum value to a string
+ * \return The pointer to the string from the read-only static string pool.
+ * \retval NULL if \p qr is out of bounds and \c errno set to \c EINVAL
+ */
const char *prne_resolv_qr_tostr (const prne_resolv_qr_t qr);
+/**
+ * \brief Convert the enum value to a string
+ * \return The pointer to the string from the read-only static string pool.
+ * \retval NULL if \p rc is out of bounds and \c errno set to \c EINVAL
+ */
const char *prne_resolv_rcode_tostr (const prne_resolv_rcode_t rc);
+/**
+ * \brief Convert the enum value to a string
+ * \return The pointer to the string from the read-only static string pool.
+ * \retval NULL if \p rrt is out of bounds and \c errno set to \c EINVAL
+ */
const char *prne_resolv_rrtype_tostr (const uint16_t rrt);