summaryrefslogtreecommitdiff
path: root/src/dns.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/dns.erl')
-rw-r--r--src/dns.erl69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/dns.erl b/src/dns.erl
new file mode 100644
index 0000000..24fb8fb
--- /dev/null
+++ b/src/dns.erl
@@ -0,0 +1,69 @@
+%%% Copyright (c) 2016, NORDUnet A/S.
+%%% See LICENSE for licensing information.
+
+-module(dns).
+-export([split_rrset/1, encode_rr/1, encode_rrset/1]).
+
+decode_name_label(Name) ->
+ <<Len:8/integer, Label:Len/binary, Rest/binary>> = Name,
+ {Label, Rest}.
+
+encode_name_label(Label) ->
+ Len = byte_size(Label),
+ <<Len:8/integer, Label/binary>>.
+
+decode_name(RR) ->
+ decode_name(RR, []).
+decode_name(<<0, Rest/binary>>, Acc) ->
+ {lists:reverse(Acc), Rest};
+decode_name(Name, Acc) ->
+ {Label, Rest} = decode_name_label(Name),
+ decode_name(Rest, [Label | Acc]).
+
+-spec encode_name(list()) -> binary().
+encode_name(Name) ->
+ encode_name(Name, []).
+encode_name([], Acc) ->
+ Bin = list_to_binary(lists:reverse(Acc)),
+ <<Bin/binary, 0>>;
+encode_name([H|T], Acc) ->
+ encode_name(T, [encode_name_label(H) | Acc]).
+
+-spec decode_rr(binary()) -> {list(), binary()}.
+decode_rr(RR) ->
+ {Name, RestRR} = decode_name(RR),
+ <<Type:2/binary,
+ Class:2/binary,
+ TTL:4/integer-unit:8,
+ RDLength:2/integer-unit:8,
+ RDATA:RDLength/binary,
+ Rest/binary>> = RestRR,
+ {[Name, Type, Class, TTL, RDATA], Rest}.
+
+-spec split_rrset(binary()) -> list().
+split_rrset(RRSet) ->
+ split_rrset(RRSet, []).
+split_rrset(<<>>, Acc) ->
+ lists:reverse(Acc);
+split_rrset(RRSet, Acc) ->
+ {RR, Rest} = decode_rr(RRSet),
+ split_rrset(Rest, [RR | Acc]).
+
+-spec encode_rr(list()) -> binary().
+encode_rr([Name, Type, Class, TTL, RDATA]) ->
+ EncodedName = encode_name(Name),
+ RDLength = byte_size(RDATA),
+ <<EncodedName/binary,
+ Type:2/binary,
+ Class:2/binary,
+ TTL:4/integer-unit:8,
+ RDLength:2/integer-unit:8,
+ RDATA/binary>>.
+
+-spec encode_rrset(list()) -> binary().
+encode_rrset(RRSet) ->
+ encode_rrset(RRSet, []).
+encode_rrset([], Acc) ->
+ list_to_binary(lists:reverse(Acc));
+encode_rrset([H|T], Acc) ->
+ encode_rrset(T, [encode_rr(H) | Acc]).