No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

clandnstine-main.cpp 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. #include <Rcpp.h>
  2. #include <getdns/getdns.h>
  3. #include <getdns/getdns_extra.h>
  4. #include <arpa/inet.h>
  5. using namespace Rcpp;
  6. extern void check_is_xptr(SEXP s);
  7. //' Return gdns library version
  8. //'
  9. //' @family utlity functions
  10. //' @export
  11. // [[Rcpp::export]]
  12. std::string gdns_lib_version() {
  13. return(std::string(getdns_get_version()));
  14. }
  15. //' Internal version of gdns_update_resolvers
  16. //' @keywords internal
  17. // [[Rcpp::export]]
  18. SEXP int_gdns_update_resolvers(SEXP gctx, std::vector< std::string > resolvers) {
  19. check_is_xptr(gctx);
  20. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  21. if (gctx == NULL) return(R_NilValue);
  22. getdns_return_t r;
  23. // TODO Validate we don't need to free these
  24. getdns_dict *resolver_dict = getdns_dict_create();
  25. getdns_list *resolver_list = getdns_list_create();
  26. for (int i = 0; i<resolvers.size(); i++) {
  27. r = getdns_str2dict(resolvers[i].c_str(), &resolver_dict);
  28. r = getdns_list_set_dict(resolver_list, i, resolver_dict);
  29. }
  30. if ((r = getdns_context_set_upstream_recursive_servers(ctxt, resolver_list))) {
  31. Rf_error(getdns_get_errorstr_by_id(r));
  32. }
  33. return(gctx);
  34. }
  35. //' Specify the number of milliseconds to wait for request to return
  36. //'
  37. //' @param gctx gdns resolver context created with [gdns_resolver()]
  38. //' @param timeout number of milliseconds (integer; i.e. not-fractional)
  39. //' @family context functions
  40. //' @export
  41. // [[Rcpp::export]]
  42. SEXP gdns_set_timeout(SEXP gctx, long timeout) {
  43. check_is_xptr(gctx);
  44. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  45. if (gctx == NULL) return(CharacterVector());
  46. getdns_return_t r;
  47. if ((r = getdns_context_set_timeout(ctxt, (uint64_t)timeout))) {
  48. Rf_error(getdns_get_errorstr_by_id(r));
  49. }
  50. return(gctx);
  51. }
  52. //' Retreive the number of milliseconds to wait for request to return
  53. //'
  54. //' @param gctx gdns resolver context created with [gdns_resolver()]
  55. //' @family context functions
  56. //' @export
  57. // [[Rcpp::export]]
  58. DoubleVector gdns_get_timeout(SEXP gctx) {
  59. check_is_xptr(gctx);
  60. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  61. if (gctx == NULL) return(R_NilValue);
  62. getdns_return_t r;
  63. uint64_t timeout;
  64. if ((r = getdns_context_get_timeout(ctxt, &timeout))) {
  65. Rf_error(getdns_get_errorstr_by_id(r));
  66. }
  67. DoubleVector out(1);
  68. out[0] = (uint32_t)timeout;
  69. return(out);
  70. }
  71. //' Set/unset context to round robin queries over the available upstreams
  72. //' when resolving with the stub resolution type.
  73. //'
  74. //' @md
  75. //' @param gctx gdns resolver context created with [gdns_resolver()]
  76. //' @param flag if `TRUE` (the default) round robin queries when using more than one stub resolver,
  77. //' @family context functions
  78. //' @export
  79. // [[Rcpp::export]]
  80. SEXP gdns_set_round_robin_upstreams(SEXP gctx, bool flag=true) {
  81. check_is_xptr(gctx);
  82. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  83. if (gctx == NULL) return(R_NilValue);
  84. getdns_return_t r;
  85. if ((r = getdns_context_set_round_robin_upstreams(ctxt, flag ? 1 : 0))) {
  86. Rf_error(getdns_get_errorstr_by_id(r));
  87. }
  88. return(gctx);
  89. }
  90. //' Internal version of gdns_set_hosts()
  91. //' @keywords internal
  92. // [[Rcpp::export]]
  93. SEXP int_gdns_set_hosts(SEXP gctx, std::string hosts) {
  94. check_is_xptr(gctx);
  95. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  96. if (gctx == NULL) return(R_NilValue);
  97. getdns_return_t r;
  98. if ((r = getdns_context_set_hosts(ctxt, hosts.c_str()))) {
  99. Rf_error(getdns_get_errorstr_by_id(r));
  100. }
  101. return(gctx);
  102. }
  103. //' Internal version of set_transports()
  104. //' @keywords internal
  105. // [[Rcpp::export]]
  106. SEXP int_gdns_set_transports(SEXP gctx, IntegerVector trans) {
  107. check_is_xptr(gctx);
  108. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  109. if (gctx == NULL) return(R_NilValue);
  110. getdns_return_t r;
  111. getdns_transport_list_t tls_transport[trans.size()];
  112. for (int i=0; i<trans.size(); i++) {
  113. switch(trans[i]) {
  114. case 1200 : tls_transport[i] = GETDNS_TRANSPORT_UDP; break;
  115. case 1201 : tls_transport[i] = GETDNS_TRANSPORT_TCP; break;
  116. case 1202 : tls_transport[i] = GETDNS_TRANSPORT_TLS; break;
  117. }
  118. }
  119. if ((r = getdns_context_set_dns_transport_list(ctxt, trans.size(), tls_transport))) {
  120. Rf_error(getdns_get_errorstr_by_id(r));
  121. }
  122. return(gctx);
  123. }
  124. //' Internal version of gdns_set_resolution_type()
  125. //' @keywords internal
  126. // [[Rcpp::export]]
  127. SEXP int_gdns_set_resolution_type(SEXP gctx, int res_type) {
  128. check_is_xptr(gctx);
  129. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  130. if (gctx == NULL) return(R_NilValue);
  131. getdns_return_t r;
  132. if ((r = getdns_context_set_resolution_type(ctxt, res_type == 520 ? GETDNS_RESOLUTION_STUB : GETDNS_RESOLUTION_RECURSING))) {
  133. Rf_error(getdns_get_errorstr_by_id(r));
  134. }
  135. return(gctx);
  136. }
  137. //' Retreive what transports are used for DNS lookups.
  138. //'
  139. //' @param gctx gdns resolver context created with [gdns_resolver()]
  140. //' @family context functions
  141. //' @export
  142. // [[Rcpp::export]]
  143. CharacterVector gdns_get_transports(SEXP gctx) {
  144. check_is_xptr(gctx);
  145. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  146. if (gctx == NULL) return(R_NilValue);
  147. getdns_return_t r;
  148. size_t sz;
  149. getdns_transport_list_t *trans;
  150. if ((r = getdns_context_get_dns_transport_list(ctxt, &sz, &trans))) {
  151. Rf_error(getdns_get_errorstr_by_id(r));
  152. }
  153. CharacterVector out(sz);
  154. for (int i=0; i<sz; i++) {
  155. switch(trans[i]) {
  156. case GETDNS_TRANSPORT_UDP : out[i] = "udp"; break;
  157. case GETDNS_TRANSPORT_TCP : out[i] = "tcp"; break;
  158. case GETDNS_TRANSPORT_TLS : out[i] = "tls"; break;
  159. }
  160. }
  161. if (trans) free(trans);
  162. return(out);
  163. }
  164. //' Retreive the value of the localnames namespace
  165. //'
  166. //' @param gctx gdns resolver context created with [gdns_resolver()]
  167. //' @family context functions
  168. //' @export
  169. // [[Rcpp::export]]
  170. CharacterVector gdns_get_hosts(SEXP gctx) {
  171. check_is_xptr(gctx);
  172. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  173. if (gctx == NULL) return(R_NilValue);
  174. getdns_return_t r;
  175. const char *hosts;
  176. if ((r = getdns_context_get_hosts(ctxt, &hosts))) {
  177. Rf_error(getdns_get_errorstr_by_id(r));
  178. }
  179. return(std::string(hosts));
  180. }
  181. //' Retreive the value with which the context's upstream recursive servers and suffixes were initialized
  182. //'
  183. //' @param gctx gdns resolver context created with [gdns_resolver()]
  184. //' @family context functions
  185. //' @export
  186. // [[Rcpp::export]]
  187. CharacterVector gdns_get_resolvconf(SEXP gctx) {
  188. check_is_xptr(gctx);
  189. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  190. if (gctx == NULL) return(R_NilValue);
  191. getdns_return_t r;
  192. const char *resolv;
  193. if ((r = getdns_context_get_resolvconf(ctxt, &resolv))) {
  194. Rf_error(getdns_get_errorstr_by_id(r));
  195. }
  196. return(std::string(resolv));
  197. }
  198. //' Retreive the value with which the context's upstream recursive servers and suffixes were initialized
  199. //'
  200. //' @param gctx gdns resolver context created with [gdns_resolver()]
  201. //' @family context functions
  202. //' @export
  203. // [[Rcpp::export]]
  204. StringVector gdns_get_tls_ca_path(SEXP gctx) {
  205. check_is_xptr(gctx);
  206. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  207. if (gctx == NULL) return(R_NilValue);
  208. getdns_return_t r;
  209. const char *ca_path;
  210. if ((r = getdns_context_get_tls_ca_path(ctxt, &ca_path))) {
  211. Rf_error(getdns_get_errorstr_by_id(r));
  212. }
  213. return(ca_path ? std::string(ca_path) : CharacterVector());
  214. }
  215. //' Retreive the file location with CA certificates for verification purposes
  216. //'
  217. //' @param gctx gdns resolver context created with [gdns_resolver()]
  218. //' @family context functions
  219. //' @export
  220. // [[Rcpp::export]]
  221. StringVector gdns_get_tls_ca_file(SEXP gctx) {
  222. check_is_xptr(gctx);
  223. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  224. if (gctx == NULL) return(R_NilValue);
  225. getdns_return_t r;
  226. const char *ca_file;
  227. if ((r = getdns_context_get_tls_ca_path(ctxt, &ca_file))) {
  228. Rf_error(getdns_get_errorstr_by_id(r));
  229. }
  230. return(ca_file ? std::string(ca_file) : CharacterVector());
  231. }
  232. //' Specify where the location for CA certificates for verification purposes are located
  233. //'
  234. //' @param gctx gdns resolver context created with [gdns_resolver()]
  235. //' @param ca_path directory with Certificate Authority certificates
  236. //' @family context functions
  237. //' @export
  238. // [[Rcpp::export]]
  239. SEXP gdns_set_tls_ca_path(SEXP gctx, std::string ca_path) {
  240. check_is_xptr(gctx);
  241. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  242. if (gctx == NULL) return(R_NilValue);
  243. getdns_return_t r;
  244. if ((r = getdns_context_set_tls_ca_path(ctxt, ca_path.c_str()))) {
  245. Rf_error(getdns_get_errorstr_by_id(r));
  246. }
  247. return(gctx);
  248. }
  249. //' Specify the file with CA certificates for verification purposes
  250. //'
  251. //' @param gctx gdns resolver context created with [gdns_resolver()]
  252. //' @param ca_file file with Certificate Authority certificates
  253. //' @family context functions
  254. //' @export
  255. // [[Rcpp::export]]
  256. SEXP gdns_set_tls_ca_file(SEXP gctx, std::string ca_file) {
  257. check_is_xptr(gctx);
  258. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  259. if (gctx == NULL) return(R_NilValue);
  260. getdns_return_t r;
  261. if ((r = getdns_context_set_tls_ca_file(ctxt, ca_file.c_str()))) {
  262. Rf_error(getdns_get_errorstr_by_id(r));
  263. }
  264. return(gctx);
  265. }
  266. //' Retrieve the list of addresses in use for looking up top-level domains in use by the context.
  267. //'
  268. //' @param gctx gdns resolver context created with [gdns_resolver()]
  269. //' @keywords internal
  270. // [[Rcpp::export]]
  271. CharacterVector int_gdns_get_root_servers(SEXP gctx) {
  272. check_is_xptr(gctx);
  273. getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
  274. if (gctx == NULL) return(R_NilValue);
  275. getdns_return_t r;
  276. getdns_list *addresses;
  277. if ((r = getdns_context_get_dns_root_servers(ctxt, &addresses))) {
  278. Rf_error(getdns_get_errorstr_by_id(r));
  279. }
  280. if (addresses) {
  281. Rcout << "HERE" << std::endl;
  282. char *lst = getdns_print_json_list(addresses, 0);
  283. if (lst) {
  284. Rcout << lst << std::endl;
  285. std::string out = std::string(lst);
  286. free(lst);
  287. free(addresses);
  288. return(wrap(out));
  289. } else {
  290. free(addresses);
  291. return(CharacterVector());
  292. }
  293. } else {
  294. return(CharacterVector());
  295. }
  296. }