Commit be81c07f authored by Jan Včelák's avatar Jan Včelák 🚀

getdns API, basic cmake config

parent 47fcc12d
cmake_minimum_required(VERSION 2.8)
project(resolver C)
set(RESOLVER_VERSION 0.0.1)
set(LIBS_VERSION 0.0.1)
# Compiler flags
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type specified, setting to 'Release'.")
set(CMAKE_BUILD_TYPE "Release")
endif()
set(CMAKE_C_FLAGS "-std=gnu99 -Wall -g")
set(CMAKE_C_FLAGS_DEBUG "-O0")
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
# Modules compilation
include_directories(include)
set(resolver_sources
lib/context.c
lib/info.c
)
add_library(resolver SHARED ${resolver_sources})
set_target_properties(resolver PROPERTIES VERSION ${LIBS_VERSION})
# Knot DNS Resolver
## Compilation
mkdir _build
cd _build
cmake ..
make
Run cmake with '-DCMAKE_BUILD_TYPE=Debug' parameter to disable optimizations and enable asserts.
#pragma once
#include <stdint.h>
#include <stdlib.h>
#define GETDNS_COMPILATION_COMMENT "Knot Resolver 0.0.1"
enum getdns_return {
GETDNS_RETURN_GOOD,
GETDNS_RETURN_GENERIC_ERROR,
GETDNS_RETURN_BAD_DOMAIN_NAME,
GETDNS_RETURN_BAD_CONTEXT,
GETDNS_RETURN_CONTEXT_UPDATE_FAIL,
GETDNS_RETURN_UNKNOWN_TRANSACTION,
GETDNS_RETURN_NO_SUCH_LIST_ITEM,
GETDNS_RETURN_NO_SUCH_DICT_NAME,
GETDNS_RETURN_WRONG_TYPE_REQUESTED,
GETDNS_RETURN_NO_SUCH_EXTENSION,
GETDNS_RETURN_EXTENSION_MISFORMAT,
GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED,
GETDNS_RETURN_MEMORY_ERROR,
GETDNS_RETURN_INVALID_PARAMETER,
};
typedef enum getdns_return getdns_return_t;
enum {
/*! At least one response was retuned. */
GETDNS_RESPSTATUS_GOOD,
/*! Query for the name yielded a negative response. */
GETDNS_RESPSTATUS_NO_NAME,
/*! All queries timed out. */
GETDNS_RESPSTATUS_ALL_TIMEOUT,
/*! At least one response was retuned, but not secured by DNSSEC. */
GETDNS_RESPSTATUS_NO_SECURE_ANSWERS,
};
enum {
/*! DNS name service. */
GETDNS_NAMETYPE_DNS,
/*! WINS name service. */
GETDNS_NAMETYPE_WINS,
};
struct getdns_dict;
typedef struct getdns_dict getdns_dict;
struct getdns_list;
typedef struct getdns_list getdns_list;
struct getdns_bindata {
size_t size;
uint8_t *data;
};
typedef struct getdns_bindata getdns_bindata;
/*
* Resolution context.
*/
struct getdns_context;
typedef struct getdns_context getdns_context;
/*!
* Create a new resolution context with default values.
*
* \param[out] context Newly created context.
* \param[in] set_from_os Set some defaults from the operating system.
*/
getdns_return_t getdns_context_create(
getdns_context **context,
int set_from_os
);
/*!
* Create a new resolution context using custom memory allocator with a global context.
*
* \see getdns_context_create
*
* \param malloc Callback for \c malloc.
* \param realloc Callback for \c realloc (not actually used, can be NULL).
* \param free Callback fro \c free.
*/
getdns_return_t getdns_context_create_with_memory_functions(
getdns_context **context,
int set_from_os,
void *(*malloc)(size_t),
void *(*realloc)(void *, size_t),
void (*free)(void *)
);
/*!
* Create a new resolution context using custom memory allocator with a local context.
*
* \see getdns_context_create_with_memory_functions
*
* \param userarg Memory allocation context passed to allocation functions.
*/
getdns_return_t getdns_context_create_with_extended_memory_functions(
getdns_context **context,
int set_from_os,
void *userarg,
void *(*malloc)(void *userarg, size_t),
void *(*realloc)(void *userarg, void *, size_t),
void (*free)(void *userarg, void *)
);
/*!
* Destroy resolution context including all running transactions.
*
* Callbacks for unprocessed transactions will be called with the
* \c callback_type parameter set to \c GETDNS_CALLBACK_CANCEL.
*
* \param context Context to be destroyed.
*/
void getdns_context_destroy(getdns_context *context);
enum getdns_context_code {
GETDNS_CONTEXT_CODE_NAMESPACES,
GETDNS_CONTEXT_CODE_RESOLUTION_TYPE,
GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS,
GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS,
GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS,
GETDNS_CONTEXT_CODE_DNS_TRANSPORT,
GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES,
GETDNS_CONTEXT_CODE_APPEND_NAME,
GETDNS_CONTEXT_CODE_SUFFIX,
GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS,
GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE,
GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE,
GETDNS_CONTEXT_CODE_EDNS_VERSION,
GETDNS_CONTEXT_CODE_EDNS_DO_BIT,
GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW,
GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS,
GETDNS_CONTEXT_CODE_TIMEOUT,
};
typedef enum getdns_context_code getdns_context_code_t;
/*!
* Set callback to notify the application when the resolution context changes.
*
* \param context Resolution context.
* \param value Callback to be used when the context changes (use NULL to clear).
*
* \retval GETDNS_RETURN_GOOD
* \retval GETDNS_RETURN_CONTEXT_UPDATE_FAIL
*/
getdns_return_t getdns_context_set_context_update_callback(
getdns_context *context,
void (*value)(getdns_context *context, getdns_context_code_t changed_item)
);
enum getdns_resolution {
GETDNS_RESOLUTION_RECURSING, // default
GETDNS_RESOLUTION_STUB,
};
typedef enum getdns_resolution getdns_resolution_t;
/*!
* Set resolution type.
*
* \retval GETDNS_RETURN_GOOD
* \retval GETDNS_RETURN_CONTEXT_UPDATE_FAIL
*/
getdns_return_t getdns_context_set_resolution_type(
getdns_context *context,
getdns_resolution_t value
);
enum getdns_namespace {
GETDNS_NAMESPACE_DNS,
GETDNS_NAMESPACE_LOCALNAMES,
GETDNS_NAMESPACE_NETBIOS,
GETDNS_NAMESPACE_MDNS,
GETDNS_NAMESPACE_NIS,
};
typedef enum getdns_namespace getdns_namespace_t;
/*!
* Set ordered list of namespaces that will be queried.
*
* \note Ignored by \c getdns_general and \c getdns_general_sync.
*/
getdns_return_t getdns_context_set_namespaces(
getdns_context *context,
size_t namespace_count,
getdns_namespace_t *namespaces
);
enum getdns_transport {
GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP, // default
GETDNS_TRANSPORT_UDP_ONLY,
GETDNS_TRANSPORT_TCP_ONLY,
GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN
};
typedef enum getdns_transport getdns_transport_t;
/*!
* Set a transport to be used for the resolutions.
*/
getdns_return_t getdns_context_set_dns_transport(
getdns_context *context,
getdns_transport_t value
);
/*!
* Set maximum number of queries being processed.
*
* \param limit Limit of outstanding queries. Zero indicates no limit.
*/
getdns_return_t getdns_context_set_limit_outstanding_queries(
getdns_context *context,
uint16_t limit
);
enum getdns_redirects {
GETDNS_REDIRECTS_FOLLOW, // default
GETDNS_REDIRECTS_DO_NOT_FOLLOW
};
typedef enum getdns_redirects getdns_redirects_t;
/*!
* Set if the CNAME and DNAME redirects should be followed.
*/
getdns_return_t getdns_context_set_follow_redirects(
getdns_context *context,
getdns_redirects_t value
);
/*!
* Set the servers for top-level domain lookup.
*
* [
* { "address_type": "IPv4", "address_data": <bindata ...> },
* { "address_type": "IPv6", "address_data": <bindata ...> },
* ...
* ]
*
*/
getdns_return_t getdns_context_set_dns_root_servers(
getdns_context *context,
getdns_list *addresses
);
enum getdns_append_name {
GETDNS_APPEND_NAME_ALWAYS, // default
GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE,
GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE,
GETDNS_APPEND_NAME_NEVER
};
typedef enum getdns_append_name getdns_append_name_t;
/*!
* Set a mode of appending a suffix to queried names.
*
* \see getdns_context_set_suffix
*/
getdns_return_t getdns_context_set_append_name(
getdns_context *context,
getdns_append_name_t value
);
/*!
* Set a list of strings to be appended to queries.
*
* \see getdns_context_set_append_mode
*/
getdns_return_t getdns_context_set_suffix(
getdns_context *context,
getdns_list *value
);
/*!
* Set DNSSEC trust anchors for queries with DNSSEC extension.
*
* \param context Resolution context.
* \param value List of RDATA (bindata) of trusted DNSKEYs.
*/
getdns_return_t getdns_context_set_dnssec_trust_anchors(
getdns_context *context,
getdns_list *value
);
/*!
* Set number of seconds of skew to allow when checking DNSSEC signatures.
*/
getdns_return_t getdns_context_set_dnssec_allowed_skew(
getdns_context *context,
uint32_t value
);
/*!
* Set upstream recursive server for stub resolution mode.
*
* \see getdns_context_set_resolution_type
*
* [
* { "address_type": "IPv4", "address_data": <bindata ...> },
* { "address_type": "IPv6", "address_data": <bindata ...>, "port": 5353,
* "tsig_algorithm": <bindata ...>, "tsig_secret": <bindata ...> },
* ...
* ]
*/
getdns_return_t getdns_context_set_upstream_recursive_servers(
getdns_context *context,
getdns_list *upstream_list
);
/*!
* Set EDNS maximum UDP payload size.
*
* \param value Maximum payload size (512-65535, default 512).
*/
getdns_return_t getdns_context_set_edns_maximum_udp_payload_size(
getdns_context *context,
uint16_t value
);
/*!
* Set EDNS extended RCODE.
*
* \param value Extended RCODE (default 0).
*/
getdns_return_t getdns_context_set_edns_extended_rcode(
getdns_context *context,
uint8_t value
);
/*!
* Set EDNS version.
*
* \param value EDNS version (default 0).
*/
getdns_return_t getdns_context_set_edns_version(
getdns_context *context,
uint8_t value
);
/*!
* Set EDNS DO (DNSSEC OK) bit.
*
* \param value EDNS DO bit (0 or 1, default 0).
*/
getdns_return_t getdns_context_set_edns_do_bit(
getdns_context *context,
uint8_t value
);
/*!
* Set memory allocation functions with a global context.
*/
getdns_return_t getdns_context_set_memory_functions(
getdns_context *context,
void *(*malloc) (size_t),
void *(*realloc) (void *, size_t),
void (*free) (void *)
);
/*!
* Set memory allocation functions with a local context.
*/
getdns_return_t getdns_context_set_extended_memory_functions(
getdns_context *context,
void *userarg,
void *(*malloc)(void *userarg, size_t sz),
void *(*realloc)(void *userarg, void *ptr, size_t sz),
void (*free)(void *userarg, void *ptr)
);
/*!
* Get information about the implementation.
*/
getdns_dict *getdns_context_get_api_information(getdns_context *context);
/*
* Data structures.
*
* GETDNS_RETURN_GOOD Success.
* GETDNS_RETURN_NO_SUCH_LIST_ITEM Index argument out of range.
* GETDNS_RETURN_NO_SUCH_DICT_NAME Name argument does not exist.
* GETDNS_RETURN_WRONG_TYPE_REQUESTED Requested data type does not match the content.
*/
enum getdns_data_type {
t_dict,
t_list,
t_int,
t_bindata
};
typedef enum getdns_data_type getdns_data_type;
/* Lists: get the length, get the data_type of the value at a given
position, and get the data at a given position */
// writing lists (the lists are extended by setting index to size of the list)
getdns_list *getdns_list_create(void);
getdns_list *getdns_list_create_with_context(getdns_context *context);
getdns_list *getdns_list_create_with_memory_functions(
void *(*malloc)(size_t),
void *(*realloc)(void *, size_t),
void (*free)(void *)
);
getdns_list *getdns_list_create_with_extended_memory_functions(
void *userarg,
void *(*malloc)(void *userarg, size_t),
void *(*realloc)(void *userarg, void *, size_t),
void (*free)(void *userarg, void *)
);
void getdns_list_destroy(getdns_list *this_list);
getdns_return_t getdns_list_set_dict(
getdns_list *this_list,
size_t index,
const getdns_dict *child_dict
);
getdns_return_t getdns_list_set_list(
getdns_list *this_list,
size_t index,
const getdns_list *child_list
);
getdns_return_t getdns_list_set_bindata(
getdns_list *this_list,
size_t index,
const getdns_bindata *child_bindata
);
getdns_return_t getdns_list_set_int(
getdns_list *this_list,
size_t index,
uint32_t child_uint32
);
// reading lists
getdns_return_t getdns_list_get_length(
const getdns_list *this_list,
size_t *answer
);
getdns_return_t getdns_list_get_data_type(
const getdns_list *this_list,
size_t index,
getdns_data_type *answer
);
getdns_return_t getdns_list_get_dict(
const getdns_list *this_list,
size_t index,
getdns_dict **answer
);
getdns_return_t getdns_list_get_list(
const getdns_list *this_list,
size_t index,
getdns_list **answer
);
getdns_return_t getdns_list_get_bindata(
const getdns_list *this_list,
size_t index,
getdns_bindata **answer
);
getdns_return_t getdns_list_get_int(
const getdns_list *this_list,
size_t index,
uint32_t *answer
);
/* Dicts: get the list of names, get the data_type of the
value at a given name, and get the data at a given name */
// writing dicts (extended by setting non-existent name)
getdns_dict *getdns_dict_create();
getdns_dict *getdns_dict_create_with_context(getdns_context *context);
getdns_dict *getdns_dict_create_with_memory_functions(
void *(*malloc)(size_t),
void *(*realloc)(void *, size_t),
void (*free)(void *)
);
getdns_dict *getdns_dict_create_with_extended_memory_functions(
void *userarg,
void *(*malloc)(void *userarg, size_t),
void *(*realloc)(void *userarg, void *, size_t),
void (*free)(void *userarg, void *)
);
void getdns_dict_destroy(getdns_dict *this_dict);
getdns_return_t getdns_dict_set_dict(
getdns_dict *this_dict,
const char *name,
const getdns_dict *child_dict
);
getdns_return_t getdns_dict_set_list(
getdns_dict *this_dict,
const char *name,
const getdns_list *child_list
);
getdns_return_t getdns_dict_set_bindata(
getdns_dict *this_dict,
const char *name,
const getdns_bindata *child_bindata
);
getdns_return_t getdns_dict_set_int(
getdns_dict *this_dict,
const char *name,
uint32_t child_uint32
);
getdns_return_t getdns_dict_remove_name(
getdns_dict *this_dict,
const char *name
);
// reading dicts
getdns_return_t getdns_dict_get_names(
const getdns_dict *this_dict,
getdns_list **answer
);
getdns_return_t getdns_dict_get_data_type(
const getdns_dict *this_dict,
const char *name,
getdns_data_type *answer
);
getdns_return_t getdns_dict_get_dict(
const getdns_dict *this_dict,
const char *name,
getdns_dict **answer
);
getdns_return_t getdns_dict_get_list(
const getdns_dict *this_dict,
const char *name,
getdns_list **answer
);
getdns_return_t getdns_dict_get_bindata(
const getdns_dict *this_dict,
const char *name,
getdns_bindata **answer
);
getdns_return_t getdns_dict_get_int(
const getdns_dict *this_dict,
const char *name,
uint32_t *answer
);
// helper functions
/*!
* Get textual representation of a dictionary.
*
* \return Dictionary in printable format. Deallocate with \c free.
*/
char *getdns_pretty_print_dict(const getdns_dict *some_dict);
/*
* Callback Functions
*/
typedef uint64_t getdns_transaction_t;
enum getdns_callback_type {
GETDNS_CALLBACK_COMPLETE, /*!< The response contains requested data. */
GETDNS_CALLBACK_CANCEL, /*!< The resolution was cancelled, response is NULL. */
GETDNS_CALLBACK_TIMEOUT, /*!< The resolution timed out. */
GETDNS_CALLBACK_ERROR, /*!< The resolutiion failed with an error. */
};
typedef enum getdns_callback_type getdns_callback_type_t;
/*!
* Callback function definition.
*
* \param context Resolution context.
* \param callback_type Reason for the callback.
* \param response An object with a response data. The object must be
* destroyed by the application (\ref getdns_dict_destroy).
* \param userarg User defined argument.
* \param tranasction_id Identifier of the transaction.
*
*/
typedef void (*getdns_callback_t)(
getdns_context *context,
getdns_callback_type_t callback_type,
getdns_dict *response,
void *userarg,
getdns_transaction_t transaction_id
);
/*!
* Cancel outstanding callback.
*
* The cancelation will cause the resolution callback to be called with the
* \c callback_type parameter set to \c GETDNS_CALLBACK_CANCEL.
*
* \param context Resolution context.
* \param transaction_id Identifier of the transaction.
*
* \retval GETDNS_RETURN_GOOD The transaction was cancelled.
* \retval GETDNS_RETURN_UNKNOWN_TRANSACTION The transaction is invalid or
* the was already processed.
*/
getdns_return_t getdns_cancel_callback(
getdns_context *context,
getdns_transaction_t transaction_id
);
/*
* Async Functions
*/
/*!
* Perform an asynchronous DNS resolution.
*
* \param[in] context Resolution context.
* \param[in] name ASCII domain name or IP address.
* \param[in] request_type RR type for the query.
* \param[in] extensions Extensions for the request (can be NULL).
* \param[in] userarg User data passed to callback function.
* \param[out] transaction_id Non-zero identifier of the transaction (can be
* NULL, set to zero on error).
* \param[in] callbackfn Callback function to process the result.
*
* \return Error code.
* \retval GETDNS_RETURN_GOOD The call was properly formatted.
* \retval GETDNS_RETURN_BAD_DOMAIN_NAME The domain name is invalid.
* \retval GETDNS_RETURN_BAD_CONTEXT The context is invalid.
* \retval GETDNS_RETURN_NO_SUCH_EXTENSION One or more extensions do not exist.
* \retval GETDNS_RETURN_EXTENSION_MISFORMAT Content of one or more extensions is incorrect.
*/
getdns_return_t getdns_general(
getdns_context *context,
const char *name,
uint16_t request_type,
getdns_dict *extensions,
void *userarg,
getdns_transaction_t *transaction_id,
getdns_callback_t callbackfn
);
/*!
* Perform an asynchronous hostname-to-address resolution.
*
* \see getdns_general
*
* The \c name parameter can be only a host name.
* The \c return_both_v4_and_v6 extension is set by default.
* The function uses all namespaces from the context.
*/
getdns_return_t getdns_address(
getdns_context *context,
const char *name,
getdns_dict *extensions,
void *userarg,
getdns_transaction_t *transaction_id,
getdns_callback_t callbackfn
);
/*!
* Perform an asynchronous address-to-hostname resolution.
*
* \see getdns_general
*
* Address is given as a dictionary with two names:
* * \c address_type (binary, "IPv4" or "IPv6" case sensitive string)
* * \c address_data (binary, address)
*/
getdns_return_t getdns_hostname(
getdns_context *context,
getdns_dict *address,
getdns_dict *extensions,
void *userarg,
getdns_transaction_t *transaction_id,
getdns_callback_t callbackfn
);
/*!
* Perform an asynchronous SRV lookup.
*
* \see getdns_general
*
* \c name must be a domain name.
*/
getdns_return_t getdns_service(
getdns_context *context,
const char *name,
getdns_dict *extensions,
void *userarg,
getdns_transaction_t *transaction_id,
getdns_callback_t callbackfn
);
/*
* Synchronous API.
*/
/*!
* Perform a synchronous DNS resolution.
*
* \see getdns_general
*
* \param[out] response Result of the resolution.
*/
getdns_return_t getdns_general_sync(
getdns_context *context,
const char *name,
uint16_t request_type,