如何在Erlang中构建DNS查询记录?

如何在Erlang中构建DNS查询记录?,erlang,dns,bonjour,zeroconf,Erlang,Dns,Bonjour,Zeroconf,我正在构建一个本机Bonjour/Zeroconf库,需要构建DNS查询记录,以便向其他机器广播。我已经试着浏览了Erlang源代码,但由于我对Erlang相对较新,它在所有inet_XXX.erl和.hrl文件的内部变得有点密集。我有一个用于接收和解析DNS记录有效负载的侦听器,我就是不知道如何创建查询记录。我真正需要知道的是,我需要传递到inet_dns:encode()以获得可以发送的二进制文件。这就是我要做的 {ok,P} = inet_dns:encode(#dns_query{dom

我正在构建一个本机Bonjour/Zeroconf库,需要构建DNS查询记录,以便向其他机器广播。我已经试着浏览了Erlang源代码,但由于我对Erlang相对较新,它在所有inet_XXX.erl和.hrl文件的内部变得有点密集。我有一个用于接收和解析DNS记录有效负载的侦听器,我就是不知道如何创建查询记录。我真正需要知道的是,我需要传递到inet_dns:encode()以获得可以发送的二进制文件。这就是我要做的

{ok,P} = inet_dns:encode(#dns_query{domain="_daap._tcp.local",type=ptr,class=in})
这是我得到的错误

10> test:send().
** exception error: {badrecord,dns_rec}
     in function  inet_dns:encode/1
     in call from test:send/0
11> 

没有inet_dns模块的文档这一事实应该让您非常小心从代码中使用它。我希望您充分意识到,如果他们(OTP团队)想要改变模块的实现和使用方式,那么您的项目将不会受到任何考虑


阅读实现思想的代码,或者直接使用基于DNS协议上的RFC的Erlang位语法创建DNS协议消息。创建一个DNS包要比解析它容易得多(我自己也经历过这一过程,最小化数据包大小的“聪明技巧”似乎不值得)

我终于明白了

send(Domain) ->
    {ok,S} = gen_udp:open(5555,[{reuseaddr,true}, {ip,{224,0,0,251}}, {multicast_ttl,4}, {multicast_loop,false}, {broadcast,true}, binary]),
    P = #dns_rec{header=#dns_header{},qdlist=[#dns_query{domain=Domain,type=ptr,class=in}]},
    gen_udp:send(S,{224,0,0,251},5353,inet_dns:encode(P)),
    gen_udp:close(S).

正如Magnus在Erlang问题邮件列表中所解释的:


您在encode/1函数中传递的是一个dns\u查询,而不是dns\u rec记录。

您应该在20多年前的情况下预测这一点,当时比特比现在昂贵得多。