aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--lib/kernel/test/socket_server.erl103
5 files changed, 206 insertions, 67 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) ->
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 8087a0ddda..3dad94b751 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -640,6 +640,7 @@ handler_init(Manager, ID, Peek, Sock) ->
RecvErr4 = GIP4(recverr),
RecvIF = GIP4(recvif), % Only dgram and raw (and FreeBSD)
RecvOPTS = GIP4(recvopts), % Not stream
+ RecvOrigDstAddr = GIP4(recvorigdstaddr),
RecvTOS = GIP4(recvtos),
RecvTTL = GIP4(recvttl), % not stream
RetOpts = GIP4(retopts), % not stream
@@ -659,57 +660,59 @@ handler_init(Manager, ID, Peek, Sock) ->
FlowInfo = GIP6(flowinfo),
UHops = GIP6(unicast_hops),
i("got continue when: "
- "~n (socket) Domain: ~p"
- "~n (socket) Type: ~p"
- "~n (socket) Protocol: ~p"
- "~n (socket) Reuse Address: ~s"
- "~n (socket) Reuse Port: ~s"
- "~n (socket) Bind To Device: ~s"
- "~n (socket) OOBInline: ~s"
- "~n (socket) RcvBuf: ~s"
- "~n (socket) RcvLW: ~s"
- "~n (socket) RcvTO: ~s"
- "~n (socket) SndBuf: ~s"
- "~n (socket) SndLW: ~s"
- "~n (socket) SndTO: ~s"
- "~n (socket) Linger: ~s"
- "~n (socket) Timestamp: ~s"
- "~n (ip) FreeBind: ~s"
- "~n (ip) MTU: ~s"
- "~n (ip) MTU Discovery: ~s"
- "~n (ip) Multicast ALL: ~s"
- "~n (ip) Multicast IF: ~s"
- "~n (ip) Multicast Loop: ~s"
- "~n (ip) Multicast TTL: ~s"
- "~n (ip) Node Frag: ~s"
- "~n (ip) Pkt Info: ~s"
- "~n (ip) Recv Err: ~s"
- "~n (ip) Recv IF: ~s"
- "~n (ip) Recv OPTS: ~s"
- "~n (ip) Recv TOS: ~s"
- "~n (ip) Recv TTL: ~s"
- "~n (ip) Ret Opts: ~s"
- "~n (ip) TOS: ~s"
- "~n (ip) Transparent: ~s"
- "~n (ip) TTL: ~s"
- "~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"
- "~n (ipv6) Hop Limit: ~s"
- "~n (ipv6) Hop Opts: ~s"
- "~n (ipv6) Dst Opts: ~s"
- "~n (ipv6) Flow Info: ~s"
- "~n (ipv6) Unicast Hops: ~s",
+ "~n (socket) Domain: ~p"
+ "~n (socket) Type: ~p"
+ "~n (socket) Protocol: ~p"
+ "~n (socket) Reuse Address: ~s"
+ "~n (socket) Reuse Port: ~s"
+ "~n (socket) Bind To Device: ~s"
+ "~n (socket) OOBInline: ~s"
+ "~n (socket) RcvBuf: ~s"
+ "~n (socket) RcvLW: ~s"
+ "~n (socket) RcvTO: ~s"
+ "~n (socket) SndBuf: ~s"
+ "~n (socket) SndLW: ~s"
+ "~n (socket) SndTO: ~s"
+ "~n (socket) Linger: ~s"
+ "~n (socket) Timestamp: ~s"
+ "~n (ip) FreeBind: ~s"
+ "~n (ip) MTU: ~s"
+ "~n (ip) MTU Discovery: ~s"
+ "~n (ip) Multicast ALL: ~s"
+ "~n (ip) Multicast IF: ~s"
+ "~n (ip) Multicast Loop: ~s"
+ "~n (ip) Multicast TTL: ~s"
+ "~n (ip) Node Frag: ~s"
+ "~n (ip) Pkt Info: ~s"
+ "~n (ip) Recv Err: ~s"
+ "~n (ip) Recv IF: ~s"
+ "~n (ip) Recv OPTS: ~s"
+ "~n (ip) Recv Orig Dst Addr: ~s"
+ "~n (ip) Recv TOS: ~s"
+ "~n (ip) Recv TTL: ~s"
+ "~n (ip) Ret Opts: ~s"
+ "~n (ip) TOS: ~s"
+ "~n (ip) Transparent: ~s"
+ "~n (ip) TTL: ~s"
+ "~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"
+ "~n (ipv6) Hop Limit: ~s"
+ "~n (ipv6) Hop Opts: ~s"
+ "~n (ipv6) Dst Opts: ~s"
+ "~n (ipv6) Flow Info: ~s"
+ "~n (ipv6) Unicast Hops: ~s",
[Domain, Type, Proto,
RA, RP, B2D, OOBI,
RcvBuf, RcvLW, RcvTO, SndBuf, SndLW, SndTO,
Linger, Timestamp,
FreeBind, MTU, MTUDisc, MALL, MIF4, MLoop4, MTTL,
- NF, PktInfo,RecvErr4, RecvIF, RecvOPTS, RecvTOS, RecvTTL, RetOpts,
+ NF, PktInfo,RecvErr4,
+ RecvIF, RecvOPTS, RecvOrigDstAddr, RecvTOS, RecvTTL, RetOpts,
TOS, Transparent, TTL,
MHops, MIF6, MLoop6, RecvErr6, RecvPktInfo,
RtHdr, AuthHdr, HopLimit, HopOpts, DstOpts, FlowInfo,
@@ -721,14 +724,14 @@ handler_init(Manager, ID, Peek, Sock) ->
socket = Sock})
end.
-%% so(Sock, Lvl, Opt, Val) ->
-%% ok = socket:setopt(Sock, Lvl, Opt, Val).
+so(Sock, Lvl, Opt, Val) ->
+ ok = socket:setopt(Sock, Lvl, Opt, Val).
%% soso(Sock, Opt, Val) ->
%% so(Sock, socket, Opt, Val).
-%% soip(Sock, Opt, Val) ->
-%% so(Sock, ip, Opt, Val).
+soip(Sock, Opt, Val) ->
+ so(Sock, ip, Opt, Val).
%% soipv6(Sock, Opt, Val) ->
%% so(Sock, ipv6, Opt, Val).