1<?xml version="1.0" encoding="utf-8" ?> 2<!DOCTYPE erlref SYSTEM "erlref.dtd"> 3 4<erlref> 5 <header> 6 <copyright> 7 <year>2009</year><year>2021</year> 8 <holder>Ericsson AB. All Rights Reserved.</holder> 9 </copyright> 10 <legalnotice> 11 Licensed under the Apache License, Version 2.0 (the "License"); 12 you may not use this file except in compliance with the License. 13 You may obtain a copy of the License at 14 15 http://www.apache.org/licenses/LICENSE-2.0 16 17 Unless required by applicable law or agreed to in writing, software 18 distributed under the License is distributed on an "AS IS" BASIS, 19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 See the License for the specific language governing permissions and 21 limitations under the License. 22 23 </legalnotice> 24 25 <title>inet_res</title> 26 <prepared>raimo@erix.ericsson.se</prepared> 27 <docno></docno> 28 <date>2009-09-11</date> 29 <rev>A</rev> 30 </header> 31 <module since="">inet_res</module> 32 <modulesummary>A rudimentary DNS client.</modulesummary> 33 <description> 34 <p>This module performs DNS name resolving to recursive name servers.</p> 35 <p>See also 36 <seeguide marker="erts:inet_cfg">ERTS User's Guide: Inet Configuration</seeguide> 37 for more information about how to configure an Erlang runtime system 38 for IP communication, and how to enable this DNS client by defining 39 <c><![CDATA['dns']]></c> as a lookup method. 40 The DNS client then acts as a backend for the resolving functions in 41 <seeerl marker="kernel:inet"><c>inet</c></seeerl>.</p> 42 <p>This DNS client can resolve DNS records even if it 43 is not used for normal name resolving in the node.</p> 44 <p>This is not a full-fledged resolver, only a 45 DNS client that relies on asking trusted recursive name servers.</p> 46 </description> 47 48 <section> 49 <title>Name Resolving</title> 50 <p>UDP queries are used unless resolver option 51 <c>usevc</c> is <c>true</c>, which forces TCP queries. 52 If the query is too large for UDP, TCP is used instead. 53 For regular DNS queries, 512 bytes is the size limit.</p> 54 55 <p>When EDNS is enabled (resolver option 56 <c>edns</c> is set to the EDNS version (that is, <c>0</c> 57 instead of <c>false</c>), resolver option 58 <c>udp_payload_size</c> sets the limit. If a name server 59 replies with the TC bit set (truncation), indicating that 60 the answer is incomplete, the query is retried 61 to that name server using TCP. Resolver option 62 <c>udp_payload_size</c> also sets the advertised 63 size for the maximum allowed reply size, if EDNS is 64 enabled, otherwise the name server uses the limit 65 512 bytes. If the reply is larger, it gets truncated, 66 forcing a TCP requery.</p> 67 68 <p>For UDP queries, resolver options <c>timeout</c> 69 and <c>retry</c> control retransmission. 70 Each name server in the <c>nameservers</c> list is 71 tried with a time-out of <c>timeout</c>/<c>retry</c>. 72 Then all name servers are tried again, doubling the 73 time-out, for a total of <c>retry</c> times.</p> 74 75 <marker id="servfail_retry_timeout"/> 76 <p>But before all name servers are tried again, there is a 77 (user configurable) timeout, <c>servfail_retry_timeout</c>. 78 The point of this is to prevent the new query to be handled by 79 a server's servfail cache (a client that is to eager will 80 actually only get what is in the servfail cache). 81 If there is too little time left 82 of the resolver call's timeout to do a retry, 83 the resolver call may return 84 before the call's timeout has expired. </p> 85 86 <p>For queries not using the <c>search</c> list, 87 if the query to all <c>nameservers</c> results in 88 <c>{error,nxdomain}</c> or an empty answer, the same 89 query is tried for <c>alt_nameservers</c>.</p> 90 </section> 91 92 <section> 93 <title>Resolver Types</title> 94 <p>The following data types concern the resolver:</p> 95 </section> 96 <datatypes> 97 <datatype> 98 <name name="res_option"/> 99 </datatype> 100 <datatype> 101 <name name="nameserver"/> 102 </datatype> 103 <datatype> 104 <name name="res_error"/> 105 </datatype> 106 </datatypes> 107 108 <section> 109 <title>DNS Types</title> 110 <p><marker id="dns_types"/> 111 The following data types concern the DNS client:</p> 112 </section> 113 114 <datatypes> 115 <datatype> 116 <name name="dns_name"/> 117 <desc><p>A string with no adjacent dots.</p></desc> 118 </datatype> 119 <datatype> 120 <name name="rr_type"/> 121 </datatype> 122 <datatype> 123 <name name="dns_class"/> 124 </datatype> 125 <datatype> 126 <name name="dns_msg"/> 127 <desc> 128 <p>This is the start of a hiearchy of opaque data structures 129 that can be examined with access functions in <c>inet_dns</c>, which 130 return lists of <c>{Field,Value}</c> tuples. The arity 2 functions 131 only return the value for a specified field.</p> 132 <pre> 133dns_msg() = DnsMsg 134 inet_dns:msg(DnsMsg) -> 135 [ {header, dns_header()} 136 | {qdlist, dns_query()} 137 | {anlist, dns_rr()} 138 | {nslist, dns_rr()} 139 | {arlist, dns_rr()} ] 140 inet_dns:msg(DnsMsg, header) -> dns_header() % for example 141 inet_dns:msg(DnsMsg, Field) -> Value 142 143dns_header() = DnsHeader 144 inet_dns:header(DnsHeader) -> 145 [ {id, integer()} 146 | {qr, boolean()} 147 | {opcode, query | iquery | status | integer()} 148 | {aa, boolean()} 149 | {tc, boolean()} 150 | {rd, boolean()} 151 | {ra, boolean()} 152 | {pr, boolean()} 153 | {rcode, integer(0..16)} ] 154 inet_dns:header(DnsHeader, Field) -> Value 155 156query_type() = axfr | mailb | maila | any | rr_type() 157 158dns_query() = DnsQuery 159 inet_dns:dns_query(DnsQuery) -> 160 [ {domain, dns_name()} 161 | {type, query_type()} 162 | {class, dns_class()} ] 163 inet_dns:dns_query(DnsQuery, Field) -> Value 164 165dns_rr() = DnsRr 166 inet_dns:rr(DnsRr) -> DnsRrFields | DnsRrOptFields 167 DnsRrFields = [ {domain, dns_name()} 168 | {type, rr_type()} 169 | {class, dns_class()} 170 | {ttl, integer()} 171 | {data, dns_data()} ] 172 DnsRrOptFields = [ {domain, dns_name()} 173 | {type, opt} 174 | {udp_payload_size, integer()} 175 | {ext_rcode, integer()} 176 | {version, integer()} 177 | {z, integer()} 178 | {data, dns_data()} ] 179 inet_dns:rr(DnsRr, Field) -> Value</pre> 180 <p>There is an information function for the types above:</p> 181 <pre> 182inet_dns:record_type(dns_msg()) -> msg; 183inet_dns:record_type(dns_header()) -> header; 184inet_dns:record_type(dns_query()) -> dns_query; 185inet_dns:record_type(dns_rr()) -> rr; 186inet_dns:record_type(_) -> undefined.</pre> 187 <p>So, <c>inet_dns:(inet_dns:record_type(X))(X)</c> converts 188 any of these data structures into a <c>{Field,Value}</c> list.</p> 189 </desc> 190 </datatype> 191 <datatype> 192 <name name="dns_data"/> 193 <desc> 194 <p><c><anno>Regexp</anno></c> is a string with characters encoded 195 in the UTF-8 coding standard.</p> 196 </desc> 197 </datatype> 198 </datatypes> 199 200 <funcs> 201 <func> 202 <name name="getbyname" arity="2" since=""/> 203 <name name="getbyname" arity="3" since=""/> 204 <fsummary>Resolve a DNS record of the specified type for the specified 205 host.</fsummary> 206 <desc> 207 <p>Resolves a DNS record of the specified type for the specified host, 208 of class <c>in</c>. Returns, on success, a <c>hostent()</c> record 209 with <c>dns_data()</c> elements in the address list field.</p> 210 <p>This function uses resolver option <c>search</c> that 211 is a list of domain names. If the name to resolve contains 212 no dots, it is prepended to each domain name in the 213 search list, and they are tried in order. If the name 214 contains dots, it is first tried as an absolute name 215 and if that fails, the search list is used. If the name 216 has a trailing dot, it is supposed to be 217 an absolute name and the search list is not used.</p> 218 </desc> 219 </func> 220 221 <func> 222 <name name="gethostbyaddr" arity="1" since=""/> 223 <name name="gethostbyaddr" arity="2" since=""/> 224 <fsummary>Return a hostent record for the host with the specified 225 address.</fsummary> 226 <desc> 227 <p>Backend functions used by 228 <seemfa marker="kernel:inet#gethostbyaddr/1"><c>inet:gethostbyaddr/1</c></seemfa>. 229 </p> 230 </desc> 231 </func> 232 233 <func> 234 <name name="gethostbyname" arity="1" since=""/> 235 <name name="gethostbyname" arity="2" since=""/> 236 <name name="gethostbyname" arity="3" since=""/> 237 <fsummary>Return a hostent record for the host with the specified name. 238 </fsummary> 239 <desc> 240 <p>Backend functions used by 241 <seemfa marker="kernel:inet#gethostbyname/1"><c>inet:gethostbyname/1,2</c></seemfa>. 242 </p> 243 <p>This function uses resolver option <c>search</c> just like 244 <seemfa marker="#getbyname/2"><c>getbyname/2,3</c></seemfa>. 245 </p> 246 <p>If resolver option <c>inet6</c> is <c>true</c>, 247 an IPv6 address is looked up.</p> 248 </desc> 249 </func> 250 251 <func> 252 <name name="lookup" arity="3" since=""/> 253 <name name="lookup" arity="4" since=""/> 254 <name name="lookup" arity="5" since=""/> 255 <fsummary>Resolve the DNS data for the record of the specified type 256 and class for the specified name.</fsummary> 257 <desc> 258 <p>Resolves the DNS data for the record of the specified type and class 259 for the specified name. On success, filters out the answer records 260 with the correct <c><anno>Class</anno></c> and 261 <c><anno>Type</anno></c>, and returns 262 a list of their data fields. So, a lookup for type <c>any</c> 263 gives an empty answer, as the answer records have 264 specific types that are not <c>any</c>. An empty answer 265 or a failed lookup returns an empty list.</p> 266 <p>Calls 267 <seemfa marker="#resolve/3"><c>resolve/*</c></seemfa> 268 with the same arguments and filters the result, so 269 <c><anno>Opts</anno></c> is described for those functions.</p> 270 </desc> 271 </func> 272 273 <func> 274 <name name="resolve" arity="3" since=""/> 275 <name name="resolve" arity="4" since=""/> 276 <name name="resolve" arity="5" since=""/> 277 <fsummary>Resolve a DNS record of the specified type and class 278 for the specified name.</fsummary> 279 <desc> 280 <p>Resolves a DNS record of the specified type and class for the 281 specified name. The returned <c>dns_msg()</c> can be examined using 282 access functions in <c>inet_db</c>, as described in section 283 in <seeerl marker="#dns_types">DNS Types</seeerl>.</p> 284 <p>If <c><anno>Name</anno></c> is an <c>ip_address()</c>, the domain 285 name to query for is generated as the standard reverse 286 <c>".IN-ADDR.ARPA."</c> name for an IPv4 address, or the 287 <c>".IP6.ARPA."</c> name for an IPv6 address. 288 In this case, you most probably want to use 289 <c><anno>Class</anno> = in</c> and <c><anno>Type</anno> = ptr</c>, 290 but it is not done automatically.</p> 291 <p><c><anno>Opts</anno></c> overrides the corresponding resolver 292 options. If option <c>nameservers</c> is specified, it is 293 assumed that it is the complete list of name serves, 294 so resolver option <c>alt_nameserves</c> is ignored. 295 However, if option <c>alt_nameserves</c> is also specified to this 296 function, it is used.</p> 297 <p>Option <c>verbose</c> (or rather <c>{verbose,true}</c>) 298 causes diagnostics printout through 299 <seemfa marker="stdlib:io#format/3"><c>io:format/2</c></seemfa> 300 of queries, replies retransmissions, and so on, similar 301 to from utilities, such as <c>dig</c> and <c>nslookup</c>.</p> 302 <p>If <c><anno>Opt</anno></c> is any atom, it is interpreted 303 as <c>{<anno>Opt</anno>,true}</c> unless the atom string starts with 304 <c>"no"</c>, making the 305 interpretation <c>{<anno>Opt</anno>,false}</c>. 306 For example, <c>usevc</c> is an alias for <c>{usevc,true}</c> 307 and <c>nousevc</c> is an alias for <c>{usevc,false}</c>.</p> 308 <p>Option <c>inet6</c> has no effect on this function. You 309 probably want to use <c><anno>Type</anno> = a | aaaa</c> instead.</p> 310 </desc> 311 </func> 312 </funcs> 313 314 <section> 315 <title>Example</title> 316 <p>This access functions example shows how 317 <seemfa marker="#lookup/3"><c>lookup/3</c></seemfa> 318 can be implemented using 319 <seemfa marker="#resolve/3"><c>resolve/3</c></seemfa> 320 from outside the module:</p> 321 <code type="none"> 322example_lookup(Name, Class, Type) -> 323 case inet_res:resolve(Name, Class, Type) of 324 {ok,Msg} -> 325 [inet_dns:rr(RR, data) 326 || RR <- inet_dns:msg(Msg, anlist), 327 inet_dns:rr(RR, type) =:= Type, 328 inet_dns:rr(RR, class) =:= Class]; 329 {error,_} -> 330 [] 331 end.</code> 332 </section> 333 334 335 336 <funcs> 337 <fsdescription> 338 <title>Legacy Functions</title> 339 <p>These are deprecated because the annoying double 340 meaning of the name servers/time-out argument, and 341 because they have no decent place for a resolver options list.</p> 342 </fsdescription> 343 <func> 344 <name name="nslookup" arity="3" since=""/> 345 <name name="nslookup" arity="4" clause_i="1" since=""/> 346 <name name="nslookup" arity="4" clause_i="2" since=""/> 347 <fsummary>Resolve a DNS record of the specified type and class for the 348 specified name.</fsummary> 349 <type variable="Name"/> 350 <type variable="Class"/> 351 <type variable="Type"/> 352 <type variable="Timeout" name_i="2"/> 353 <type variable="Nameservers"/> 354 <type variable="Reason"/> 355 <desc> 356 <p>Resolves a DNS record of the specified type and class for the 357 specified name.</p> 358 </desc> 359 </func> 360 361 <func> 362 <name name="nnslookup" arity="4" since=""/> 363 <name name="nnslookup" arity="5" since=""/> 364 <fsummary>Resolve a DNS record of the specified type and class 365 for the specified name.</fsummary> 366 <desc> 367 <p>Resolves a DNS record of the specified type and class for the 368 specified name.</p> 369 </desc> 370 </func> 371 </funcs> 372</erlref> 373