Skip to content

Commit

Permalink
Merge pull request #74 from emqtt/develop
Browse files Browse the repository at this point in the history
Allow esockd_udp binding on ipv6 port
  • Loading branch information
Feng Lee authored Jan 17, 2018
2 parents 3322998 + ee143fe commit 547b9a7
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
5 changes: 5 additions & 0 deletions docs/reuseaddr.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

# SO_REUSEADDR and SO_REUSEPORT

https://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t

29 changes: 28 additions & 1 deletion src/esockd_udp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,16 @@
-spec(server(atom(), inet:port() | {inet:ip_address(), inet:port()},
list(gen_udp:option()), mfa()) -> {ok, pid()}).
server(Protocol, Port, Opts, MFA) when is_integer(Port) ->
gen_server:start_link(?MODULE, [Protocol, Port, Opts, MFA], []).
gen_server:start_link(?MODULE, [Protocol, Port, Opts, MFA], []);

server(Protocol, {Address, Port}, Opts, MFA) when is_integer(Port) ->
{IPAddr, _Port} = fixaddr({Address, Port}),
OptAddr = proplists:get_value(ip, proplists:get_value(sockopts, Opts, [])),
if
(OptAddr == undefined) or (OptAddr == IPAddr) -> ok;
true -> error(badmatch_ipaddress)
end,
gen_server:start_link(?MODULE, [Protocol, Port, merge_addr(IPAddr, Opts), MFA], []).

stop(Server) ->
gen_server:call(Server, stop).
Expand Down Expand Up @@ -134,6 +143,24 @@ log_error(Logger, Peer, Reason) ->
Logger:error("Failed to start client for udp ~s, reason: ~p",
[esockd_net:format(Peer), Reason]).


%% @doc Parse Address
%% @private
fixaddr(Port) when is_integer(Port) ->
Port;
fixaddr({Addr, Port}) when is_list(Addr) and is_integer(Port) ->
{ok, IPAddr} = inet:parse_address(Addr), {IPAddr, Port};
fixaddr({Addr, Port}) when is_tuple(Addr) and is_integer(Port) ->
case esockd_cidr:is_ipv6(Addr) or esockd_cidr:is_ipv4(Addr) of
true -> {Addr, Port};
false -> error(invalid_ipaddress)
end.


merge_addr(Addr, SockOpts) ->
lists:keystore(ip, 1, SockOpts, {ip, Addr}).


-ifdef(TEST).

-include_lib("eunit/include/eunit.hrl").
Expand Down

0 comments on commit 547b9a7

Please sign in to comment.