查看源代码 inet_res (内核 v10.2)

一个基本的 DNS 客户端。

此模块执行向递归名称服务器的 DNS 名称解析。

另请参阅 ERTS 用户指南:Inet 配置,以获取有关如何为 IP 通信配置 Erlang 运行时系统,以及如何通过将 'dns' 定义为查找方法来启用此 DNS 客户端的更多信息。然后,DNS 客户端充当 inet 中解析函数的后端。

即使此 DNS 客户端未用于节点中的常规名称解析,它也可以解析 DNS 记录。

这不是一个功能齐全的解析器,只是一个依赖于询问受信任的递归名称服务器的 DNS 客户端。

名称解析

除非解析器选项 usevctrue(强制使用 TCP 查询),否则使用 UDP 查询。如果查询对于 UDP 来说太大,则会改用 TCP。对于常规 DNS 查询,大小限制为 512 字节。

当启用 EDNS 时(解析器选项 edns 设置为 EDNS 版本,即:0 而不是 false),解析器选项 udp_payload_size 设置有效负载大小限制。如果名称服务器回复时设置了 TC 位(截断),表示答案不完整,则会使用 TCP 向同一名称服务器重试查询。如果启用了 EDNS,解析器选项 udp_payload_size 还会设置允许的最大回复大小的通告大小,否则名称服务器会使用 512 字节的限制。如果回复较大,则会被截断,从而强制进行 TCP 重新查询。

对于 UDP 查询,解析器选项 timeoutretry 控制重传。nameservers 列表中的每个名称服务器都会尝试使用 timeout/retry 的超时时间。然后,所有名称服务器都会再次尝试,超时时间加倍,总共尝试 retry 次。

但是在再次尝试所有名称服务器之前,有一个(用户可配置的)超时时间 servfail_retry_timeout。这样做的目的是防止新查询被服务器的 servfail 缓存处理(一个太急切的客户端实际上只会得到 servfail 缓存中的内容)。如果解析器调用的超时时间剩余太少而无法进行重试,则解析器调用可能会在调用超时时间过期之前返回。

对于不使用 search 列表的查询,如果对所有 nameservers 的查询结果为 {error,nxdomain} 或空答案,则会为 alt_nameservers 尝试相同的查询。

解析器类型

以下数据类型与解析器有关

DNS 类型

以下数据类型与 DNS 客户端有关

示例

此访问函数示例显示了如何使用模块外部的 resolve/3 实现 lookup/3

example_lookup(Name, Class, Type) ->
    case inet_res:resolve(Name, Class, Type) of
        {ok,Msg} ->
            [inet_dns:rr(RR, data)
             || RR <- inet_dns:msg(Msg, anlist),
                 inet_dns:rr(RR, type) =:= Type,
                 inet_dns:rr(RR, class) =:= Class];
        {error,_} ->
            []
     end.

摘要

类型

DNS 记录数据(内容)

DNS 消息。

一个没有相邻点的字符串。

inet:hostent/0 的扩展变体。

类型

链接到此类型

dns_class()

查看源代码 (未导出)
-type dns_class() :: in | chaos | hs | any.
链接到此类型

dns_data()

查看源代码 (未导出)
-type dns_data() ::
          dns_name() |
          inet:ip4_address() |
          inet:ip6_address() |
          {MName :: dns_name(),
           RName :: dns_name(),
           Serial :: integer(),
           Refresh :: integer(),
           Retry :: integer(),
           Expiry :: integer(),
           Minimum :: integer()} |
          {inet:ip4_address(), Proto :: integer(), BitMap :: binary()} |
          {CpuString :: string(), OsString :: string()} |
          {RM :: dns_name(), EM :: dns_name()} |
          {Prio :: integer(), dns_name()} |
          {Prio :: integer(), Weight :: integer(), Port :: integer(), dns_name()} |
          {Order :: integer(),
           Preference :: integer(),
           Flags :: string(),
           Services :: string(),
           Regexp :: string(),
           dns_name()} |
          [string()] |
          binary().

