aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/nifs/common/socket_nif.c43
-rw-r--r--erts/preloaded/ebin/socket.beambin46292 -> 46328 bytes
-rw-r--r--erts/preloaded/src/socket.erl10
-rw-r--r--lib/kernel/test/socket_server.erl49
4 files changed, 74 insertions, 28 deletions
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index 141b42a3cd..713153d7c5 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -360,6 +360,7 @@ typedef union {
#define SOCKET_OPT_SOCK_PROTOCOL 18
#define SOCKET_OPT_SOCK_RCVBUF 19
#define SOCKET_OPT_SOCK_REUSEADDR 23
+#define SOCKET_OPT_SOCK_REUSEPORT 24
#define SOCKET_OPT_SOCK_SNDBUF 27
#define SOCKET_OPT_SOCK_TYPE 32
@@ -862,6 +863,11 @@ static ERL_NIF_TERM nsetopt_lvl_sock_reuseaddr(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(SO_REUSEPORT)
+static ERL_NIF_TERM nsetopt_lvl_sock_reuseport(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(SO_SNDBUF)
static ERL_NIF_TERM nsetopt_lvl_sock_sndbuf(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1140,6 +1146,10 @@ static ERL_NIF_TERM ngetopt_lvl_sock_rcvbuf(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_sock_reuseaddr(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(SO_REUSEPORT)
+static ERL_NIF_TERM ngetopt_lvl_sock_reuseport(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(SO_SNDBUF)
static ERL_NIF_TERM ngetopt_lvl_sock_sndbuf(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -3980,6 +3990,12 @@ ERL_NIF_TERM nsetopt_lvl_socket(ErlNifEnv* env,
break;
#endif
+#if defined(SO_REUSEPORT)
+ case SOCKET_OPT_SOCK_REUSEPORT:
+ result = nsetopt_lvl_sock_reuseport(env, descP, eVal);
+ break;
+#endif
+
#if defined(SO_SNDBUF)
case SOCKET_OPT_SOCK_SNDBUF:
result = nsetopt_lvl_sock_sndbuf(env, descP, eVal);
@@ -4133,6 +4149,17 @@ ERL_NIF_TERM nsetopt_lvl_sock_reuseaddr(ErlNifEnv* env,
#endif
+#if defined(SO_REUSEPORT)
+static
+ERL_NIF_TERM nsetopt_lvl_sock_reuseport(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEPORT, eVal);
+}
+#endif
+
+
#if defined(SO_SNDBUF)
static
ERL_NIF_TERM nsetopt_lvl_sock_sndbuf(ErlNifEnv* env,
@@ -5777,6 +5804,12 @@ ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env,
break;
#endif
+#if defined(SO_REUSEPORT)
+ case SOCKET_OPT_SOCK_REUSEPORT:
+ result = ngetopt_lvl_sock_reuseport(env, descP);
+ break;
+#endif
+
#if defined(SO_SNDBUF)
case SOCKET_OPT_SOCK_SNDBUF:
result = ngetopt_lvl_sock_sndbuf(env, descP);
@@ -6035,6 +6068,16 @@ ERL_NIF_TERM ngetopt_lvl_sock_reuseaddr(ErlNifEnv* env,
#endif
+#if defined(SO_REUSEPORT)
+static
+ERL_NIF_TERM ngetopt_lvl_sock_reuseport(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEPORT);
+}
+#endif
+
+
#if defined(SO_SNDBUF)
static
ERL_NIF_TERM ngetopt_lvl_sock_sndbuf(ErlNifEnv* env,
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 5032366c93..9baf6a422e 100644
--- a/erts/preloaded/ebin/socket.beam
+++ b/erts/preloaded/ebin/socket.beam
Binary files differ
diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl
index d4bf55511c..fbfd1903a1 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -517,7 +517,7 @@
%% -define(SOCKET_OPT_SOCK_RCVLOWAT, 21).
%% -define(SOCKET_OPT_SOCK_RCVTIMEO, 22).
-define(SOCKET_OPT_SOCK_REUSEADDR, 23).
-%% -define(SOCKET_OPT_SOCK_REUSEPORT, 24).
+-define(SOCKET_OPT_SOCK_REUSEPORT, 24).
%% -define(SOCKET_OPT_SOCK_RXQ_OVFL, 25).
%% -define(SOCKET_OPT_SOCK_SETFIB, 26).
-define(SOCKET_OPT_SOCK_SNDBUF, 27).
@@ -1984,6 +1984,8 @@ enc_setopt_value(socket, rcvbuf, V, _D, _T, _P) when is_integer(V) ->
V;
enc_setopt_value(socket, reuseaddr, V, _D, _T, _P) when is_boolean(V) ->
V;
+enc_setopt_value(socket, reuseport, V, _D, _T, _P) when is_boolean(V) ->
+ V;
enc_setopt_value(socket, sndbuf, V, _D, _T, _P) when is_integer(V) ->
V;
enc_setopt_value(socket = L, Opt, V, _D, _T, _P) ->
@@ -2301,11 +2303,11 @@ enc_sockopt_key(socket = L, rcvlowat = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(socket, rcvtimeo = Opt, _Dir, _D, _T, _P) ->
not_supported(Opt);
-enc_sockopt_key(socket, reuseaddr = _Opt, _Dir, _D, _T, _P) ->
+enc_sockopt_key(socket = _L, reuseaddr = _Opt, _Dir, _D, _T, _P) ->
?SOCKET_OPT_SOCK_REUSEADDR;
-enc_sockopt_key(socket = L, reuseport = Opt, _Dir, D, _T, _P)
+enc_sockopt_key(socket = _L, reuseport = _Opt, _Dir, D, _T, _P)
when ((D =:= inet) orelse (D =:= inet6)) ->
- not_supported({L, Opt});
+ ?SOCKET_OPT_SOCK_REUSEPORT;
enc_sockopt_key(socket = L, rxq_ovfl = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(socket = L, setfib = Opt, set = _Dir, _D, _T, _P) ->
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 6d002db38e..d9bbf00e85 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -129,16 +129,13 @@ manager_init(Domain, dgram = Type, Proto, Peek) ->
{error, BReason} ->
throw({bind, BReason})
end,
- socket:setopt(Sock, otp, debug, true),
i("bound to: "
"~n ~s"
- "~n (socket) Bind To Device: ~s"
"~n => try start handler",
[case socket:sockname(Sock) of
{ok, Name} -> f("~p", [Name]);
{error, R} -> f("error: ~p", [R])
- end,
- F(bindtodevice)]),
+ end]),
case handler_start(1, Sock, Peek) of
{ok, {Pid, MRef}} ->
i("handler (~p) started", [Pid]),
@@ -457,16 +454,18 @@ handler_init(Manager, ID, Peek, Sock) ->
{ok, Type} = socket:getopt(Sock, socket, type),
{ok, Proto} = socket:getopt(Sock, socket, protocol),
B2D = GSO(bindtodevice),
- {ok, OOBI} = socket:getopt(Sock, socket, oobinline),
- {ok, SndBuf} = socket:getopt(Sock, socket, sndbuf),
- {ok, RcvBuf} = socket:getopt(Sock, socket, rcvbuf),
- {ok, Linger} = socket:getopt(Sock, socket, linger),
+ RA = GSO(reuseaddr),
+ RP = GSO(reuseport),
+ OOBI = GSO(oobinline),
+ SndBuf = GSO(sndbuf),
+ RcvBuf = GSO(rcvbuf),
+ Linger = GSO(linger),
MTU = GIP(mtu),
MTUDisc = GIP(mtu_discover),
- {ok, MALL} = socket:getopt(Sock, ip, multicast_all),
- {ok, MIF} = socket:getopt(Sock, ip, multicast_if),
- {ok, MLoop} = socket:getopt(Sock, ip, multicast_loop),
- {ok, MTTL} = socket:getopt(Sock, ip, multicast_ttl),
+ MALL = GIP(multicast_all),
+ MIF = GIP(multicast_if),
+ MLoop = GIP(multicast_loop),
+ MTTL = GIP(multicast_ttl),
NF = GIP(nodefrag), % raw only
RecvTOS = GIP(recvtos),
RecvTTL = GIP(recvttl), % not stream
@@ -474,22 +473,24 @@ handler_init(Manager, ID, Peek, Sock) ->
"~n (socket) Domain: ~p"
"~n (socket) Type: ~p"
"~n (socket) Protocol: ~p"
+ "~n (socket) Reuse Address: ~s"
+ "~n (socket) Reuse Port: ~s"
"~n (socket) Bind To Device: ~s"
- "~n (socket) OOBInline: ~p"
- "~n (socket) SndBuf: ~p"
- "~n (socket) RcvBuf: ~p"
- "~n (socket) Linger: ~p"
+ "~n (socket) OOBInline: ~s"
+ "~n (socket) SndBuf: ~s"
+ "~n (socket) RcvBuf: ~s"
+ "~n (socket) Linger: ~s"
"~n (ip) MTU: ~s"
"~n (ip) MTU Discovery: ~s"
- "~n (ip) Multicast ALL: ~p"
- "~n (ip) Multicast IF: ~p"
- "~n (ip) Multicast Loop: ~p"
- "~n (ip) Multicast TTL: ~p"
- "~n (ip) NodeFrag: ~s"
- "~n (ip) RecvTOS: ~s"
- "~n (ip) RecvTTL: ~s",
+ "~n (ip) Multicast ALL: ~s"
+ "~n (ip) Multicast IF: ~s"
+ "~n (ip) Multicast Loop: ~s"
+ "~n (ip) Multicast TTL: ~s"
+ "~n (ip) Node Frag: ~s"
+ "~n (ip) Recv TOS: ~s"
+ "~n (ip) Recv TTL: ~s",
[Domain, Type, Proto,
- B2D, OOBI, SndBuf, RcvBuf, Linger,
+ RA, RP, B2D, OOBI, SndBuf, RcvBuf, Linger,
MTU, MTUDisc, MALL, MIF, MLoop, MTTL,
NF, RecvTOS, RecvTTL]),
%% socket:setopt(Sock, otp, debug, true),