1inet_res(3) Erlang Module Definition inet_res(3)
2
3
4
6 inet_res - A rudimentary DNS client.
7
9 This module performs DNS name resolving to recursive name servers.
10
11 See also ERTS User's Guide: Inet Configuration for more information
12 about how to configure an Erlang runtime system for IP communication,
13 and how to enable this DNS client by defining 'dns' as a lookup method.
14 The DNS client then acts as a backend for the resolving functions in
15 inet.
16
17 This DNS client can resolve DNS records even if it is not used for nor‐
18 mal name resolving in the node.
19
20 This is not a full-fledged resolver, only a DNS client that relies on
21 asking trusted recursive name servers.
22
24 UDP queries are used unless resolver option usevc is true, which forces
25 TCP queries. If the query is too large for UDP, TCP is used instead.
26 For regular DNS queries, 512 bytes is the size limit.
27
28 When EDNS is enabled (resolver option edns is set to the EDNS version
29 (that is, 0 instead of false), resolver option udp_payload_size sets
30 the limit. If a name server replies with the TC bit set (truncation),
31 indicating that the answer is incomplete, the query is retried to that
32 name server using TCP. Resolver option udp_payload_size also sets the
33 advertised size for the maximum allowed reply size, if EDNS is enabled,
34 otherwise the name server uses the limit 512 bytes. If the reply is
35 larger, it gets truncated, forcing a TCP requery.
36
37 For UDP queries, resolver options timeout and retry control retransmis‐
38 sion. Each name server in the nameservers list is tried with a time-out
39 of timeout/retry. Then all name servers are tried again, doubling the
40 time-out, for a total of retry times.
41
42 For queries not using the search list, if the query to all nameservers
43 results in {error,nxdomain} or an empty answer, the same query is tried
44 for alt_nameservers.
45
47 The following data types concern the resolver:
48
50 res_option() =
51 {alt_nameservers, [nameserver()]} |
52 {edns, 0 | false} |
53 {inet6, boolean()} |
54 {nameservers, [nameserver()]} |
55 {recurse, boolean()} |
56 {retry, integer()} |
57 {timeout, integer()} |
58 {udp_payload_size, integer()} |
59 {usevc, boolean()}
60
61 nameserver() = {inet:ip_address(), Port :: 1..65535}
62
63 res_error() =
64 formerr |
65 qfmterror |
66 servfail |
67 nxdomain |
68 notimp |
69 refused |
70 badvers |
71 timeout
72
74 The following data types concern the DNS client:
75
77 dns_name() = string()
78
79 A string with no adjacent dots.
80
81 rr_type() =
82 a |
83 aaaa |
84 cname |
85 gid |
86 hinfo |
87 ns |
88 mb |
89 md |
90 mg |
91 mf |
92 minfo |
93 mx |
94 naptr |
95 null |
96 ptr |
97 soa |
98 spf |
99 srv |
100 txt |
101 uid |
102 uinfo |
103 unspec |
104 wks
105
106 dns_class() = in | chaos | hs | any
107
108 dns_msg() = term()
109
110 This is the start of a hiearchy of opaque data structures that
111 can be examined with access functions in inet_dns, which return
112 lists of {Field,Value} tuples. The arity 2 functions only return
113 the value for a specified field.
114
115 dns_msg() = DnsMsg
116 inet_dns:msg(DnsMsg) ->
117 [ {header, dns_header()}
118 | {qdlist, dns_query()}
119 | {anlist, dns_rr()}
120 | {nslist, dns_rr()}
121 | {arlist, dns_rr()} ]
122 inet_dns:msg(DnsMsg, header) -> dns_header() % for example
123 inet_dns:msg(DnsMsg, Field) -> Value
124
125 dns_header() = DnsHeader
126 inet_dns:header(DnsHeader) ->
127 [ {id, integer()}
128 | {qr, boolean()}
129 | {opcode, query | iquery | status | integer()}
130 | {aa, boolean()}
131 | {tc, boolean()}
132 | {rd, boolean()}
133 | {ra, boolean()}
134 | {pr, boolean()}
135 | {rcode, integer(0..16)} ]
136 inet_dns:header(DnsHeader, Field) -> Value
137
138 query_type() = axfr | mailb | maila | any | rr_type()
139
140 dns_query() = DnsQuery
141 inet_dns:dns_query(DnsQuery) ->
142 [ {domain, dns_name()}
143 | {type, query_type()}
144 | {class, dns_class()} ]
145 inet_dns:dns_query(DnsQuery, Field) -> Value
146
147 dns_rr() = DnsRr
148 inet_dns:rr(DnsRr) -> DnsRrFields | DnsRrOptFields
149 DnsRrFields = [ {domain, dns_name()}
150 | {type, rr_type()}
151 | {class, dns_class()}
152 | {ttl, integer()}
153 | {data, dns_data()} ]
154 DnsRrOptFields = [ {domain, dns_name()}
155 | {type, opt}
156 | {udp_payload_size, integer()}
157 | {ext_rcode, integer()}
158 | {version, integer()}
159 | {z, integer()}
160 | {data, dns_data()} ]
161 inet_dns:rr(DnsRr, Field) -> Value
162
163 There is an information function for the types above:
164
165 inet_dns:record_type(dns_msg()) -> msg;
166 inet_dns:record_type(dns_header()) -> header;
167 inet_dns:record_type(dns_query()) -> dns_query;
168 inet_dns:record_type(dns_rr()) -> rr;
169 inet_dns:record_type(_) -> undefined.
170
171 So, inet_dns:(inet_dns:record_type(X))(X) converts any of these
172 data structures into a {Field,Value} list.
173
174 dns_data() =
175 dns_name() |
176 inet:ip4_address() |
177 inet:ip6_address() |
178 {MName :: dns_name(),
179 RName :: dns_name(),
180 Serial :: integer(),
181 Refresh :: integer(),
182 Retry :: integer(),
183 Expiry :: integer(),
184 Minimum :: integer()} |
185 {inet:ip4_address(), Proto :: integer(), BitMap :: binary()} |
186 {CpuString :: string(), OsString :: string()} |
187 {RM :: dns_name(), EM :: dns_name()} |
188 {Prio :: integer(), dns_name()} |
189 {Prio :: integer(),
190 Weight :: integer(),
191 Port :: integer(),
192 dns_name()} |
193 {Order :: integer(),
194 Preference :: integer(),
195 Flags :: string(),
196 Services :: string(),
197 Regexp :: string(),
198 dns_name()} |
199 [string()] |
200 binary()
201
202 Regexp is a string with characters encoded in the UTF-8 coding
203 standard.
204
206 getbyname(Name, Type) -> {ok, Hostent} | {error, Reason}
207
208 getbyname(Name, Type, Timeout) -> {ok, Hostent} | {error, Reason}
209
210 Types:
211
212 Name = dns_name()
213 Type = rr_type()
214 Timeout = timeout()
215 Hostent = inet:hostent()
216 Reason = inet:posix() | res_error()
217
218 Resolves a DNS record of the specified type for the specified
219 host, of class in. Returns, on success, a hostent() record with
220 dns_data() elements in the address list field.
221
222 This function uses resolver option search that is a list of
223 domain names. If the name to resolve contains no dots, it is
224 prepended to each domain name in the search list, and they are
225 tried in order. If the name contains dots, it is first tried as
226 an absolute name and if that fails, the search list is used. If
227 the name has a trailing dot, it is supposed to be an absolute
228 name and the search list is not used.
229
230 gethostbyaddr(Address) -> {ok, Hostent} | {error, Reason}
231
232 gethostbyaddr(Address, Timeout) -> {ok, Hostent} | {error, Reason}
233
234 Types:
235
236 Address = inet:ip_address()
237 Timeout = timeout()
238 Hostent = inet:hostent()
239 Reason = inet:posix() | res_error()
240
241 Backend functions used by inet:gethostbyaddr/1.
242
243 gethostbyname(Name) -> {ok, Hostent} | {error, Reason}
244
245 gethostbyname(Name, Family) -> {ok, Hostent} | {error, Reason}
246
247 gethostbyname(Name, Family, Timeout) ->
248 {ok, Hostent} | {error, Reason}
249
250 Types:
251
252 Name = dns_name()
253 Hostent = inet:hostent()
254 Timeout = timeout()
255 Family = inet:address_family()
256 Reason = inet:posix() | res_error()
257
258 Backend functions used by inet:gethostbyname/1,2.
259
260 This function uses resolver option search just like getby‐
261 name/2,3.
262
263 If resolver option inet6 is true, an IPv6 address is looked up.
264
265 lookup(Name, Class, Type) -> [dns_data()]
266
267 lookup(Name, Class, Type, Opts) -> [dns_data()]
268
269 lookup(Name, Class, Type, Opts, Timeout) -> [dns_data()]
270
271 Types:
272
273 Name = dns_name() | inet:ip_address()
274 Class = dns_class()
275 Type = rr_type()
276 Opts = [res_option() | verbose]
277 Timeout = timeout()
278
279 Resolves the DNS data for the record of the specified type and
280 class for the specified name. On success, filters out the answer
281 records with the correct Class and Type, and returns a list of
282 their data fields. So, a lookup for type any gives an empty
283 answer, as the answer records have specific types that are not
284 any. An empty answer or a failed lookup returns an empty list.
285
286 Calls resolve/* with the same arguments and filters the result,
287 so Opts is described for those functions.
288
289 resolve(Name, Class, Type) -> {ok, dns_msg()} | Error
290
291 resolve(Name, Class, Type, Opts) -> {ok, dns_msg()} | Error
292
293 resolve(Name, Class, Type, Opts, Timeout) ->
294 {ok, dns_msg()} | Error
295
296 Types:
297
298 Name = dns_name() | inet:ip_address()
299 Class = dns_class()
300 Type = rr_type()
301 Opts = [Opt]
302 Opt = res_option() | verbose | atom()
303 Timeout = timeout()
304 Error = {error, Reason} | {error, {Reason, dns_msg()}}
305 Reason = inet:posix() | res_error()
306
307 Resolves a DNS record of the specified type and class for the
308 specified name. The returned dns_msg() can be examined using
309 access functions in inet_db, as described in section in DNS
310 Types.
311
312 If Name is an ip_address(), the domain name to query for is gen‐
313 erated as the standard reverse ".IN-ADDR.ARPA." name for an IPv4
314 address, or the ".IP6.ARPA." name for an IPv6 address. In this
315 case, you most probably want to use Class = in and Type = ptr,
316 but it is not done automatically.
317
318 Opts overrides the corresponding resolver options. If option
319 nameservers is specified, it is assumed that it is the complete
320 list of name serves, so resolver option alt_nameserves is
321 ignored. However, if option alt_nameserves is also specified to
322 this function, it is used.
323
324 Option verbose (or rather {verbose,true}) causes diagnostics
325 printout through io:format/2 of queries, replies retransmis‐
326 sions, and so on, similar to from utilities, such as dig and
327 nslookup.
328
329 If Opt is any atom, it is interpreted as {Opt,true} unless the
330 atom string starts with "no", making the interpretation
331 {Opt,false}. For example, usevc is an alias for {usevc,true} and
332 nousevc is an alias for {usevc,false}.
333
334 Option inet6 has no effect on this function. You probably want
335 to use Type = a | aaaa instead.
336
338 This access functions example shows how lookup/3 can be implemented
339 using resolve/3 from outside the module:
340
341 example_lookup(Name, Class, Type) ->
342 case inet_res:resolve(Name, Class, Type) of
343 {ok,Msg} ->
344 [inet_dns:rr(RR, data)
345 || RR <- inet_dns:msg(Msg, anlist),
346 inet_dns:rr(RR, type) =:= Type,
347 inet_dns:rr(RR, class) =:= Class];
348 {error,_} ->
349 []
350 end.
351
353 These are deprecated because the annoying double meaning of the name
354 servers/time-out argument, and because they have no decent place for a
355 resolver options list.
356
358 nslookup(Name, Class, Type) -> {ok, dns_msg()} | {error, Reason}
359
360 nslookup(Name, Class, Type, Timeout) ->
361 {ok, dns_msg()} | {error, Reason}
362
363 nslookup(Name, Class, Type, Nameservers) ->
364 {ok, dns_msg()} | {error, Reason}
365
366 Types:
367
368 Name = dns_name() | inet:ip_address()
369 Class = dns_class()
370 Type = rr_type()
371 Timeout = timeout()
372 Nameservers = [nameserver()]
373 Reason = inet:posix() | res_error()
374
375 Resolves a DNS record of the specified type and class for the
376 specified name.
377
378 nnslookup(Name, Class, Type, Nameservers) ->
379 {ok, dns_msg()} | {error, Reason}
380
381 nnslookup(Name, Class, Type, Nameservers, Timeout) ->
382 {ok, dns_msg()} | {error, Reason}
383
384 Types:
385
386 Name = dns_name() | inet:ip_address()
387 Class = dns_class()
388 Type = rr_type()
389 Timeout = timeout()
390 Nameservers = [nameserver()]
391 Reason = inet:posix()
392
393 Resolves a DNS record of the specified type and class for the
394 specified name.
395
396
397
398Ericsson AB kernel 6.3.1.1 inet_res(3)