inet:fdopen/2 fix for supporting externally open fd's of AF_LOCAL address family

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

inet:fdopen/2 fix for supporting externally open fd's of AF_LOCAL address family

Serge Aleynikov-3
When a AF_LOCAL (a.k.a. AF_UNIX) file descriptor is created externally
(e.g. Unix Domain Socket) and passed to `gen_tcp:listen(0, [{fd, FD}])`, the
present implementation incorrectly assigns the address family to be equal
to `inet`, which in the inet_drv driver translats to AF_INET instead
of AF_LOCAL (or AF_UNIX), and an `einval` error code is returned.

This patch fixes this problem such that the file descriptors of the
`local` address family are properly supported when such a file descriptor
is passed to the inet:fdopen/5, gen_tcp:connect/3, gen_tcp:listen/2, gen_udp:open/2
calls via {fd, FD::integer()} option.

In order to connect a socket to a Unix Domain file descriptor use the following options:

    1> FD = ... % Open the AF_LOCAL *server* file descriptor
    2> {ok, Sock} = gen_tcp:listen(0, [local, {fd,FD} | OtherOptions]).
    % Now use the socket using gen_tcp module:
    3> gen_tcp:send(Sock, <<"abc">>).

    FD = ... % Open the AF_LOCAL *client* file descriptor
    2> {ok, Sock} = gen_tcp:connect(0, [local, {fd,FD} | OtherOptions]).
    % Now use the socket using gen_tcp module:
    3> inet:setopts(S, [{active, once}]),
    4> receive Msg -> Msg end.
    {tcp,#Port<0.1195>,"abc"}
    5> inet:setopts(S, [{active, false}]).
    6> gen_tcp:recv(S,0,1000).
    {ok,"efg"}

Note that in case of UDP client in order to preserve the active socket signature {udp, ErlPort, Addr, Port, Data} and passive socket's gen_udp:recv3 return signature ({ok, {Address, Port, Packet}}), the Address on local socket family is a string containing the underlying socket's filename, and Port=0. E.g.:

    {ok, {"/tmp/test.sock", 0, <<"some data">>}} = gen_udp:recv(S, 0, 1000).



A sample project using this patch can be found here: https://github.com/saleyn/euds. It uses a NIF library to create and FD of AF_LOCAL family, and passes it to either gen_tcp or gen_udp for further handling.

Regards,

Serge



_______________________________________________
erlang-patches mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-patches