boB Rudis преди 10 месеца
родител
ревизия
b99cffd36c
No known key found for this signature in database
променени са 21 файла, в които са добавени 586 реда и са изтрити 169 реда
  1. 0
    1
      DESCRIPTION
  2. 2
    2
      NAMESPACE
  3. 13
    19
      R/RcppExports.R
  4. 88
    0
      R/aaa.R
  5. 1
    1
      R/clandnstine-package.R
  6. 7
    2
      R/print-context.R
  7. 128
    0
      R/resolver.R
  8. 28
    7
      README.Rmd
  9. 54
    18
      README.md
  10. 1
    0
      man/check_is_xptr.Rd
  11. 1
    0
      man/clandnstine.Rd
  12. 11
    0
      man/gdns_lib_version.Rd
  13. 115
    0
      man/gdns_query.Rd
  14. 4
    3
      man/gdns_resolver.Rd
  15. 0
    21
      man/get_address.Rd
  16. 12
    0
      man/int_gdns_resolver.Rd
  17. 1
    0
      man/is_null_xptr_.Rd
  18. 25
    13
      src/RcppExports.cpp
  19. 25
    68
      src/clandnstine-main.cpp
  20. 50
    12
      src/resolver.cpp
  21. 20
    2
      tests/testthat/test-clandnstine.R

+ 0
- 1
DESCRIPTION Целия файл

@@ -21,7 +21,6 @@ Suggests:
21 21
 Depends:
22 22
     R (>= 3.2.0)
23 23
 Imports:
24
-    httr,
25 24
     jsonlite,
26 25
     Rcpp,
27 26
     magrittr

+ 2
- 2
NAMESPACE Целия файл

@@ -3,9 +3,9 @@
3 3
 S3method(print,gctx)
4 4
 export("%>%")
5 5
 export(gdns_get_address)
6
+export(gdns_lib_version)
7
+export(gdns_query)
6 8
 export(gdns_resolver)
7
-export(get_address)
8
-import(httr)
9 9
 importFrom(Rcpp,sourceCpp)
10 10
 importFrom(jsonlite,fromJSON)
11 11
 importFrom(magrittr,"%>%")

+ 13
- 19
R/RcppExports.R Целия файл

@@ -1,22 +1,17 @@
1 1
 # Generated by using Rcpp::compileAttributes() -> do not edit by hand
2 2
 # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
3 3
 
4
-#' Lookup IP Address(es) for a Given Host
4
+#' Return gdns library version
5 5
 #'
6
-#' @param host host (length 1 <chr>)
7
-#' @param resolver resolver address. defaults to Quad9; (length 1 <chr>)
8 6
 #' @export
