2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%% The contents of this file are subject to the Mozilla Public License
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%% Version 1.1 (the "License"); you may not use this file except in
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%% compliance with the License. You may obtain a copy of the License
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%% at http://www.mozilla.org/MPL/
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%% Software distributed under the License is distributed on an "AS IS"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%% the License for the specific language governing rights and
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%% limitations under the License.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%% The Original Code is RabbitMQ.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%%
							 | 
						
					
						
							
								
									
										
										
										
											2013-07-01 17:49:14 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								%% The Initial Developer of the Original Code is GoPivotal, Inc.
							 | 
						
					
						
							
								
									
										
										
										
											2014-03-18 01:25:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								%% Copyright (c) 2007-2014 GoPivotal, Inc.  All rights reserved.
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%%
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								-module(rabbit_mqtt_reader).
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								-behaviour(gen_server2).
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 23:38:14 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								-export([start_link/0]).
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								         code_change/3, terminate/2]).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-01-07 01:50:02 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								-export([conserve_resources/3, start_keepalive/2]).
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								-include_lib("amqp_client/include/amqp_client.hrl").
							 | 
						
					
						
							
								
									
										
										
										
											2012-09-12 21:34:41 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								-include("rabbit_mqtt.hrl").
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%%----------------------------------------------------------------------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 23:38:14 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								start_link() ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    gen_server2:start_link(?MODULE, [], []).
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2013-02-28 20:27:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								conserve_resources(Pid, _, Conserve) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Pid ! {conserve_resources, Conserve},
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ok.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%%----------------------------------------------------------------------------
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 23:38:14 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								init([]) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {ok, undefined, hibernate, {backoff, 1000, 1000, 10000}}.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-04-15 19:20:49 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_call(Msg, From, State) ->
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    {stop, {mqtt_unexpected_call, Msg, From}, State}.
							 | 
						
					
						
							
								
									
										
										
										
											2014-04-15 19:20:49 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								handle_cast({go, Sock0, SockTransform, KeepaliveSup}, undefined) ->
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    process_flag(trap_exit, true),
							 | 
						
					
						
							
								
									
										
										
										
											2014-04-15 19:20:49 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    case rabbit_net:connection_string(Sock0, inbound) of
							 | 
						
					
						
							
								
									
										
										
										
											2013-03-01 18:49:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        {ok, ConnStr} ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            log(info, "accepting MQTT connection (~s)~n", [ConnStr]),
							 | 
						
					
						
							
								
									
										
										
										
											2014-04-15 19:20:49 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            case SockTransform(Sock0) of
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {ok, Sock} ->
							 | 
						
					
						
							
								
									
										
										
										
											2014-04-15 21:18:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    rabbit_alarm:register(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                      self(), {?MODULE, conserve_resources, []}),
							 | 
						
					
						
							
								
									
										
										
										
											2014-04-15 19:20:49 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    ProcessorState = rabbit_mqtt_processor:initial_state(Sock),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    {noreply,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                     control_throttle(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                       #state{socket           = Sock,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              conn_name        = ConnStr,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              await_recv       = false,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              connection_state = running,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              keepalive        = {none, none},
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              keepalive_sup    = KeepaliveSup,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              conserve         = false,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              parse_state      = rabbit_mqtt_frame:initial_state(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              proc_state       = ProcessorState }),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                     hibernate};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {error, Reason} ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    rabbit_net:fast_close(Sock0),
							 | 
						
					
						
							
								
									
										
										
										
											2014-07-03 20:03:51 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    {stop, {network_error, Reason, ConnStr}, undefined}
							 | 
						
					
						
							
								
									
										
										
										
											2014-04-15 19:20:49 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            end;
							 | 
						
					
						
							
								
									
										
										
										
											2014-07-03 19:46:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        {network_error, Reason} ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            rabbit_net:fast_close(Sock0),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {stop, {shutdown, Reason}, undefined};
							 | 
						
					
						
							
								
									
										
										
										
											2013-03-01 18:49:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        {error, enotconn} ->
							 | 
						
					
						
							
								
									
										
										
										
											2014-04-15 19:20:49 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            rabbit_net:fast_close(Sock0),
							 | 
						
					
						
							
								
									
										
										
										
											2013-03-01 18:49:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            {stop, shutdown, undefined};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {error, Reason} ->
							 | 
						
					
						
							
								
									
										
										
										
											2014-04-15 19:20:49 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            rabbit_net:fast_close(Sock0),
							 | 
						
					
						
							
								
									
										
										
										
											2013-03-01 18:49:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            {stop, {network_error, Reason}, undefined}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end;
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2013-11-14 21:48:14 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_cast(duplicate_id,
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            State = #state{ proc_state = PState,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            conn_name  = ConnName }) ->
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    log(warning, "MQTT disconnecting duplicate client id ~p (~p)~n",
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                 [rabbit_mqtt_processor:info(client_id, PState), ConnName]),
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    {stop, {shutdown, duplicate_id}, State};
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								handle_cast(Msg, State) ->
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    {stop, {mqtt_unexpected_cast, Msg}, State}.
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_info({#'basic.deliver'{}, #amqp_msg{}} = Delivery,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            State = #state{ proc_state = ProcState }) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    callback_reply(State, rabbit_mqtt_processor:amqp_callback(Delivery, ProcState));
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_info(#'basic.ack'{} = Ack, State = #state{ proc_state = ProcState }) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    callback_reply(State, rabbit_mqtt_processor:amqp_callback(Ack, ProcState));
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_info(#'basic.consume_ok'{}, State) ->
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    {noreply, State, hibernate};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_info(#'basic.cancel'{}, State) ->
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    {stop, {shutdown, subscription_cancelled}, State};
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-16 21:57:31 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_info({'EXIT', _Conn, Reason}, State) ->
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    {stop, {connection_died, Reason}, State};
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								handle_info({inet_reply, _Ref, ok}, State) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {noreply, State, hibernate};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_info({inet_async, Sock, _Ref, {ok, Data}},
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            State = #state{ socket = Sock }) ->
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    process_received_bytes(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      Data, control_throttle(State #state{ await_recv = false }));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_info({inet_async, _Sock, _Ref, {error, Reason}}, State = #state {}) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    network_error(Reason, State);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								handle_info({inet_reply, _Sock, {error, Reason}}, State = #state {}) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    network_error(Reason, State);
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								handle_info({conserve_resources, Conserve}, State) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {noreply, control_throttle(State #state{ conserve = Conserve }), hibernate};
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_info({bump_credit, Msg}, State) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    credit_flow:handle_bump_msg(Msg),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {noreply, control_throttle(State), hibernate};
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-01-20 18:33:27 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_info({start_keepalives, Keepalive},
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            State = #state { keepalive_sup = KeepaliveSup, socket = Sock }) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    %% Only the client has the responsibility for sending keepalives
							 | 
						
					
						
							
								
									
										
										
										
											2014-01-07 01:50:02 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    SendFun = fun() -> ok end,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Parent = self(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ReceiveFun = fun() -> Parent ! keepalive_timeout end,
							 | 
						
					
						
							
								
									
										
										
										
											2014-01-20 18:33:27 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    Heartbeater = rabbit_heartbeat:start(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    KeepaliveSup, Sock, 0, SendFun, Keepalive, ReceiveFun),
							 | 
						
					
						
							
								
									
										
										
										
											2014-01-07 01:50:02 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    {noreply, State #state { keepalive = Heartbeater }};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								handle_info(keepalive_timeout, State = #state { conn_name = ConnStr }) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log(error, "closing MQTT connection ~p (keepalive timeout)~n", [ConnStr]),
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    {stop, {shutdown, keepalive_timeout}, State};
							 | 
						
					
						
							
								
									
										
										
										
											2014-01-07 01:50:02 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								handle_info(Msg, State) ->
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    {stop, {mqtt_unexpected_msg, Msg}, State}.
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-07-03 20:03:51 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								terminate({network_error, {ssl_upgrade_error, closed}, ConnStr}, _State) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log(error, "MQTT detected TLS upgrade error on ~s: connection closed~n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								       [ConnStr]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								terminate({network_error,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								           {ssl_upgrade_error,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {tls_alert, "handshake failure"}}, ConnStr}, _State) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log(error, "MQTT detected TLS upgrade error on ~s: handshake failure~n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								       [ConnStr]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								terminate({network_error,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								           {ssl_upgrade_error,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {tls_alert, Alert}}, ConnStr}, _State) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log(error, "MQTT detected TLS upgrade error on ~s: alert ~s~n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								       [ConnStr, Alert]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								terminate({network_error, {ssl_upgrade_error, Reason}, ConnStr}, _State) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log(error, "MQTT detected TLS upgrade error on ~s: ~p~n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        [ConnStr, Reason]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								terminate({network_error, Reason, ConnStr}, _State) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log(error, "MQTT detected network error on ~s: ~p~n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        [ConnStr, Reason]);
							 | 
						
					
						
							
								
									
										
										
										
											2014-07-03 19:46:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								terminate({network_error, Reason}, _State) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log(error, "MQTT detected network error: ~p~n", [Reason]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								terminate(_Reason, State = #state{ proc_state = ProcState}) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    rabbit_mqtt_processor:close_connection(ProcState),
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    ok.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								code_change(_OldVsn, State, _Extra) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {ok, State}.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%%----------------------------------------------------------------------------
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								process_received_bytes(<<>>, State) ->
							 | 
						
					
						
							
								
									
										
										
										
											2013-02-28 21:04:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    {noreply, State, hibernate};
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-13 23:32:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								process_received_bytes(Bytes,
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                       State = #state{ parse_state = ParseState,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                       proc_state  = ProcState,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                       conn_name   = ConnStr }) ->
							 | 
						
					
						
							
								
									
										
										
										
											2013-02-28 20:27:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    case rabbit_mqtt_frame:parse(Bytes, ParseState) of
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {more, ParseState1} ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            {noreply,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								             control_throttle( State #state{ parse_state = ParseState1 }),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								             hibernate};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {ok, Frame, Rest} ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            case rabbit_mqtt_processor:process_frame(Frame, ProcState) of
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {ok, ProcState1} ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    PS = rabbit_mqtt_frame:initial_state(),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    process_received_bytes(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                      Rest,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                      State #state{ parse_state = PS,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    proc_state = ProcState1 });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {err, Reason, ProcState1} ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    log(info, "MQTT protocol error ~p for connection ~p~n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        [Reason, ConnStr]),
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    {stop, {shutdown, Reason}, pstate(State, ProcState1)};
							 | 
						
					
						
							
								
									
										
										
										
											2013-02-28 20:27:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                {stop, ProcState1} ->
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    {stop, normal, pstate(State, ProcState1)}
							 | 
						
					
						
							
								
									
										
										
										
											2013-02-28 20:27:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            end;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {error, Error} ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            log(error, "MQTT detected framing error ~p for connection ~p~n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                [ConnStr, Error]),
							 | 
						
					
						
							
								
									
										
										
										
											2014-05-21 15:13:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            {stop, {shutdown, Error}, State}
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								callback_reply(State, {ok, ProcState}) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {noreply, pstate(State, ProcState), hibernate};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								callback_reply(State, {err, Reason, ProcState}) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {stop, Reason, pstate(State, ProcState)}.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-01-07 01:50:02 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								start_keepalive(_,   0        ) -> ok;
							 | 
						
					
						
							
								
									
										
										
										
											2014-01-20 18:33:27 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								start_keepalive(Pid, Keepalive) -> Pid ! {start_keepalives, Keepalive}.
							 | 
						
					
						
							
								
									
										
										
										
											2014-01-07 01:50:02 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								pstate(State = #state {}, PState = #proc_state{}) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    State #state{ proc_state = PState }.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								%%----------------------------------------------------------------------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-07-03 19:46:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								log(Level, Fmt)       -> rabbit_log:log(connection, Level, Fmt, []).
							 | 
						
					
						
							
								
									
										
										
										
											2013-02-28 20:27:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								log(Level, Fmt, Args) -> rabbit_log:log(connection, Level, Fmt, Args).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-07-03 19:46:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								send_will_and_terminate(PState, State) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    rabbit_mqtt_processor:send_will(PState),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    % todo: flush channel after publish
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {stop, {shutdown, conn_closed}, State}.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								network_error(closed,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              State = #state{ conn_name  = ConnStr,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              proc_state = PState }) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log(info, "MQTT detected network error for ~p: peer closed TCP connection~n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        [ConnStr]),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    send_will_and_terminate(PState, State);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 00:30:13 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								network_error(Reason,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              State = #state{ conn_name  = ConnStr,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              proc_state = PState }) ->
							 | 
						
					
						
							
								
									
										
										
										
											2013-02-27 19:01:09 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    log(info, "MQTT detected network error for ~p: ~p~n", [ConnStr, Reason]),
							 | 
						
					
						
							
								
									
										
										
										
											2014-07-03 19:46:59 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    send_will_and_terminate(PState, State).
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-27 00:57:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 23:45:14 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								run_socket(State = #state{ connection_state = blocked }) ->
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    State;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								run_socket(State = #state{ await_recv = true }) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    State;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								run_socket(State = #state{ socket = Sock }) ->
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    rabbit_net:async_recv(Sock, 0, infinity),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    State#state{ await_recv = true }.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 23:45:14 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								control_throttle(State = #state{ connection_state = Flow,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                 conserve         = Conserve }) ->
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    case {Flow, Conserve orelse credit_flow:blocked()} of
							 | 
						
					
						
							
								
									
										
										
										
											2014-01-07 01:50:02 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        {running,   true} -> ok = rabbit_heartbeat:pause_monitor(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    State#state.keepalive),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                             State #state{ connection_state = blocked };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        {blocked,  false} -> ok = rabbit_heartbeat:resume_monitor(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    State#state.keepalive),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                             run_socket(State #state{
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-21 23:45:14 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                                connection_state = running });
							 | 
						
					
						
							
								
									
										
										
										
											2012-08-06 06:52:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        {_,            _} -> run_socket(State)
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-17 05:52:53 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    end.
							 |