aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Chmielowski <pchmielowski@process-one.net>2020-07-28 12:19:24 +0200
committerPaweł Chmielowski <pchmielowski@process-one.net>2020-07-28 12:19:30 +0200
commit1b168e7d5cf2f84bca88e49acd99cae38e248d1b (patch)
tree94d622c53efd41adaa5e62f1abb4c3e0e3c8c098
parentDon't log http errors when socket get closed after processing one request (diff)
Add support for unix socket in listeners
To use it you just need to set port value to "unix:/path/to/socket"
-rw-r--r--src/ejabberd_listener.erl46
1 files changed, 35 insertions, 11 deletions
diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl
index 64db7e4df..50601261b 100644
--- a/src/ejabberd_listener.erl
+++ b/src/ejabberd_listener.erl
@@ -105,10 +105,18 @@ init({_, _, Transport} = EndPoint, Module, AllOpts) ->
-spec init(endpoint(), module(), opts(), [gen_tcp:option()]) -> ok.
init({Port, _, udp} = EndPoint, Module, Opts, SockOpts) ->
- case gen_udp:open(Port, [binary,
+ {Port2, ExtraOpts} = case Port of
+ <<"unix:", Path/binary>> ->
+ SO = lists:keydelete(ip, 1, SockOpts),
+ file:delete(Path),
+ {0, [{ip, {local, Path}} | SO]};
+ _ ->
+ {Port, SockOpts}
+ end,
+ case gen_udp:open(Port2, [binary,
{active, false},
{reuseaddr, true} |
- SockOpts]) of
+ ExtraOpts]) of
{ok, Socket} ->
case inet:sockname(Socket) of
{ok, {Addr, Port1}} ->
@@ -174,15 +182,22 @@ init({Port, _, tcp} = EndPoint, Module, Opts, SockOpts) ->
-spec listen_tcp(inet:port_number(), [gen_tcp:option()]) ->
{ok, inet:socket()} | {error, system_limit | inet:posix()}.
listen_tcp(Port, SockOpts) ->
- Res = gen_tcp:listen(Port, [binary,
+ {Port2, ExtraOpts} = case Port of
+ <<"unix:", Path/binary>> ->
+ SO = lists:keydelete(ip, 1, SockOpts),
+ file:delete(Path),
+ {0, [{ip, {local, Path}} | SO]};
+ _ ->
+ {Port, SockOpts}
+ end,
+ Res = gen_tcp:listen(Port2, [binary,
{packet, 0},
{active, false},
{reuseaddr, true},
{nodelay, true},
{send_timeout, ?TCP_SEND_TIMEOUT},
{send_timeout_close, true},
- {keepalive, true} |
- SockOpts]),
+ {keepalive, true} | ExtraOpts]),
case Res of
{ok, ListenSocket} ->
{ok, ListenSocket};
@@ -226,6 +241,8 @@ accept(ListenSocket, Module, State, Sup, Interval, Proxy, Arity) ->
?ERROR_MSG("(~w) Proxy protocol parsing failed: ~ts",
[ListenSocket, format_error(Err)]),
gen_tcp:close(Socket);
+ {undefined, undefined} ->
+ gen_tcp:close(Socket);
{{Addr, Port}, {PAddr, PPort}} = SP ->
%% THIS IS WRONG
State2 = [{sock_peer_name, SP} | State],
@@ -464,11 +481,16 @@ format_error(Reason) ->
-spec format_endpoint(endpoint()) -> string().
format_endpoint({Port, IP, _Transport}) ->
- IPStr = case tuple_size(IP) of
- 4 -> inet:ntoa(IP);
- 8 -> "[" ++ inet:ntoa(IP) ++ "]"
- end,
- IPStr ++ ":" ++ integer_to_list(Port).
+ case Port of
+ Unix when is_binary(Unix) ->
+ <<"unix:", Unix/binary>>;
+ _ ->
+ IPStr = case tuple_size(IP) of
+ 4 -> inet:ntoa(IP);
+ 8 -> "[" ++ inet:ntoa(IP) ++ "]"
+ end,
+ IPStr ++ ":" ++ integer_to_list(Port)
+ end.
-spec format_transport(transport(), opts()) -> string().
format_transport(Transport, Opts) ->
@@ -623,7 +645,9 @@ partition(Fun, Opts) ->
-spec listen_opt_type(atom()) -> econf:validator().
listen_opt_type(port) ->
- econf:int(0, 65535);
+ econf:either(
+ econf:int(0, 65535),
+ econf:binary("^unix:.*"));
listen_opt_type(module) ->
econf:beam([[{start, 3}, {start, 2}],
[{start_link, 3}, {start_link, 2}],