aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/doc/src/socket_usage.xml7
-rw-r--r--erts/emulator/nifs/common/socket_nif.c43
-rw-r--r--erts/preloaded/ebin/socket.beambin57388 -> 57468 bytes
-rw-r--r--erts/preloaded/src/socket.erl11
-rw-r--r--lib/kernel/test/socket_server.erl8
5 files changed, 63 insertions, 6 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index b13582dfbc..87b44f139f 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -433,6 +433,13 @@
<cell>none</cell>
</row>
<row>
+ <cell>dstopts</cell>
+ <cell>boolean()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>type = dgram | raw, requires superuser privileges to update</cell>
+ </row>
+ <row>
<cell>hoplimit</cell>
<cell>boolean()</cell>
<cell>yes</cell>
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index 42a9bc3cb6..9504643cb8 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -538,6 +538,7 @@ typedef union {
#define SOCKET_OPT_IPV6_ADD_MEMBERSHIP 2
#define SOCKET_OPT_IPV6_AUTHHDR 3
#define SOCKET_OPT_IPV6_DROP_MEMBERSHIP 6
+#define SOCKET_OPT_IPV6_DSTOPTS 7
#define SOCKET_OPT_IPV6_HOPLIMIT 12
#define SOCKET_OPT_IPV6_HOPOPTS 13
#define SOCKET_OPT_IPV6_MTU 17
@@ -1213,6 +1214,11 @@ static ERL_NIF_TERM nsetopt_lvl_ipv6_drop_membership(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IPV6_DSTOPTS)
+static ERL_NIF_TERM nsetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(IPV6_HOPLIMIT)
static ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1539,6 +1545,10 @@ static ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(IPV6_DSTOPTS)
+static ERL_NIF_TERM ngetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IPV6_HOPLIMIT)
static ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -5581,6 +5591,12 @@ ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env,
break;
#endif
+#if defined(IPV6_DSTOPTS)
+ case SOCKET_OPT_IPV6_DSTOPTS:
+ result = nsetopt_lvl_ipv6_dstopts(env, descP, eVal);
+ break;
+#endif
+
#if defined(IPV6_HOPLIMIT)
case SOCKET_OPT_IPV6_HOPLIMIT:
result = nsetopt_lvl_ipv6_hoplimit(env, descP, eVal);
@@ -5692,6 +5708,17 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_drop_membership(ErlNifEnv* env,
#endif
+#if defined(IPV6_DSTOPTS)
+static
+ERL_NIF_TERM nsetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ return nsetopt_bool_opt(env, descP, SOL_IPV6, IPV6_DSTOPTS, eVal);
+}
+#endif
+
+
#if defined(IPV6_HOPLIMIT)
static
ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
@@ -8157,6 +8184,12 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
break;
#endif
+#if defined(IPV6_DSTOPTS)
+ case SOCKET_OPT_IPV6_DSTOPTS:
+ result = ngetopt_lvl_ipv6_dstopts(env, descP);
+ break;
+#endif
+
#if defined(IPV6_HOPLIMIT)
case SOCKET_OPT_IPV6_HOPLIMIT:
result = ngetopt_lvl_ipv6_hoplimit(env, descP);
@@ -8241,6 +8274,16 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
#endif
+#if defined(IPV6_DSTOPTS)
+static
+ERL_NIF_TERM ngetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ return ngetopt_bool_opt(env, descP, SOL_IPV6, IPV6_DSTOPTS);
+}
+#endif
+
+
#if defined(IPV6_HOPLIMIT)
static
ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index da825abb98..17622c5341 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 3c0dc6e95b..2bab42267a 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -636,7 +636,7 @@
%% -define(SOCKET_OPT_IPV6_AUTH_LEVEL, 4).
%% -define(SOCKET_OPT_IPV6_CHECKSUM, 5).
-define(SOCKET_OPT_IPV6_DROP_MEMBERSHIP, 6).
-%% -define(SOCKET_OPT_IPV6_DSTOPTS, 7).
+-define(SOCKET_OPT_IPV6_DSTOPTS, 7).
%% -define(SOCKET_OPT_IPV6_ESP_TRANS_LEVEL, 8).
%% -define(SOCKET_OPT_IPV6_ESP_NETWORK_LEVEL, 9).
%% -define(SOCKET_OPT_IPV6_FAITH, 10).
@@ -2255,6 +2255,9 @@ enc_setopt_value(ipv6, add_membership, #{multiaddr := MA,
enc_setopt_value(ipv6, authhdr, V, _D, T, _P)
when is_boolean(V) andalso ((T =:= dgram) orelse (T =:= raw)) ->
V;
+enc_setopt_value(ipv6, dstopts, V, _D, T, _P)
+ when is_boolean(V) andalso ((T =:= dgram) orelse (T =:= raw)) ->
+ V;
enc_setopt_value(ipv6, drop_membership, #{multiaddr := MA,
interface := IF} = V, _D, _T, _P)
when ((is_tuple(MA) andalso (size(MA) =:= 8)) andalso
@@ -2692,14 +2695,14 @@ enc_sockopt_key(ipv6 = L, checksum = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ipv6, drop_membership = _Opt, set = _Dir, _D, _T, _P) ->
?SOCKET_OPT_IPV6_DROP_MEMBERSHIP;
-enc_sockopt_key(ipv6 = L, dstopts = Opt, set = _Dir, _D, T, _P)
+enc_sockopt_key(ipv6 = _L, dstopts = _Opt, _Dir, _D, T, _P)
when (T =:= dgram) orelse (T =:= raw) ->
- not_supported({L, Opt});
+ ?SOCKET_OPT_IPV6_DSTOPTS;
enc_sockopt_key(ipv6 = L, esp_trans_level = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ipv6 = L, esp_network_level = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
-enc_sockopt_key(ipv6 = L, flowinfo = Opt, set = _Dir, _D, T, _P)
+enc_sockopt_key(ipv6 = L, flowinfo = Opt, _Dir, _D, T, _P)
when (T =:= dgram) orelse (T =:= raw) ->
not_supported({L, Opt});
enc_sockopt_key(ipv6, hoplimit = _Opt, _Dir, _D, T, _P)
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 1cd0ec1202..8436b39372 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -635,7 +635,9 @@ handler_init(Manager, ID, Peek, Sock) ->
RecvPktInfo = GIP6(recvpktinfo),
RtHdr = GIP6(rthdr),
AuthHdr = GIP6(authhdr),
+ HopLimit = GIP6(hoplimit),
HopOpts = GIP6(hopopts),
+ DstOpts = GIP6(dstopts),
i("got continue when: "
"~n (socket) Domain: ~p"
"~n (socket) Type: ~p"
@@ -670,7 +672,9 @@ handler_init(Manager, ID, Peek, Sock) ->
"~n (ipv6) Recv Pkt Info: ~s"
"~n (ipv6) RT Hdr: ~s"
"~n (ipv6) Auth Hdr: ~s"
- "~n (ipv6) Hop Opts: ~s",
+ "~n (ipv6) Hop Limit: ~s"
+ "~n (ipv6) Hop Opts: ~s"
+ "~n (ipv6) Dst Opts: ~s",
[Domain, Type, Proto,
RA, RP, B2D, OOBI,
RcvBuf, RcvLW, RcvTO, SndBuf, SndLW, SndTO,
@@ -678,7 +682,7 @@ handler_init(Manager, ID, Peek, Sock) ->
FreeBind, MTU, MTUDisc, MALL, MIF4, MLoop4, MTTL,
NF, RecvIF, RecvOPTS, RecvTOS, RecvTTL,
MHops, MIF6, MLoop6, RecvPktInfo,
- RtHdr, AuthHdr, HopOpts]),
+ RtHdr, AuthHdr, HopLimit, HopOpts, DstOpts]),
handler_loop(#handler{peek = Peek,
manager = Manager,