DNS 记录数据(内容)

此类型中指定了每个数据元素的基本类型。

Regexp 是一个 UTF-8 string/0。其他 string/0 实际上是 Latin-1 字符串。

链接到此类型

dns_msg()

查看源代码 (未导出)
-type dns_msg() :: term().

DNS 消息。

这是一个不透明数据结构层次结构的开始,可以使用 inet_dns 中的访问函数检查,这些函数返回 {Field,Value} 元组的列表。arity 2 函数返回指定字段的值。

dns_msg() = DnsMsg
    inet_dns:msg(DnsMsg) ->
        [ {header, dns_header()}
        | {qdlist, dns_query()}
        | {anlist, dns_rr()}
        | {nslist, dns_rr()}
        | {arlist, dns_rr()} ]
    inet_dns:msg(DnsMsg, header) -> dns_header() % for example
    inet_dns:msg(DnsMsg, Field) -> Value

dns_header() = DnsHeader
    inet_dns:header(DnsHeader) ->
        [ {id, integer()}
        | {qr, boolean()}
        | {opcode, query | iquery | status | integer()}
        | {aa, boolean()}
        | {tc, boolean()}
        | {rd, boolean()}
        | {ra, boolean()}
        | {pr, boolean()}
        | {rcode, integer(0..16)} ]
    inet_dns:header(DnsHeader, Field) -> Value

query_type() = axfr | mailb | maila | any | dns_rr_type()

dns_query() = DnsQuery
    inet_dns:dns_query(DnsQuery) ->
        [ {domain, dns_name()}
        | {type, query_type()}
        | {class, dns_class()} ]
    inet_dns:dns_query(DnsQuery, Field) -> Value

dns_rr() = DnsRr
    inet_dns:rr(DnsRr) -> DnsRrFields | DnsRrOptFields
    DnsRrFields = [ {domain, dns_name()}
                  | {type, dns_rr_type()}
                  | {class, dns_class()}
                  | {ttl, integer()}
                  | {data, dns_data()} ]
    DnsRrOptFields = [ {domain, dns_name()}
                     | {type, opt}
                     | {udp_payload_size, integer()}
                     | {ext_rcode, integer()}
                     | {version, integer()}
                     | {z, integer()}
                     | {data, dns_data()} ]
    inet_dns:rr(DnsRr, Field) -> Value

上述类型有一个信息函数

inet_dns:record_type(dns_msg()) -> msg;
inet_dns:record_type(dns_header()) -> header;
inet_dns:record_type(dns_query()) -> dns_query;
inet_dns:record_type(dns_rr()) -> rr;
inet_dns:record_type(_) -> undefined.

因此,inet_dns:(inet_dns:record_type(X))(X) 将任何这些数据结构转换为 {Field,Value} 列表。

链接到此类型

dns_name()

查看源代码 (未导出)
-type dns_name() :: string().

一个没有相邻点的字符串。

链接到此类型

dns_rr_type()

查看源代码 (未导出)
-type dns_rr_type() ::
          a | aaaa | caa | cname | gid | hinfo | ns | mb | md | mg | mf | minfo | mx | naptr | null |
          ptr | soa | spf | srv | txt | uid | uinfo | unspec | uri | wks.
-type hostent() ::
          inet:hostent() |
          {hostent,
           H_name :: inet:hostname(),
           H_aliases :: [inet:hostname()],
           H_addrtype :: dns_rr_type(),
           H_length :: non_neg_integer(),
           H_addr_list :: [dns_data()]}.

inet:hostent/0 的扩展变体。

允许 dns_rr_type/0 用于 #hostent{}.h_addrtype 字段,以及 [dns_data/0] 用于 #hostent{}.h_addr_list 字段。

