Browse Source

lookup works

boB Rudis 10 months ago
parent
commit
42d845fbbc
No known key found for this signature in database
11 changed files with 398 additions and 8 deletions
  1. 8
    3
      DESCRIPTION
  2. 3
    0
      NAMESPACE
  3. 16
    0
      R/RcppExports.R
  4. 9
    4
      R/clandnstine-package.R
  5. 73
    1
      README.Rmd
  6. 154
    0
      README.md
  7. 21
    0
      man/get_address.Rd
  8. 3
    0
      src/.gitignore
  9. 3
    0
      src/Makevars
  10. 29
    0
      src/RcppExports.cpp
  11. 79
    0
      src/clandnstine-main.cpp

+ 8
- 3
DESCRIPTION View File

@@ -1,6 +1,6 @@
1 1
 Package: clandnstine
2 2
 Type: Package
3
-Title: clandnstine title goes here otherwise CRAN checks fail
3
+Title: Perform 'DNS' over 'TLS' Queries
4 4
 Version: 0.1.0
5 5
 Date: 2019-01-18
6 6
 Authors@R: c(
@@ -8,7 +8,9 @@ Authors@R: c(
8 8
            comment = c(ORCID = "0000-0001-5670-2640"))
9 9
   )
10 10
 Maintainer: Bob Rudis <bob@rud.is>
11
-Description: A good description goes here otherwise CRAN checks fail.
11
+Description: Something something 'DNS. Something something 'TLS'. 
12
+    Something something 'getdns API/library'.
13
+SystemRequirements: C++11
12 14
 URL: https://gitlab.com/hrbrmstr/clandnstine
13 15
 BugReports: https://gitlab.com/hrbrmstr/clandnstine/issues
14 16
 Encoding: UTF-8
@@ -20,6 +22,9 @@ Depends:
20 22
     R (>= 3.2.0)
21 23
 Imports:
22 24
     httr,
23
-    jsonlite
25
+    jsonlite,
26
+    Rcpp
24 27
 Roxygen: list(markdown = TRUE)
25 28
 RoxygenNote: 6.1.1
29
+LinkingTo: 
30
+    Rcpp

+ 3
- 0
NAMESPACE View File

@@ -1,4 +1,7 @@
1 1
 # Generated by roxygen2: do not edit by hand
2 2
 
3
+export(get_address)
3 4
 import(httr)
5
+importFrom(Rcpp,sourceCpp)
4 6
 importFrom(jsonlite,fromJSON)
7
+useDynLib(clandnstine, .registration = TRUE)

+ 16
- 0
R/RcppExports.R View File

@@ -0,0 +1,16 @@
1
+# Generated by using Rcpp::compileAttributes() -> do not edit by hand
2
+# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
3
+
4
+#' Lookup IP Address(es) for a Given Host
5
+#'
6
+#' @param host host (length 1 <chr>)
7
+#' @param resolver resolver address. defaults to Quad9; (length 1 <chr>)
8
+#' @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)
15
+}
16
+

+ 9
- 4
R/clandnstine-package.R View File

@@ -1,12 +1,17 @@
1
-#' ...
2
-#' 
1
+#' Perform 'DNS' over 'TLS' Queries
2
+#'
3
+#' Something something 'DNS. Something something 'TLS'.
4
+#' Something something 'getdns API/library'.
5
+#'
3 6
 #' - URL: <https://gitlab.com/hrbrmstr/clandnstine>
4 7
 #' - BugReports: <https://gitlab.com/hrbrmstr/clandnstine/issues>
5
-#' 
8
+#'
6 9
 #' @md
7 10
 #' @name clandnstine
8 11
 #' @docType package
9 12
 #' @author Bob Rudis (bob@@rud.is)
10 13
 #' @import httr
11 14
 #' @importFrom jsonlite fromJSON
12
-NULL
15
+#' @useDynLib clandnstine, .registration = TRUE
16
+#' @importFrom Rcpp sourceCpp
17
+NULL

+ 73
- 1
README.Rmd View File

@@ -4,7 +4,7 @@ editor_options:
4 4
   chunk_output_type: inline
5 5
 ---
6 6
 ```{r pkg-knitr-opts, include=FALSE}
7
-knitr$opts_chunk$set(collapse=TRUE, fig.retina=2, message=FALSE, warning=FALSE)
7
+knitr::opts_chunk$set(collapse=TRUE, fig.retina=2, message=FALSE, warning=FALSE)
8 8
 options(width=120)
9 9
 ```
10 10
 
@@ -14,12 +14,76 @@ options(width=120)
14 14
 
15 15
 # clandnstine
16 16
 
