diff --git a/R/RcppExports.R b/R/RcppExports.R index 04a0605..e9f09aa 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -47,7 +47,7 @@ int_get_resolvers <- function(gctx) { .Call(`_clandnstine_int_get_resolvers`, gctx) } -int_gdns_query <- function(gctx, name, rr) { - .Call(`_clandnstine_int_gdns_query`, gctx, name, rr) +int_gdns_query <- function(gctx, name, rr, include_reporting = FALSE) { + .Call(`_clandnstine_int_gdns_query`, gctx, name, rr, include_reporting) } diff --git a/R/resolver.R b/R/resolver.R index 7dadc37..d4156a2 100644 --- a/R/resolver.R +++ b/R/resolver.R @@ -1,6 +1,8 @@ #' Create a gdns DNS over TLS context and populate it with a resolver #' for use in resolution functions #' +#' @note [DNS Privacy](https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers#DNSPrivacyTestServers-DoTservers) +#' maintains a list of DNS over TLS servers. #' @param resolvers character vector of valid DNS over TLS resolvers; #' Defaults to Quad9 (`9.9.9.9`). #' @export @@ -112,15 +114,22 @@ gdns_resolver <- function(resolvers = "9.9.9.9") { #' @param gctx gdns resolver context created with [gdns_resolver()] #' @param name an entity to query for #' @param rr_type what resource record type do you want to queyr for? See `Details`. +#' @param include_reporting if `TRUE` include debugging information for queries +#' such as the length of time it takes for each query. Default: `FALSE` #' @references #' @export #' @examples #' x <- gdns_resolver() #' gdns_query(x, "example.com") -gdns_query <- function(gctx, name, rr_type = "txt") { +gdns_query <- function(gctx, name, rr_type = "txt", rr_class = 1L, + include_reporting = FALSE) { + + rr_class <- rr_class[1] + if (!rr_class %in% c(1, 3, 4, 254, 255)) rr_class <- 1 rr_type <- match.arg(trimws(tolower(rr_type[1])), names(rr_types)) - res <- int_gdns_query(gctx, name, unname(as.integer(rr_types[rr_type]))) + res <- int_gdns_query(gctx, name, unname(as.integer(rr_types[rr_type])), + as.integer(rr_class), as.logical(include_reporting)) if (length(res)) { out <- jsonlite::fromJSON(res) class(out) <- c("gdns_response", "list") diff --git a/man/gdns_query.Rd b/man/gdns_query.Rd index ffa4c8f..1b2d54e 100644 --- a/man/gdns_query.Rd +++ b/man/gdns_query.Rd @@ -4,7 +4,8 @@ \alias{gdns_query} \title{Arbitrary DNS queries} \usage{ -gdns_query(gctx, name, rr_type = "txt") +gdns_query(gctx, name, rr_type = "txt", rr_class = 1L, + include_reporting = FALSE) } \arguments{ \item{gctx}{gdns resolver context created with \code{\link[=gdns_resolver]{gdns_resolver()}}} @@ -12,6 +13,9 @@ gdns_query(gctx, name, rr_type = "txt") \item{name}{an entity to query for} \item{rr_type}{what resource record type do you want to queyr for? See \code{Details}.} + +\item{include_reporting}{if \code{TRUE} include debugging information for queries +such as the length of time it takes for each query. Default: \code{FALSE}} } \description{ Perform any valid resource record inquiry for a given name. See \code{Details}. diff --git a/man/gdns_resolver.Rd b/man/gdns_resolver.Rd index f8bee09..33681da 100644 --- a/man/gdns_resolver.Rd +++ b/man/gdns_resolver.Rd @@ -15,6 +15,10 @@ Defaults to Quad9 (\code{9.9.9.9}).} Create a gdns DNS over TLS context and populate it with a resolver for use in resolution functions } +\note{ +\href{https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers#DNSPrivacyTestServers-DoTservers}{DNS Privacy} +maintains a list of DNS over TLS servers. +} \examples{ x <- gdns_resolver() x <- gdns_resolver("1.1.1.1") diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 910ef48..1b5d582 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -71,15 +71,16 @@ BEGIN_RCPP END_RCPP } // int_gdns_query -CharacterVector int_gdns_query(SEXP gctx, std::string name, uint16_t rr); -RcppExport SEXP _clandnstine_int_gdns_query(SEXP gctxSEXP, SEXP nameSEXP, SEXP rrSEXP) { +CharacterVector int_gdns_query(SEXP gctx, std::string name, uint16_t rr, bool include_reporting); +RcppExport SEXP _clandnstine_int_gdns_query(SEXP gctxSEXP, SEXP nameSEXP, SEXP rrSEXP, SEXP include_reportingSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< SEXP >::type gctx(gctxSEXP); Rcpp::traits::input_parameter< std::string >::type name(nameSEXP); Rcpp::traits::input_parameter< uint16_t >::type rr(rrSEXP); - rcpp_result_gen = Rcpp::wrap(int_gdns_query(gctx, name, rr)); + Rcpp::traits::input_parameter< bool >::type include_reporting(include_reportingSEXP); + rcpp_result_gen = Rcpp::wrap(int_gdns_query(gctx, name, rr, include_reporting)); return rcpp_result_gen; END_RCPP } @@ -91,7 +92,7 @@ static const R_CallMethodDef CallEntries[] = { {"_clandnstine_int_gdns_resolver", (DL_FUNC) &_clandnstine_int_gdns_resolver, 1}, {"_clandnstine_gdns_get_address", (DL_FUNC) &_clandnstine_gdns_get_address, 2}, {"_clandnstine_int_get_resolvers", (DL_FUNC) &_clandnstine_int_get_resolvers, 1}, - {"_clandnstine_int_gdns_query", (DL_FUNC) &_clandnstine_int_gdns_query, 3}, + {"_clandnstine_int_gdns_query", (DL_FUNC) &_clandnstine_int_gdns_query, 4}, {NULL, NULL, 0} }; diff --git a/src/resolver.cpp b/src/resolver.cpp index 1c00e27..9fc164c 100644 --- a/src/resolver.cpp +++ b/src/resolver.cpp @@ -195,7 +195,8 @@ CharacterVector int_get_resolvers(SEXP gctx) { // [[Rcpp::export]] -CharacterVector int_gdns_query(SEXP gctx, std::string name, uint16_t rr) { +CharacterVector int_gdns_query(SEXP gctx, std::string name, uint16_t rr, + bool include_reporting = false) { uint32_t err; // size_t sz; @@ -210,7 +211,16 @@ CharacterVector int_gdns_query(SEXP gctx, std::string name, uint16_t rr) { getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx); if (gctx == NULL) return(CharacterVector()); - if ((r = getdns_general_sync(ctxt, name.c_str(), rr, NULL, &resp))) { + getdns_dict *ext_d = getdns_dict_create(); + if (include_reporting) { + getdns_dict_set_int(ext_d, "return_call_reporting", GETDNS_EXTENSION_TRUE); + } + // if (rrclass != 1) { + // getdns_dict_set_int(ext_d, "specify_class", (uint32_t)rrclass); + // } + + if ((r = getdns_general_sync(ctxt, name.c_str(), rr, ext_d, &resp))) { + Rf_warning("Bad query"); } else if ((r = getdns_dict_get_int(resp, "status", &err))) { } else if (err != GETDNS_RESPSTATUS_GOOD) { } else { @@ -229,8 +239,10 @@ CharacterVector int_gdns_query(SEXP gctx, std::string name, uint16_t rr) { } + if (ext_d) getdns_dict_destroy(ext_d); + if (resp) getdns_dict_destroy(resp); if (ok) return(wrap(out)); else return(CharacterVector()); -} +} \ No newline at end of file