aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-07-24 17:01:46 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commit4e24993aff4c5a0cb2bec96e5499131a660a79f9 (patch)
tree01dbfd99552c6b7f1baddcc101ba6d664c68d877
parent00a2425bde77ddb9ae4c03b8c4e5470064773981 (diff)
downloadotp-4e24993aff4c5a0cb2bec96e5499131a660a79f9.tar.gz
otp-4e24993aff4c5a0cb2bec96e5499131a660a79f9.tar.bz2
otp-4e24993aff4c5a0cb2bec96e5499131a660a79f9.zip
[socket-nif] Add support for socket (level ipv6) option recverr
Added support for the IPv6 socket option RECVERR. To actually make use of this option, we need the recvmsg function, which we don't have yet. Baby steps. OTP-14831.
-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.beambin58076 -> 58080 bytes
-rw-r--r--erts/preloaded/src/socket.erl11
-rw-r--r--lib/kernel/test/socket_server.erl4
5 files changed, 60 insertions, 5 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index b791567c22..30b855f925 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -511,6 +511,13 @@
<cell>none</cell>
</row>
<row>
+ <cell>recverr</cell>
+ <cell>boolean()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>none</cell>
+ </row>
+ <row>
<cell>recvpktinfo | pktinfo</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 86a81c882b..3f87232000 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -551,6 +551,7 @@ typedef union {
#define SOCKET_OPT_IPV6_MULTICAST_HOPS 19
#define SOCKET_OPT_IPV6_MULTICAST_IF 20
#define SOCKET_OPT_IPV6_MULTICAST_LOOP 21
+#define SOCKET_OPT_IPV6_RECVERR 24
#define SOCKET_OPT_IPV6_RECVPKTINFO 25 // PKTINFO on FreeBSD
#define SOCKET_OPT_IPV6_ROUTER_ALERT 27
#define SOCKET_OPT_IPV6_RTHDR 28
@@ -1276,6 +1277,11 @@ static ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IPV6_RECVERR)
+static ERL_NIF_TERM nsetopt_lvl_ipv6_recverr(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
static ERL_NIF_TERM nsetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1617,6 +1623,10 @@ static ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(IPV6_RECVERR)
+static ERL_NIF_TERM ngetopt_lvl_ipv6_recverr(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
static ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -5726,6 +5736,12 @@ ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env,
break;
#endif
+#if defined(IPV6_RECVERR)
+ case SOCKET_OPT_IPV6_RECVERR:
+ result = nsetopt_lvl_ipv6_recverr(env, descP, eVal);
+ break;
+#endif
+
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
case SOCKET_OPT_IPV6_RECVPKTINFO:
result = nsetopt_lvl_ipv6_recvpktinfo(env, descP, eVal);
@@ -5975,6 +5991,17 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
#endif
+#if defined(IPV6_RECVERR)
+static
+ERL_NIF_TERM nsetopt_lvl_ipv6_recverr(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ return nsetopt_bool_opt(env, descP, SOL_IPV6, IPV6_RECVERR, eVal);
+}
+#endif
+
+
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
static
ERL_NIF_TERM nsetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
@@ -8438,6 +8465,12 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
break;
#endif
+#if defined(IPV6_RECVERR)
+ case SOCKET_OPT_IPV6_RECVERR:
+ result = ngetopt_lvl_ipv6_recverr(env, descP);
+ break;
+#endif
+
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
case SOCKET_OPT_IPV6_RECVPKTINFO:
result = ngetopt_lvl_ipv6_recvpktinfo(env, descP);
@@ -8601,6 +8634,16 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
#endif
+#if defined(IPV6_RECVERR)
+static
+ERL_NIF_TERM ngetopt_lvl_ipv6_recverr(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ return ngetopt_bool_opt(env, descP, SOL_IPV6, IPV6_RECVERR);
+}
+#endif
+
+
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
static
ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index e2b988f8a6..8ca75307bc 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 0a101008c6..5695e45ac5 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -658,7 +658,7 @@
-define(SOCKET_OPT_IPV6_MULTICAST_LOOP, 21).
%% -define(SOCKET_OPT_IPV6_PORTRANGE, 22). % FreeBSD
%% -define(SOCKET_OPT_IPV6_PKTOPTIONS, 23). % FreeBSD
-%% -define(SOCKET_OPT_IPV6_RECVERR, 24).
+-define(SOCKET_OPT_IPV6_RECVERR, 24).
-define(SOCKET_OPT_IPV6_RECVPKTINFO, 25). % On FreeBSD: PKTINFO
%% -define(SOCKET_OPT_IPV6_RECVTCLASS, 26).
-define(SOCKET_OPT_IPV6_ROUTER_ALERT, 27).
@@ -2308,6 +2308,9 @@ enc_setopt_value(ipv6, multicast_if, V, _D, _T, _P)
enc_setopt_value(ipv6, multicast_loop, V, _D, _T, _P)
when is_boolean(V) ->
V;
+enc_setopt_value(ipv6, recverr, V, _D, _T, _P)
+ when is_boolean(V) ->
+ V;
enc_setopt_value(ipv6, Opt, V, _D, _T, _P)
when ((Opt =:= recvpktinfo) orelse (Opt =:= pktinfo)) andalso
is_boolean(V) ->
@@ -2759,8 +2762,8 @@ enc_sockopt_key(ipv6 = L, portrange = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ipv6 = L, pktoptions = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
-enc_sockopt_key(ipv6 = L, recverr = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
+enc_sockopt_key(ipv6 = _L, recverr = _Opt, _Dir, _D, _T, _P) ->
+ ?SOCKET_OPT_IPV6_RECVERR;
enc_sockopt_key(ipv6 = _L, Opt, _Dir, _D, T, _P)
when ((Opt =:= recvpktinfo) orelse (Opt =:= pktinfo)) andalso
((T =:= dgram) orelse (T =:= raw)) ->
@@ -2781,7 +2784,7 @@ enc_sockopt_key(ipv6 = L, use_min_mtu = Opt, _Dir, _D, _T, _P) ->
enc_sockopt_key(ipv6 = _L, v6only = _Opt, _Dir, _D, _T, _P) ->
?SOCKET_OPT_IPV6_V6ONLY;
enc_sockopt_key(ipv6 = L, UnknownOpt, _Dir, _D, _T, _P) ->
- unknown({L, UnknownOpt, _Dir, _D, _T, _P});
+ unknown({L, UnknownOpt});
%% TCP socket options
%% There are other options that would be useful; info,
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 43f6f5ac75..4b032c586c 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -644,6 +644,7 @@ handler_init(Manager, ID, Peek, Sock) ->
MHops = GIP6(multicast_hops),
MIF6 = GIP6(multicast_if), % Only dgram and raw
MLoop6 = GIP6(multicast_loop),
+ RecvErr6 = GIP6(recverr),
RecvPktInfo = GIP6(recvpktinfo),
RtHdr = GIP6(rthdr),
AuthHdr = GIP6(authhdr),
@@ -684,6 +685,7 @@ handler_init(Manager, ID, Peek, Sock) ->
"~n (ipv6) Multicast Hops: ~s"
"~n (ipv6) Multicast IF: ~s"
"~n (ipv6) Multicast Loop: ~s"
+ "~n (ipv6) Recv Err: ~s"
"~n (ipv6) Recv Pkt Info: ~s"
"~n (ipv6) RT Hdr: ~s"
"~n (ipv6) Auth Hdr: ~s"
@@ -698,7 +700,7 @@ handler_init(Manager, ID, Peek, Sock) ->
Linger, Timestamp,
FreeBind, MTU, MTUDisc, MALL, MIF4, MLoop4, MTTL,
NF, RecvErr4, RecvIF, RecvOPTS, RecvTOS, RecvTTL,
- MHops, MIF6, MLoop6, RecvPktInfo,
+ MHops, MIF6, MLoop6, RecvErr6, RecvPktInfo,
RtHdr, AuthHdr, HopLimit, HopOpts, DstOpts, FlowInfo,
UHops]),