anchor.diff:      end.
   
   %%--------------------------------------------------------------------
  -%% Function: check_proxy_request(Request)
  -%% Descrip.: Prepares a request for proxying. Checks Max-Forwards,
  -%%           etc. Not guaranteed to return, might
  -%%           throw a siperror if the request should not be proxied.
  -%% Returns : {ok, NewHeader, ApproxMsgSize} |
  +%% Function: stateless_route_proxy_request(Request)
  +%%           Request = request record()
  +%% Descrip.: Inspect a request that some Yxa application has found it
  +%%           should proxy statelessly. Figure out a single sipdst
  +%%           destination for this request (sorry, stateless SIP does
  +%%           not handle multiple destinations) and return that
  +%%           destination plus a new request (the headers might change
  +%%           if we have popped a Route header).
  +%% Returns : {ok, Dst, NewRequest} |
   %%           throw {siperror, ...}
  -%%--------------------------------------------------------------------
  -check_proxy_request(Request) when is_record(Request, request) ->
  -    NewHeader1 = proxy_check_maxforwards(Request#request.header),
  -    check_valid_proxy_request(Request#request.method, NewHeader1),
  -    NewHeader2 = fix_content_length(NewHeader1, Request#request.body),
  -    BinLine1 = list_to_binary([Request#request.method, " ", sipurl:print(Request#request.uri), " SIP/2.0"]),
  -    BinMsg = binary_make_message(BinLine1, NewHeader2, list_to_binary(Request#request.body)),
  -    ViaLen = 92 + length(siprequest:myhostname()),
  -    %% The size is _approximate_. The exact size cannot be calculated here
  -    %% since it is dependent on the right Request-URI and length of the final
  -    %% Via header we insert, not the 92 bytes + hostname _estimate_.
  -    ApproxMsgSize = size(BinMsg) + ViaLen,
  -    {ok, NewHeader2, ApproxMsgSize}.
  -
  -
  -%%--------------------------------------------------------------------
  -%% Function: send_proxy_request(Socket, Request, Dst, ViaParameters)
  -%%           SrvTHandler   = thandler record() | none
  -%%           Request       = request record()
  -%%           Dst           = list() of sipdst record() |
  -%%                           sipdst record() |
  -%%                           sipurl record()
  -%%           ViaParameters = list() of {key, value} tuple()
  -%% Descrip.: Prepare for proxying a request. The preparation process
  -%%           is basically to get us a list() of sipdst records and
  -%%           then calling send_to_available_dst().
  -%% Returns : throw()         |
  -%%           {error, Reason} |
  -%%           Result
  -%%           Reason = string()
  -%%           Result = term(), result of send_to_available_dst().
  -%%--------------------------------------------------------------------
  -
  -%%
  -%% Turn Dst into a list()
  -%%
  -send_proxy_request(Socket, Request, Dst, ViaParameters) when is_record(Dst, sipdst) ->
  -    send_proxy_request(Socket, Request, [Dst], ViaParameters);
  -
  -%%
  -%% Explicit destination(s) provided, just send
  -%%
  -send_proxy_request(Socket, Request, [Dst | DstT], ViaParameters) 
  -  when is_record(Socket, sipsocket); Socket == none, is_record(Request, request), is_record(Dst, sipdst) ->
  -    {ok, NewHeader1, _ApproxMsgSize} = check_proxy_request(Request),
  -    DstList = [Dst | DstT],
  -    logger:log(debug, "Siprequest (transport layer) : Destination list for request is (~p entrys) :~n~p",
  -	       [length(DstList), sipdst:debugfriendly(DstList)]),
  -    NewRequest = Request#request{header=NewHeader1},
  -    send_to_available_dst(DstList, NewRequest, ViaParameters);
  -
  -%%
  -%% Dst is URI - turn it into a list of sipdst records. First check Route header though.
  -%% XXX we should remove this now that we are only stateful. The TU or transaction layer
  -%% should provide us with destinations.
  -send_proxy_request(Socket, Request, URI, ViaParameters)
  -  when is_record(Socket, sipsocket); Socket == none, is_record(URI, sipurl) ->
  -    {ok, _, ApproxMsgSize} = check_proxy_request(Request),
  -    case process_route_header(Request#request.header, URI) of
  +%%           Dst        = sipdst record()
  +%%           NewRequest = request record()
  +%%--------------------------------------------------------------------
  +stateless_route_proxy_request(Request) when is_record(Request, request) ->
  +    {ok, NewHeader, ApproxMsgSize} = check_proxy_request(Request),
  +    case stateless_route_proxy_request2(Request#request{header=NewHeader}, ApproxMsgSize) of
  +	{ok, [Dst], NewRequest} ->
  +	    {ok, Dst, NewRequest};
  +	{ok, [Dst | Rest], NewRequest} ->
  +	    logger:log(debug, "Warning: request being forwarded statelessly had more than one destination, "
  +		       "ignoring all but the first one :~n~p", [sipdst:debugfriendly([Dst | Rest])]),
  +	    {ok, Dst, NewRequest};
  +	_ ->
  +	    {error, "stateless_route_proxy_request() failed"}
  +    end.
  +
  +%% part of stateless_route_proxy_request/1
  +stateless_route_proxy_request2(Request, ApproxMsgSize) ->
  +    {Header, URI} = {Request#request.header, Request#request.uri},
  +    case process_route_header(Header, URI) of
   	nomatch ->
   	    case sipdst:url_to_dstlist(URI, ApproxMsgSize, URI) of
   		DstList when is_list(DstList) ->
  -		    send_proxy_request(Socket, Request, DstList, ViaParameters);
  +		    {ok, DstList, Request};
   		Unknown ->
   		    logger:log(error, "Siprequest (transport layer) : Failed resolving URI ~s : ~p",
   			       [sipurl:print(URI), Unknown]),
   		    {error, "Failed resolving destination"}
   	    end;
  -	{ok, NewHeaderX, DstURI, ReqURI} when is_record(DstURI, sipurl), is_record(ReqURI, sipurl) ->
  -	    %% XXX is it correct to just ditch NewHeaderX or should we stuff it into the Request
  -	    %% we send to send_proxy_request()?
  +	{ok, NewHeader1, DstURI, ReqURI} when is_record(DstURI, sipurl), is_record(ReqURI, sipurl) ->
   	    logger:log(debug, "Siprequest (transport layer) : Routing request as per the Route header,"
   		       " Destination ~p, Request-URI ~p",
   		       [sipurl:print(DstURI), sipurl:print(ReqURI)]),
   	    case sipdst:url_to_dstlist(DstURI, ApproxMsgSize, ReqURI) of
   		DstList when is_list(DstList) ->
  -		    send_proxy_request(Socket, Request, DstList, ViaParameters);
  +		    {ok, DstList, Request#request{header=NewHeader1}};
   		Unknown ->
   		    logger:log(error, "Siprequest (transport layer) : Failed resolving URI "
   			       "(from Route header) ~s : ~p", [sipurl:print(URI), Unknown]),
  
positive.code:     end.
  
  %%--------------------------------------------------------------------
  %% Function: send_to_available_dst(DstList, Request, ViaParam)
  %%           DstList       = list() of sipdst record()
  %%           Request       = request record()
  %%           ViaParam      = list() of {key, value} tuple()
  %% Descrip.: Sequentially try to get sockets for, and send request
  %%           to, the destinations listed in DstList.
  %% Returns : {ok, Socket, Branch} |
  %%           {error, Reason}      |
  %%           Socket = sipsocket record(), the socket finally used
  %%           Branch = string(), the branch we put in the Via header
  %%           Reason = string()
  %% Note    : XXX This function should no longer accept a list - we are
  %%           always transaction stateful now!
  %%--------------------------------------------------------------------
  send_to_available_dst([], Request, _ViaParam) when is_record(Request, request) ->
      {Method, URI, Header, Body} = {Request#request.method, Request#request.uri,
  				   Request#request.header, Request#request.body},
      BinLine1 = list_to_binary([Method, " ", sipurl:print(URI), " SIP/2.0"]),
      BinMsg = binary_make_message(BinLine1, Header, list_to_binary(Body)),
      Message = binary_to_list(BinMsg),
      logger:log(debug, "Siprequest (transport layer) : Failed sending request"
  	       " (my Via not added, original URI shown) :~n~s", [Message]),
      {senderror, "failed"};
  send_to_available_dst([Dst | DstT], Request, ViaParam)
    when is_record(Dst, sipdst), is_record(Request, request) ->
      IP = Dst#sipdst.addr,
      Port = Dst#sipdst.port,
      Proto = Dst#sipdst.proto,
      SocketModule = sipsocket:proto2module(Proto),
      DestStr = sipdst:dst2str(Dst),
      case sipsocket:get_socket(SocketModule, Proto, IP, Port) of
  	{error, What} ->
  	    logger:log(debug, "Siprequest (transport layer) : Failed to get ~p socket for ~s : ~p",
  		       [Proto, DestStr, What]),
  	    %% try next
  	    send_to_available_dst(DstT, Request, ViaParam);
  	SipSocket when is_record(SipSocket, sipsocket) ->
  	    {Method, OrigURI, Header, Body} = {Request#request.method, Request#request.uri,
  					       Request#request.header, Request#request.body},
  	    NewHeader1 = proxy_add_via(Header, OrigURI, ViaParam, Proto),
  	    BinLine1 = list_to_binary([Method, " ", sipurl:print(Dst#sipdst.uri), " SIP/2.0"]),
  	    BinMsg = binary_make_message(BinLine1, NewHeader1, list_to_binary(Body)),
  	    SendRes = sipsocket:send(SipSocket, Proto, IP, Port, BinMsg),
  	    case SendRes of
  		ok ->
  		    logger:log(debug, "Siprequest (transport layer) : sent request(dst=~s) :~n~s~n",
  			       [DestStr, binary_to_list(BinMsg)]),
  		    TopVia = sipheader:topvia(NewHeader1),
  		    UsedBranch = lists:flatten(sipheader:get_via_branch_full(TopVia)),
  		    {ok, SipSocket, UsedBranch};
  		{error, E} ->
  		    logger:log(debug, "Siprequest (transport layer) : Failed sending message to ~p:~s:~p, error ~p",
  			       [Proto, IP, Port, E]),
  		    send_to_available_dst(DstT, Request, ViaParam)
  	    end
      end;
  send_to_available_dst([Dst | DstT], Request, ViaParam) ->
      logger:log(error, "Siprequest (transport layer) : send_to_available_dst called with illegal dst ~p", [Dst]),
      send_to_available_dst(DstT, Request, ViaParam).
  
  
  %%--------------------------------------------------------------------
  %% Function: proxy_check_maxforwards(Header)
  
negative.code: %%====================================================================
  %% External functions
  %%====================================================================
  
  %%--------------------------------------------------------------------
  %% Function: fix_content_length(Header, Body)
  