9
-#' @examples
10
-#' get_address("r-project.org")
11
-#' get_address("yahoo.com", "1.1.1.1")
12
-#' get_address("microsoft.com", "8.8.8.8")
13
-get_address <- function(host, resolver = "9.9.9.9") {
14
-    .Call(`_clandnstine_get_address`, host, resolver)
7
+gdns_lib_version <- function() {
8
+    .Call(`_clandnstine_gdns_lib_version`)
15 9
 }
16 10
 
17 11
 #' Test whether an object is an external pointer
18 12
 #'
19 13
 #' @param x object to test
14
+#' @keywords internal
20 15
 check_is_xptr <- function(s) {
21 16
     invisible(.Call(`_clandnstine_check_is_xptr`, s))
22 17
 }
@@ -24,20 +19,15 @@ check_is_xptr <- function(s) {
24 19
 #' Test whether an external pointer is null
25 20
 #'
26 21
 #' @param x object to test
22
+#' @keywords internal
27 23
 is_null_xptr_ <- function(s) {
28 24
     .Call(`_clandnstine_is_null_xptr_`, s)
29 25
 }
30 26
 
31
-#' Create a gdns DNS over TLS context and populate it with a resolver
32
-#' for use in resolution functions
33
-#'
34
-#' @param resolver length 1 <chr> of a valid DNS over TLS resolver;
35
-#'        Defaults to Quad9 (`9.9.9.9`).
36
-#' @export
37
-#' @examples
38
-#' x <- gdns_resolver()
39
-gdns_resolver <- function(resolver = "9.9.9.9") {
40
-    .Call(`_clandnstine_gdns_resolver`, resolver)
27
+#' Internal version of gdns_resolver
28
+#' @keywords internal
29
+int_gdns_resolver <- function(resolvers) {
30
+    .Call(`_clandnstine_int_gdns_resolver`, resolvers)
41 31
 }
42 32
 
43 33
 #' Resolve a host to an addrss
@@ -57,3 +47,7 @@ int_get_resolvers <- function(gctx) {
57 47
     .Call(`_clandnstine_int_get_resolvers`, gctx)
58 48
 }
59 49
 
50
+int_gdns_query <- function(gctx, name, rr) {
51
+    .Call(`_clandnstine_int_gdns_query`, gctx, name, rr)
52
+}
53
+

+ 88
- 0
R/aaa.R Целия файл

@@ -0,0 +1,88 @@
1
+rr_types <- c(
2
+a = 1,
3
+ns = 2,
4
+md = 3,
5
+mf = 4,
6
+cname = 5,
7
+soa = 6,
8
+mb = 7,
9
+mg = 8,
10
+mr = 9,
11
+null = 10,
12
+wks = 11,
13
+ptr = 12,
14
+hinfo = 13,
15
+minfo = 14,
16
+mx = 15,
17
+txt = 16,
18
+rp = 17,
19
+afsdb = 18,
20
+x25 = 19,
21
+isdn = 20,
22
+rt = 21,
23
+nsap = 22,
24
+nsap_ptr = 23,
25
+sig = 24,
26
+key = 25,
27
+px = 26,
28
+gpos = 27,
29
+aaaa = 28,
30
+loc = 29,
31
+nxt = 30,
32
+eid = 31,
33
+nimloc = 32,
34
+srv = 33,
35
+atma = 34,
36
+naptr = 35,
37
+kx = 36,
38
+cert = 37,
39
+a6 = 38,
40
+dname = 39,
41
+sink = 40,
42
+opt = 41,
43
+apl = 42,
44
+ds = 43,
45
+sshfp = 44,
46
+ipseckey = 45,
47
+rrsig = 46,
48
+nsec = 47,
49
+dnskey = 48,
50
+dhcid = 49,
51
+nsec3 = 50,
52
+nsec3param = 51,
53
+tlsa = 52,
54
+smimea = 53,
55
+hip = 55,
56
+ninfo = 56,
57
+rkey = 57,
58
+talink = 58,
59
+cds = 59,
60
+cdnskey = 60,
61
+openpgpkey = 61,
62
+csync = 62,
63
+zonemd = 63,
64
+spf = 99,
65
+uinfo = 100,
66
+uid = 101,
67
+gid = 102,
68
+unspec = 103,
69
+nid = 104,
70
+l32 = 105,
71
+l64 = 106,
72
+lp = 107,
73
+eui48 = 108,
74
+eui64 = 109,
75
+tkey = 249,
76
+tsig = 250,
77
+ixfr = 251,
78
+axfr = 252,
79
+mailb = 253,
80
+maila = 254,
81
+any = 255,
82
+uri = 256,
83
+caa = 257,
84
+avc = 258,
85
+doa = 259,
86
+ta = 32768,
87
+dlv = 32769
88
+)

+ 1
- 1
R/clandnstine-package.R Целия файл

@@ -10,7 +10,7 @@
10 10
 #' @name clandnstine
11 11
 #' @docType package
12 12
 #' @author Bob Rudis (bob@@rud.is)
13
-#' @import httr
13
+#' @keywords internal
14 14
 #' @importFrom jsonlite fromJSON
15 15
 #' @useDynLib clandnstine, .registration = TRUE
16 16
 #' @importFrom Rcpp sourceCpp

+ 7
- 2
R/print-context.R Целия файл

@@ -6,8 +6,13 @@
6 6
 #' @export
7 7
 print.gctx <- function(x, ...) {
8 8
   if (is_null_xptr_(x)) {
9
-    cat("<gdns resolver context (INVALID)>\n")
9
+    cat("<gdns v", gdns_lib_version(), " resolver context (INVALID)>\n")
10 10
   } else {
11
-    cat("<gdns resolver context; resolvers: ", int_get_resolvers(x) ,">\n", sep="")
11
+    cat(
12
+      "<gdns v", gdns_lib_version(),
13
+      " resolver context; resolvers: [",
14
+      paste0(int_get_resolvers(x), collapse=", "),
15
+      "]>\n", sep = ""
16
+    )
12 17
   }
13 18
 }

+ 128
- 0
R/resolver.R Целия файл

@@ -0,0 +1,128 @@
1
+#' Create a gdns DNS over TLS context and populate it with a resolver
2
+#' for use in resolution functions
3
+#'
4
+#' @param resolver character vector of valid DNS over TLS resolvers;
5
+#'        Defaults to Quad9 (`9.9.9.9`).
6
+#' @export
7
+#' @examples
8
+#' x <- gdns_resolver()
9
+#' x <- gdns_resolver("1.1.1.1")
10
+gdns_resolver <- function(resolvers = "9.9.9.9") {
11
+  int_gdns_resolver(resolvers)
12
+}
13
+
14
+#' Arbitrary DNS queries
15
+#'
16
+#' Perform any valid resource record inquiry for a given name. See `Details`.
17
+#'
18
+#' This returns a fairly complex result object but that is the nature
19
+#' of DNS queries. You're likely going to want what is in `$replies_tree$answer`
20
+#' but the rest of the structure contains lovely metadata about the query and
21
+#' remote query environment. There will eventually be "as data frame"-ish helpers
22
+#' for this object.
23
+#'
24
+#' Valid values for `rr_type`:
25
+#' - `a`
26
+#' - `a6`
27
+#' - `aaaa`
28
+#' - `afsdb`
29
+#' - `any`
30
+#' - `apl`
31
+#' - `atma`
32
+#' - `avc`
33
+#' - `axfr`
34
+#' - `caa`
35
+#' - `cdnskey`
36
+#' - `cds`
37
+#' - `cert`
38
+#' - `cname`
39
+#' - `csync`
40
+#' - `dhcid`
41
+#' - `dlv`
42
+#' - `dname`
43
+#' - `dnskey`
44
+#' - `doa`
45
+#' - `ds`
46
+#' - `eid`
47
+#' - `eui48`
48
+#' - `eui64`
49
+#' - `gid`
50
+#' - `gpos`
51
+#' - `hinfo`
52
+#' - `hip`
53
+#' - `ipseckey`
54
+#' - `isdn`
55
+#' - `ixfr`
56
+#' - `key`
57
+#' - `kx`
58
+#' - `l32`
59
+#' - `l64`
60
+#' - `loc`
61
+#' - `lp`
62
+#' - `maila`
63
+#' - `mailb`
64
+#' - `mb`
65
+#' - `md`
66
+#' - `mf`
67
+#' - `mg`
68
+#' - `minfo`
69
+#' - `mr`
70
+#' - `mx`
71
+#' - `naptr`
72
+#' - `nid`
73
+#' - `nimloc`
74
+#' - `ninfo`
75
+#' - `ns`
76
+#' - `nsap`
77
+#' - `nsap_ptr`
78
+#' - `nsec`
79
+#' - `nsec3`
80
+#' - `nsec3param`
81
+#' - `null`
82
+#' - `nxt`
83
+#' - `openpgpkey`
84
+#' - `opt`
85
+#' - `ptr`
86
+#' - `px`
87
+#' - `rkey`
88
+#' - `rp`
89
+#' - `rrsig`
90
+#' - `rt`
91
+#' - `sig`
92
+#' - `sink`
93
+#' - `smimea`
94
+#' - `soa`
95
+#' - `spf`
96
+#' - `srv`
97
+#' - `sshfp`
98
+#' - `ta`
99
+#' - `talink`
100
+#' - `tkey`
101
+#' - `tlsa`
102
+#' - `tsig`
103
+#' - `txt`
104
+#' - `uid`
105
+#' - `uinfo`
106
+#' - `unspec`
107
+#' - `uri`
108
+#' - `wks`
109
+#' - `x25`
110
+#' - `zonemd`
111
+#'
112
+#' @references <https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml>
113
+#' @export
114
+#' @examples
115
+#' x <- gdns_resolver()
116
+#' gdns_query(x, "example.com")
117
+gdns_query <- function(gcx, name, rr_type = "txt") {
118
+
119
+  rr_type <- match.arg(trimws(tolower(rr_type[1])), names(rr_types))
120
+  res <- int_gdns_query(gcx, name, unname(as.integer(rr_types[rr_type])))
121
+  if (length(res)) {
122
+    out <- jsonlite::fromJSON(res)
123
+    out
124
+  } else {
125
+    NULL
126
+  }
127
+
128
+}

+ 28
- 7
README.Rmd Целия файл

@@ -1,7 +1,7 @@
1 1
 ---
2 2
 output: rmarkdown::github_document
3 3
 editor_options: 
4
-  chunk_output_type: inline
4
+  chunk_output_type: console
5 5
 ---
6 6
 ```{r pkg-knitr-opts, include=FALSE}
7 7
 knitr::opts_chunk$set(collapse=TRUE, fig.retina=2, message=FALSE, warning=FALSE)
@@ -32,8 +32,6 @@ Requires [`getdns`](https://getdnsapi.net/) to be installed and available for co
32 32
 
33 33
 I finally grok the getdns api so the package api is going to change wildly and fast. It's only going to support DNS over TLS but will support all types of DNS queries. 
34 34
 
35
-The current "got it working" single function is stupid slow since it creates and destroys a context or each lookup. DNS over TLS was designed to support maintaining a session to avoid this overhead so the package is going to migrate to a "create a resolver" then "use this resolver to resolve X" then "destroy (or have R autodestroy)" the C-size resolver context when the R object goes away model pretty quickly. 
36
-
37 35
 ## Why?
38 36
 
39 37
 Well, for starters, to help research DNS over TLS servers. Plus, for fun!
@@ -82,7 +80,10 @@ It's stupid slow, consumes more CPU and bandwidth but forces adversaries to work
82 80
 
83 81
 The following functions are implemented:
84 82
 
85
-- `get_address`:	Lookup IP Address(es) for a Given Host
83
+- `gdns_get_address`:	Resolve a host to an addrss
84
+- `gdns_lib_version`:	Return gdns library version
85
+- `gdns_query`:	Arbitrary DNS queries
86
+- `gdns_resolver`:	Create a gdns DNS over TLS context and populate it with a resolver for use in resolution functions
86 87
 
87 88
 ## Installation
88 89
 
@@ -102,14 +103,34 @@ packageVersion("clandnstine")
102 103
 
103 104
 ```
104 105
 
106
+### Get an address(es) from a name:
107
+
105 108
 ```{r addr}
106
-get_address("r-project.org") # use built-in default of Quad9 (9.9.9.9)
109
+gdns_lib_version()
110
+
111
+(x <- gdns_resolver())
112
+
113
+(x <- gdns_resolver("1.1.1.1"))
114
+
115
+(x <- gdns_resolver(c("8.8.8.8", "1.1.1.1", "9.9.9.9")))
116
+
117
+(gdns_get_address(x, "rud.is"))
107 118
 
108
-get_address("yahoo.com", "8.8.8.8") # use google and get a bigger return back, too
119
+(gdns_get_address(x, "yahoo.com"))
109 120
 
110
-get_address("doesnotexist.commmm", "1.1.1.1") # nothing to find
121
+(gdns_get_address(x, "yahoo.commmm"))
111 122
 ```
112 123
 
124
+### Any record type query:
125
+
126
+```{r generic}
127
+str(leno <- gdns_query(x, "lenovo.com", "txt"), 1)
128
+
129
+sort(unlist(leno$replies_tree$answer[[1]]$rdata$txt_strings))
130
+```
131
+
132
+Yep. Advertising even in DNS `TXT` records (see item number 8).
133
+
113 134
 ## clandnstine Metrics
114 135
 
115 136
 ```{r cloc, echo=FALSE}

+ 54
- 18
README.md Целия файл

@@ -29,13 +29,6 @@ I finally grok the getdns api so the package api is going to change
29 29
 wildly and fast. It’s only going to support DNS over TLS but will
30 30
 support all types of DNS queries.
31 31
 
32
-The current “got it working” single function is stupid slow since it
33
-creates and destroys a context or each lookup. DNS over TLS was designed
34
-to support maintaining a session to avoid this overhead so the package
35
-is going to migrate to a “create a resolver” then “use this resolver to
36
-resolve X” then “destroy (or have R autodestroy)” the C-size resolver
37
-context when the R object goes away model pretty quickly.
38
-
39 32
 ## Why?
40 33
 
41 34
 Well, for starters, to help research DNS over TLS servers. Plus, for
@@ -108,7 +101,11 @@ to work pretty hard to try to figure out what you’re looking for.
108 101
 
109 102
 The following functions are implemented:
110 103
 
111
-  - `get_address`: Lookup IP Address(es) for a Given Host
104
+  - `gdns_get_address`: Resolve a host to an addrss
105
+  - `gdns_lib_version`: Return gdns library version
106
+  - `gdns_query`: Arbitrary DNS queries
107
+  - `gdns_resolver`: Create a gdns DNS over TLS context and populate it
108
+    with a resolver for use in resolution functions
112 109
 
113 110
 ## Installation
114 111
 
@@ -128,26 +125,65 @@ packageVersion("clandnstine")
128 125
 ## [1] '0.1.0'
129 126
 ```
130 127
 
128
+### Get an address(es) from a name:
129
+
131 130
 ``` r
132
-get_address("r-project.org") # use built-in default of Quad9 (9.9.9.9)
133
-## [1] "137.208.57.37"
131
+gdns_lib_version()
132
+## [1] "1.5.1"
133
+
134
+(x <- gdns_resolver())
135
+## <gdns v1.5.1 resolver context; resolvers: [9.9.9.9]>
136
+
137
+(x <- gdns_resolver("1.1.1.1"))
138
+## <gdns v1.5.1 resolver context; resolvers: [1.1.1.1]>
139
+
140
+(x <- gdns_resolver(c("8.8.8.8", "1.1.1.1", "9.9.9.9")))
141
+## <gdns v1.5.1 resolver context; resolvers: [8.8.8.8, 1.1.1.1, 9.9.9.9]>
142
+
143
+(gdns_get_address(x, "rud.is"))
144
+## [1] "2604:a880:800:10::6bc:2001" "104.236.112.222"
134 145
 
135
-get_address("yahoo.com", "8.8.8.8") # use google and get a bigger return back, too
136
-##  [1] "2001:4998:c:1023::4"   "2001:4998:c:1023::5"   "2001:4998:58:1836::11" "2001:4998:44:41d::4"  
137
-##  [5] "2001:4998:58:1836::10" "2001:4998:44:41d::3"   "72.30.35.10"           "98.137.246.7"         
138
-##  [9] "98.137.246.8"          "98.138.219.231"        "72.30.35.9"            "98.138.219.232"
146
+(gdns_get_address(x, "yahoo.com"))
147
+##  [1] "2001:4998:58:1836::11" "2001:4998:58:1836::10" "2001:4998:c:1023::5"   "2001:4998:c:1023::4"  
148
+##  [5] "2001:4998:44:41d::3"   "2001:4998:44:41d::4"   "98.138.219.232"        "98.138.219.231"       
149
+##  [9] "98.137.246.8"          "98.137.246.7"          "72.30.35.10"           "72.30.35.9"
139 150
 
140
-get_address("doesnotexist.commmm", "1.1.1.1") # nothing to find
151
+(gdns_get_address(x, "yahoo.commmm"))
141 152
 ## character(0)
142 153
 ```
143 154
 
155
+### Any record type query:
156
+
157
+``` r
158
+str(leno <- gdns_query(x, "lenovo.com", "txt"), 1)
159
+## List of 5
160
+##  $ answer_type   : int 800
161
+##  $ canonical_name: chr "lenovo.com."
162
+##  $ replies_full  : int [1, 1:600] 55 84 129 128 0 1 0 8 0 0 ...
163
+##  $ replies_tree  :'data.frame':  1 obs. of  7 variables:
164
+##  $ status        : int 900
165
+
166
+sort(unlist(leno$replies_tree$answer[[1]]$rdata$txt_strings))
167
+## [1] "a82c74b37aa84e7c8580f0e32f4d795d"                                                        
168
+## [2] "ece42d7743c84d6889abda7011fe6f53"                                                        
169
+## [3] "facebook-domain-verification=1r2am7c2bhzrxpqyt0mda0djoquqsi"                             
170
+## [4] "google-site-verification=VxW_e6r_Ka7A518qfX2MmIMHGnkpGbnACsjSxKFCBw0"                    
171
+## [5] "iHzQJvsKnyGP2Nm2qBgL3fyBJ0CC9z4GkY/flfk4EzLP8lPxWHDDPKqZWm1TkeF5kEIL+NotYOF1wo7JtUDXXw=="
172
+## [6] "qh7hdmqm4lzs85p704d6wsybgrpsly0j"                                                        
173
+## [7] "v=spf1 include:spf.messagelabs.com include:_netblocks.eloqua.com ~all"                   
174
+## [8] "Visit www.lenovo.com/think for information about Lenovo products and services"
175
+```
176
+
177
+Yep. Advertising even in DNS `TXT` records (see item number
178
+8).
179
+
144 180
 ## clandnstine Metrics
145 181
 
146 182
 | Lang | \# Files |  (%) | LoC |  (%) | Blank lines |  (%) | \# Lines |  (%) |
147 183
 | :--- | -------: | ---: | --: | ---: | ----------: | ---: | -------: | ---: |
148
-| C++  |        2 | 0.29 |  72 | 0.79 |          23 | 0.35 |       13 | 0.11 |
149
-| Rmd  |        1 | 0.14 |  10 | 0.11 |          38 | 0.58 |       74 | 0.64 |
150
-| R    |        4 | 0.57 |   9 | 0.10 |           4 | 0.06 |       28 | 0.24 |
184
+| C++  |        3 | 0.25 | 240 | 0.59 |          66 | 0.50 |       61 | 0.20 |
185
+| R    |        8 | 0.67 | 154 | 0.38 |          20 | 0.15 |      168 | 0.54 |
186
+| Rmd  |        1 | 0.08 |  16 | 0.04 |          46 | 0.35 |       81 | 0.26 |
151 187
 
152 188
 ## Code of Conduct
153 189
 

+ 1
- 0
man/check_is_xptr.Rd Целия файл

@@ -12,3 +12,4 @@ check_is_xptr(s)
12 12
 \description{
13 13
 Test whether an object is an external pointer
14 14
 }
15
+\keyword{internal}

+ 1
- 0
man/clandnstine.Rd Целия файл

@@ -18,3 +18,4 @@ Something something 'getdns API/library'.
18 18
 \author{
19 19
 Bob Rudis (bob@rud.is)
20 20
 }
21
+\keyword{internal}

+ 11
- 0
man/gdns_lib_version.Rd Целия файл

@@ -0,0 +1,11 @@
1
+% Generated by roxygen2: do not edit by hand
2
+% Please edit documentation in R/RcppExports.R
3
+\name{gdns_lib_version}
4
+\alias{gdns_lib_version}
5
+\title{Return gdns library version}
6
+\usage{
7
+gdns_lib_version()
8
+}
9
+\description{
10
+Return gdns library version
11
+}

+ 115
- 0
man/gdns_query.Rd Целия файл

@@ -0,0 +1,115 @@
1
+% Generated by roxygen2: do not edit by hand
2
+% Please edit documentation in R/resolver.R
3
+\name{gdns_query}
4
+\alias{gdns_query}
5
+\title{Arbitrary DNS queries}
6
+\usage{
7
+gdns_query(gcx, name, rr_type = "txt")
8
+}
9
+\description{
10
+Perform any valid resource record inquiry for a given name. See \code{Details}.
11
+}
12
+\details{
13
+This returns a fairly complex result object but that is the nature
14
+of DNS queries. You're likely going to want what is in \code{$replies_tree$answer}
15
+but the rest of the structure contains lovely metadata about the query and
16
+remote query environment. There will eventually be "as data frame"-ish helpers
17
+for this object.
18
+
19
+Valid values for \code{rr_type}:
20
+\itemize{
21
+\item \code{a}
22
+\item \code{a6}
23
+\item \code{aaaa}
24
+\item \code{afsdb}
25
+\item \code{any}
26
+\item \code{apl}
27
+\item \code{atma}
28
+\item \code{avc}
29
+\item \code{axfr}
30
+\item \code{caa}
31
+\item \code{cdnskey}
32
+\item \code{cds}
33
+\item \code{cert}
34
+\item \code{cname}
35
+\item \code{csync}
36
+\item \code{dhcid}
37
+\item \code{dlv}
38
+\item \code{dname}
39
+\item \code{dnskey}
40
+\item \code{doa}
41
+\item \code{ds}
42
+\item \code{eid}
43
+\item \code{eui48}
44
+\item \code{eui64}
45
+\item \code{gid}
46
+\item \code{gpos}
47
+\item \code{hinfo}
48
+\item \code{hip}
49
+\item \code{ipseckey}
50
+\item \code{isdn}
51
+\item \code{ixfr}
52
+\item \code{key}
53
+\item \code{kx}
54
+\item \code{l32}
55
+\item \code{l64}
56
+\item \code{loc}
57
+\item \code{lp}
58
+\item \code{maila}
59
+\item \code{mailb}
60
+\item \code{mb}
61
+\item \code{md}
62
+\item \code{mf}
63
+\item \code{mg}
64
+\item \code{minfo}
65
+\item \code{mr}
66
+\item \code{mx}
67
+\item \code{naptr}
68
+\item \code{nid}
69
+\item \code{nimloc}
70
+\item \code{ninfo}
71
+\item \code{ns}
72
+\item \code{nsap}
73
+\item \code{nsap_ptr}
74
+\item \code{nsec}
75
+\item \code{nsec3}
76
+\item \code{nsec3param}
77
+\item \code{null}
78
+\item \code{nxt}
79
+\item \code{openpgpkey}
80
+\item \code{opt}
81
+\item \code{ptr}
82
+\item \code{px}
83
+\item \code{rkey}
84
+\item \code{rp}
85
+\item \code{rrsig}
86
+\item \code{rt}
87
+\item \code{sig}
88
+\item \code{sink}
89
+\item \code{smimea}
90
+\item \code{soa}
91
+\item \code{spf}
92
+\item \code{srv}
93
+\item \code{sshfp}
94
+\item \code{ta}
95
+\item \code{talink}
96
+\item \code{tkey}
97
+\item \code{tlsa}
98
+\item \code{tsig}
99
+\item \code{txt}
100
+\item \code{uid}
101
+\item \code{uinfo}
102
+\item \code{unspec}
103
+\item \code{uri}
104
+\item \code{wks}
105
+\item \code{x25}
106
+\item \code{zonemd}
107
+}
108
+}
109
+\examples{
110
+x <- gdns_resolver()
111
+gdns_query(x, "example.com")
112
+}
113
+\references{
114
+\url{https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml}
115
+}

+ 4
- 3
man/gdns_resolver.Rd Целия файл

@@ -1,14 +1,14 @@
1 1
 % Generated by roxygen2: do not edit by hand
2
-% Please edit documentation in R/RcppExports.R
2
+% Please edit documentation in R/resolver.R
3 3
 \name{gdns_resolver}
4 4
 \alias{gdns_resolver}
5 5
 \title{Create a gdns DNS over TLS context and populate it with a resolver
6 6
 for use in resolution functions}
7 7
 \usage{
8
-gdns_resolver(resolver = "9.9.9.9")
8
+gdns_resolver(resolvers = "9.9.9.9")
9 9
 }
10 10
 \arguments{
11
-\item{resolver}{length 1 <chr> of a valid DNS over TLS resolver;
11
+\item{resolver}{character vector of valid DNS over TLS resolvers;
12 12
 Defaults to Quad9 (\code{9.9.9.9}).}
13 13
 }
14 14
 \description{
@@ -17,4 +17,5 @@ for use in resolution functions
17 17
 }
18 18
 \examples{
19 19
 x <- gdns_resolver()
20
+x <- gdns_resolver("1.1.1.1")
20 21
 }

+ 0
- 21
man/get_address.Rd Целия файл

@@ -1,21 +0,0 @@
1
-% Generated by roxygen2: do not edit by hand
2
-% Please edit documentation in R/RcppExports.R
3
-\name{get_address}
4
-\alias{get_address}
5
-\title{Lookup IP Address(es) for a Given Host}
6
-\usage{
7
-get_address(host, resolver = "9.9.9.9")
8
-}
9
-\arguments{
10
-\item{host}{host (length 1 <chr>)}
11
-
12
-\item{resolver}{resolver address. defaults to Quad9; (length 1 <chr>)}
13
-}
14
-\description{
15
-Lookup IP Address(es) for a Given Host
16
-}
17
-\examples{
18
-get_address("r-project.org")
19
-get_address("yahoo.com", "1.1.1.1")
20
-get_address("microsoft.com", "8.8.8.8")
21
-}

+ 12
- 0
man/int_gdns_resolver.Rd Целия файл

@@ -0,0 +1,12 @@
1
+% Generated by roxygen2: do not edit by hand
2
+% Please edit documentation in R/RcppExports.R
3
+\name{int_gdns_resolver}
4
+\alias{int_gdns_resolver}
5
+\title{Internal version of gdns_resolver}
6
+\usage{
7
+int_gdns_resolver(resolvers)
8
+}
9
+\description{
10
+Internal version of gdns_resolver
11
+}
12
+\keyword{internal}

+ 1
- 0
man/is_null_xptr_.Rd Целия файл

@@ -12,3 +12,4 @@ is_null_xptr_(s)
12 12
 \description{
13 13
 Test whether an external pointer is null
14 14
 }
15
+\keyword{internal}

+ 25
- 13
src/RcppExports.cpp Целия файл

@@ -5,15 +5,13 @@
5 5
 
6 6
 using namespace Rcpp;
7 7
 
8
-// get_address
9
-CharacterVector get_address(std::string host, std::string resolver);
10
-RcppExport SEXP _clandnstine_get_address(SEXP hostSEXP, SEXP resolverSEXP) {
8
+// gdns_lib_version
9
+std::string gdns_lib_version();
10
+RcppExport SEXP _clandnstine_gdns_lib_version() {
11 11
 BEGIN_RCPP
12 12
     Rcpp::RObject rcpp_result_gen;
13 13
     Rcpp::RNGScope rcpp_rngScope_gen;
14
-    Rcpp::traits::input_parameter< std::string >::type host(hostSEXP);
15
-    Rcpp::traits::input_parameter< std::string >::type resolver(resolverSEXP);
16
-    rcpp_result_gen = Rcpp::wrap(get_address(host, resolver));
14
+    rcpp_result_gen = Rcpp::wrap(gdns_lib_version());
17 15
     return rcpp_result_gen;
18 16
 END_RCPP
19 17
 }
@@ -38,14 +36,14 @@ BEGIN_RCPP
38 36
     return rcpp_result_gen;
39 37
 END_RCPP
40 38
 }
41
-// gdns_resolver
42
-SEXP gdns_resolver(std::string resolver);
43
-RcppExport SEXP _clandnstine_gdns_resolver(SEXP resolverSEXP) {
39
+// int_gdns_resolver
40
+SEXP int_gdns_resolver(std::vector< std::string > resolvers);
41
+RcppExport SEXP _clandnstine_int_gdns_resolver(SEXP resolversSEXP) {
44 42
 BEGIN_RCPP
45 43
     Rcpp::RObject rcpp_result_gen;
46 44
     Rcpp::RNGScope rcpp_rngScope_gen;
47
-    Rcpp::traits::input_parameter< std::string >::type resolver(resolverSEXP);
48
-    rcpp_result_gen = Rcpp::wrap(gdns_resolver(resolver));
45
+    Rcpp::traits::input_parameter< std::vector< std::string > >::type resolvers(resolversSEXP);
46
+    rcpp_result_gen = Rcpp::wrap(int_gdns_resolver(resolvers));
49 47
     return rcpp_result_gen;
50 48
 END_RCPP
51 49
 }
@@ -72,14 +70,28 @@ BEGIN_RCPP
72 70
     return rcpp_result_gen;
73 71
 END_RCPP
74 72
 }
73
+// int_gdns_query
74
+CharacterVector int_gdns_query(SEXP gctx, std::string name, uint16_t rr);
75
+RcppExport SEXP _clandnstine_int_gdns_query(SEXP gctxSEXP, SEXP nameSEXP, SEXP rrSEXP) {
76
+BEGIN_RCPP
77
+    Rcpp::RObject rcpp_result_gen;
78
+    Rcpp::RNGScope rcpp_rngScope_gen;
79
+    Rcpp::traits::input_parameter< SEXP >::type gctx(gctxSEXP);
80
+    Rcpp::traits::input_parameter< std::string >::type name(nameSEXP);
81
+    Rcpp::traits::input_parameter< uint16_t >::type rr(rrSEXP);
82
+    rcpp_result_gen = Rcpp::wrap(int_gdns_query(gctx, name, rr));
83
+    return rcpp_result_gen;
84
+END_RCPP
85
+}
75 86
 
76 87
 static const R_CallMethodDef CallEntries[] = {
77
-    {"_clandnstine_get_address", (DL_FUNC) &_clandnstine_get_address, 2},
88
+    {"_clandnstine_gdns_lib_version", (DL_FUNC) &_clandnstine_gdns_lib_version, 0},
78 89
     {"_clandnstine_check_is_xptr", (DL_FUNC) &_clandnstine_check_is_xptr, 1},
79 90
     {"_clandnstine_is_null_xptr_", (DL_FUNC) &_clandnstine_is_null_xptr_, 1},
80
-    {"_clandnstine_gdns_resolver", (DL_FUNC) &_clandnstine_gdns_resolver, 1},
91
+    {"_clandnstine_int_gdns_resolver", (DL_FUNC) &_clandnstine_int_gdns_resolver, 1},
81 92
     {"_clandnstine_gdns_get_address", (DL_FUNC) &_clandnstine_gdns_get_address, 2},
82 93
     {"_clandnstine_int_get_resolvers", (DL_FUNC) &_clandnstine_int_get_resolvers, 1},
94
+    {"_clandnstine_int_gdns_query", (DL_FUNC) &_clandnstine_int_gdns_query, 3},
83 95
     {NULL, NULL, 0}
84 96
 };
85 97
 

+ 25
- 68
src/clandnstine-main.cpp Целия файл

@@ -4,76 +4,33 @@
4 4
 #include <arpa/inet.h>
5 5
 using namespace Rcpp;
6 6
 
7
-//' Lookup IP Address(es) for a Given Host
7
+
8
+//' Return gdns library version
8 9
 //'
9
-//' @param host host (length 1 <chr>)
10
-//' @param resolver resolver address. defaults to Quad9; (length 1 <chr>)
11 10
 //' @export
12
-//' @examples
13
-//' get_address("r-project.org")
14
-//' get_address("yahoo.com", "1.1.1.1")
15
-//' get_address("microsoft.com", "8.8.8.8")
16 11
 // [[Rcpp::export]]
17
-CharacterVector get_address(std::string host, std::string resolver = "9.9.9.9") {
18
-
19
-  uint32_t err;
20
-  size_t sz;
21
-  getdns_return_t r;
22
-  getdns_context *ctxt = NULL;
23
-  getdns_dict *resp = NULL;
24
-  getdns_list *addrs;
25
-  std::vector< std::string > out;
26
-  bool ok = false;
27
-
28
-  getdns_dict *resolver_dict = getdns_dict_create();
29
-  r = getdns_str2dict(resolver.c_str(), &resolver_dict);
30
-
31
-  getdns_list *resolver_list = getdns_list_create();
32
-  r = getdns_list_set_dict(resolver_list, 0, resolver_dict);
33
-
34
-  getdns_transport_list_t tls_transport[] = { GETDNS_TRANSPORT_TLS };
35
-
36
-  if ((r = getdns_context_create(&ctxt, 1))) {
37
-  } else if ((r = getdns_context_set_dns_transport_list(ctxt, 1, tls_transport))) {
38
-  } else if ((r = getdns_context_set_upstream_recursive_servers(ctxt, resolver_list))) {
39
-  } else if ((r = getdns_context_set_resolution_type(ctxt, GETDNS_RESOLUTION_STUB))) {
40
-  } else if ((r = getdns_address_sync(ctxt, host.c_str(), NULL, &resp))) {
41
-  } else if ((r = getdns_dict_get_int(resp, "status", &err))) {
42
-  } else if (err != GETDNS_RESPSTATUS_GOOD) {
43
-  } else if ((r = getdns_dict_get_list(resp, "just_address_answers", &addrs))) {
44
-  } else if (r != GETDNS_RETURN_GOOD) {
45
-  } else if ((r = getdns_list_get_length(addrs, &sz))) {
46
-  } else {
47
-    ok = true;
48
-  }
49
-
50
-  if (ok) {
51
-
52
-    out.reserve(sz);
53
-
54
-    for (size_t i = 0; i < sz; ++i) {
55
-
56
-      getdns_dict *cur_addr;
57
-      getdns_bindata *address;
58
-
59
-      r = getdns_list_get_dict(addrs, i, &cur_addr);
60
-      r = getdns_dict_get_bindata(cur_addr, "address_data", &address);
61
-
62
-      if (address->size == 4 || address->size == 16) { // this is unlikely to be bad
63
-        char *addr_str = getdns_display_ip_address(address);
64
-        out.push_back(addr_str);
65
-        if (addr_str) free(addr_str);
66
-      }
67
-
68
-    }
69
-
70
-    out.shrink_to_fit();
71
-
72
-  }
73
-
74
-  if (resp) getdns_dict_destroy(resp);
75
-  if (ctxt) getdns_context_destroy(ctxt);
12
+std::string gdns_lib_version() {
13
+  return(std::string(getdns_get_version()));
14
+}
76 15
 
77
-  if (ok) return(wrap(out)); else return(CharacterVector());
78 16
 
79
-}
17
+// CharacterVector int_gdns_list_to_r() {
18
+//
19
+//   getdns_list *gl;
20
+//
21
+//   std::string out;
22
+//
23
+//   // if (!lst) return(CharacterVector());
24
+//   //
25
+//   // char *res = getdns_print_json_list(lst, 0);
26
+//   // if (res) {
27
+//   //   out = std::string(res);
28
+//   //   free(res);
29
+//   // } else {
30
+//   //   return(CharacterVector());
31
+//   // }
32
+//
33
+//   return(wrap(out));
34
+//
35
+// }
36
+//

+ 50
- 12
src/resolver.cpp Целия файл

@@ -7,6 +7,7 @@ using namespace Rcpp;
7 7
 //' Test whether an object is an external pointer
8 8
 //'
9 9
 //' @param x object to test
10
+//' @keywords internal
10 11
 // [[Rcpp::export]]
11 12
 void check_is_xptr(SEXP s) {
12 13
   if (TYPEOF(s) != EXTPTRSXP) {
@@ -17,6 +18,7 @@ void check_is_xptr(SEXP s) {
17 18
 //' Test whether an external pointer is null
18 19
 //'
19 20
 //' @param x object to test
21
+//' @keywords internal
20 22
 // [[Rcpp::export]]
21 23
 SEXP is_null_xptr_(SEXP s) {
22 24
   check_is_xptr(s);
@@ -30,27 +32,24 @@ static void gctx_finalizer(SEXP ptr) {
30 32
   R_ClearExternalPtr(ptr); /* not really needed */
31 33
 }
32 34
 
33
-//' Create a gdns DNS over TLS context and populate it with a resolver
34
-//' for use in resolution functions
35
-//'
36
-//' @param resolver length 1 <chr> of a valid DNS over TLS resolver;
37
-//'        Defaults to Quad9 (`9.9.9.9`).
38
-//' @export
39
-//' @examples
40
-//' x <- gdns_resolver()
35
+//' Internal version of gdns_resolver
36
+//' @keywords internal
41 37
 // [[Rcpp::export]]
42
-SEXP gdns_resolver(std::string resolver = "9.9.9.9") {
38
+SEXP int_gdns_resolver(std::vector< std::string > resolvers) {
43 39
 
44 40
   bool ok = false;
45 41
   SEXP ptr;
46 42
   getdns_return_t r;
47 43
   getdns_context *ctxt = NULL;
48 44
 
45
+  // TODO Validate we don't need to free these
49 46
   getdns_dict *resolver_dict = getdns_dict_create();
50
-  r = getdns_str2dict(resolver.c_str(), &resolver_dict);
51
-
52 47
   getdns_list *resolver_list = getdns_list_create();
53
-  r = getdns_list_set_dict(resolver_list, 0, resolver_dict);
48
+
49
+  for (int i = 0; i<resolvers.size(); i++) {
50
+    r = getdns_str2dict(resolvers[i].c_str(), &resolver_dict);
51
+    r = getdns_list_set_dict(resolver_list, i, resolver_dict);
52
+  }
54 53
 
55 54
   getdns_transport_list_t tls_transport[] = { GETDNS_TRANSPORT_TLS };
56 55
 
@@ -116,6 +115,7 @@ CharacterVector gdns_get_address(SEXP gctx, std::string host) {
116 115
       getdns_dict *cur_addr;
117 116
       getdns_bindata *address;
118 117
 
118
+      // TODO Validate we don't need to free these
119 119
       r = getdns_list_get_dict(addrs, i, &cur_addr);
120 120
       r = getdns_dict_get_bindata(cur_addr, "address_data", &address);
121 121
 
@@ -166,6 +166,7 @@ CharacterVector int_get_resolvers(SEXP gctx) {
166 166
       getdns_dict *cur_addr;
167 167
       getdns_bindata *address;
168 168
 
169
+      // TODO Validate we don't need to free these
169 170
       r = getdns_list_get_dict(addrs, i, &cur_addr);
170 171
       r = getdns_dict_get_bindata(cur_addr, "address_data", &address);
171 172
 
@@ -188,5 +189,42 @@ CharacterVector int_get_resolvers(SEXP gctx) {
188 189
 }
189 190
 
190 191
 
192
+// [[Rcpp::export]]
193
+CharacterVector int_gdns_query(SEXP gctx, std::string name, uint16_t rr) {
194
+
195
+  uint32_t err;
196
+  size_t sz;
197
+  getdns_return_t r;
198
+  getdns_dict *resp = NULL;
199
+  getdns_list *results;
200
+  std::string out;
201
+  bool ok = false;
202
+
203
+  getdns_context *ctxt = (getdns_context *)R_ExternalPtrAddr(gctx);
204
+
205
+  if (gctx == NULL) return(CharacterVector());
206
+
207
+  if ((r = getdns_general_sync(ctxt, name.c_str(), rr, NULL, &resp))) {
208
+  } else if ((r = getdns_dict_get_int(resp, "status", &err))) {
209
+  } else if (err != GETDNS_RESPSTATUS_GOOD) {
210
+  } else {
211
+    ok = true;
212
+  }
191 213
 
214
+  if (ok) {
192 215
 
216
+    char *charout = getdns_print_json_dict(resp, 0);
217
+    if (charout) {
218
+      out = std::string(charout);
219
+      free(charout);
220
+    } else {
221
+      ok = false;
222
+    }
223
+
224
+  }
225
+
226
+  if (resp) getdns_dict_destroy(resp);
227
+
228
+  if (ok) return(wrap(out)); else return(CharacterVector());
229
+
230
+}

+ 20
- 2
tests/testthat/test-clandnstine.R Целия файл

@@ -1,7 +1,25 @@
1 1
 context("basic wrapper works")
2
-test_that("we can do something", {
2
+test_that("basic wrapper works", {
3 3
 
4
-  x <- get_address("example.com")
4
+  expect_is(gdns_lib_version(), "character")
5
+
6
+  r <- gdns_resolver()
7
+
8
+  x <- gdns_get_address(r, "example.com")
9
+  expect_true(all(c("2606:2800:220:1:248:1893:25c8:1946", "93.184.216.34") %in% x))
10
+
11
+  r <- gdns_resolver(c("8.8.8.8", "1.1.1.1", "9.9.9.9"))
12
+
13
+  x <- gdns_get_address(r, "example.com")
5 14
   expect_true(all(c("2606:2800:220:1:248:1893:25c8:1946", "93.184.216.34") %in% x))
6 15
 
16
+  x <- gdns_get_address(r, "example.commm")
17
+  expect_length(x, 0)
18
+
19
+  x <- gdns_query(r, "example.com", "txt")
20
+
21
+  expect_equal(x$answer_type, 800)
22
+  expect_equal(x$canonical_name, "example.com.")
23
+  expect_true(grepl("spf", unlist(x$replies_tree$answer[[1]]$rdata$txt_strings)))
24
+
7 25
 })

Loading…
Отказ
Запис