Skip to content
This repository has been archived by the owner on Jun 18, 2023. It is now read-only.

saleyn/euds

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Erlang Unix Domain Socket (euds)

This project implements a NIF library to support Unix Domain Sockets.

UPDATE: this project will be deprecated beginning with Erlang 19RC2, which will include native support for Unix Domain Sockets.

The implementation uses two C functions (do_bind, do_connect) to setup a socket, and then Erlang implementation assigns an open file descriptor to either gen_tcp or gen_udp Erlang socket. This allows to reuse existing Erlang send/receive API on file descriptors set up externally.

From the academic point of view TCP and UDP protocols are not implemented over Unix Domain Sockets (UDS). Rather, UDS use stream and datagram transports that have identical library API to TCP and UDP. For this reason a UDS file descriptor can be passed to gen_tcp or gen_udp to handle stream or dgram communications.

Additionally this NIF library has functions send_fd/2 and recv_fd/1 do send and receive file descriptors through a Unix Domain Socket.

Note: there is a bug in the OTP socket management which requires the Erlang distribution to be patched in order for this project to work. The patch can be found here: https://github.com/saleyn/otp/compare/uds. It was submitted in the form of a pull request to the Erlang/OTP team: erlang/otp#612.

See these instructions if you need to debug the Erlang's inet_drv.c network driver.

Important

Once the above-stated patch is applied, rebuild the OTP distribution, and check that erts/preloaded/src/*.erl have been compiled into erts/preloaded/ebin/*.beam (note that the Makefile in that directory tends to place compiled files in the same directory where the sources are instead of creating them in ebin/ (see this closed issue that illustrates this solution: #1).

Author

Serge Aleynikov <saleyn at gmail dot com>

Installation:

  1. Apply the following patch to the latest Erlang release: https://github.com/saleyn/otp/compare/uds.patch
  2. Ensure you have a local installation of rebar.
  3. git clone https://github.com/saleyn/euds.git
  4. make

Usage:

TCP example

% TCP Unix Domain Socket Server:
1> file:delete("/tmp/test.sock").
ok
2> {ok, S} = gen_uds:listen("/tmp/test.sock", [stream]).
{ok,#Port<0.980>}
3> {ok, CS} = gen_tcp:accept(S).
{ok,#Port<0.981>}
4> inet:setopts(CS, [{active, false}]).
ok
5> gen_tcp:recv(CS, 0).
{ok,"abc"}
6> gen_tcp:close(CS).
ok
7> gen_tcp:close(S).
ok

% TCP Unix Domain Socket Client:
1> {ok, S} = gen_uds:connect("/tmp/test.sock", [stream]).
{ok,#Port<0.949>}
2> gen_tcp:send(S, "abc").
ok
3> gen_tcp:close(S).
ok

UDP example

% UDP Unix Domain Socket Server:
1> file:delete("/tmp/test.sock").
ok
2> {ok, S} = gen_uds:listen("/tmp/test.sock", [dgram]).
{ok,#Port<0.980>}
3> inet:setopts(S, [{active, once}]).
4> receive Msg -> Msg end,
{udp,#Port<0.980>,"/tmp/test.sock",0,"abc"}
5> inet:setopts(S, [{active, false}]).
ok
6> gen_udp:recv(S, 0).
{ok,{"/tmp/test.sock", 0, "efg"}}
7> gen_udp:close(S).
ok

% UDP Unix Domain Socket Client:
1> {ok, S} = gen_uds:connect("/tmp/test.sock", [dgram]).
{ok,#Port<0.949>}
2> gen_udp:send(S, "abc").
ok
3> gen_udp:send(S, "efg").
ok
4> gen_udp:close(S).
ok

About

Erlang Unix Domain Socket support

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published