-type nameserver() :: {inet:ip_address(), Port :: 1..65535}.
-type res_error() :: formerr | qfmterror | servfail | nxdomain | notimp | refused | badvers | timeout.
-type res_option() ::
          {alt_nameservers, [nameserver()]} |
          {edns, 0 | false} |
          {inet6, boolean()} |
          {nameservers, [nameserver()]} |
          {recurse, boolean()} |
          {retry, integer()} |
          {timeout, integer()} |
          {udp_payload_size, integer()} |
          {dnssec_ok, boolean()} |
          {usevc, boolean()} |
          {nxdomain_reply, boolean()}.

旧函数

链接到此函数

nnslookup(Name, Class, Type, Nameservers)

查看源代码
-spec nnslookup(Name, Class, Type, Nameservers) -> {ok, dns_msg()} | {error, Reason}
                   when
                       Name :: dns_name() | inet:ip_address(),
                       Class :: dns_class(),
                       Type :: dns_rr_type(),
                       Nameservers :: [nameserver()],
                       Reason :: inet:posix().

等效于 nnslookup(Name, Class, Type, NSs, infinity)

链接到此函数

nnslookup(Name, Class, Type, Nameservers, Timeout)

查看源代码
-spec nnslookup(Name, Class, Type, Nameservers, Timeout) -> {ok, dns_msg()} | {error, Reason}
                   when
                       Name :: dns_name() | inet:ip_address(),
                       Class :: dns_class(),
                       Type :: dns_rr_type(),
                       Timeout :: timeout(),
                       Nameservers :: [nameserver()],
                       Reason :: inet:posix().

解析 DNS 查询。

nslookup/4 类似,但使用参数 Opts = [{nameservers, Nameservers}]Timeout 调用 resolve/5

链接到此函数

nslookup(Name, Class, Type)

查看源代码
-spec nslookup(Name, Class, Type) -> {ok, dns_msg()} | {error, Reason}
                  when
                      Name :: dns_name() | inet:ip_address(),
                      Class :: dns_class(),
                      Type :: dns_rr_type(),
                      Reason :: inet:posix() | res_error().

等效于 nslookup(Name, Class, Type, infinity)

-spec nslookup(Name, Class, Type, Timeout) -> {ok, dns_msg()} | {error, Reason}
                  when
                      Name :: dns_name() | inet:ip_address(),
                      Class :: dns_class(),
                      Type :: dns_rr_type(),
                      Timeout :: timeout(),
                      Reason :: inet:posix() | res_error();
              (Name, Class, Type, Nameservers) -> {ok, dns_msg()} | {error, Reason}
                  when
                      Name :: dns_name() | inet:ip_address(),
                      Class :: dns_class(),
                      Type :: dns_rr_type(),
                      Nameservers :: [nameserver()],
                      Reason :: inet:posix() | res_error().

解析 DNS 查询。

此函数是 resolve/5 的旧包装器,可简化将错误 {error, {Reason, _}} 匹配为 {error, Reason}{error, einval}

使用参数 Timeout 调用 resolve/5,其中 Opts = []

使用参数 Nameservers 调用 resolve/5,其中 Opts = [{nameservers, Nameservers}]Timeout = infinity

函数

-spec getbyname(Name, Type) -> {ok, Hostent} | {error, Reason}
                   when
                       Name :: dns_name(),
                       Type :: dns_rr_type(),
                       Hostent :: inet:hostent() | hostent(),
                       Reason :: inet:posix() | res_error().

等效于 getbyname(Name, Type, infinity)

链接到此函数

getbyname(Name, Type, Timeout)

查看源代码
-spec getbyname(Name, Type, Timeout) -> {ok, Hostent} | {error, Reason}
                   when
                       Name :: dns_name(),
                       Type :: dns_rr_type(),
                       Timeout :: timeout(),
                       Hostent :: inet:hostent() | hostent(),
                       Reason :: inet:posix() | res_error().

解析 DNS 查询。

