anchor.diff:  	    transactionlayer:send_response_handler(THandler, 500, "Server Internal Error")
       end.
   
  -relay_dst2str(URI) when record(URI, sipurl) ->
  +relay_dst2str(URI) when is_record(URI, sipurl) ->
       sipurl:print(URI);
   relay_dst2str(route) ->
       "according to Route header";
  
positive.code: 	    true
      end.
  
  
  %% Function: do_request/2
  %% Description: Calls route_request() to determine what to do with a
  %%              request, and then takes whatever action we are
  %%              supposed to.
  %% Returns: Does not matter
  %%--------------------------------------------------------------------
  do_request(RequestIn, Origin) when record(RequestIn, request), record(Origin, siporigin) ->
      {Method, URI} = {RequestIn#request.method, RequestIn#request.uri},
      logger:log(debug, "~s ~s~n",
  	       [Method, sipurl:print(URI)]),
      Header = case sipserver:get_env(record_route, false) of
  	true -> siprequest:add_record_route(RequestIn#request.header, Origin);
  	false -> RequestIn#request.header
      end,
      Request = RequestIn#request{header = Header},
      Location = route_request(Request),
      logger:log(debug, "Location: ~p", [Location]),
  
negative.code: 		true ->
  		    do_request(Request, Origin);
  		false ->
  		    logger:log(normal, "~s: incomingproxy: Not authorized to use this From: -> 403 Forbidden",
  			       [LogTag]),
  		    transactionlayer:send_response_handler(THandler, 403, "Forbidden");
  		drop ->
  		    ok;
  		Unknown ->
  		    logger:log(error, "~s: Unknown result from verify_homedomain_user() :~n~p",
  			       [LogStr, Unknown]),
  		    transactionlayer:send_response_handler(THandler, 500, "Server Internal Error")
  	    end;
  	_ ->
  	    do_request(Request, Origin)
      end,
      ok.
  
  %%--------------------------------------------------------------------
  %% Function: response(Response, Origin, LogStr)
  %%           Request = response record()
  %%           Origin  = siporigin record()
  %%           LogStr  = string(), description of response
  %% Descrip.: Yxa applications must export an response/3 function.
  %% Returns : Yet to be specified. Return 'ok' for now.
  %%--------------------------------------------------------------------
  response(Response, Origin, LogStr) when is_record(Response, response), is_record(Origin, siporigin) ->
      {Status, Reason} = {Response#response.status, Response#response.reason},
      logger:log(normal, "incomingproxy: Response to ~s: '~p ~s', no matching transaction - proxying statelessly",
  	       [LogStr, Status, Reason]),
      transportlayer:send_proxy_response(none, Response),
      ok.
  
  
  %%====================================================================
  %% Internal functions
  %%====================================================================
  
  %%--------------------------------------------------------------------
  %% Function: register_request(Request, Origin, LogStr)
  %%           Request = response record()
  %%           Origin  = siporigin record()
  %%           LogStr  = string(), description of request
  %% Descrip.: Process a received REGISTER. First check if it is for
  %%           one of our domains (homedomain), then check that it
  %%           contains proper authentication and that the authenticated
  %%           user is allowed to register using this address-of-record.
  %%           Finally, let siplocation:process_register_isauth()
  %%           process all the Contact headers and update the location
  %%           database.
  %% Returns : Does not matter.
  %%--------------------------------------------------------------------
  register_request(Request, Origin, LogStr) when is_record(Request, request), is_record(Origin, siporigin) ->
      URL = Request#request.uri,
      logger:log(debug, "incomingproxy: REGISTER ~p", [sipurl:print(URL)]),
      THandler = transactionlayer:get_handler_for_request(Request),
      LogTag = get_branch_from_handler(THandler),
      %% RFC 3261 chapter 10.3 - Processing REGISTER Request - step 1
      %% check if this registrar handles the domain the request wants to register for
      case local:homedomain(URL#sipurl.host) of
  	true ->
  	    register_require_supported(Request, Origin, LogStr, THandler, LogTag);
  	_ ->
  	    %% act as proxy and forward message to other domain
  	    logger:log(debug, "incomingproxy: REGISTER for non-homedomain ~p", [URL#sipurl.host]),
  	    do_request(Request, Origin)
      end.
  
  %% part of register_request/3
  register_require_supported(Request, Origin, LogStr, THandler, LogTag) ->
      Header = Request#request.header,
      %% RFC 3261 chapter 10.3 - Processing REGISTER Request - step 2
      case is_valid_register_request(Header) of
  	true ->
  	    register_authenticate(Request, Origin, LogStr, THandler, LogTag);
  	{siperror, Status, Reason, ExtraHeaders} ->
  	    transactionlayer:send_response_handler(THandler, Status, Reason, ExtraHeaders)
      end.
  
  %% part of register_request/3
  register_authenticate(Request, _Origin, LogStr, THandler, LogTag) ->
      {URL, Header} =
  	{Request#request.uri, Request#request.header},
      logger:log(debug, "incomingproxy: ~s -> processing", [LogStr]),
      %% delete any present Record-Route header (RFC3261, #10.3)
      NewHeader = keylist:delete("Record-Route", Header),
      {_, ToURL} = sipheader:to(Header),
      %% RFC 3261 chapter 10.3 - Processing REGISTER Request - step 3, step 4 and step 5
      %% authenticate UAC
      case local:can_register(NewHeader, ToURL) of
  	{{true, _}, SIPuser} ->
  	    Contacts = sipheader:contact(Header),
  	    logger:log(debug, "Register: Contact(s) ~p", [sipheader:contact_print(Contacts)]),
  	    logger:log(debug, "~s: Registering contacts for SIP user ~p", [LogTag, SIPuser]),
  	    %% RFC 3261 chapter 10.3 - Processing REGISTER Request - step 6, step 7 and step 8
  	    case catch siplocation:process_register_isauth(LogTag ++ ": incomingproxy",
  							   NewHeader, SIPuser, Contacts) of
  		{ok, {Status, Reason, ExtraHeaders}} ->
  		    transactionlayer:send_response_handler(THandler, Status, Reason, ExtraHeaders);
  		{siperror, Status, Reason} ->
  		    transactionlayer:send_response_handler(THandler, Status, Reason);
  		{siperror, Status, Reason, ExtraHeaders} ->
  		    transactionlayer:send_response_handler(THandler, Status, Reason, ExtraHeaders);
  		{'EXIT', Reason} ->
  		    logger:log(error, "=ERROR REPORT==== siplocation:process_register_isauth() failed :~n~p~n",
  			       [Reason]),
  		    transactionlayer:send_response_handler(THandler, 500, "Server Internal Error");
  		_ ->
  		    true
  	    end;
  	{stale, _} ->
  	    logger:log(normal, "~s -> Authentication is STALE, sending new challenge", [LogStr]),
  	    transactionlayer:send_challenge(THandler, www, true, none);
  	{{false, eperm}, SipUser} when SipUser /= none ->
  	    logger:log(normal, "~s: incomingproxy: SipUser ~p NOT ALLOWED to REGISTER address ~s",
  		       [LogTag, SipUser, sipurl:print(ToURL)]),
  	    transactionlayer:send_response_handler(THandler, 403, "Forbidden");
  	{{false, nomatch}, SipUser} when SipUser /= none ->
  	    logger:log(normal, "~s: incomingproxy: SipUser ~p tried to REGISTER invalid address ~s",
  		       [LogTag, SipUser, sipurl:print(ToURL)]),
  	    transactionlayer:send_response_handler(THandler, 404, "Not Found");
  	{false, none} ->
  	    Prio = case keylist:fetch("Authorization", Header) of
  		       [] -> debug;
  		       _ -> normal
  		   end,
  	    %% XXX send new challenge (current behavior) or send 403 Forbidden when authentication fails?
  	    logger:log(Prio, "~s -> Authentication FAILED, sending challenge", [LogStr]),
  	    transactionlayer:send_challenge(THandler, www, false, 3);
  	Unknown ->
  	    logger:log(error, "Register: Unknown result from local:can_register() URL ~p :~n~p",
  		       [sipurl:print(URL), Unknown]),
  	    transactionlayer:send_response_handler(THandler, 500, "Server Internal Error")
      end.
  
  
  %%--------------------------------------------------------------------
  %% Function: is_valid_register_request(Header)
  %%           Header = keylist record()
  %% Descrip.: looks for unsupported extensions.
  %% Returns : true | SipError
  %%--------------------------------------------------------------------
  is_valid_register_request(Header) ->
      Require = keylist:fetch("Require", Header),
      case Require of
  	[] ->
  	    true;
  	_ ->
  	    %% we support no extensions, so all are unsupported
  	    logger:log(normal, "Request check: The client requires unsupported extension(s) ~p", [Require]),
  	    {siperror, 420, "Bad Extension", [{"Unsupported", Require}]}
      end.
  
  
  %%--------------------------------------------------------------------
  %% Function: verify_homedomain_user(Request, LogTag)
  %%           Request = request record()
  %%           LogTag  = string(), prefix for logging
  %% Descrip.: If a request has a From: matching our homedomains,
  %%           this function is called to make sure the user really
  %%           is who it says it is, and not someone else forging
  %%           our users identity.
  %% Returns:  true | false | drop
  %%--------------------------------------------------------------------
  verify_homedomain_user(Request, LogTag) when is_record(Request, request) ->
      Method = Request#request.method,
      Header = Request#request.header,
      case sipserver:get_env(always_verify_homedomain_user, true) of
  	true ->
  	    {_, FromURI} = sipheader:from(Header),
  	    %% Request has a From: address matching one of my domains.
  	    %% Verify sending user.
  	    case local:get_user_verified_proxy(Header, Method) of
  		{authenticated, SIPUser} ->
  		    case local:can_use_address(SIPUser, FromURI) of
  			true ->
  			    logger:log(debug, "Request: User ~p is allowed to use From: address ~p",
  				       [SIPUser, sipurl:print(FromURI)]),
  			    true;
  			false ->
  			    logger:log(error, "Authenticated user ~p may NOT use address ~p",
  				       [SIPUser, sipurl:print(FromURI)]),
  			    false
  		    end;
  		stale ->
  