aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/doc/src/socket_usage.xml9
-rw-r--r--erts/emulator/nifs/common/socket_nif.c59
-rw-r--r--erts/preloaded/ebin/socket.beambin58020 -> 58076 bytes
-rw-r--r--erts/preloaded/src/socket.erl33
-rw-r--r--lib/kernel/test/socket_server.erl4
5 files changed, 88 insertions, 17 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index 8480af315e..b791567c22 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -339,7 +339,7 @@
</row>
<row>
<cell>multicast_ttl</cell>
- <cell>0..255</cell>
+ <cell>uint8()</cell>
<cell>yes</cell>
<cell>yes</cell>
<cell>none</cell>
@@ -352,6 +352,13 @@
<cell>type = raw</cell>
</row>
<row>
+ <cell>recverr</cell>
+ <cell>boolean()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>none</cell>
+ </row>
+ <row>
<cell>recvif</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 f7053d77fa..86a81c882b 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -528,6 +528,7 @@ typedef union {
#define SOCKET_OPT_IP_MULTICAST_LOOP 15
#define SOCKET_OPT_IP_MULTICAST_TTL 16
#define SOCKET_OPT_IP_NODEFRAG 17
+#define SOCKET_OPT_IP_RECVERR 20
#define SOCKET_OPT_IP_RECVIF 21
#define SOCKET_OPT_IP_RECVOPTS 23
#define SOCKET_OPT_IP_RECVTOS 25
@@ -1142,6 +1143,11 @@ static ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IP_RECVERR)
+static ERL_NIF_TERM nsetopt_lvl_ip_recverr(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(IP_RECVIF)
static ERL_NIF_TERM nsetopt_lvl_ip_recvif(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1535,6 +1541,10 @@ static ERL_NIF_TERM ngetopt_lvl_ip_multicast_ttl(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_ip_nodefrag(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(IP_RECVERR)
+static ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IP_RECVIF)
static ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -4950,6 +4960,12 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
break;
#endif
+#if defined(IP_RECVERR)
+ case SOCKET_OPT_IP_RECVERR:
+ result = nsetopt_lvl_ip_recverr(env, descP, eVal);
+ break;
+#endif
+
#if defined(IP_RECVIF)
case SOCKET_OPT_IP_RECVIF:
result = nsetopt_lvl_ip_recvif(env, descP, eVal);
@@ -5308,6 +5324,25 @@ ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env,
#endif
+/* nsetopt_lvl_ip_recverr - Level IP RECVERR option
+ */
+#if defined(IP_RECVERR)
+static
+ERL_NIF_TERM nsetopt_lvl_ip_recverr(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+#if defined(SOL_IP)
+ int level = SOL_IP;
+#else
+ int level = IPPROTO_IP;
+#endif
+
+ return nsetopt_bool_opt(env, descP, level, IP_RECVERR, eVal);
+}
+#endif
+
+
/* nsetopt_lvl_ip_recvif - Level IP RECVIF option
*/
#if defined(IP_RECVIF)
@@ -7910,6 +7945,12 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
break;
#endif
+#if defined(IP_RECVERR)
+ case SOCKET_OPT_IP_RECVERR:
+ result = ngetopt_lvl_ip_recverr(env, descP);
+ break;
+#endif
+
#if defined(IP_RECVIF)
case SOCKET_OPT_IP_RECVIF:
result = ngetopt_lvl_ip_recvif(env, descP);
@@ -8200,6 +8241,24 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env,
#endif
+/* ngetopt_lvl_ip_recverr - Level IP RECVERR option
+ */
+#if defined(IP_RECVERR)
+static
+ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+#if defined(SOL_IP)
+ int level = SOL_IP;
+#else
+ int level = IPPROTO_IP;
+#endif
+
+ return ngetopt_bool_opt(env, descP, level, IP_RECVERR);
+}
+#endif
+
+
/* ngetopt_lvl_ip_recvopt - Level IP RECVOPTS option
*/
#if defined(IP_RECVOPTS)
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 20f2cf659b..e2b988f8a6 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 0c3a17b54d..0a101008c6 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -620,7 +620,7 @@
-define(SOCKET_OPT_IP_NODEFRAG, 17).
%% -define(SOCKET_OPT_IP_OPTIONS, 18).
%% -define(SOCKET_OPT_IP_PKTINFO, 19).
-%% -define(SOCKET_OPT_IP_RECVERR, 20).
+-define(SOCKET_OPT_IP_RECVERR, 20).
-define(SOCKET_OPT_IP_RECVIF, 21).
%% -define(SOCKET_OPT_IP_RECVDSTADDR, 22).
-define(SOCKET_OPT_IP_RECVOPTS, 23).
@@ -638,34 +638,34 @@
-define(SOCKET_OPT_IPV6_ADDRFORM, 1).
-define(SOCKET_OPT_IPV6_ADD_MEMBERSHIP, 2).
-define(SOCKET_OPT_IPV6_AUTHHDR, 3). % Obsolete?
-%% -define(SOCKET_OPT_IPV6_AUTH_LEVEL, 4).
-%% -define(SOCKET_OPT_IPV6_CHECKSUM, 5).
+%% -define(SOCKET_OPT_IPV6_AUTH_LEVEL, 4). % FreeBSD
+%% -define(SOCKET_OPT_IPV6_CHECKSUM, 5). % FreeBSD
-define(SOCKET_OPT_IPV6_DROP_MEMBERSHIP, 6).
-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).
+%% -define(SOCKET_OPT_IPV6_ESP_TRANS_LEVEL, 8). % FreeBSD
+%% -define(SOCKET_OPT_IPV6_ESP_NETWORK_LEVEL, 9). % FreeBSD
+%% -define(SOCKET_OPT_IPV6_FAITH, 10). % FreeBSD
-define(SOCKET_OPT_IPV6_FLOWINFO, 11).
-define(SOCKET_OPT_IPV6_HOPLIMIT, 12).
-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).
+%% -define(SOCKET_OPT_IPV6_IPCOMP_LEVEL, 14). % FreeBSD
+%% -define(SOCKET_OPT_IPV6_JOIN_GROUP, 15). % FreeBSD
+%% -define(SOCKET_OPT_IPV6_LEAVE_GROUP, 16). % FreeBSD
-define(SOCKET_OPT_IPV6_MTU, 17).
-define(SOCKET_OPT_IPV6_MTU_DISCOVER, 18).
-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_PORTRANGE, 22).
-%% -define(SOCKET_OPT_IPV6_PKTOPTIONS, 23).
+%% -define(SOCKET_OPT_IPV6_PORTRANGE, 22). % FreeBSD
+%% -define(SOCKET_OPT_IPV6_PKTOPTIONS, 23). % FreeBSD
%% -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).
-define(SOCKET_OPT_IPV6_RTHDR, 28).
-%% -define(SOCKET_OPT_IPV6_TCLASS, 29).
+%% -define(SOCKET_OPT_IPV6_TCLASS, 29). % FreeBSD
-define(SOCKET_OPT_IPV6_UNICAST_HOPS, 30).
-%% -define(SOCKET_OPT_IPV6_USE_MIN_MTU, 31).
+%% -define(SOCKET_OPT_IPV6_USE_MIN_MTU, 31). % FreeBSD
-define(SOCKET_OPT_IPV6_V6ONLY, 32).
-define(SOCKET_OPT_TCP_CONGESTION, 1).
@@ -2219,6 +2219,9 @@ enc_setopt_value(ip, multicast_ttl, V, _D, _T, _P)
enc_setopt_value(ip, nodefrag, V, _D, _T, _P)
when is_boolean(V) ->
V;
+enc_setopt_value(ip, recverr, V, _D, _T, _P)
+ when is_boolean(V) ->
+ V;
enc_setopt_value(ip, recvif, V, _D, _T, _P)
when is_boolean(V) ->
V;
@@ -2672,8 +2675,8 @@ enc_sockopt_key(ip = L, pktinfo = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
%% This require special code for accessing the errors.
%% via calling the recvmsg with the MSG_ERRQUEUE flag set,
-enc_sockopt_key(ip = L, recverr = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
+enc_sockopt_key(ip = _L, recverr = _Opt, _Dir, _D, _T, _P) ->
+ ?SOCKET_OPT_IP_RECVERR;
enc_sockopt_key(ip = _L, recvif = _Opt, _Dir, _D, T, _P)
when (T =:= dgram) orelse (T =:= raw) ->
?SOCKET_OPT_IP_RECVIF;
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 54e9244d19..43f6f5ac75 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -636,6 +636,7 @@ handler_init(Manager, ID, Peek, Sock) ->
MLoop4 = GIP4(multicast_loop),
MTTL = GIP4(multicast_ttl),
NF = GIP4(nodefrag), % raw only
+ RecvErr4 = GIP4(recverr),
RecvIF = GIP4(recvif), % Only dgram and raw (and FreeBSD)
RecvOPTS = GIP4(recvopts), % Not stream
RecvTOS = GIP4(recvtos),
@@ -675,6 +676,7 @@ handler_init(Manager, ID, Peek, Sock) ->
"~n (ip) Multicast Loop: ~s"
"~n (ip) Multicast TTL: ~s"
"~n (ip) Node Frag: ~s"
+ "~n (ip) Recv Err: ~s"
"~n (ip) Recv IF: ~s"
"~n (ip) Recv OPTS: ~s"
"~n (ip) Recv TOS: ~s"
@@ -695,7 +697,7 @@ handler_init(Manager, ID, Peek, Sock) ->
RcvBuf, RcvLW, RcvTO, SndBuf, SndLW, SndTO,
Linger, Timestamp,
FreeBind, MTU, MTUDisc, MALL, MIF4, MLoop4, MTTL,
- NF, RecvIF, RecvOPTS, RecvTOS, RecvTTL,
+ NF, RecvErr4, RecvIF, RecvOPTS, RecvTOS, RecvTTL,
MHops, MIF6, MLoop6, RecvPktInfo,
RtHdr, AuthHdr, HopLimit, HopOpts, DstOpts, FlowInfo,
UHops]),