aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2012-07-22 05:50:10 +0200
committerLoïc Hoguin <[email protected]>2012-07-22 05:56:55 +0200
commit45348170f468fadd73e7541aac5bc6f664475d0d (patch)
tree844dda58afef65944cc3eca0a6aa6fba7556c257
parent46ada7fff0bca928cca0d9d03cb0ef54b3232787 (diff)
downloadranch-45348170f468fadd73e7541aac5bc6f664475d0d.tar.gz
ranch-45348170f468fadd73e7541aac5bc6f664475d0d.tar.bz2
ranch-45348170f468fadd73e7541aac5bc6f664475d0d.zip
Add support for listening on random port numbers (port 0)
ranch:get_port/1 returns the given listener's port.
-rw-r--r--src/ranch.app.src2
-rw-r--r--src/ranch.erl8
-rw-r--r--src/ranch_acceptors_sup.erl2
-rw-r--r--src/ranch_listener.erl17
-rw-r--r--test/acceptor_SUITE.erl7
5 files changed, 31 insertions, 5 deletions
diff --git a/src/ranch.app.src b/src/ranch.app.src
index 88e1362..dd2840c 100644
--- a/src/ranch.app.src
+++ b/src/ranch.app.src
@@ -14,7 +14,7 @@
{application, ranch, [
{description, "Socket acceptor pool for TCP protocols."},
- {vsn, "0.2.1"},
+ {vsn, git},
{modules, []},
{registered, [ranch_sup]},
{applications, [
diff --git a/src/ranch.erl b/src/ranch.erl
index b6008fa..3f07df7 100644
--- a/src/ranch.erl
+++ b/src/ranch.erl
@@ -19,6 +19,7 @@
-export([stop_listener/1]).
-export([child_spec/6]).
-export([accept_ack/1]).
+-export([get_port/1]).
-export([get_protocol_options/1]).
-export([set_protocol_options/2]).
@@ -88,6 +89,13 @@ child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts)
accept_ack(ListenerPid) ->
receive {shoot, ListenerPid} -> ok end.
+%% @doc Return the listener's port.
+-spec get_port(any()) -> inet:port_number().
+get_port(Ref) ->
+ ListenerPid = ref_to_listener_pid(Ref),
+ {ok, Port} = ranch_listener:get_port(ListenerPid),
+ Port.
+
%% @doc Return the current protocol options for the given listener.
-spec get_protocol_options(any()) -> any().
get_protocol_options(Ref) ->
diff --git a/src/ranch_acceptors_sup.erl b/src/ranch_acceptors_sup.erl
index 963b4d3..5617873 100644
--- a/src/ranch_acceptors_sup.erl
+++ b/src/ranch_acceptors_sup.erl
@@ -36,6 +36,8 @@ start_link(NbAcceptors, Transport, TransOpts,
init([NbAcceptors, Transport, TransOpts,
Protocol, ProtoOpts, ListenerPid, ConnsPid]) ->
{ok, LSocket} = Transport:listen(TransOpts),
+ {ok, {_, Port}} = Transport:sockname(LSocket),
+ ranch_listener:set_port(ListenerPid, Port),
Procs = [{{acceptor, self(), N}, {ranch_acceptor, start_link, [
LSocket, Transport, Protocol, ProtoOpts,
ListenerPid, ConnsPid
diff --git a/src/ranch_listener.erl b/src/ranch_listener.erl
index 8a78472..40528f5 100644
--- a/src/ranch_listener.erl
+++ b/src/ranch_listener.erl
@@ -23,6 +23,8 @@
-export([move_connection/3]).
-export([remove_connection/2]).
-export([check_upgrades/2]).
+-export([get_port/1]).
+-export([set_port/2]).
-export([get_protocol_options/1]).
-export([set_protocol_options/2]).
@@ -41,6 +43,7 @@
conns_table :: ets:tid(),
queue = undefined :: queue(),
max_conns = undefined :: non_neg_integer(),
+ port = undefined :: undefined | inet:port_number(),
proto_opts :: any(),
proto_opts_vsn = 1 :: non_neg_integer()
}).
@@ -102,6 +105,16 @@ remove_connection(ServerPid, ConnPid) ->
check_upgrades(ServerPid, OptsVsn) ->
gen_server:call(ServerPid, {check_upgrades, OptsVsn}).
+%% @doc Return the listener's port.
+-spec get_port(pid()) -> {ok, inet:port_number()}.
+get_port(ServerPid) ->
+ gen_server:call(ServerPid, get_port).
+
+%% @private
+-spec set_port(pid(), inet:port_number()) -> ok.
+set_port(ServerPid, Port) ->
+ gen_server:cast(ServerPid, {set_port, Port}).
+
%% @doc Return the current protocol options.
-spec get_protocol_options(pid()) -> {ok, any()}.
get_protocol_options(ServerPid) ->
@@ -143,6 +156,8 @@ handle_call({check_upgrades, AccOptsVsn}, _From, State=#state{
true ->
{reply, ok, State}
end;
+handle_call(get_port, _From, State=#state{port=Port}) ->
+ {reply, {ok, Port}, State};
handle_call(get_protocol_options, _From, State=#state{proto_opts=ProtoOpts}) ->
{reply, {ok, ProtoOpts}, State};
handle_call({set_protocol_options, ProtoOpts}, _From,
@@ -154,6 +169,8 @@ handle_call(_, _From, State) ->
{reply, ignored, State}.
%% @private
+handle_cast({set_port, Port}, State) ->
+ {noreply, State#state{port=Port}};
handle_cast({move_connection, DestPool, ConnPid}, State=#state{
conn_pools=Pools, conns_table=ConnsTable}) ->
Pools2 = move_pid(ConnPid, DestPool, Pools, ConnsTable),
diff --git a/test/acceptor_SUITE.erl b/test/acceptor_SUITE.erl
index cfb5cd8..0a15916 100644
--- a/test/acceptor_SUITE.erl
+++ b/test/acceptor_SUITE.erl
@@ -39,11 +39,10 @@ end_per_suite(_) ->
%% tcp.
tcp_echo(_) ->
- %% @todo Don't use a fixed port. start_listener should return the port used?
{ok, _} = ranch:start_listener(tcp_echo, 1,
- ranch_tcp, [{port, 33333}],
- echo_protocol, []),
- {ok, Socket} = gen_tcp:connect("localhost", 33333,
+ ranch_tcp, [{port, 0}], echo_protocol, []),
+ Port = ranch:get_port(tcp_echo),
+ {ok, Socket} = gen_tcp:connect("localhost", Port,
[binary, {active, false}, {packet, raw}]),
ok = gen_tcp:send(Socket, <<"Ranch is working!">>),
{ok, <<"Ranch is working!">>} = gen_tcp:recv(Socket, 0, 1000),