aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/socket_usage.xml14
-rw-r--r--erts/emulator/nifs/common/socket_nif.c132
-rw-r--r--erts/preloaded/ebin/socket.beambin59600 -> 59660 bytes
-rw-r--r--erts/preloaded/src/socket.erl24
4 files changed, 153 insertions, 17 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index 79cafa0162..f69aa75820 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -373,6 +373,13 @@
<cell>type = dgram</cell>
</row>
<row>
+ <cell>recvdstaddr</cell>
+ <cell>boolean()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>type = dgram</cell>
+ </row>
+ <row>
<cell>recverr</cell>
<cell>boolean()</cell>
<cell>yes</cell>
@@ -394,6 +401,13 @@
<cell>type =/= stream</cell>
</row>
<row>
+ <cell>recvorigdstaddr</cell>
+ <cell>boolean()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>none</cell>
+ </row>
+ <row>
<cell>recvttl</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 288188d2dd..4ba94f4f60 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -531,9 +531,11 @@ typedef union {
#define SOCKET_OPT_IP_MULTICAST_TTL 16
#define SOCKET_OPT_IP_NODEFRAG 17
#define SOCKET_OPT_IP_PKTINFO 19
-#define SOCKET_OPT_IP_RECVERR 20
-#define SOCKET_OPT_IP_RECVIF 21
+#define SOCKET_OPT_IP_RECVDSTADDR 20
+#define SOCKET_OPT_IP_RECVERR 21
+#define SOCKET_OPT_IP_RECVIF 22
#define SOCKET_OPT_IP_RECVOPTS 23
+#define SOCKET_OPT_IP_RECVORIGDSTADDR 24
#define SOCKET_OPT_IP_RECVTOS 25
#define SOCKET_OPT_IP_RECVTTL 26
#define SOCKET_OPT_IP_RETOPTS 27
@@ -1171,6 +1173,11 @@ static ERL_NIF_TERM nsetopt_lvl_ip_pktinfo(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IP_RECVDSTADDR)
+static ERL_NIF_TERM nsetopt_lvl_ip_recvdstaddr(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,
@@ -1186,6 +1193,11 @@ static ERL_NIF_TERM nsetopt_lvl_ip_recvopts(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IP_RECVORIGDSTADDR)
+static ERL_NIF_TERM nsetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(IP_RECVTOS)
static ERL_NIF_TERM nsetopt_lvl_ip_recvtos(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1592,6 +1604,10 @@ static ERL_NIF_TERM ngetopt_lvl_ip_nodefrag(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_ip_pktinfo(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(IP_RECVDSTADDRS)
+static ERL_NIF_TERM ngetopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IP_RECVERR)
static ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -1604,6 +1620,10 @@ static ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_ip_recvopts(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(IP_RECVORIGDSTADDR)
+static ERL_NIF_TERM ngetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IP_RECVTOS)
static ERL_NIF_TERM ngetopt_lvl_ip_recvtos(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -5051,6 +5071,12 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
break;
#endif
+#if defined(IP_RECVDSTADDR)
+ case SOCKET_OPT_IP_RECVDSTADDR:
+ result = nsetopt_lvl_ip_recvdstaddr(env, descP, eVal);
+ break;
+#endif
+
#if defined(IP_RECVERR)
case SOCKET_OPT_IP_RECVERR:
result = nsetopt_lvl_ip_recverr(env, descP, eVal);
@@ -5069,6 +5095,12 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
break;
#endif
+#if defined(IP_RECVORIGDSTADDR)
+ case SOCKET_OPT_IP_RECVORIGDSTADDR:
+ result = nsetopt_lvl_ip_recvorigdstaddr(env, descP, eVal);
+ break;
+#endif
+
#if defined(IP_RECVTOS)
case SOCKET_OPT_IP_RECVTOS:
result = nsetopt_lvl_ip_recvtos(env, descP, eVal);
@@ -5605,6 +5637,25 @@ ERL_NIF_TERM nsetopt_lvl_ip_pktinfo(ErlNifEnv* env,
#endif
+/* nsetopt_lvl_ip_recvdstaddr - Level IP RECVDSTADDR option
+ */
+#if defined(IP_RECVDSTADDR)
+static
+ERL_NIF_TERM nsetopt_lvl_ip_recvdstaddr(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_RECVDSTADDR, eVal);
+}
+#endif
+
+
/* nsetopt_lvl_ip_recverr - Level IP RECVERR option
*/
#if defined(IP_RECVERR)
@@ -5662,6 +5713,25 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvopts(ErlNifEnv* env,
#endif
+/* nsetopt_lvl_ip_recvorigdstaddr - Level IP RECVORIGDSTADDR option
+ */
+#if defined(IP_RECVORIGDSTADDR)
+static
+ERL_NIF_TERM nsetopt_lvl_ip_recvorigdstaddr(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_RECVORIGDSTADDR, eVal);
+}
+#endif
+
+
/* nsetopt_lvl_ip_recvtos - Level IP RECVTOS option
*/
#if defined(IP_RECVTOS)
@@ -8294,6 +8364,12 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
break;
#endif
+#if defined(IP_RECVDSTADDR)
+ case SOCKET_OPT_IP_RECVDSTADDR:
+ result = ngetopt_lvl_ip_recvdstaddr(env, descP);
+ break;
+#endif
+
#if defined(IP_RECVERR)
case SOCKET_OPT_IP_RECVERR:
result = ngetopt_lvl_ip_recverr(env, descP);
@@ -8312,6 +8388,12 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
break;
#endif
+#if defined(IP_RECVORIGDSTADDR)
+ case SOCKET_OPT_IP_RECVORIGDSTADDR:
+ result = ngetopt_lvl_ip_recvorigdstaddr(env, descP);
+ break;
+#endif
+
#if defined(IP_RECVTOS)
case SOCKET_OPT_IP_RECVTOS:
result = ngetopt_lvl_ip_recvtos(env, descP);
@@ -8620,12 +8702,12 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvtos(ErlNifEnv* env,
#endif
-/* ngetopt_lvl_ip_recvif - Level IP RECVIF option
+/* ngetopt_lvl_ip_recvdstaddr - Level IP RECVDSTADDR option
*/
-#if defined(IP_RECVIF)
+#if defined(IP_RECVDSTADDR)
static
-ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env,
- SocketDescriptor* descP)
+ERL_NIF_TERM ngetopt_lvl_ip_recvdstaddr(ErlNifEnv* env,
+ SocketDescriptor* descP)
{
#if defined(SOL_IP)
int level = SOL_IP;
@@ -8633,7 +8715,7 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env,
int level = IPPROTO_IP;
#endif
- return ngetopt_bool_opt(env, descP, level, IP_RECVIF);
+ return ngetopt_bool_opt(env, descP, level, IP_RECVDSTADDR);
}
#endif
@@ -8656,6 +8738,24 @@ ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env,
#endif
+/* ngetopt_lvl_ip_recvif - Level IP RECVIF option
+ */
+#if defined(IP_RECVIF)
+static
+ERL_NIF_TERM ngetopt_lvl_ip_recvif(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_RECVIF);
+}
+#endif
+
+
/* ngetopt_lvl_ip_recvopt - Level IP RECVOPTS option
*/
#if defined(IP_RECVOPTS)
@@ -8674,6 +8774,24 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvopts(ErlNifEnv* env,
#endif
+/* ngetopt_lvl_ip_recvorigdstaddr - Level IP RECVORIGDSTADDR option
+ */
+#if defined(IP_RECVORIGDSTADDR)
+static
+ERL_NIF_TERM ngetopt_lvl_ip_recvorigdstaddr(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_RECVORIGDSTADDR);
+}
+#endif
+
+
/* ngetopt_lvl_ip_recvttl - Level IP RECVTTL option
*/
#if defined(IP_RECVTTL)
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 9c626feff2..90cb657178 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 fcc052a25d..68b7d3f4b0 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -629,11 +629,11 @@
-define(SOCKET_OPT_IP_NODEFRAG, 17).
%% -define(SOCKET_OPT_IP_OPTIONS, 18). % FreeBSD
-define(SOCKET_OPT_IP_PKTINFO, 19).
--define(SOCKET_OPT_IP_RECVERR, 20).
--define(SOCKET_OPT_IP_RECVIF, 21).
-%% -define(SOCKET_OPT_IP_RECVDSTADDR, 22).
+-define(SOCKET_OPT_IP_RECVDSTADDR, 20). % FreeBSD
+-define(SOCKET_OPT_IP_RECVERR, 21).
+-define(SOCKET_OPT_IP_RECVIF, 22).
-define(SOCKET_OPT_IP_RECVOPTS, 23).
-%% -define(SOCKET_OPT_IP_RECVORIGDSTADDR, 24).
+-define(SOCKET_OPT_IP_RECVORIGDSTADDR, 24).
-define(SOCKET_OPT_IP_RECVTOS, 25).
-define(SOCKET_OPT_IP_RECVTTL, 26).
-define(SOCKET_OPT_IP_RETOPTS, 27).
@@ -2289,6 +2289,9 @@ enc_setopt_value(ip, nodefrag, V, _D, _T, _P)
enc_setopt_value(ip, pktinfo, V, _D, _T, _P)
when is_boolean(V) ->
V;
+enc_setopt_value(ip, recvdstaddr, V, _D, _T, _P)
+ when is_boolean(V) ->
+ V;
enc_setopt_value(ip, recverr, V, _D, _T, _P)
when is_boolean(V) ->
V;
@@ -2298,6 +2301,9 @@ enc_setopt_value(ip, recvif, V, _D, _T, _P)
enc_setopt_value(ip, recvopts, V, _D, _T, _P)
when is_boolean(V) ->
V;
+enc_setopt_value(ip, recvorigdstaddr, V, _D, _T, _P)
+ when is_boolean(V) ->
+ V;
enc_setopt_value(ip, recvtos, V, _D, _T, _P)
when is_boolean(V) ->
V;
@@ -2751,19 +2757,17 @@ enc_sockopt_key(ip = L, options = Opt, _Dir, _D, _T, _P) ->
not_supported({Opt, L});
enc_sockopt_key(ip = _L, pktinfo = _Opt, _Dir, _D, dgram = _T, _P) ->
?SOCKET_OPT_IP_PKTINFO;
-%% This require special code for accessing the errors.
-%% via calling the recvmsg with the MSG_ERRQUEUE flag set,
+enc_sockopt_key(ip = _L, recvdstaddr = _Opt, _Dir, _D, T, _P) when (T =:= dgram) ->
+ ?SOCKET_OPT_IP_RECVDSTADDR;
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;
-enc_sockopt_key(ip = L, recvdstaddr = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
enc_sockopt_key(ip = _L, recvopts = _Opt, _Dir, _D, T, _P) when (T =/= stream) ->
?SOCKET_OPT_IP_RECVOPTS;
-enc_sockopt_key(ip = L, recvorigdstaddr = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
+enc_sockopt_key(ip = _L, recvorigdstaddr = _Opt, _Dir, _D, _T, _P) ->
+ ?SOCKET_OPT_IP_RECVORIGDSTADDR;
enc_sockopt_key(ip, recvtos = _Opt, _Dir, _D, _T, _P) ->
?SOCKET_OPT_IP_RECVTOS;
enc_sockopt_key(ip = _L, recvttl = _Opt, _Dir, _D, T, _P) when (T =/= stream) ->