{ok,{dns_rec,{dns_header,0,true,'query',true,false,false,false,false,0},
[],
[{dns_rr,"_see._tcp.local",ptr,in,0,0,
"jhr@Blackintosh._see._tcp.local",undefined,[],
false}],
[],[]}}
I have the following code where Sub is a dict:
receiver(Sub) ->
receive
{udp, _Socket, IP, InPortNo, Packet} ->
DnsRec = inet_dns:decode(Packet),
io:format("~n~nFrom: ~p~nPort: ~p~nData:
~p~n",[IP,InPortNo,DnsRec]),
receiver(Sub);
stop ->
true;
AnythingElse ->
%io:format("RECEIVED: ~p~n",[AnythingElse]),
receiver(Sub)
end.
I want to match on the "_see._tcp.local" and see if it is in the dns_rr
record and only do the io:format() if that is in my subscriptions dict.
Can anyone point me in the right direction of what idiom to use? This
pattern matching stuff is difficult for us olde school if () ers
I can't understand exactly what you want, so I'll give you an example.
Suppose DomainsSet is a sets of domains and DnsRec is a dns_rec. This
would be a list of the domains that are present in some resource
record and in DomainsSet:
[Domain || #dns_rr{domain = Domain} <- DnsRec#dns_rec.anlist,
sets:is_element(Domain, DomainsSet)]
Is that helpful?
Igor.
--
"The secret of joy in work is contained in one word - excellence. To
know how to do something well is to enjoy it." - Pearl S. Buck.
________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org
> Hi, Jarrod.
>
> I can't understand exactly what you want, so I'll give you an example.
>
> Suppose DomainsSet is a sets of domains and DnsRec is a dns_rec. This
> would be a list of the domains that are present in some resource
> record and in DomainsSet:
> [Domain || #dns_rr{domain = Domain} <- DnsRec#dns_rec.anlist,
> sets:is_element(Domain, DomainsSet)]
>
> Is that helpful?
>
> Igor.
>
> thanks it is a place for me to start
> Hi, Jarrod.
>
> I can't understand exactly what you want, so I'll give you an example.
>
> Suppose DomainsSet is a sets of domains and DnsRec is a dns_rec. This
> would be a list of the domains that are present in some resource
> record and in DomainsSet:
> [Domain || #dns_rr{domain = Domain} <- DnsRec#dns_rec.anlist,
> sets:is_element(Domain, DomainsSet)]
>
> Is that helpful?
>
> Igor.
>
> Ok have tried and tried, and your snippet won't compile.
I have both Erlang books and can't figure out how to do this logic.
here is how I would do it in pseudo-code in languages that I am familar
with.
for (dns_rr in dns_rec.getAnList())
{
if (dns_rr.domain == "_test._tcp.local")
{
// do some logic here
}
}
receiver(Subs) ->
receive
{udp, _Socket, IP, InPortNo, Packet} ->
{ok,DnsRec} = inet_dns:decode(Packet),
% this is where I want the "domain" detecting logic from the
dns_rr records
io:format("~n~nFrom: ~p~nPort: ~p~nData:
~p~n",[IP,InPortNo,DnsRec]),
receiver(Subs);
stop ->
true;
AnythingElse ->
%io:format("RECEIVED: ~p~n",[AnythingElse]),
receiver(Subs)
end.
First off, to get the record definitions for #dns_rec and #dns_rr, you
need to include this line in your module (normally near the top):
-include_lib("kernel/src/inet_dns.hrl").
Now I would code it something like:
receive
{udp, _Socket, IP, InPortNo, Packet} ->
process_dnsrec(Sub,inet_dns:decode(Packet)),
receiver(Sub);
...
process_dnsrec(Sub,{error,E}) ->
%% do some error handling here (if required)
;
process_dnsrec(Sub,{ok,#dnsrec{anlist=Responses}) ->
%% Responses is a list of #dns_rr records, so we want to handle them one at a time
process_dnsrec1(Sub,Responses).
process_dnsrec1(_,[]) ->
%% no more responses
;
process_dnsrec1(Sub,[#dns_rr{domain=Dom}|Rest]) ->
%% lookup the domain field from the #dns_rr record
case dict:find(Dom,Sub) of
[Result] ->
io:format("Interesting domain ~p~n",[Result]);
error ->
%% do nothing for non-interesting domains
ok
end,
process_dnsrec1(Sub,Rest).
Cheers
Rob
start() ->
S=open({224,0,0,251},5353),
Pid=spawn(?MODULE,receiver,[dict:store("_see._tcp.local",[],dict:new())]),
gen_udp:controlling_process(S,Pid),
{S,Pid}.
receiver(Sub) ->
receive
{udp, _Socket, _IP, _InPortNo, Packet} ->
process_dnsrec(Sub,inet_dns:decode(Packet)),
receiver(Sub);
stop ->
true;
AnythingElse ->
io:format("RECEIVED: ~p~n",[AnythingElse]),
receiver(Sub)
end.
process_dnsrec(_Sub,{error,E}) -> io:format("Error: ~p~n", [E]);
process_dnsrec(Sub,{ok,#dns_rec{anlist=Responses}}) ->
process_dnsrec1(Sub,Responses).
process_dnsrec1(_,[]) -> ok;
process_dnsrec1(Sub,[#dns_rr{domain=Dom}|Rest]) ->
case dict:find(Dom,Sub) of
[Result] ->
io:format("Interesting domain ~p=~p~n",[Dom,Result]);
error ->
%% do nothing for non-interesting domains
ok
end,
process_dnsrec1(Sub,Rest).
and here is the Error I am getting
Erlang R13B02 (erts-5.7.3) [source] [smp:2:2] [rq:2] [async-threads:0]
[kernel-poll:false]
Eshell V5.7.3 (abort with ^G)
1> zeroconf:start().
{#Port<0.442>,<0.34.0>}
2>
=ERROR REPORT==== 24-Nov-2009::15:16:40 ===
Error in process <0.34.0> with exit value:
{{case_clause,{ok,[]}},[{zeroconf,process_dnsrec1,2},{zeroconf,receiver,1}]}
>
> process_dnsrec1(Sub,[#dns_rr{domain=Dom}|Rest]) ->
> case dict:find(Dom,Sub) of
> [Result] ->
> io:format("Interesting domain ~p=~p~n",[Dom,Result]);
>
thanks for reading I figured it out by trial and error.
I replaced the [Result] with {ok,Result} and it started working as expected
-------------------------
1> D = dict:store("_see._tcp.local", [], dict:new()).
{dict,1,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
{{[],[],[],[],
[["_see._tcp.local"]],
[],[],[],[],[],[],[],[],[],[],[]}}}
2> dict:find("_see._tcp.local", D).
{ok,[]}
3> S = sets:add_element("_see._tcp.local", sets:new()).
{set,1,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
{{[],[],[],[],
["_see._tcp.local"],
[],[],[],[],[],[],[],[],[],[],[]}}}
4> sets:is_element("_see._tcp.local", S).
true
-------------------------
See also gb_sets and ordsets.
Igor.
--
"The secret of joy in work is contained in one word - excellence. To
know how to do something well is to enjoy it." - Pearl S. Buck.
________________________________________________________________