解析指定主机的指定 Type 的 DNS 查询,类为 in。成功时,解析 Type = a|aaaa DNS 记录时,返回一个 #hostent{} 记录,其中 #hostent.h_addrtype = inet|inet6,分别;请参阅 inet:hostent/0

当解析其他 Type = dns_rr_type():s(类为 in)时,也会返回一个 #hostent{} 记录,但在 #hostent.h_addrtype 中使用 dns_rr_type/0,并在 #hostent.h_addr_list 中使用已解析的 dns_data/0;请参阅 hostent/0

此函数使用解析器选项 search,它是一个域名列表。如果要解析的名称不包含点,则会将其前置到搜索列表中的每个域名,并按顺序尝试。如果名称包含点,则首先将其作为绝对名称尝试,如果失败,则使用搜索列表。如果名称带有尾点,则应将其视为绝对名称,并且不使用搜索列表。

链接到此函数

gethostbyaddr(Address)

查看源代码
-spec gethostbyaddr(Address) -> {ok, Hostent} | {error, Reason}
                       when
                           Address :: inet:ip_address(),
                           Hostent :: inet:hostent(),
                           Reason :: inet:posix() | res_error().

等效于 gethostbyaddr(Address, infinity)

链接到此函数

gethostbyaddr(Address, Timeout)

查看源代码
-spec gethostbyaddr(Address, Timeout) -> {ok, Hostent} | {error, Reason}
                       when
                           Address :: inet:ip_address(),
                           Timeout :: timeout(),
                           Hostent :: inet:hostent(),
                           Reason :: inet:posix() | res_error().

inet:gethostbyaddr/1 使用的后端函数。

-spec gethostbyname(Name) -> {ok, Hostent} | {error, Reason}
                       when
                           Name :: dns_name(),
                           Hostent :: inet:hostent(),
                           Reason :: inet:posix() | res_error().

inet:gethostbyname/1,2 使用的后端函数。

如果解析器选项 inet6true,则等效于 gethostbyname(Name, inet6, infinity),否则等效于 gethostbyname(Name, inet, infinity)

链接到此函数

gethostbyname(Name, Family)

查看源代码
-spec gethostbyname(Name, Family) -> {ok, Hostent} | {error, Reason}
                       when
                           Name :: dns_name(),
                           Hostent :: inet:hostent(),
                           Family :: inet:address_family(),
                           Reason :: inet:posix() | res_error().

等效于 gethostbyname(Name, Family, infinity)

链接到此函数

gethostbyname(Name, Family, Timeout)

查看源代码
-spec gethostbyname(Name, Family, Timeout) -> {ok, Hostent} | {error, Reason}
                       when
                           Name :: dns_name(),
                           Hostent :: inet:hostent(),
                           Timeout :: timeout(),
                           Family :: inet:address_family(),
                           Reason :: inet:posix() | res_error().

inet:gethostbyname/1,2 使用的后端函数。

此函数像 getbyname/2,3 一样使用解析器选项 search

链接到此函数

lookup(Name, Class, Type)

查看源代码
-spec lookup(Name, Class, Type) -> [dns_data()]
                when Name :: dns_name() | inet:ip_address(), Class :: dns_class(), Type :: dns_rr_type().

等效于 lookup(Name, Class, Type, [], infinity)

链接到此函数

lookup(Name, Class, Type, Opts)

查看源代码
-spec lookup(Name, Class, Type, Opts) -> [dns_data()]
                when
                    Name :: dns_name() | inet:ip_address(),
                    Class :: dns_class(),
                    Type :: dns_rr_type(),
                    Opts :: [res_option() | verbose].

等效于 lookup(Name, Class, Type, Opts, infinity)

链接到此函数

lookup(Name, Class, Type, Opts, Timeout)

