anchor.diff:  send_auth_req(Header, Socket, Auth, Stale) ->
       ExtraHeaders = [{"WWW-Authenticate",
   		     sipheader:auth_print(Auth, Stale)}],
  -    send_response(Socket, 401, "Authentication Required",
  -		  standardcopy(Header, ExtraHeaders),
  -		  "").
  +    Response = #response{status=401, reason="Authentication Required",
  +			 header=standardcopy(Header, ExtraHeaders), body=""},
  +    send_response(Socket, Response).
   
   send_proxyauth_req(Header, Socket, Auth, Stale) ->
       ExtraHeaders = [{"Proxy-Authenticate",
   		     sipheader:auth_print(Auth, Stale)}],
  -    send_response(Socket, 407, "Proxy Authentication Required",
  -		  standardcopy(Header, ExtraHeaders),
  -		  "").
  -
  -send_redirect(Location, Header, Socket) ->
  +    Response = #response{status=407, reason="Proxy Authentication Required",
  +                         header=standardcopy(Header, ExtraHeaders), body=""},
  +    send_response(Socket, Response).
  +
  +send_redirect(Location, Header, Socket) when record(Location, sipurl) ->
       Contact = [{none, Location}],
       ExtraHeaders = [{"Contact",
   		     sipheader:contact_print(Contact)}],
  -    send_response(Socket, 302, "Moved Temporarily",
  -		  standardcopy(Header, ExtraHeaders),
  -		  "").
  -
  +    Response = #response{status=302, reason="Moved Temporarily",
  +			 header=standardcopy(Header, ExtraHeaders), body=""},
  +    send_response(Socket, Response).
   
   send_notfound(Header, Socket) ->
  -    send_response(Socket, 404, "Not found",
  -		  standardcopy(Header, []),
  -		  "").
  +    Response = #response{status=404, reason="Not found",
  +			 header=standardcopy(Header, []), body=""},
  +    send_response(Socket, Response).
   
   send_notavail(Header, Socket) ->
       %% XXX CHECK THIS! SUSPECT IT SHOULD BE ["180"]
       ExtraHeaders = [{"Retry-After", "180"}],
  -    send_response(Socket, 480, "Temporarily unavailable",
  -		  standardcopy(Header, ExtraHeaders),
  -		  "").
  +    Response = #response{status=480, reason="Temporarily unavailable",
  +                         header=standardcopy(Header, ExtraHeaders), body=""},
  +    send_response(Socket, Response).
   
   send_answer(Header, Socket, Body) ->
       %% XXX CHECK THIS! SUSPECT IT SHOULD BE ["application/sdp"] AND [integer_to_list(length(Body))]
       ExtraHeaders = [{"Content-Type", "application/sdp"},
   		    {"Content-Length",
   		     integer_to_list(length(Body))}],
  -    send_response(Socket, 200, "OK",
  -		  standardcopy(Header, ExtraHeaders),
  -		  Body).
  -
  -send_result(Header, Socket, Body, Code, Description) ->
  -    send_response(Socket, Code, Description,
  -		  standardcopy(Header, []),
  -		  Body).
  -
  -send_result(Header, Socket, Body, Code, Description, ExtraHeaders) ->
  -    send_response(Socket, Code, Description,
  -		  standardcopy(Header, ExtraHeaders),
  -		  Body).
  -
  -send_proxy_response(Socket, Status, Reason, Header, Body) ->
  -    case sipheader:via(keylist:fetch("Via", Header)) of
  +    Response = #response{status=200, reason="OK",
  +			 header=standardcopy(Header, ExtraHeaders), body=""},
  +    send_response(Socket, Response).
  +
  +send_result(RequestHeader, Socket, Body, Status, Reason) ->
  +    Response = #response{status=Status, reason=Reason,
  +			 header=standardcopy(RequestHeader, []), body=Body},
  +    send_response(Socket, Response).
  +
  +send_result(RequestHeader, Socket, Body, Status, Reason, ExtraHeaders) ->
  +    Response = #response{status=Status, reason=Reason,
  +			 header=standardcopy(RequestHeader, ExtraHeaders), body=Body},
  +    send_response(Socket, Response).
  +
  +send_proxy_response(Socket, Response) when record(Response, response) ->
  +    case sipheader:via(keylist:fetch("Via", Response#response.header)) of
   	[Self] ->
   	    logger:log(error, "Can't proxy response ~p ~s because it contains just one or less Via and that should be mine!",
  -		       [Status, Reason]),
  +		       [Response#response.status, Response#response.reason]),
   	    {error, invalid_Via};
   	[Self | Via] ->
   	    %% Remove Via matching me (XXX should check that it does)
  -	    NewHeader = keylist:set("Via", sipheader:via_print(Via), Header),
  +	    NewHeader = keylist:set("Via", sipheader:via_print(Via), Response#response.header),
   	    %% Now look for the correct "server transaction" to use when sending this response upstreams
   	    [NextVia | _] = Via,
  -	    send_response(Socket, Status, Reason, NewHeader, Body)
  -    end.
  -
  +	    NewResponse = Response#response{header=NewHeader},
  +	    send_response(Socket, NewResponse)
  +    end.
   
   make_response(Status, Reason, Body, ExtraHeaders, ViaParameters, SipSocket, Request) when record(SipSocket, sipsocket) ->
       make_response(Status, Reason, Body, ExtraHeaders, ViaParameters, SipSocket#sipsocket.proto, Request);
  -make_response(Status, Reason, Body, ExtraHeaders, ViaParameters, Proto, Request) ->
  -    {Method, URI, ReqHeader, _} = Request,
  +make_response(Status, Reason, Body, ExtraHeaders, ViaParameters, Proto, Request) when record(Request, request) ->
  +    ReqHeader = Request#request.header,
       AnswerHeader1 = keylist:appendlist(keylist:copy(ReqHeader, ["Via", "From", "To", "Call-ID", "CSeq",
   								"Record-Route", "Timestamp", "Content-Type"]),
   				       ExtraHeaders),
  
positive.code: %%--------------------------------------------------------------------
  %% Function: url_to_dstlist_not_ip/3
  %% Description: Called from url_to_dstlist/1 when the Host part of the
  %% URI was not an IP address
  %% Returns: ListOfDsts | {error, Reason}
  %%--------------------------------------------------------------------
  url_to_dstlist_not_ip(URL, ApproxMsgSize, ReqURI) ->
      {User, Pass, InHost, InPort, Parameters} = URL,
      case dnsutil:siplookup(InHost) of
  	[{error, nxdomain} | _] ->
  	    %% A SRV-lookup of the Host part of the URL returned NXDOMAIN, this is
  	    %% not an error and we will now try to resolve the Host-part directly
  	    %% (look for A or AAAA record)
  	    host_port_to_dstlist(InHost, InPort, ApproxMsgSize, ReqURI);
  	[{error, What} | _] ->
  	    %% If first element returned from siplookup is an error then they all are.
  	    {error, What};
  	none ->
  	    host_port_to_dstlist(InHost, InPort, ApproxMsgSize, ReqURI);
  	DstList ->
  	    format_siplookup_result(InPort, ReqURI, ApproxMsgSize, DstList)
      end.
  
  %%--------------------------------------------------------------------
  %% Function: host_port_to_dstlist/4
  %% Description: Resolves a hostname and returns a list of sipdst
  %%              records. Needs approximate message size to determine
  %%              if UDP protocol is applicable or should be excluded.
  %%              Inport should either be an integer, or the atom 'none'
  %%              to use the default port for the different protocols
  %%              the resolving might turn up.
  %% Returns: ListOfDsts | {error, Reason}
  %%--------------------------------------------------------------------
  host_port_to_dstlist(InHost, PortStr, ApproxMsgSize, URI) when list(PortStr) ->
      host_port_to_dstlist(InHost, list_to_integer(PortStr), ApproxMsgSize, URI);
  host_port_to_dstlist(InHost, InPort, ApproxMsgSize, URI) when integer(InPort) ; InPort == none ->
      %% RFC3263 4.1 says we SHOULD use UDP if port is explicitly provided
      %% except if other things (such as packet > 1300 bytes) suggests use
      %% of other transport
      case dnsutil:get_ip_port(InHost, InPort) of
  	{error, What} ->
  	    {error, What};
  	L when list(L) ->
  	    %% L is a list of tuples like {IP, Addr, Port}. IP is string,
  	    %% Addr is another tuple (get_ip_port uses inet:getaddr()).
  	    TCP = make_sipdst_from_hostport(tcp, URI, L),
  	    UDP = make_sipdst_from_hostport(udp, URI, L),
  	    case InPort of
  		none ->
  		    logger:log(debug, "Warning: ~p has no SRV records in DNS, defaulting to TCP and then UDP",
  			       [InHost]),
  		    lists:append(TCP, UDP);
  		_ ->
  		    if
  			ApproxMsgSize > 1200 ->
  			    logger:log(debug, "Warning: ~p has no SRV records in DNS, and an explicit port was given (~p) " ++
  				       "but the message size is > 1200 bytes. Resolving hostname and trying TCP and then UDP.",
  				       [InHost]),
  			    lists:append(TCP, UDP);
  			true ->
  			    logger:log(debug, "Warning: ~p has no SRV records in DNS, but an explicit port was given (~p). " ++
  				       "Resolving hostname and defaulting to UDP.", [InHost, InPort]),
  			    UDP
  		    end
  	    end
      end.
  
  %%--------------------------------------------------------------------
  
negative.code:     logger:log(debug, "Warning: Skipping unrecognized element when formatting siplookup results : ~p", [H]),
      format_siplookup_result2(InPort, ReqURI, ApproxMsgSize, T, Res).
  
  %% Function: process_route_header/2
  %% Description: Looks at the Route header. If it exists, we return a
  %%              new destination URL for this request, and if there was
  %%              no loose router flag in the new destination we append
  %%              the original Request-URI to the list of routes, to
  %%              traverse strict (RFC2543) proxys.
  %% Returns: {ok, NewHeader, NewDestURI, NewRequestURI}  |
  %%          nomatch
  %%--------------------------------------------------------------------
  process_route_header(Header, URI) when record(URI, sipurl) ->
      Route = sipheader:contact(keylist:fetch("Route", Header)),
      case Route of
          [{_, FirstRoute} | NewRoute1] ->
  	    {NewHeader, NewURI} = case is_loose_router({none, FirstRoute}) of
  				      true ->
  					  {set_route(NewRoute1, Header), URI};
  				      false ->
  					  logger:log(debug, "Routing: First Route ~p is a strict (RFC2543) router, appending original " ++
  						     "destination URI ~p to Route header", [sipurl:print(FirstRoute), sipurl:print(URI)]),
  					  NewRoute2 = lists:append(NewRoute1, [{none, URI}]),
  					  {set_route(NewRoute2, Header), FirstRoute}
  				  end,
  	    logger:log(debug, "Routing: New destination is ~p, new Request-URI is ~p", [sipurl:print(FirstRoute), sipurl:print(NewURI)]),
  	    {ok, NewHeader, FirstRoute, NewURI};
  	[] ->
  	    nomatch
      end.
  
  set_route([], Header) ->
      keylist:delete("Route", Header);
  set_route(Route, Header) ->
      keylist:set("Route", sipheader:contact_print(Route), Header).
  
  is_loose_router(Route) ->
      case dict:find("lr", sipheader:contact_params(Route)) of
  