Просмотр исходного кода

Delete possibly existing socket file when listening on a local socket

juhlig 5 лет назад
Родитель
Сommit
821937cea1
3 измененных файлов с 39 добавлено и 2 удалено
  1. 9 0
      src/ranch_ssl.erl
  2. 9 0
      src/ranch_tcp.erl
  3. 21 2
      test/acceptor_SUITE.erl

+ 9 - 0
src/ranch_ssl.erl

@@ -124,6 +124,15 @@ do_listen(SocketOpts0, Logger) ->
 	SocketOpts2 = ranch:set_option_default(SocketOpts1, nodelay, true),
 	SocketOpts3 = ranch:set_option_default(SocketOpts2, send_timeout, 30000),
 	SocketOpts = ranch:set_option_default(SocketOpts3, send_timeout_close, true),
+	%% In case of a local socket, we remove the socket file first.
+	%% It is possible to have multiple ip tuples in the socket options,
+	%% and the last one will be used (undocumented).
+	_ = case lists:keyfind(ip, 1, lists:reverse(SocketOpts0)) of
+		{ip, {local, SockFile}} ->
+			file:delete(SockFile);
+		_ ->
+			ok
+	end,
 	%% We set the port to 0 because it is given in the Opts directly.
 	%% The port in the options takes precedence over the one in the
 	%% first argument.

+ 9 - 0
src/ranch_tcp.erl

@@ -92,6 +92,15 @@ listen(TransOpts) ->
 	SocketOpts2 = ranch:set_option_default(SocketOpts1, nodelay, true),
 	SocketOpts3 = ranch:set_option_default(SocketOpts2, send_timeout, 30000),
 	SocketOpts4 = ranch:set_option_default(SocketOpts3, send_timeout_close, true),
+	%% In case of a local socket, we remove the socket file first.
+	%% It is possible to have multiple ip tuples in the socket options,
+	%% and the last one will be used (undocumented).
+	_ = case lists:keyfind(ip, 1, lists:reverse(SocketOpts0)) of
+		{ip, {local, SockFile}} ->
+			file:delete(SockFile);
+		_ ->
+			ok
+	end,
 	%% We set the port to 0 because it is given in the Opts directly.
 	%% The port in the options takes precedence over the one in the
 	%% first argument.

+ 21 - 2
test/acceptor_SUITE.erl

@@ -76,7 +76,8 @@ groups() ->
 		misc_info_embedded,
 		misc_opts_logger,
 		misc_set_transport_options,
-		misc_wait_for_connections
+		misc_wait_for_connections,
+		misc_multiple_ips_in_listen_opts
 	]}, {supervisor, [
 		connection_type_supervisor,
 		connection_type_supervisor_separate_from_connection,
@@ -404,6 +405,24 @@ do_expect_waiter(WaiterPid) ->
 			end
 	end.
 
+misc_multiple_ips_in_listen_opts(_) ->
+	case do_os_supports_local_sockets() of
+		true ->
+			do_misc_multiple_ips_in_listen_opts();
+		false ->
+			{skip, "No local socket support."}
+	end.
+
+do_misc_multiple_ips_in_listen_opts() ->
+	doc("Ensure that a listener uses the expected ip option if multiple are given."),
+	Name = name(),
+	SockFile1 = do_tempname(),
+	SockFile2 = do_tempname(),
+	Opts = [{ip, {local, SockFile1}}, {ip, {local, SockFile2}}],
+	{ok, _} = ranch:start_listener(Name, ranch_tcp, #{socket_opts => Opts}, echo_protocol, []),
+	{local, SockFile2} = ranch:get_addr(Name),
+	ok = ranch:stop_listener(Name).
+
 %% ssl.
 
 ssl_accept_error(_) ->
@@ -1586,4 +1605,4 @@ do_os_supports_local_sockets() ->
 	end.
 
 do_tempname() ->
-	lists:droplast(os:cmd("mktemp -u")).
+	list_to_binary(lists:droplast(os:cmd("mktemp -u"))).