Skip to content

Commit

Permalink
Handle the fd socket option when listening
Browse files Browse the repository at this point in the history
  • Loading branch information
tomas-abrahamsson committed May 11, 2022
1 parent 1fbde82 commit f362678
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
14 changes: 13 additions & 1 deletion src/grpcbox_socket.erl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ init([Pool, ListenOpts, PoolOpts]) ->
%% Trapping exit so can close socket in terminate/2
_ = process_flag(trap_exit, true),
Opts = [{active, false}, {mode, binary}, {packet, raw}, {ip, IPAddress} | SocketOpts],
case gen_tcp:listen(Port, Opts) of
{LPort, LOpts} = maybe_adjust_port_opts_for_fdopt(Port, Opts),
case gen_tcp:listen(LPort, LOpts) of
{ok, Socket} ->
%% acceptor could close the socket if there is a problem
MRef = monitor(port, Socket),
Expand All @@ -40,6 +41,17 @@ init([Pool, ListenOpts, PoolOpts]) ->
{stop, Reason}
end.

maybe_adjust_port_opts_for_fdopt(Port, Opts) ->
case lists:keymember(fd, 1, Opts) of
true ->
%% If an already opened (bound) file descriptor is passed,
%% we must not set port or ip, or there will be an error
%% when it would have gotten bound again.
{0, lists:keydelete(ip, 1, Opts)};
false ->
{Port, Opts}
end.

handle_call(Req, _, State) ->
{stop, {bad_call, Req}, State}.

Expand Down
30 changes: 29 additions & 1 deletion test/grpcbox_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ groups() ->
[{ssl, [], [unary_authenticated]},
{tcp, [], [unary_no_auth, multiple_servers,
unary_garbage_collect_streams]},
{socket_options, [], [fd_socket_option]},
{concurrent, [{repeat_until_any_fail, 5}], [unary_concurrent]},
{negative_tests, [], [unimplemented, closed_stream, generate_error, streaming_generate_error]},
{negative_ssl, [], [unauthorized]},
Expand All @@ -22,6 +23,7 @@ groups() ->
all() ->
[{group, ssl},
{group, tcp},
{group, socket_options},
{group, concurrent},
{group, negative_tests},
{group, negative_ssl},
Expand Down Expand Up @@ -75,6 +77,14 @@ init_per_group(tcp, Config) ->
transport_opts => #{}}]),
application:ensure_all_started(grpcbox),
Config;
init_per_group(socket_options, Config) ->
application:set_env(grpcbox, client, #{channels => [{default_channel, [{http, "localhost", 8080, []}],
#{}}]}),
application:set_env(grpcbox, servers, [#{grpc_opts => #{service_protos => [route_guide_pb],
services => #{'routeguide.RouteGuide' =>
routeguide_route_guide}},
transport_opts => #{}}]),
Config;
init_per_group(concurrent, Config) ->
application:set_env(grpcbox, client, #{channels => [{default_channel, [{http, "localhost", 8080, []}],
#{}}]}),
Expand Down Expand Up @@ -310,7 +320,7 @@ end_per_testcase(unary_no_auth, _Config) ->
ok;
end_per_testcase(multiple_servers, _Config) ->
ok;
end_per_testcase(unary_garbage_collect_streams, _Config) ->
end_per_testcase(fd_socket_option, _Config) ->
ok;
end_per_testcase(unary_concurrent, _Config) ->
ok;
Expand Down Expand Up @@ -563,6 +573,24 @@ multiple_servers(_Config) ->
unary(_Config),
unary(_Config).

fd_socket_option(_Config) ->
%% Use the fd option to dynamically select a free port
{ok, Ip} = inet:getaddr("localhost", inet),
{ok, Sock} = gen_tcp:listen(0, [{ip, Ip}, inet]),
{ok, Fd} = inet:getfd(Sock),
{ok, {_ListenIp, ListenPort}} = inet:sockname(Sock),
application:set_env(grpcbox, client, #{channels => [{default_channel,
[{http, "localhost", ListenPort, []}], #{}}]}),

application:set_env(grpcbox, servers, [#{grpc_opts => #{service_protos => [route_guide_pb],
services => #{'routeguide.RouteGuide' =>
routeguide_route_guide}},
listen_opts => #{socket_options => [{fd, Fd}]}}]),
{ok, _} = application:ensure_all_started(grpcbox),
unary(_Config),
application:stop(grpcbox),
gen_tcp:close(Sock).

unary_concurrent(Config) ->
Nrs = lists:seq(1,100),
ParentPid = self(),
Expand Down

0 comments on commit f362678

Please sign in to comment.