Browse Source

Handle Transport:controlling_socket/2 errors and close the socket

Loïc Hoguin 10 years ago
parent
commit
02ff6533bb
2 changed files with 25 additions and 15 deletions
  1. 8 4
      src/ranch_acceptor.erl
  2. 17 11
      src/ranch_conns_sup.erl

+ 8 - 4
src/ranch_acceptor.erl

@@ -27,10 +27,14 @@ start_link(LSocket, Transport, ConnsSup) ->
 loop(LSocket, Transport, ConnsSup) ->
 loop(LSocket, Transport, ConnsSup) ->
 	_ = case Transport:accept(LSocket, infinity) of
 	_ = case Transport:accept(LSocket, infinity) of
 		{ok, CSocket} ->
 		{ok, CSocket} ->
-			Transport:controlling_process(CSocket, ConnsSup),
-			%% This call will not return until process has been started
-			%% AND we are below the maximum number of connections.
-			ranch_conns_sup:start_protocol(ConnsSup, CSocket);
+			case Transport:controlling_process(CSocket, ConnsSup) of
+				ok ->
+					%% This call will not return until process has been started
+					%% AND we are below the maximum number of connections.
+					ranch_conns_sup:start_protocol(ConnsSup, CSocket);
+				{error, _} ->
+					Transport:close(CSocket)
+			end;
 		%% Reduce the accept rate if we run out of file descriptors.
 		%% Reduce the accept rate if we run out of file descriptors.
 		%% We can't accept anymore anyway, so we might as well wait
 		%% We can't accept anymore anyway, so we might as well wait
 		%% a little for the situation to resolve itself.
 		%% a little for the situation to resolve itself.

+ 17 - 11
src/ranch_conns_sup.erl

@@ -114,17 +114,23 @@ loop(State=#state{parent=Parent, ref=Ref, conn_type=ConnType,
 		{?MODULE, start_protocol, To, Socket} ->
 		{?MODULE, start_protocol, To, Socket} ->
 			case Protocol:start_link(Ref, Socket, Transport, Opts) of
 			case Protocol:start_link(Ref, Socket, Transport, Opts) of
 				{ok, Pid} ->
 				{ok, Pid} ->
-					Transport:controlling_process(Socket, Pid),
-					Pid ! {shoot, Ref, Transport, Socket, AckTimeout},
-					put(Pid, true),
-					CurConns2 = CurConns + 1,
-					if CurConns2 < MaxConns ->
-							To ! self(),
-							loop(State, CurConns2, NbChildren + 1,
-								Sleepers);
-						true ->
-							loop(State, CurConns2, NbChildren + 1,
-								[To|Sleepers])
+					case Transport:controlling_process(Socket, Pid) of
+						ok ->
+							Pid ! {shoot, Ref, Transport, Socket, AckTimeout},
+							put(Pid, true),
+							CurConns2 = CurConns + 1,
+							if CurConns2 < MaxConns ->
+									To ! self(),
+									loop(State, CurConns2, NbChildren + 1,
+										Sleepers);
+								true ->
+									loop(State, CurConns2, NbChildren + 1,
+										[To|Sleepers])
+							end;
+						{error, _} ->
+							Transport:close(Socket),
+							exit(Pid, kill),
+							loop(State, CurConns, NbChildren, Sleepers)
 					end;
 					end;
 				Ret ->
 				Ret ->
 					To ! self(),
 					To ! self(),