anchor.diff:  
   %% recv/2
   
  -recv(#diameter_packet{header = #diameter_header{} = Hdr}
  -     = Pkt,
  -     #state{dictionary = Dict0}
  -     = S) ->
  -    recv1(diameter_codec:msg_name(Dict0, Hdr), Pkt, S);
  -
  -recv(#diameter_packet{header = undefined,
  -                      bin = Bin}
  -     = Pkt,
  -     S) ->
  -    recv(diameter_codec:decode_header(Bin), Pkt, S);
  +recv(#diameter_packet{bin = Bin} = Pkt, S) ->
  +    recv(Bin, Pkt, S);
   
   recv(Bin, S) ->
  -    recv(#diameter_packet{bin = Bin}, S).
  -
  -%% recv1/3
  -
  -recv1(_,
  -      #diameter_packet{header = H, bin = Bin},
  -      #state{incoming_maxlen = M})
  +    recv(Bin, Bin, S).
  +
  +%% recv/3
  +
  +recv(Bin, Msg, S) ->
  +    recv(diameter_codec:decode_header(Bin), Bin, Msg, S).
  +
  +%% recv/4
  +
  +recv(false, Bin, _, #state{length_errors = E}) ->
  +    invalid(E, truncated_header, Bin),
  +    Bin;
  +
  +recv(#diameter_header{length = Len} = H, Bin, Msg, #state{length_errors = E,
  +                                                          incoming_maxlen = M,
  +                                                          dictionary = Dict0}
  +                                                   = S)
  +  when E == handle;
  +       0 == Len rem 4, bit_size(Bin) == 8*Len, size(Bin) =< M ->
  +    recv1(diameter_codec:msg_name(Dict0, H), H, Msg, S);
  +
  +recv(H, Bin, _, #state{incoming_maxlen = M})
     when M < size(Bin) ->
       invalid(false, incoming_maxlen_exceeded, {size(Bin), H}),
       H;
   
  +recv(H, Bin, _, #state{length_errors = E}) ->
  +    T = {size(Bin), bit_size(Bin) rem 8, H},
  +    invalid(E, message_length_mismatch, T),
  +    H.
  +
  +%% recv1/4
  +
   %% Ignore anything but an expected CER/CEA if so configured. This is
   %% non-standard behaviour.
  -recv1(Name, #diameter_packet{header = H}, #state{state = {'Wait-CEA', _, _},
  -                                                 strict = false})
  +recv1(Name, H, _, #state{state = {'Wait-CEA', _, _},
  +                         strict = false})
     when Name /= 'CEA' ->
       H;
  -recv1(Name, #diameter_packet{header = H}, #state{state = recv_CER,
  -                                                 strict = false})
  +recv1(Name, H, _, #state{state = recv_CER,
  +                         strict = false})
     when Name /= 'CER' ->
       H;
   
   %% Incoming request after outgoing DPR: discard. Don't discard DPR, so
   %% both ends don't do so when sending simultaneously.
  -recv1(Name,
  -      #diameter_packet{header = #diameter_header{is_request = true} = H},
  -      #state{dpr = {_,_,_}})
  +recv1(Name, #diameter_header{is_request = true} = H, _, #state{dpr = {_,_,_}})
     when Name /= 'DPR' ->
       invalid(false, recv_after_outgoing_dpr, H),
       H;
   
   %% Incoming request after incoming DPR: discard.
  -recv1(_,
  -      #diameter_packet{header = #diameter_header{is_request = true} = H},
  -      #state{dpr = true}) ->
  +recv1(_, #diameter_header{is_request = true} = H, _, #state{dpr = true}) ->
       invalid(false, recv_after_incoming_dpr, H),
       H;
   
   %% DPA with identifier mismatch, or in response to a DPR initiated by
   %% the service.
  -recv1('DPA' = N,
  -      #diameter_packet{header = #diameter_header{hop_by_hop_id = Hid,
  -                                                 end_to_end_id = Eid}}
  -      = Pkt,
  -      #state{dpr = {X,H,E}}
  +recv1('DPA' = Name,
  +      #diameter_header{hop_by_hop_id = Hid, end_to_end_id = Eid}
  +      = H,
  +      Msg,
  +      #state{dpr = {X,HI,EI}}
         = S)
  -  when H /= Hid;
  -       E /= Eid;
  +  when HI /= Hid;
  +       EI /= Eid;
          not X ->
  -    rcv(N, Pkt, S);
  -
  -%% Any other message with a header and no length errors: send to the
  -%% parent.
  -recv1(Name, Pkt, #state{}) ->
  -    {recv, Name, Pkt}.
  -
  -%% recv/3
  -
  -recv(#diameter_header{length = Len}
  -     = H,
  -     #diameter_packet{bin = Bin}
  -     = Pkt,
  -     #state{length_errors = E}
  -     = S)
  -  when E == handle;
  -       0 == Len rem 4, bit_size(Bin) == 8*Len ->
  -    recv(Pkt#diameter_packet{header = H}, S);
  -
  -recv(#diameter_header{}
  -     = H,
  -     #diameter_packet{bin = Bin},
  -     #state{length_errors = E}) ->
  -    T = {size(Bin), bit_size(Bin) rem 8, H},
  -    invalid(E, message_length_mismatch, T),
  -    Bin;
  -
  -recv(false, #diameter_packet{bin = Bin}, #state{length_errors = E}) ->
  -    invalid(E, truncated_header, Bin),
  -    Bin.
  +    Pkt = pkt(H, Msg),
  +    handle(Name, Pkt, S);
  +
  +%% Any other message with a header and no length errors.
  +recv1(Name, H, Msg, #state{parent = Pid, ack = Ack} = S) ->
  +    Pkt = pkt(H, Msg),
  +    Pid ! {recv, self(), get_route(Ack, Pkt), Name, Pkt},
  +    handle(Name, Pkt, S).
  +
  +%% pkt/2
  +
  +pkt(H, Bin)
  +  when is_binary(Bin) ->
  +    #diameter_packet{header = H,
  +                     bin = Bin};
  +
  +pkt(H, Pkt) ->
  +    Pkt#diameter_packet{header = H}.
  +
  +%% invalid/3
   
   %% Note that counters here only count discarded messages.
   invalid(E, Reason, T) ->
  
positive.code: 
  %% incoming/2
  
  incoming({recv = T, Name, Pkt}, #state{parent = Pid, ack = Ack} = S) ->
      Pid ! {T, self(), get_route(Ack, Pkt), Name, Pkt},
      rcv(Name, Pkt, S);
  
  incoming(#diameter_header{is_request = R}, #state{transport = TPid,
                                                    ack = Ack}) ->
      R andalso Ack andalso send(TPid, false),
  
negative.code:     ?LOG(Reason, T),
      ok.
  
  %% handle/3
  
  %% Incoming CEA.
  handle('CEA' = N,
         #diameter_packet{header = #diameter_header{end_to_end_id = Eid,
                                                    hop_by_hop_id = Hid}}
         = Pkt,
         #state{state = {'Wait-CEA', Hid, Eid}}
         = S) ->
      ?LOG(recv, N),
      handle_CEA(Pkt, S);
  
  %% Incoming CER
  handle('CER' = N, Pkt, #state{state = recv_CER} = S) ->
      handle_request(N, Pkt, S);
  
  %% Anything but CER/CEA in a non-Open state is an error, as is
  %% CER/CEA in anything but recv_CER/Wait-CEA.
  handle(Name, _, #state{state = PS})
    when PS /= 'Open';
         Name == 'CER';
         Name == 'CEA' ->
      {stop, {Name, PS}};
  
  handle('DPR' = N, Pkt, S) ->
      handle_request(N, Pkt, S);
  
  %% DPA in response to DPR, with the expected identifiers.
  handle('DPA' = N,
         #diameter_packet{header = #diameter_header{end_to_end_id = Eid,
                                                    hop_by_hop_id = Hid}
                                 = H}
         = Pkt,
      #state{dictionary = Dict0,
             transport = TPid,
             dpr = {X, Hid, Eid},
  