查看源代码
-spec lookup(Name, Class, Type, Opts, Timeout) -> [dns_data()]
                when
                    Name :: dns_name() | inet:ip_address(),
                    Class :: dns_class(),
                    Type :: dns_rr_type(),
                    Opts :: [res_option() | verbose],
                    Timeout :: timeout().

查找 DNS 数据。

解析指定 ClassType 的记录 Name 的 DNS 数据。成功时,会筛选出具有正确 ClassType 的应答记录,并返回其数据字段的列表。因此,对 any 类型的查找会返回一个空答案,因为应答记录具有不是 any 的特定类型。空答案或失败的查找会返回一个空列表。

使用相同的参数调用 resolve/* 并筛选结果,因此 Opts 在这些函数中描述。

链接到此函数

resolve(Name, Class, Type)

查看源代码
-spec resolve(Name, Class, Type) -> {ok, dns_msg()} | Error
                 when
                     Name :: dns_name() | inet:ip_address(),
                     Class :: dns_class(),
                     Type :: dns_rr_type(),
                     Error :: {error, Reason} | {error, {Reason, dns_msg()}},
                     Reason :: inet:posix() | res_error().

等效于 resolve(Name, Class, Type, [], infinity)

链接到此函数

resolve(Name, Class, Type, Opts)

查看源代码
-spec resolve(Name, Class, Type, Opts) -> {ok, dns_msg()} | Error
                 when
                     Name :: dns_name() | inet:ip_address(),
                     Class :: dns_class(),
                     Type :: dns_rr_type(),
                     Opts :: [Opt],
                     Opt :: res_option() | verbose | atom(),
                     Error :: {error, Reason} | {error, {Reason, dns_msg()}},
                     Reason :: inet:posix() | res_error().

等效于 resolve(Name, Class, Type, Opts, infinity)

链接到此函数

resolve(Name, Class, Type, Opts, Timeout)

查看源代码
-spec resolve(Name, Class, Type, Opts, Timeout) -> {ok, dns_msg()} | Error
                 when
                     Name :: dns_name() | inet:ip_address(),
                     Class :: dns_class(),
                     Type :: dns_rr_type(),
                     Opts :: [Opt],
                     Opt :: res_option() | verbose | atom(),
                     Timeout :: timeout(),
                     Error :: {error, Reason} | {error, {Reason, dns_msg()}},
                     Reason :: inet:posix() | res_error().

解析 DNS 查询。

将指定 TypeClassName 的 DNS 查询解析为可能包含资源记录的 DNS 消息。可以使用 inet_db 中的访问函数来检查返回的 dns_msg/0,如DNS 类型部分所述。

如果 Nameip_address(),则要查询的域名将生成为 IPv4 地址的标准反向 ".IN-ADDR.ARPA." 名称,或 IPv6 地址的 ".IP6.ARPA." 名称。在这种情况下,你很可能想使用 Class = inType = ptr,但这不是自动完成的。

Opts 会覆盖相应的解析器选项。如果指定了选项 nameservers,则假定它是完整的名称服务器列表,因此将忽略解析器选项 alt_nameserves。但是,如果也为此函数指定了选项 alt_nameserves,则将使用它。

选项 verbose(或者更确切地说,{verbose,true})会导致通过 io:format/2 输出查询、回复、重传等的诊断信息,类似于诸如 dignslookup 之类的实用程序。

选项 nxdomain_reply(或者更确切地说,{nxdomain_reply, true})会导致来自 DNS 服务器的 NXDOMAIN 错误作为 {error, {nxdomain, dns_msg()}} 返回。dns_msg/0 包含应答服务器包含的附加部分。这主要用于检查 SOA 记录以获取负缓存的 TTL。

如果 Opt 是任何原子,则将其解释为 {Opt,true},除非原子字符串以 "no" 开头,否则将其解释为 {Opt,false}。例如,usevc{usevc, true} 的别名,而 nousevc{usevc, false} 的别名。

选项 inet6 对此函数没有影响。你可能想要使用 Type = a | aaaa 代替。