aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-07-26 10:10:16 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commit8ed757c8df2df54e19e67ca0a0734cd5a0f9ab23 (patch)
tree6fd78d10feec2f4b60901a9a24d2bdc51a80d56d
parent91d965f2ddfb420100ba685a059ec84eba18d0f9 (diff)
downloadotp-8ed757c8df2df54e19e67ca0a0734cd5a0f9ab23.tar.gz
otp-8ed757c8df2df54e19e67ca0a0734cd5a0f9ab23.tar.bz2
otp-8ed757c8df2df54e19e67ca0a0734cd5a0f9ab23.zip
[socket-nif] Add support for socket (level ip) option recvorigdstaddr
Added support for ip level socket option RECVORIGDSTADDR. This option requires recvmsg to actually use, so we cannot test this fully at the moment (although both set and get works). OTP-14831
-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).