anchor.diff:      {NsBuf,AnList,AnTC} = decode_rr_section(AnBuf,AnCount,Buffer),
       {ArBuf,NsList,NsTC} = decode_rr_section(NsBuf,NsCount,Buffer),
       {Rest,ArList,ArTC} = decode_rr_section(ArBuf,ArCount,Buffer),
  -	case Rest of
  -	    <<>> ->
  -		HdrTC = decode_boolean(TC),
  -		DnsHdr =
  -		    #dns_header{id=Id,
  -				qr=decode_boolean(QR),
  -				opcode=decode_opcode(Opcode),
  -				aa=decode_boolean(AA),
  -				tc=HdrTC,
  -				rd=decode_boolean(RD),
  -				ra=decode_boolean(RA),
  -				pr=decode_boolean(PR),
  -				rcode=Rcode},
  -		case QdTC or AnTC or NsTC or ArTC of
  -		    true when not HdrTC ->
  -			throw(?DECODE_ERROR);
  -		    _ ->
  -			#dns_rec{header=DnsHdr,
  -				 qdlist=QdList,
  -				 anlist=AnList,
  -				 nslist=NsList,
  -				 arlist=ArList}
  -		end;
  -	    _ ->
  -		%% Garbage data after DNS message
  -		throw(?DECODE_ERROR)
  -	end;
  +    ?MATCH_ELSE_DECODE_ERROR(
  +       Rest,
  +       <<>>,
  +       begin
  +           HdrTC = decode_boolean(TC),
  +           DnsHdr =
  +               #dns_header{id=Id,
  +                           qr=decode_boolean(QR),
  +                           opcode=decode_opcode(Opcode),
  +                           aa=decode_boolean(AA),
  +                           tc=HdrTC,
  +                           rd=decode_boolean(RD),
  +                           ra=decode_boolean(RA),
  +                           pr=decode_boolean(PR),
  +                           rcode=Rcode},
  +           ?MATCH_ELSE_DECODE_ERROR(
  +              %% Header marked as truncated, or no section
  +              %% marked as truncated.
  +              %% The converse; a section marked as truncated,
  +              %% but not the header - is a parse error.
  +              %%
  +              HdrTC or (not (QdTC or AnTC or NsTC or ArTC)),
  +              true,
  +              begin
  +                  #dns_rec{header=DnsHdr,
  +                           qdlist=QdList,
  +                           anlist=AnList,
  +                           nslist=NsList,
  +                           arlist=ArList}
  +              end)
  +       end);
   do_decode(_) ->
       %% DNS message does not even match header
       throw(?DECODE_ERROR).
  