17
+Perform 'DNS' over 'TLS' Queries
18
+
17 19
 ## Description
18 20
 
21
+Something something 'DNS. Something something 'TLS'.  Something something 'getdns API/library'.
22
+
23
+## NOTE
24
+
25
+Requires [`getdns`](https://getdnsapi.net/) to be installed and available for compilation (no guard rails setup yet):
26
+
27
+- Use `brew install getdns` on macOS
28
+- Install `libgetdns-dev` on debian/ubuntu
29
+- (Nothing to see here Windows folks stuck in a backwards ecosysem)
30
+
31
+## TODO/WAT
32
+
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
+
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
+## Why?
38
+
39
+Well, for starters, to help research DNS over TLS servers. Plus, for fun!
40
+
41
+If you're asking "Why DNS over TLS at all?" then "faux" privacy. Why "faux"? Well, _something_ is handing your query and that something knows your IP address and what you looked for. So, you're relying on the good faith, honest nature and technical capability of the destination server to not mess with you. I don't trust Cloudflare or Google and am witholding judgement on Quad9 either way (they've been doing good things and are less "look at how cool we are" than CF is).
42
+
43
+Also "faux" in that you're going to be using a standard port (853) and a TLS session for the queries so your internet provider will know you're doing _something_ and the current, sorry state of SSL certificates, certificate authorities, and authoritarian companies and regimes combined means confidentiality and integrity are always kinda in question unless done super-well.
44
+
45
+## What's Different About This vs Regular DNS?
46
+
47
+Well, if we lookup the addresses for `yahoo.com` the old-fashioned way it's cleartext UDP on the wire:
48
+
49
+    1   0.000000   10.1.10.57 → 10.1.10.200  DNS 80 Standard query 0x8af8 A yahoo.com OPT
50
+    2   0.003297  10.1.10.200 → 10.1.10.57   DNS 176 Standard query response 0x8af8 A yahoo.com A 72.30.35.10 A 98.138.219.231 A 72.30.35.9 A 98.137.246.7 A 98.138.219.232 A 98.137.246.8 OPT
51
+    
52
+I watched for port 53 UDP traffic with `tshark` as `yahoo.com` was being looked up. Notice the fast and diminuitive &mdash; and plaintext &mdash; response. (I'm fibbing a bit since I pre-loaded the local home DNS server with this query since I tested it alot before knitting this readme. My home server forwards all queries to a custom DNS over TLS server since I really don't trust any of the providers when it comes down to it. So, in reality for me, it's even slower than the below &mdash; at least initially).
53
+
54
+This is the same query via DNS over TLS
55
+
56
+     1   0.000000   10.1.10.57 → 9.9.9.9      TCP 78 52128 → 853 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=64 TSval=602885491 TSecr=0 SACK_PERM=1 TFO=R
57
+     2   0.021188      9.9.9.9 → 10.1.10.57   TCP 74 853 → 52128 [SYN, ACK] Seq=0 Ack=1 Win=28960 Len=0 MSS=1460 SACK_PERM=1 TSval=3426782438 TSecr=602885491 WS=256
58
+     3   0.021308   10.1.10.57 → 9.9.9.9      TLSv1 373 Client Hello
59
+     4   0.045324      9.9.9.9 → 10.1.10.57   TLSv1.2 1514 Server Hello
60
+     5   0.045333      9.9.9.9 → 10.1.10.57   TLSv1.2 73 [TCP Previous segment not captured] , Ignored Unknown Record
61
+     6   0.045334      9.9.9.9 → 10.1.10.57   TCP 1514 [TCP Out-Of-Order] 853 → 52128 [ACK] Seq=1449 Ack=308 Win=30208 Len=1448 TSval=3426782459 TSecr=602885512
62
+     7   0.045491   10.1.10.57 → 9.9.9.9      TCP 78 52128 → 853 [ACK] Seq=308 Ack=1449 Win=130304 Len=0 TSval=602885536 TSecr=3426782459 SLE=2897 SRE=2904
63
+     8   0.045492   10.1.10.57 → 9.9.9.9      TCP 66 52128 → 853 [ACK] Seq=308 Ack=2904 Win=128832 Len=0 TSval=602885536 TSecr=3426782459
64
+     9   0.050527   10.1.10.57 → 9.9.9.9      TLSv1.2 192 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
65
+    10   0.069107      9.9.9.9 → 10.1.10.57   TLSv1.2 117 Change Cipher Spec, Encrypted Handshake Message
66
+    11   0.069255   10.1.10.57 → 9.9.9.9      TCP 66 52128 → 853 [ACK] Seq=434 Ack=2955 Win=131008 Len=0 TSval=602885559 TSecr=3426782487
67
+    12   0.069516   10.1.10.57 → 9.9.9.9      TLSv1.2 225 Application Data
68
+    13   0.091087      9.9.9.9 → 10.1.10.57   TLSv1.2 303 Application Data
69
+    14   0.091207   10.1.10.57 → 9.9.9.9      TLSv1.2 225 Application Data
70
+    15   0.106738      9.9.9.9 → 10.1.10.57   TLSv1.2 231 Application Data
71
+    16   0.106836   10.1.10.57 → 9.9.9.9      TCP 66 52128 → 853 [ACK] Seq=752 Ack=3357 Win=130880 Len=0 TSval=602885595 TSecr=3426782525
72
+    17   0.107200   10.1.10.57 → 9.9.9.9      TLSv1.2 97 Encrypted Alert
73
+    18   0.107411   10.1.10.57 → 9.9.9.9      TCP 66 52128 → 853 [FIN, ACK] Seq=783 Ack=3357 Win=131072 Len=0 TSval=602885595 TSecr=3426782525
74
+    19   0.126603      9.9.9.9 → 10.1.10.57   TLSv1.2 97 Encrypted Alert
75
+    20   0.126608      9.9.9.9 → 10.1.10.57   TCP 66 853 → 52128 [FIN, ACK] Seq=3388 Ack=784 Win=32256 Len=0 TSval=3426782545 TSecr=602885595
76
+    21   0.126717   10.1.10.57 → 9.9.9.9      TCP 54 52128 → 853 [RST] Seq=784 Win=0 Len=0
77
+    22   0.126718   10.1.10.57 → 9.9.9.9      TCP 54 52128 → 853 [RST] Seq=784 Win=0 Len=0
78
+
79
+It's stupid slow, consumes more CPU and bandwidth but forces adversaries to work pretty hard to try to figure out what you're looking for.
80
+
19 81
 ## What's Inside The Tin
20 82
 
21 83
 The following functions are implemented:
22 84
 
85
+- `get_address`:	Lookup IP Address(es) for a Given Host
86
+
23 87
 ## Installation
24 88
 
25 89
 ```{r install-ex, eval=FALSE}
@@ -38,6 +102,14 @@ packageVersion("clandnstine")
38 102
 
39 103
 ```
40 104
 
105
+```{r addr}
106
+get_address("r-project.org") # use built-in default of Quad9 (9.9.9.9)
107
+
108
+get_address("yahoo.com", "8.8.8.8") # use google and get a bigger return back, too
109
+
110
+get_address("doesnotexist.commmm", "1.1.1.1") # nothing to find
111
+```
112
+
41 113
 ## clandnstine Metrics
42 114
 
43 115
 ```{r cloc, echo=FALSE}

+ 154
- 0
README.md View File

@@ -1,2 +1,156 @@
1
+
2
+[![Travis-CI Build
3
+Status](https://travis-ci.org/hrbrmstr/clandnstine.svg?branch=master)](https://travis-ci.org/hrbrmstr/clandnstine)
4
+[![Coverage
5
+Status](https://codecov.io/gh/hrbrmstr/clandnstine/branch/master/graph/badge.svg)](https://codecov.io/gh/hrbrmstr/clandnstine)
6
+[![CRAN\_Status\_Badge](http://www.r-pkg.org/badges/version/clandnstine)](https://cran.r-project.org/package=clandnstine)
7
+
1 8
 # clandnstine
2 9
 
10
+Perform ‘DNS’ over ‘TLS’ Queries
11
+
12
+## Description
13
+
14
+Something something ‘DNS. Something something ’TLS’. Something something
15
+‘getdns API/library’.
16
+
17
+## NOTE
18
+
19
+Requires [`getdns`](https://getdnsapi.net/) to be installed and
20
+available for compilation (no guard rails setup yet):
21
+
22
+  - Use `brew install getdns` on macOS
23
+  - Install `libgetdns-dev` on debian/ubuntu
24
+  - (Nothing to see here Windows folks stuck in a backwards ecosysem)
25
+
26
+## TODO/WAT
27
+
28
+I finally grok the getdns api so the package api is going to change
29
+wildly and fast. It’s only going to support DNS over TLS but will
30
+support all types of DNS queries.
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
+## Why?
40
+
41
+Well, for starters, to help research DNS over TLS servers. Plus, for
42
+fun\!
43
+
44
+If you’re asking “Why DNS over TLS at all?” then “faux” privacy. Why
45
+“faux”? Well, *something* is handing your query and that something
46
+knows your IP address and what you looked for. So, you’re relying on the
47
+good faith, honest nature and technical capability of the destination
48
+server to not mess with you. I don’t trust Cloudflare or Google and am
49
+witholding judgement on Quad9 either way (they’ve been doing good things
50
+and are less “look at how cool we are” than CF is).
51
+
52
+Also “faux” in that you’re going to be using a standard port (853) and a
53
+TLS session for the queries so your internet provider will know you’re
54
+doing *something* and the current, sorry state of SSL certificates,
55
+certificate authorities, and authoritarian companies and regimes
56
+combined means confidentiality and integrity are always kinda in
57
+question unless done super-well.
58
+
59
+## What’s Different About This vs Regular DNS?
60
+
61
+Well, if we lookup the addresses for `yahoo.com` the old-fashioned way
62
+it’s cleartext UDP on the
63
+    wire:
64
+
65
+    1   0.000000   10.1.10.57 → 10.1.10.200  DNS 80 Standard query 0x8af8 A yahoo.com OPT
66
+    2   0.003297  10.1.10.200 → 10.1.10.57   DNS 176 Standard query response 0x8af8 A yahoo.com A 72.30.35.10 A 98.138.219.231 A 72.30.35.9 A 98.137.246.7 A 98.138.219.232 A 98.137.246.8 OPT
67
+
68
+I watched for port 53 UDP traffic with `tshark` as `yahoo.com` was being
69
+looked up. Notice the fast and diminuitive — and plaintext — response.
70
+(I’m fibbing a bit since I pre-loaded the local home DNS server with
71
+this query since I tested it alot before knitting this readme. My home
72
+server forwards all queries to a custom DNS over TLS server since I
73
+really don’t trust any of the providers when it comes down to it. So, in
74
+reality for me, it’s even slower than the below — at least initially).
75
+
76
+This is the same query via DNS over
77
+TLS
78
+
79
+``` 
80
+ 1   0.000000   10.1.10.57 → 9.9.9.9      TCP 78 52128 → 853 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=64 TSval=602885491 TSecr=0 SACK_PERM=1 TFO=R
81
+ 2   0.021188      9.9.9.9 → 10.1.10.57   TCP 74 853 → 52128 [SYN, ACK] Seq=0 Ack=1 Win=28960 Len=0 MSS=1460 SACK_PERM=1 TSval=3426782438 TSecr=602885491 WS=256
82
+ 3   0.021308   10.1.10.57 → 9.9.9.9      TLSv1 373 Client Hello
83
+ 4   0.045324      9.9.9.9 → 10.1.10.57   TLSv1.2 1514 Server Hello
84
+ 5   0.045333      9.9.9.9 → 10.1.10.57   TLSv1.2 73 [TCP Previous segment not captured] , Ignored Unknown Record
85
+ 6   0.045334      9.9.9.9 → 10.1.10.57   TCP 1514 [TCP Out-Of-Order] 853 → 52128 [ACK] Seq=1449 Ack=308 Win=30208 Len=1448 TSval=3426782459 TSecr=602885512
86
+ 7   0.045491   10.1.10.57 → 9.9.9.9      TCP 78 52128 → 853 [ACK] Seq=308 Ack=1449 Win=130304 Len=0 TSval=602885536 TSecr=3426782459 SLE=2897 SRE=2904
87
+ 8   0.045492   10.1.10.57 → 9.9.9.9      TCP 66 52128 → 853 [ACK] Seq=308 Ack=2904 Win=128832 Len=0 TSval=602885536 TSecr=3426782459
88
+ 9   0.050527   10.1.10.57 → 9.9.9.9      TLSv1.2 192 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
89
+10   0.069107      9.9.9.9 → 10.1.10.57   TLSv1.2 117 Change Cipher Spec, Encrypted Handshake Message
90
+11   0.069255   10.1.10.57 → 9.9.9.9      TCP 66 52128 → 853 [ACK] Seq=434 Ack=2955 Win=131008 Len=0 TSval=602885559 TSecr=3426782487
91
+12   0.069516   10.1.10.57 → 9.9.9.9      TLSv1.2 225 Application Data
92
+13   0.091087      9.9.9.9 → 10.1.10.57   TLSv1.2 303 Application Data
93
+14   0.091207   10.1.10.57 → 9.9.9.9      TLSv1.2 225 Application Data
94
+15   0.106738      9.9.9.9 → 10.1.10.57   TLSv1.2 231 Application Data
95
+16   0.106836   10.1.10.57 → 9.9.9.9      TCP 66 52128 → 853 [ACK] Seq=752 Ack=3357 Win=130880 Len=0 TSval=602885595 TSecr=3426782525
96
+17   0.107200   10.1.10.57 → 9.9.9.9      TLSv1.2 97 Encrypted Alert
97
+18   0.107411   10.1.10.57 → 9.9.9.9      TCP 66 52128 → 853 [FIN, ACK] Seq=783 Ack=3357 Win=131072 Len=0 TSval=602885595 TSecr=3426782525
98
+19   0.126603      9.9.9.9 → 10.1.10.57   TLSv1.2 97 Encrypted Alert
99
+20   0.126608      9.9.9.9 → 10.1.10.57   TCP 66 853 → 52128 [FIN, ACK] Seq=3388 Ack=784 Win=32256 Len=0 TSval=3426782545 TSecr=602885595
100
+21   0.126717   10.1.10.57 → 9.9.9.9      TCP 54 52128 → 853 [RST] Seq=784 Win=0 Len=0
101
+22   0.126718   10.1.10.57 → 9.9.9.9      TCP 54 52128 → 853 [RST] Seq=784 Win=0 Len=0
102
+```
103
+
104
+It’s stupid slow, consumes more CPU and bandwidth but forces adversaries
105
+to work pretty hard to try to figure out what you’re looking for.
106
+
107
+## What’s Inside The Tin
108
+
109
+The following functions are implemented:
110
+
111
+  - `get_address`: Lookup IP Address(es) for a Given Host
112
+
113
+## Installation
114
+
115
+``` r
116
+devtools::install_git("https://gitlab.com/hrbrmstr/clandnstine.git")
117
+# or
118
+devtools::install_github("hrbrmstr/clandnstine")
119
+```
120
+
121
+## Usage
122
+
123
+``` r
124
+library(clandnstine)
125
+
126
+# current version
127
+packageVersion("clandnstine")
128
+## [1] '0.1.0'
129
+```
130
+
131
+``` r
132
+get_address("r-project.org") # use built-in default of Quad9 (9.9.9.9)
133
+## [1] "137.208.57.37"
134
+
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"
139
+
140
+get_address("doesnotexist.commmm", "1.1.1.1") # nothing to find
141
+## character(0)
142
+```
143
+
144
+## clandnstine Metrics
145
+
146
+| Lang | \# Files |  (%) | LoC |  (%) | Blank lines |  (%) | \# Lines |  (%) |
147
+| :--- | -------: | ---: | --: | ---: | ----------: | ---: | -------: | ---: |
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 |
151
+
152
+## Code of Conduct
153
+
154
+Please note that this project is released with a [Contributor Code of
155
+Conduct](CONDUCT.md). By participating in this project you agree to
156
+abide by its terms.

+ 21
- 0
man/get_address.Rd View File

@@ -0,0 +1,21 @@
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
+}

+ 3
- 0
src/.gitignore View File

@@ -0,0 +1,3 @@
1
+*.o
2
+*.so
3
+*.dll

+ 3
- 0
src/Makevars View File

@@ -0,0 +1,3 @@
1
+CXX_STD = CXX11
2
+PKG_CXXFLAGS =
3
+PKG_LIBS = -lgetdns

+ 29
- 0
src/RcppExports.cpp View File

@@ -0,0 +1,29 @@
1
+// Generated by using Rcpp::compileAttributes() -> do not edit by hand
2
+// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
3
+
4
+#include <Rcpp.h>
5
+
6
+using namespace Rcpp;
7
+
8
+// get_address
9
+CharacterVector get_address(std::string host, std::string resolver);
10
+RcppExport SEXP _clandnstine_get_address(SEXP hostSEXP, SEXP resolverSEXP) {
11
+BEGIN_RCPP
12
+    Rcpp::RObject rcpp_result_gen;
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));
17
+    return rcpp_result_gen;
18
+END_RCPP
19
+}
20
+
21
+static const R_CallMethodDef CallEntries[] = {
22
+    {"_clandnstine_get_address", (DL_FUNC) &_clandnstine_get_address, 2},
23
+    {NULL, NULL, 0}
24
+};
25
+
26
+RcppExport void R_init_clandnstine(DllInfo *dll) {
27
+    R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
28
+    R_useDynamicSymbols(dll, FALSE);
29
+}

+ 79
- 0
src/clandnstine-main.cpp View File

@@ -0,0 +1,79 @@
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
+
7
+//' Lookup IP Address(es) for a Given Host
8
+//'
9
+//' @param host host (length 1 <chr>)
10
+//' @param resolver resolver address. defaults to Quad9; (length 1 <chr>)
11
+//' @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
+// [[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
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);
76
+
77
+  if (ok) return(wrap(out)); else return(CharacterVector());
78
+
79
+}

Loading…
Cancel
Save