aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/doc/src/socket_usage.xml18
-rw-r--r--erts/emulator/nifs/common/socket_nif.c102
-rw-r--r--erts/preloaded/ebin/socket.beambin57224 -> 57388 bytes
-rw-r--r--erts/preloaded/src/socket.erl27
-rw-r--r--lib/kernel/test/socket_server.erl9
5 files changed, 142 insertions, 14 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index b3ee38dbcb..b13582dfbc 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -419,6 +419,13 @@
<cell>none</cell>
</row>
<row>
+ <cell>authhdr</cell>
+ <cell>boolean()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>type = dgram | raw, obsolete?</cell>
+ </row>
+ <row>
<cell>drop_membership</cell>
<cell>ipv6_mreq()</cell>
<cell>yes</cell>
@@ -429,8 +436,15 @@
<cell>hoplimit</cell>
<cell>boolean()</cell>
<cell>yes</cell>
- <cell>no</cell>
- <cell>type = dgram | raw</cell>
+ <cell>yes</cell>
+ <cell>type = dgram | raw, requires superuser privileges to update</cell>
+ </row>
+ <row>
+ <cell>hopopts</cell>
+ <cell>boolean()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>type = dgram | raw, requires superuser privileges to update</cell>
</row>
<row>
<cell>mtu</cell>
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index f4ac43a9cd..42a9bc3cb6 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -536,8 +536,10 @@ typedef union {
#define SOCKET_OPT_IP_UNBLOCK_SOURCE 33
#define SOCKET_OPT_IPV6_ADD_MEMBERSHIP 2
+#define SOCKET_OPT_IPV6_AUTHHDR 3
#define SOCKET_OPT_IPV6_DROP_MEMBERSHIP 6
#define SOCKET_OPT_IPV6_HOPLIMIT 12
+#define SOCKET_OPT_IPV6_HOPOPTS 13
#define SOCKET_OPT_IPV6_MTU 17
#define SOCKET_OPT_IPV6_MTU_DISCOVER 18
#define SOCKET_OPT_IPV6_MULTICAST_HOPS 19
@@ -1201,6 +1203,11 @@ static ERL_NIF_TERM nsetopt_lvl_ipv6_add_membership(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IPV6_AUTHHDR)
+static ERL_NIF_TERM nsetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(IPV6_DROP_MEMBERSHIP)
static ERL_NIF_TERM nsetopt_lvl_ipv6_drop_membership(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1211,6 +1218,11 @@ static ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IPV6_HOPOPTS)
+static ERL_NIF_TERM nsetopt_lvl_ipv6_hopopts(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(IPV6_MTU)
static ERL_NIF_TERM nsetopt_lvl_ipv6_mtu(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1523,10 +1535,18 @@ static ERL_NIF_TERM ngetopt_lvl_ip_ttl(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
SocketDescriptor* descP,
int eOpt);
+#if defined(IPV6_AUTHHDR)
+static ERL_NIF_TERM ngetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IPV6_HOPLIMIT)
static ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(IPV6_HOPOPTS)
+static ERL_NIF_TERM ngetopt_lvl_ipv6_hopopts(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IPV6_MTU)
static ERL_NIF_TERM ngetopt_lvl_ipv6_mtu(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -1553,7 +1573,7 @@ static ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
#endif
#if defined(IPV6_RTHDR)
static ERL_NIF_TERM ngetopt_lvl_ipv6_rthdr(ErlNifEnv* env,
- SocketDescriptor* descP);
+ SocketDescriptor* descP);
#endif
#if defined(IPV6_V6ONLY)
static ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env,
@@ -5549,6 +5569,12 @@ ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env,
break;
#endif
+#if defined(IPV6_AUTHHDR)
+ case SOCKET_OPT_IPV6_AUTHHDR:
+ result = nsetopt_lvl_ipv6_authhdr(env, descP, eVal);
+ break;
+#endif
+
#if defined(IPV6_DROP_MEMBERSHIP)
case SOCKET_OPT_IPV6_DROP_MEMBERSHIP:
result = nsetopt_lvl_ipv6_drop_membership(env, descP, eVal);
@@ -5561,6 +5587,12 @@ ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env,
break;
#endif
+#if defined(IPV6_HOPOPTS)
+ case SOCKET_OPT_IPV6_HOPOPTS:
+ result = nsetopt_lvl_ipv6_hopopts(env, descP, eVal);
+ break;
+#endif
+
#if defined(IPV6_MTU)
case SOCKET_OPT_IPV6_MTU:
result = nsetopt_lvl_ipv6_mtu(env, descP, eVal);
@@ -5637,6 +5669,17 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_add_membership(ErlNifEnv* env,
#endif
+#if defined(IPV6_AUTHHDR)
+static
+ERL_NIF_TERM nsetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ return nsetopt_bool_opt(env, descP, SOL_IPV6, IPV6_AUTHHDR, eVal);
+}
+#endif
+
+
#if defined(IPV6_DROP_MEMBERSHIP)
static
ERL_NIF_TERM nsetopt_lvl_ipv6_drop_membership(ErlNifEnv* env,
@@ -5660,6 +5703,17 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
#endif
+#if defined(IPV6_HOPOPTS)
+static
+ERL_NIF_TERM nsetopt_lvl_ipv6_hopopts(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ return nsetopt_bool_opt(env, descP, SOL_IPV6, IPV6_HOPOPTS, eVal);
+}
+#endif
+
+
#if defined(IPV6_MTU)
static
ERL_NIF_TERM nsetopt_lvl_ipv6_mtu(ErlNifEnv* env,
@@ -8097,12 +8151,24 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
"\r\n", eOpt) );
switch (eOpt) {
+#if defined(IPV6_AUTHHDR)
+ case SOCKET_OPT_IPV6_AUTHHDR:
+ result = ngetopt_lvl_ipv6_authhdr(env, descP);
+ break;
+#endif
+
#if defined(IPV6_HOPLIMIT)
case SOCKET_OPT_IPV6_HOPLIMIT:
result = ngetopt_lvl_ipv6_hoplimit(env, descP);
break;
#endif
+#if defined(IPV6_HOPOPTS)
+ case SOCKET_OPT_IPV6_HOPOPTS:
+ result = ngetopt_lvl_ipv6_hopopts(env, descP);
+ break;
+#endif
+
#if defined(IPV6_MTU)
case SOCKET_OPT_IPV6_MTU:
result = ngetopt_lvl_ipv6_mtu(env, descP);
@@ -8165,6 +8231,16 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
}
+#if defined(IPV6_AUTHHDR)
+static
+ERL_NIF_TERM ngetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ return ngetopt_bool_opt(env, descP, SOL_IPV6, IPV6_AUTHHDR);
+}
+#endif
+
+
#if defined(IPV6_HOPLIMIT)
static
ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
@@ -8175,6 +8251,16 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
#endif
+#if defined(IPV6_HOPOPTS)
+static
+ERL_NIF_TERM ngetopt_lvl_ipv6_hopopts(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ return ngetopt_bool_opt(env, descP, SOL_IPV6, IPV6_HOPOPTS);
+}
+#endif
+
+
#if defined(IPV6_MTU)
static
ERL_NIF_TERM ngetopt_lvl_ipv6_mtu(ErlNifEnv* env,
@@ -8707,6 +8793,13 @@ ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env,
SOCKOPTLEN_T valSz = sizeof(val);
int res;
+ /*
+ SSDBG( descP, ("SOCKET", "ngetopt_bool_opt -> entry with"
+ "\r\n: level: %d"
+ "\r\n: opt: %d"
+ "\r\n", level, opt) );
+ */
+
res = sock_getopt(descP->sock, level, opt, &val, &valSz);
if (res != 0) {
@@ -8717,6 +8810,13 @@ ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env,
result = esock_make_ok2(env, bval);
}
+ /*
+ SSDBG( descP, ("SOCKET", "ngetopt_bool_opt -> done when"
+ "\r\n: res: %d"
+ "\r\n: result: %T"
+ "\r\n", res, result) );
+ */
+
return result;
}
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 1873289486..da825abb98 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 d2267192e5..3c0dc6e95b 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -632,7 +632,7 @@
%% -define(SOCKET_OPT_IPV6_ADDFORM, 1).
-define(SOCKET_OPT_IPV6_ADD_MEMBERSHIP, 2).
-%% -define(SOCKET_OPT_IPV6_AUTHHDR, 3).
+-define(SOCKET_OPT_IPV6_AUTHHDR, 3). % Obsolete?
%% -define(SOCKET_OPT_IPV6_AUTH_LEVEL, 4).
%% -define(SOCKET_OPT_IPV6_CHECKSUM, 5).
-define(SOCKET_OPT_IPV6_DROP_MEMBERSHIP, 6).
@@ -642,7 +642,7 @@
%% -define(SOCKET_OPT_IPV6_FAITH, 10).
%% -define(SOCKET_OPT_IPV6_FLOWINFO, 11).
-define(SOCKET_OPT_IPV6_HOPLIMIT, 12).
-%% -define(SOCKET_OPT_IPV6_HOPOPTS, 13).
+-define(SOCKET_OPT_IPV6_HOPOPTS, 13).
%% -define(SOCKET_OPT_IPV6_IPCOMP_LEVEL, 14).
%% -define(SOCKET_OPT_IPV6_JOIN_GROUP, 15).
%% -define(SOCKET_OPT_IPV6_LEAVE_GROUP, 16).
@@ -2249,6 +2249,12 @@ enc_setopt_value(ipv6, add_membership, #{multiaddr := MA,
when ((is_tuple(MA) andalso (size(MA) =:= 8)) andalso
(is_integer(IF) andalso (IF >= 0))) ->
V;
+%% Is this obsolete? When get, the result is enoprotoopt and in the
+%% header file it says 'obsolete'...
+%% But there might be (old?) versions of linux where it still works...
+enc_setopt_value(ipv6, authhdr, 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
@@ -2257,6 +2263,9 @@ enc_setopt_value(ipv6, drop_membership, #{multiaddr := MA,
enc_setopt_value(ipv6, hoplimit, V, _D, T, _P)
when is_boolean(V) andalso ((T =:= dgram) orelse (T =:= raw)) ->
V;
+enc_setopt_value(ipv6, hopopts, V, _D, T, _P)
+ when is_boolean(V) andalso ((T =:= dgram) orelse (T =:= raw)) ->
+ V;
enc_setopt_value(ipv6, mtu, V, _D, _T, _P) when is_integer(V) ->
V;
enc_setopt_value(ipv6, mtu_discover, V, _D, _T, _P)
@@ -2282,8 +2291,8 @@ enc_setopt_value(ipv6, Opt, V, _D, _T, _P)
when ((Opt =:= recvpktinfo) orelse (Opt =:= pktinfo)) andalso
is_boolean(V) ->
V;
-enc_setopt_value(ipv6, rthdr, V, _D, _T, _P)
- when is_boolean(V) ->
+enc_setopt_value(ipv6, rthdr, V, _D, T, _P)
+ when is_boolean(V) andalso ((T =:= dgram) orelse (T =:= raw)) ->
V;
enc_setopt_value(ipv6, v6only, V, _D, _T, _P) when is_boolean(V) ->
V;
@@ -2674,9 +2683,9 @@ enc_sockopt_key(ipv6 = L, addrform = Opt, set = _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ipv6, add_membership = _Opt, set = _Dir, _D, _T, _P) ->
?SOCKET_OPT_IPV6_ADD_MEMBERSHIP;
-enc_sockopt_key(ipv6 = L, authhdr = Opt, set = _Dir, _D, T, _P)
+enc_sockopt_key(ipv6 = _L, authhdr = _Opt, _Dir, _D, T, _P)
when ((T =:= dgram) orelse (T =:= raw)) ->
- not_supported({L, Opt});
+ ?SOCKET_OPT_IPV6_AUTHHDR;
enc_sockopt_key(ipv6 = L, auth_level = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ipv6 = L, checksum = Opt, _Dir, _D, _T, _P) ->
@@ -2693,12 +2702,12 @@ enc_sockopt_key(ipv6 = L, esp_network_level = Opt, _Dir, _D, _T, _P) ->
enc_sockopt_key(ipv6 = L, flowinfo = Opt, set = _Dir, _D, T, _P)
when (T =:= dgram) orelse (T =:= raw) ->
not_supported({L, Opt});
-enc_sockopt_key(ipv6, hoplimit = _Opt, _Dir, set = _D, T, _P)
+enc_sockopt_key(ipv6, hoplimit = _Opt, _Dir, _D, T, _P)
when (T =:= dgram) orelse (T =:= raw) ->
?SOCKET_OPT_IPV6_HOPLIMIT;
-enc_sockopt_key(ipv6 = L, hopopts = Opt, set = _Dir, _D, T, _P)
+enc_sockopt_key(ipv6 = _L, hopopts = _Opt, _Dir, _D, T, _P)
when ((T =:= dgram) orelse (T =:= raw)) ->
- not_supported({L, Opt});
+ ?SOCKET_OPT_IPV6_HOPOPTS;
enc_sockopt_key(ipv6 = L, ipcomp_level = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ipv6 = L, join_group = Opt, _Dir, _D, _T, _P) ->
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 75cede75e5..1cd0ec1202 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -634,6 +634,8 @@ handler_init(Manager, ID, Peek, Sock) ->
MLoop6 = GIP6(multicast_loop),
RecvPktInfo = GIP6(recvpktinfo),
RtHdr = GIP6(rthdr),
+ AuthHdr = GIP6(authhdr),
+ HopOpts = GIP6(hopopts),
i("got continue when: "
"~n (socket) Domain: ~p"
"~n (socket) Type: ~p"
@@ -666,14 +668,17 @@ handler_init(Manager, ID, Peek, Sock) ->
"~n (ipv6) Multicast IF: ~s"
"~n (ipv6) Multicast Loop: ~s"
"~n (ipv6) Recv Pkt Info: ~s"
- "~n (ipv6) RT Hdr: ~s",
+ "~n (ipv6) RT Hdr: ~s"
+ "~n (ipv6) Auth Hdr: ~s"
+ "~n (ipv6) Hop Opts: ~s",
[Domain, Type, Proto,
RA, RP, B2D, OOBI,
RcvBuf, RcvLW, RcvTO, SndBuf, SndLW, SndTO,
Linger, Timestamp,
FreeBind, MTU, MTUDisc, MALL, MIF4, MLoop4, MTTL,
NF, RecvIF, RecvOPTS, RecvTOS, RecvTTL,
- MHops, MIF6, MLoop6, RecvPktInfo, RtHdr]),
+ MHops, MIF6, MLoop6, RecvPktInfo,
+ RtHdr, AuthHdr, HopOpts]),
handler_loop(#handler{peek = Peek,
manager = Manager,