Skip to content

Commit 1a07f7e

Browse files
weppossan983NelsonVides
authored
SPF/TXT multipart handling (#150)
* Add example for multi-parts SPF/TXT * Change SPF to use parts when available * Refactor TXT handler to call shared function * Change TXT to use parts when available * Refactor case to use pattern matching * Fix syntax * Format * Fix unbound type * Ignore rebar3 _checkouts dir for local testing * Upgrade dns_erlang to 3.0.0 --------- Co-authored-by: Santiago Traversa <[email protected]> Co-authored-by: Nelson Vides <[email protected]>
1 parent f735a87 commit 1a07f7e

7 files changed

+167
-31
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ erldns.config
1616
# rebar 3
1717
.rebar3
1818
_build/
19+
_checkouts/
1920
doc/

priv/zones-test.json

+116
Original file line numberDiff line numberDiff line change
@@ -2686,6 +2686,122 @@
26862686
}
26872687
]
26882688
},
2689+
{
2690+
"name": "multipart.example",
2691+
"records": [
2692+
{
2693+
"name": "multipart.example",
2694+
"type": "SOA",
2695+
"data": {
2696+
"mname": "ns1.example.com",
2697+
"rname": "ahu.example.com",
2698+
"serial": 2000081501,
2699+
"refresh": 28800,
2700+
"retry": 7200,
2701+
"expire": 604800,
2702+
"minimum": 86400
2703+
},
2704+
"ttl": 120
2705+
},
2706+
{
2707+
"name": "multipart.example",
2708+
"type": "NS",
2709+
"ttl": 120,
2710+
"data": {
2711+
"dname": "ns1.example.com"
2712+
}
2713+
},
2714+
{
2715+
"name": "multipart.example",
2716+
"type": "NS",
2717+
"ttl": 120,
2718+
"data": {
2719+
"dname": "ns2.example.com"
2720+
}
2721+
},
2722+
{
2723+
"name": "txt1a.multipart.example",
2724+
"type": "TXT",
2725+
"ttl": 120,
2726+
"data": {
2727+
"txt": "string one"
2728+
}
2729+
},
2730+
{
2731+
"name": "txt1b.multipart.example",
2732+
"type": "TXT",
2733+
"ttl": 120,
2734+
"data": {
2735+
"txt": "string one",
2736+
"txts": [
2737+
"string one"
2738+
]
2739+
}
2740+
},
2741+
{
2742+
"name": "txt2a.multipart.example",
2743+
"type": "TXT",
2744+
"ttl": 120,
2745+
"data": {
2746+
"txt": "\"string one\" \"string two\""
2747+
}
2748+
},
2749+
{
2750+
"name": "txt2b.multipart.example",
2751+
"type": "TXT",
2752+
"ttl": 120,
2753+
"data": {
2754+
"txt": "\"string one\" \"string two\"",
2755+
"txts": [
2756+
"string one",
2757+
"string two"
2758+
]
2759+
}
2760+
},
2761+
{
2762+
"name": "txt2c.multipart.example",
2763+
"type": "TXT",
2764+
"ttl": 120,
2765+
"data": {
2766+
"txts": [
2767+
"string one",
2768+
"string two"
2769+
]
2770+
}
2771+
},
2772+
{
2773+
"name": "txt2d.multipart.example",
2774+
"type": "TXT",
2775+
"ttl": 120,
2776+
"data": {
2777+
"txt": "\"string a\" \"string b\"",
2778+
"txts": [
2779+
"string c",
2780+
"string d"
2781+
]
2782+
}
2783+
},
2784+
{
2785+
"name": "spf1a.multipart.example",
2786+
"type": "SPF",
2787+
"ttl": 120,
2788+
"data": {
2789+
"spf": "v=spf1 include:_spf.spf.example.com ~all"
2790+
}
2791+
},
2792+
{
2793+
"name": "spf1b.multipart.example",
2794+
"type": "SPF",
2795+
"ttl": 120,
2796+
"data": {
2797+
"spf": "v=spf1 include:_spf.spf.example.com ~all",
2798+
"txts": [
2799+
"v=spf1 include:_spf.txts.example.com ~all"
2800+
]
2801+
}
2802+
}
2803+
]
2804+
},
26892805
{
26902806
"name": "test.com",
26912807
"records": [

rebar.config

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
{lager, "3.9.2"},
1919
recon,
2020
folsom,
21-
{dns_erlang, "2.0.0"},
21+
{dns_erlang, "3.0.2"},
2222
iso8601,
2323
{nodefinder, "2.0.7"},
2424
{meck, "1.0.0"}

rebar.lock

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{"1.2.0",
22
[{<<"base32">>,{pkg,<<"base32">>,<<"0.1.0">>},1},
33
{<<"bear">>,{pkg,<<"bear">>,<<"1.0.0">>},1},
4-
{<<"dns_erlang">>,{pkg,<<"dns_erlang">>,<<"2.0.0">>},0},
4+
{<<"dns_erlang">>,{pkg,<<"dns_erlang">>,<<"3.0.2">>},0},
55
{<<"folsom">>,{pkg,<<"folsom">>,<<"1.0.0">>},0},
66
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1},
77
{<<"iso8601">>,{pkg,<<"iso8601">>,<<"1.3.4">>},0},
@@ -13,7 +13,7 @@
1313
{pkg_hash,[
1414
{<<"base32">>, <<"044F6DC95709727CA2176F3E97A41DDAA76B5BC690D3536908618C0CB32616A2">>},
1515
{<<"bear">>, <<"430419C1126B477686CDE843E88BA0F2C7DC5CDF0881C677500074F704339A99">>},
16-
{<<"dns_erlang">>, <<"2C6E08842101AC04FFD634ABF7E2761A92F010ECD824AD950E9B5478F25D6F37">>},
16+
{<<"dns_erlang">>, <<"BC29B2C30F0ED1195035FEBF38F8137F999FCA91C03A62C1EDF15D346B8D5A2F">>},
1717
{<<"folsom">>, <<"50ECC998D2149939F1D5E0AA3E32788F8ED16A58E390D81B5C0BE4CC4EF25589">>},
1818
{<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>},
1919
{<<"iso8601">>, <<"7B1F095F86F6CF65E1E5A77872E8E8BF69BD58D4C3A415B3F77D9CC9423ECBB9">>},
@@ -24,7 +24,7 @@
2424
{pkg_hash_ext,[
2525
{<<"base32">>, <<"10A73951D857D8CB1ECEEA8EB96C6941F6A76E105947AD09C2B73977DEE07638">>},
2626
{<<"bear">>, <<"157B67901ADF84FF0DA6EAE035CA1292A0AC18AA55148154D8C582B2C68959DB">>},
27-
{<<"dns_erlang">>, <<"3C68246BC17C375FDB187E2D75951A83850257FCABC47E52E447EBAD5F34B690">>},
27+
{<<"dns_erlang">>, <<"306A2F1AB47E8EDBE3630C77DB79C8EE22AED35E8CCA4C1BA6F1E977CFCB092F">>},
2828
{<<"folsom">>, <<"DD6AB97278E94F9E4CFC43E188224A7B8C7EAEC0DD2E935007005177F3EEBB0E">>},
2929
{<<"goldrush">>, <<"99CB4128CFFCB3227581E5D4D803D5413FA643F4EB96523F77D9E6937D994CEB">>},
3030
{<<"iso8601">>, <<"A334469C07F1C219326BC891A95F5EEC8EB12DD8071A3FFF56A7843CB20FAE34">>},

src/erldns_resolver.erl

+1-1
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ additional_processing(Message, _Host, _Zone, _Names, Records) ->
780780
Message#dns_message{additional = Message#dns_message.additional ++ Records}.
781781

782782
%% Given a list of answers find the names that require additional processing.
783-
-spec requires_additional_processing(Records :: [dns:rr()], RecordsRequiringAdditionalProcessing :: [dns:rr()]) -> [dns:rr()].
783+
-spec requires_additional_processing(Records :: [dns:rr()], RequiresAdditional :: [dns:dname()]) -> [dns:dname()].
784784
requires_additional_processing([], RequiresAdditional) ->
785785
RequiresAdditional;
786786
requires_additional_processing([Answer | Rest], RequiresAdditional) ->

src/erldns_worker_process.erl

+4-5
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,10 @@ send_tcp_message(Socket, EncodedMessage) ->
106106
max_payload_size(Message) ->
107107
case Message#dns_message.additional of
108108
[Opt | _] when is_record(Opt, dns_optrr) ->
109-
case Opt#dns_optrr.udp_payload_size of
110-
[] ->
111-
?MAX_PACKET_SIZE;
112-
_ ->
113-
Opt#dns_optrr.udp_payload_size
109+
Size = Opt#dns_optrr.udp_payload_size,
110+
case Size < ?MAX_PACKET_SIZE of
111+
true -> Size;
112+
false -> ?MAX_PACKET_SIZE
114113
end;
115114
_ ->
116115
?MAX_PACKET_SIZE

src/erldns_zone_parser.erl

+41-21
Original file line numberDiff line numberDiff line change
@@ -509,23 +509,29 @@ json_record_to_erlang([Name, <<"RP">>, Ttl, Data, _Context]) ->
509509
ttl = Ttl
510510
};
511511
json_record_to_erlang([Name, Type = <<"TXT">>, Ttl, Data, _Context]) when is_map(Data) ->
512-
%% This function call may crash. Handle it as a bad record.
513-
try erldns_txt:parse(maps:get(<<"txt">>, Data)) of
514-
ParsedText ->
515-
#dns_rr{
516-
name = Name,
517-
type = ?DNS_TYPE_TXT,
518-
data = #dns_rrdata_txt{txt = lists:flatten(ParsedText)},
519-
ttl = Ttl
520-
}
521-
catch
522-
Exception:Reason ->
523-
erldns_events:notify({?MODULE, error, {Name, Type, Data, Exception, Reason}}),
524-
{}
525-
end;
512+
Txts =
513+
case maps:is_key(<<"txts">>, Data) of
514+
true -> maps:get(<<"txts">>, Data);
515+
false -> maps:get(<<"txt">>, Data)
516+
end,
517+
json_record_to_erlang([Name, Type, Ttl, Data, _Context, Txts]);
526518
json_record_to_erlang([Name, Type = <<"TXT">>, Ttl, Data, _Context]) ->
519+
Txts =
520+
case erldns_config:keyget(<<"txts">>, Data) of
521+
Value when is_list(Value) -> Value;
522+
_ -> erldns_config:keyget(<<"txt">>, Data)
523+
end,
524+
json_record_to_erlang([Name, Type, Ttl, Data, _Context, Txts]);
525+
json_record_to_erlang([Name, <<"TXT">>, Ttl, _Data, _Context, Value]) when is_list(Value) ->
526+
#dns_rr{
527+
name = Name,
528+
type = ?DNS_TYPE_TXT,
529+
data = #dns_rrdata_txt{txt = Value},
530+
ttl = Ttl
531+
};
532+
json_record_to_erlang([Name, Type = <<"TXT">>, Ttl, Data, _Context, Value]) ->
527533
%% This function call may crash. Handle it as a bad record.
528-
try erldns_txt:parse(erldns_config:keyget(<<"txt">>, Data)) of
534+
try erldns_txt:parse(Value) of
529535
ParsedText ->
530536
#dns_rr{
531537
name = Name,
@@ -539,17 +545,27 @@ json_record_to_erlang([Name, Type = <<"TXT">>, Ttl, Data, _Context]) ->
539545
{}
540546
end;
541547
json_record_to_erlang([Name, <<"SPF">>, Ttl, Data, _Context]) when is_map(Data) ->
548+
Txts =
549+
case maps:is_key(<<"txts">>, Data) of
550+
true -> maps:get(<<"txts">>, Data);
551+
false -> [maps:get(<<"spf">>, Data)]
552+
end,
542553
#dns_rr{
543554
name = Name,
544555
type = ?DNS_TYPE_SPF,
545-
data = #dns_rrdata_spf{spf = [maps:get(<<"spf">>, Data)]},
556+
data = #dns_rrdata_spf{spf = Txts},
546557
ttl = Ttl
547558
};
548559
json_record_to_erlang([Name, <<"SPF">>, Ttl, Data, _Context]) ->
560+
Txts =
561+
case erldns_config:keyget(<<"txts">>, Data) of
562+
Value when is_list(Value) -> Value;
563+
_ -> [erldns_config:keyget(<<"spf">>, Data)]
564+
end,
549565
#dns_rr{
550566
name = Name,
551567
type = ?DNS_TYPE_SPF,
552-
data = #dns_rrdata_spf{spf = [erldns_config:keyget(<<"spf">>, Data)]},
568+
data = #dns_rrdata_spf{spf = Txts},
553569
ttl = Ttl
554570
};
555571
json_record_to_erlang([Name, <<"PTR">>, Ttl, Data, _Context]) when is_map(Data) ->
@@ -753,7 +769,8 @@ json_record_to_erlang([Name, Type = <<"DNSKEY">>, Ttl, Data, _Context]) when is_
753769
flags = maps:get(<<"flags">>, Data),
754770
protocol = maps:get(<<"protocol">>, Data),
755771
alg = maps:get(<<"alg">>, Data),
756-
public_key = PublicKey
772+
public_key = PublicKey,
773+
key_tag = 0
757774
},
758775
ttl = Ttl
759776
})
@@ -773,7 +790,8 @@ json_record_to_erlang([Name, Type = <<"DNSKEY">>, Ttl, Data, _Context]) ->
773790
flags = erldns_config:keyget(<<"flags">>, Data),
774791
protocol = erldns_config:keyget(<<"protocol">>, Data),
775792
alg = erldns_config:keyget(<<"alg">>, Data),
776-
public_key = PublicKey
793+
public_key = PublicKey,
794+
key_tag = 0
777795
},
778796
ttl = Ttl
779797
})
@@ -793,7 +811,8 @@ json_record_to_erlang([Name, Type = <<"CDNSKEY">>, Ttl, Data, _Context]) when is
793811
flags = maps:get(<<"flags">>, Data),
794812
protocol = maps:get(<<"protocol">>, Data),
795813
alg = maps:get(<<"alg">>, Data),
796-
public_key = PublicKey
814+
public_key = PublicKey,
815+
key_tag = 0
797816
},
798817
ttl = Ttl
799818
})
@@ -813,7 +832,8 @@ json_record_to_erlang([Name, Type = <<"CDNSKEY">>, Ttl, Data, _Context]) ->
813832
flags = erldns_config:keyget(<<"flags">>, Data),
814833
protocol = erldns_config:keyget(<<"protocol">>, Data),
815834
alg = erldns_config:keyget(<<"alg">>, Data),
816-
public_key = PublicKey
835+
public_key = PublicKey,
836+
key_tag = 0
817837
},
818838
ttl = Ttl
819839
})

0 commit comments

Comments
 (0)