positive.code: decode_boolean(0) -> false;
  decode_boolean(I) when is_integer(I) -> true.
  
  %%
  %% Data field -> term() content representation
  %%
  decode_data(<<A,B,C,D>>, in, ?S_A,  _)   -> {A,B,C,D};
  decode_data(<<A:16,B:16,C:16,D:16,E:16,F:16,G:16,H:16>>, in, ?S_AAAA, _) ->
      {A,B,C,D,E,F,G,H};
  decode_data(Dom, _, ?S_NS, Buffer)    -> decode_domain(Dom, Buffer);
  decode_data(Dom, _, ?S_MD, Buffer)    -> decode_domain(Dom, Buffer); 
  decode_data(Dom, _, ?S_MF, Buffer)    -> decode_domain(Dom, Buffer); 
  decode_data(Dom, _, ?S_CNAME, Buffer) -> decode_domain(Dom, Buffer);
  decode_data(Data0, _, ?S_SOA, Buffer) ->
      {Data1,MName} = decode_name(Data0, Buffer),
      {Data,RName} = decode_name(Data1, Buffer),
      case Data of
  	<<Serial:32,Refresh:32/signed,Retry:32/signed,
  	 Expiry:32/signed,Minimum:32>> ->
  	    {MName,RName,Serial,Refresh,Retry,Expiry,Minimum};
  	_ ->
  	    %% Broken SOA RR data
  	    throw(?DECODE_ERROR)
      end;
  decode_data(Dom, _, ?S_MB, Buffer)    -> decode_domain(Dom, Buffer); 
  decode_data(Dom, _, ?S_MG, Buffer)    -> decode_domain(Dom, Buffer); 
  decode_data(Dom, _, ?S_MR, Buffer)    -> decode_domain(Dom, Buffer); 
  decode_data(Data, _, ?S_NULL, _) -> Data;
  decode_data(<<A,B,C,D,Proto,BitMap/binary>>, in, ?S_WKS, _Buffer) -> 
      {{A,B,C,D},Proto,BitMap};
  decode_data(Dom, _, ?S_PTR, Buffer)   -> decode_domain(Dom, Buffer);
  decode_data(<<CpuLen,CPU:CpuLen/binary,
  	     OsLen,OS:OsLen/binary>>, _, ?S_HINFO, _) ->
      {binary_to_list(CPU),binary_to_list(OS)};
  decode_data(Data0, _, ?S_MINFO, Buffer) ->
      {Data1,RM} = decode_name(Data0, Buffer),
      {Data,EM} = decode_name(Data1, Buffer),
      case Data of
  	<<>> -> {RM,EM};
  	_ ->
  	    %% Broken MINFO data
  	    throw(?DECODE_ERROR)
      end;
  decode_data(<<Prio:16,Dom/binary>>, _, ?S_MX, Buffer) ->
      {Prio,decode_domain(Dom, Buffer)};
  decode_data(<<Prio:16,Weight:16,Port:16,Dom/binary>>, _, ?S_SRV, Buffer) ->
      {Prio,Weight,Port,decode_domain(Dom, Buffer)};
  decode_data(<<Order:16,Preference:16,Data0/binary>>, _, ?S_NAPTR, Buffer) ->
      {Data1,Flags} = decode_string(Data0),
      {Data2,Services} = decode_string(Data1),
      {Data,Regexp} = decode_characters(Data2, utf8),
      Replacement = decode_domain(Data, Buffer),
      {Order,Preference,inet_db:tolower(Flags),inet_db:tolower(Services),
       Regexp,Replacement};
  %% ?S_OPT falls through to default
  decode_data(Data, _, ?S_TXT, _) ->
      decode_txt(Data);
  decode_data(Data, _, ?S_SPF, _) ->
      decode_txt(Data);
  decode_data(<<Prio:16,Weight:16,Data0/binary>>, _, ?S_URI, _) ->
      (1 =< byte_size(Data0))
          orelse throw(?DECODE_ERROR),
      Target = binary_to_list(Data0),
      {Prio,Weight,Target};
  decode_data(Data, _, ?S_URI, _) ->
      decode_txt(Data);
  decode_data(<<Flags:8,Data0/binary>>, _, ?S_CAA, _) ->
      {Data1,Tag} = decode_string(Data0),
      L = length(Tag),
      (1 =< L andalso L =< 15)
          orelse throw(?DECODE_ERROR),
      Value = binary_to_list(Data1),
      {Flags,inet_db:tolower(Tag),Value};
  %% malformed known RR in inet domain
  decode_data(_, in, T, _) when T == ?S_A; T == ?S_AAAA; T == ?S_WKS ->
      throw(?DECODE_ERROR);
  %% malormed known RR in any domain
  decode_data(_, _, T, _) when T == ?S_HINFO; T == ?S_MX; T == ?S_SRV;
      T == ?S_NAPTR; T == ?S_URI; T == ?S_CAA ->
      throw(?DECODE_ERROR);
  %% sofar unknown or non standard
  decode_data(Data, _, _, _) ->
      Data.
  
negative.code:     %% Bypass name compression (RFC 2915: section 2)
      {B,_} = encode_name(B3, gb_trees:empty(), Pos+byte_size(B3), Replacement),
      {B,Comp};
  encode_data(Comp, _, ?S_OPT, _, Data) -> {iolist_to_binary(Data),Comp};
  encode_data(Comp, _, ?S_TXT, _, Data) -> {encode_txt(Data),Comp};
  encode_data(Comp, _, ?S_SPF, _, Data) -> {encode_txt(Data),Comp};
  encode_data(Comp, _, ?S_URI, _, {Prio,Weight,Target}) ->
      {<<Prio:16,Weight:16,(iolist_to_binary(Target))/binary>>,Comp};
  encode_data(Comp, _, ?S_CAA, _, {Flags,Tag,Value}) ->
      B0 = <<Flags:8>>,
      B1 = encode_string(B0, iolist_to_binary(Tag)),
      B2 = iolist_to_binary(Value),
      {<<B1/binary,B2/binary>>,Comp};
  encode_data(Comp, _, ?S_CAA, _, Data) -> {encode_txt(Data),Comp};
  %%
  %% sofar unknown or non standard
  encode_data(Comp, _Pos, _Type, _Class, Data) ->
      {iolist_to_binary(Data),Comp}.
  
  %% Array of strings
  %%
  