anchor.diff:  	  linked=no
   	 }).
   
  +-record(recv, {
  +	  msg_stack=[],		%% First-in-last-out stack of received frames (messages)
  +	  frame = <<>>,		%% The current frame
  +
  +	  parsed,		%% undefined | request record() | response record()
  +	  body_offset,		%% undefined | integer(), the start position of the body in 'frame'
  +	  body_length,		%% undefined | integer(), the content length of the message
  +	  bytes_left,		%% undefined | integer(), number of bytes left on this frame -
  +				%% redundant data (we could always calculate it) but it is easier this way
  +	  origin_str		%% string(), used when logging receved frames
  +	 }).
  +
  +%%--------------------------------------------------------------------
  +%% Macros
  +%%--------------------------------------------------------------------
  +-define(CR, 16#0D).
  +-define(LF, 16#0A).
  +
   %%====================================================================
   %% External functions
   %%====================================================================
  
positive.code: %% Function: recv_loop(State, DataIn)
  %%           State  = state record()
  %%           DataIn = list()
  %% Descrip.: SSL version: Wait for data from our socket. When data is
  %%           available we check to see if we have received a complete
  %%           SIP message yet. If so, continue process it. Then loop
  %%           back to self. If we detect that the socket has been
  %%           closed, tell our parent before we break out of the loop
  %%           and terminate.
  %% Returns : void()
  %%--------------------------------------------------------------------
  recv_loop(#state{linked=no, socketmodule=ssl}=State, DataIn) when is_list(DataIn) ->
      %% Socket is SSL and this is the first time we enter recv_loop(). Link to sockets pid
      %% and set us up to receive exit signals from our parent and from the sockets pid.
      process_flag(trap_exit, true),
      SocketPid = ssl:pid(State#state.socket),
      true = link(SocketPid),
      recv_loop(State#state{linked=yes}, DataIn);
  recv_loop(State, DataIn) when record(State, state), list(DataIn), State#state.socketmodule == ssl ->
      Socket = State#state.socket,
      SocketPid = ssl:pid(State#state.socket),
      %% Must set {active, once} here even if tcp_listener did it right before us -
      %% it seems as if the SSL socket looses this status when controlling process is changed.
      ssl:setopts(State#state.socket, [{active, once}]),
      Parent = State#state.parent,
      Rest = receive
  	       {ssl, Socket, B} ->
  		   L = binary_to_list(B),
  		   logger:log(debug, "TCP receiver: Received ~p bytes of data (SSL), adding it to my buffer which contained ~p bytes of data",
  			      [length(L), length(DataIn)]),
  		   %% remove_separator() removes any leading CR or LF
  		   NewDataIn = lists:append(DataIn, L),
  		   SoFar = remove_separator(NewDataIn),
  		   %% Look for header-body separator
  		   case has_header_body_separator(SoFar) of
  		       false ->
  			   %% No Header Body separator yet, read more data
  			   SoFar;
  		       true ->
  			   case header_received(SoFar, State) of
  			       AdditionalData when is_list(AdditionalData) ->
  				   logger:log(debug, "TCP receiver: My buffer now contains ~p bytes of data (SSL)", [length(AdditionalData)]),
  				   AdditionalData;
  			       AdditionalData2 ->
  				   AdditionalData2
  			   end
  		   end;
  
  	       {ssl_closed, Socket} ->
  		   logger:log(debug, "TCP receiver: Extra debug: Socket closed (Socket: ~p, local ~p, remote ~p)",
  			      [Socket, State#state.local, State#state.remote]),
  		   {connection_closed};
  
  	       {ssl_error, Socket, Reason} ->
  		   logger:log(error, "TCP receiver: SSL error from socket ~p : ~p", [Socket, Reason]),
  		   DataIn;
  
  	       {quit_receiver, Parent} ->
  		   logger:log(debug, "TCP receiver: Closing SSL socket ~p and terminating upon request from my parent",
  			      [Socket]),
  		   {quit};
  
  	       {'EXIT', SocketPid, Reason} ->
  		   logger:log(debug, "TCP receiver: SSL socket ~p terminated, shutting down. Reason was : ~p",
  			      [Socket, Reason]),
  		   {close};
  
  	       {'EXIT', Parent, Reason} ->
  		   logger:log(debug, "TCP receiver: SSL connection handler ~p terminated, shutting down. Reason was : ~p",
  			      [Parent, Reason]),
  		   {quit};
  
  	       Unknown ->
  		   logger:log(error, "TCP receiver: Received unknown signal :~n~p", [Unknown]),
  		   DataIn
  	   after 10 * 1000 ->
  		   DataIn
  	   end,
      case Rest of
  	{connection_closed} ->
  	    gen_server:cast(Parent, {connection_closed, self()});
  	{close} ->
  	    ssl:close(State#state.socket),	%% Maybe not needed, but better safe than sorry
  	    gen_server:cast(Parent, {close, self()});
  	{quit} ->
  	    ssl:close(State#state.socket),
  	    ok;
  	_ when is_list(Rest) ->
  	    recv_loop(State, Rest)
      end;
  
  %%--------------------------------------------------------------------
  %% Function: recv_loop(State, DataIn)
  %%           State  = state record()
  %%           DataIn = list()
  %% Descrip.: Constantly try to read data from our socket. Loop back to
  %%           self. If we detect that the socket has been closed, tell
  %%           our parent before we break out of the loop and terminate.
  %% Returns : void()
  %%--------------------------------------------------------------------
  recv_loop(State, DataIn) when record(State, state) ->
      Parent = State#state.parent,
      case do_recv(DataIn, State) of
  	Data when list(Data) ->
  	    recv_loop(State, Data);
  	{connection_closed} ->
  	    gen_server:cast(Parent, {connection_closed, self()});
  	{close} ->
  	    gen_server:cast(Parent, {close, self()});
  	Unknown ->
  	    logger:log(error, "TCP receiver: Dying after unknown result from do_recv() :~n~p", [Unknown]),
  
negative.code: %%% Author  : Fredrik Thulin <ft@it.su.se>
  %%% Descrip.: TCP receiver does blocking read on a single socket and
  %%%           signals parent when a complete SIP request/response has
  %%%           been received. If we encounter something we can't handle
  %%%           we just close the socket. There is no way to know if we
  %%%           are in or out of sync with the remote end if we have
  %%%           encountered something not perfectly legal.
  %%%
  %%%           tcp_receiver processes are just the blocking-read shadow
  %%%           of tcp_connection processes. We consider the
  %%%           tcp_connection process the 'real owner' of the open
  %%%           socket, so we never for example close the sockets
  %%%           ourselves - instead we signal the tcp_connection process
  %%%           (our State#state.parent) to close it, and then we just
  %%%           terminate. This is not really true for SSL sockets
  %%%           though, since the ssl module should send received data
  %%%           to this process we are also the owner of SSL sockets.
  %%%
  %%%           Signals we send to our parent :
  %%%
  %%%           {recv_sipmsg, R} - we have received a complete SIP
  %%%                              message and parsed it into a request
  %%%                              or response record()
  %%%           {close, self()}  - close the socket, please
  %%%           {connection_closed, self()} - the other end has closed
  %%%                                         the socket
  %%%
  %%%           Signals we honor (SSL sockets only) :
  %%%
  %%%           {quit_receiver, Parent} - we should close the socket
  %%%
  %%% Created : 15 Mar 2004 by Fredrik Thulin <ft@it.su.se>
  %%%-------------------------------------------------------------------
  
  -module(tcp_receiver).
  -compile(export_all).
  
  %%--------------------------------------------------------------------
  %% External exports
  %%--------------------------------------------------------------------
  -export([start_link/5,
  	 test/0]).
  
  %%--------------------------------------------------------------------
  %% Internal exports
  