Skip to content

Addressing Mnesia backend failing on erldns_zone_cache functions #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 16, 2020

Conversation

m0rcq
Copy link
Contributor

@m0rcq m0rcq commented Jun 11, 2020

Mnesia related changes addressing #102.

Addressing Mnesia backend failing on erldns_zone_cache functions:

* added type bag on table creation (zone_records, zone_records_typed)
* set explicit type set on table creation (zones)
* refactored select/3: using ETS match spec converted to Mnesia's
match_object pattern
* using different pattern in erldns_zone_cache:zone_names_and_versions/0
depending on backend (ETS/Mnesia foldl/3 return values are different)

m0rcq added 2 commits June 11, 2020 12:16
* added type bag on table creation (zone_records, zone_records_typed)
* set explicit type set on table creation (zones)
* refactored select/3: using ETS match spec converted to Mnesia's
match_object pattern
* using different pattern in erldns_zone_cache:zone_names_and_versions/0
depending on backend (ETS/Mnesia foldl/3 return values are different)
* debug artefacts cleanup
@m0rcq m0rcq requested a review from aeden June 11, 2020 14:07
@m0rcq m0rcq self-assigned this Jun 11, 2020
@m0rcq m0rcq changed the title Bugfix/mnesia Addressing Mnesia backend failing on erldns_zone_cache functions Jun 11, 2020
@m0rcq m0rcq marked this pull request as ready for review June 11, 2020 14:13
@nisbus
Copy link
Contributor

nisbus commented Jun 12, 2020

Thanks for the fix, I was just testing it:

Config:

[
 {erldns,[
	  {servers, [
		     [{name, inet_localhost_1}, {address, "127.0.0.1"}, {port, 8053}, {family, inet}, {processes, 2}],
		     [{name, inet6_localhost_1}, {address, "::1"}, {port, 8053}, {family, inet6}]
		    ]},
	  {storage, [
	  	     {type, erldns_storage_mnesia},
	  	     {dir, "."}
	  	    ]
	  },
	  {dnssec, [
		    {enabled, true}
		   ]},
	  {use_root_hints, false},
	  {catch_exceptions, false},
	  {zones, "priv/example.zone.json"},
	  {pools, [
		   {tcp_worker_pool, erldns_worker, [
						     {size, 10},
						     {max_overflow, 20}
						    ]}
		  ]}
	 ]},
 {mnesia,
  [
   {dir, "."}
  ]}, 
 {lager, [
	  {error_logger_redirect, false}
	 ]}
].
1> erldns_zone_cache:zone_names_and_versions().
[{<<"example.com">>,[]}]

All of the calls seem to work properly from the shell, however I have issues when trying to query using dig:

 dig @127.0.0.1 -p 8053 example.com    

; <<>> DiG 9.16.1-Ubuntu <<>> @127.0.0.1 -p 8053 example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 48585
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 17c2a8de562683aa (echoed)
;; QUESTION SECTION:
;example.com.			IN	A

;; AUTHORITY SECTION:
example.com.		300	IN	SOA	ns1.example.com. admin.example.com. 2013022001 86400 7200 604800 300

;; Query time: 16 msec
;; SERVER: 127.0.0.1#8053(127.0.0.1)
;; WHEN: Fri Jun 12 12:20:52 CEST 2020
;; MSG SIZE  rcvd: 98

I haven't edited the example.zone.json at all

Also if I comment out the mnesia storage from the config then dig is working properly:

; <<>> DiG 9.16.1-Ubuntu <<>> @127.0.0.1 -p 8053 example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23513
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 7e7857c7169b399d (echoed)
;; QUESTION SECTION:
;example.com.			IN	A

;; ANSWER SECTION:
example.com.		3600	IN	A	1.2.3.4

;; Query time: 1 msec
;; SERVER: 127.0.0.1#8053(127.0.0.1)
;; WHEN: Fri Jun 12 12:26:24 CEST 2020
;; MSG SIZE  rcvd: 68

@nisbus
Copy link
Contributor

nisbus commented Jun 14, 2020

The issue is get_records_by_name
With Mnesia:

1> erldns_zone_cache:get_records_by_name(<<"example.com">>).
[]

JSON:

1> erldns_zone_cache:get_records_by_name(<<"example.com">>).
[{dns_rr,<<"example.com">>,1,1,3600,
         {dns_rrdata_a,{1,2,3,4}}},
 {dns_rr,<<"example.com">>,1,2,3600,
         {dns_rrdata_ns,<<"ns1.example.com">>}},
 {dns_rr,<<"example.com">>,1,2,3600,
         {dns_rrdata_ns,<<"ns2.example.com">>}},
 {dns_rr,<<"example.com">>,1,6,3600,
         {dns_rrdata_soa,<<"ns1.example.com">>,
                         <<"admin.example.com">>,2013022001,86400,7200,604800,300}},
 {dns_rr,<<"example.com">>,1,15,3600,
         {dns_rrdata_mx,10,<<"mail.example.com">>}},
 {dns_rr,<<"example.com">>,1,16,3600,
         {dns_rrdata_txt,[<<"Hi, this is some text">>]}},
 {dns_rr,<<"example.com">>,1,28,3600,
         {dns_rrdata_aaaa,{8193,1704,0,1,528,19455,65099,19553}}},
 {dns_rr,<<"example.com">>,1,257,3600,
         {dns_rrdata_caa,0,<<"issue">>,<<"example.net">>}}]

@nisbus
Copy link
Contributor

nisbus commented Jun 14, 2020

Here is a fix that works at least:

-spec get_records_by_name(dns:dname()) -> [dns:rr()].
get_records_by_name(Name) ->
    case find_zone_in_cache(Name) of
	{ok, Zone} ->
	    case erldns_config:storage_type() of
		erldns_storage_json ->
		    case erldns_storage:select(zone_records, {erldns:normalize_name(Zone#zone.name), erldns:normalize_name(Name)}) of
			[] -> [];
			[{_, Records}] -> Records
		    end;
		erldns_storage_mnesia ->
		    lists:filter(fun(#dns_rr{name = RecordName}) ->
					 RecordName =:= erldns:normalize_name(Name)
				    end, get_zone_records(erldns:normalize_name(Zone#zone.name)))
	    end;
	_ ->
	    []
  end.

erldns_storage:select/3 vs select/2
* added flattening returned from the select/3
@m0rcq
Copy link
Contributor Author

m0rcq commented Jun 15, 2020

Here is a fix that works at least:

-spec get_records_by_name(dns:dname()) -> [dns:rr()].
get_records_by_name(Name) ->
    case find_zone_in_cache(Name) of
	{ok, Zone} ->
	    case erldns_config:storage_type() of
		erldns_storage_json ->
		    case erldns_storage:select(zone_records, {erldns:normalize_name(Zone#zone.name), erldns:normalize_name(Name)}) of
			[] -> [];
			[{_, Records}] -> Records
		    end;
		erldns_storage_mnesia ->
		    lists:filter(fun(#dns_rr{name = RecordName}) ->
					 RecordName =:= erldns:normalize_name(Name)
				    end, get_zone_records(erldns:normalize_name(Zone#zone.name)))
	    end;
	_ ->
	    []
  end.

Hello @nisbus, thank you for flagging this up.

You're correct - get_records_by_name/1 with Mnesia backend is failing due to hitting select/2 in erldns_storage_mnesia which in turn just does mnesia:read/2 and will fail on calls with FQDN lookups.

Check: 3ccdcff - it does address this scenario and allows for proper execution of erldns_zone_cache:zone_records_by_name/1 against Mnesia and ETS' backends.

@nisbus
Copy link
Contributor

nisbus commented Jun 15, 2020

looks good to me, everything seems to be working now

@m0rcq m0rcq merged commit 99ec5e5 into master Jun 16, 2020
@m0rcq m0rcq deleted the bugfix/mnesia branch June 16, 2020 07:53
@m0rcq
Copy link
Contributor Author

m0rcq commented Jun 16, 2020

looks good to me, everything seems to be working now

@nisbus: Great to hear - all changes merged to master now.

@m0rcq m0rcq mentioned this pull request Jun 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants