aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-07-25 12:29:41 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commit70a5b8d6a01b91a6044c6a5a0f8ed8919afd509b (patch)
tree878cf90a617b2d9404c81b29e48cc589601752c3
parent587d3a9a76b6ef2c88b850d007d39d34c37b5825 (diff)
downloadotp-70a5b8d6a01b91a6044c6a5a0f8ed8919afd509b.tar.gz
otp-70a5b8d6a01b91a6044c6a5a0f8ed8919afd509b.tar.bz2
otp-70a5b8d6a01b91a6044c6a5a0f8ed8919afd509b.zip
[socket-nif] Add support for socket (level ip) option pktinfo
Added support for ip level socket option PKTINFO. This option requires sendmsg and/or 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.xml9
-rw-r--r--erts/emulator/nifs/common/socket_nif.c59
-rw-r--r--erts/preloaded/ebin/socket.beambin59016 -> 59056 bytes
-rw-r--r--erts/preloaded/src/socket.erl9
-rw-r--r--lib/kernel/test/socket_server.erl17
5 files changed, 88 insertions, 6 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index 2ddd51d1e6..443d4edec7 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -366,6 +366,13 @@
<cell>type = raw</cell>
</row>
<row>
+ <cell>pktinfo</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>
@@ -408,7 +415,7 @@
<cell>none</cell>
</row>
<row>
- <cell>tos</cell>
+ <cell>ttl</cell>
<cell>integer()</cell>
<cell>yes</cell>
<cell>yes</cell>
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index 19b40920d3..f4da7cdbb0 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -530,6 +530,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_PKTINFO 19
#define SOCKET_OPT_IP_RECVERR 20
#define SOCKET_OPT_IP_RECVIF 21
#define SOCKET_OPT_IP_RECVOPTS 23
@@ -1163,6 +1164,11 @@ static ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IP_PKTINFO)
+static ERL_NIF_TERM nsetopt_lvl_ip_pktinfo(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,
@@ -1570,6 +1576,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_PKTINFO)
+static ERL_NIF_TERM ngetopt_lvl_ip_pktinfo(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IP_RECVERR)
static ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -5015,6 +5025,12 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
break;
#endif
+#if defined(IP_PKTINFO)
+ case SOCKET_OPT_IP_PKTINFO:
+ result = nsetopt_lvl_ip_pktinfo(env, descP, eVal);
+ break;
+#endif
+
#if defined(IP_RECVERR)
case SOCKET_OPT_IP_RECVERR:
result = nsetopt_lvl_ip_recverr(env, descP, eVal);
@@ -5532,6 +5548,25 @@ ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env,
#endif
+/* nsetopt_lvl_ip_pktinfo - Level IP PKTINFO option
+ */
+#if defined(IP_PKTINFO)
+static
+ERL_NIF_TERM nsetopt_lvl_ip_pktinfo(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_PKTINFO, eVal);
+}
+#endif
+
+
/* nsetopt_lvl_ip_recverr - Level IP RECVERR option
*/
#if defined(IP_RECVERR)
@@ -8176,6 +8211,12 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
break;
#endif
+#if defined(IP_PKTINFO)
+ case SOCKET_OPT_IP_PKTINFO:
+ result = ngetopt_lvl_ip_pktinfo(env, descP);
+ break;
+#endif
+
#if defined(IP_RECVERR)
case SOCKET_OPT_IP_RECVERR:
result = ngetopt_lvl_ip_recverr(env, descP);
@@ -8454,6 +8495,24 @@ ERL_NIF_TERM ngetopt_lvl_ip_nodefrag(ErlNifEnv* env,
#endif
+/* ngetopt_lvl_ip_pktinfo - Level IP PKTINFO option
+ */
+#if defined(IP_PKTINFO)
+static
+ERL_NIF_TERM ngetopt_lvl_ip_pktinfo(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_PKTINFO);
+}
+#endif
+
+
/* ngetopt_lvl_ip_recvtos - Level IP RECVTOS option
*/
#if defined(IP_RECVTOS)
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index be5413e116..b5b18e1c3a 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 4028fa9191..28931e4ed0 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -632,7 +632,7 @@
-define(SOCKET_OPT_IP_MULTICAST_TTL, 16).
-define(SOCKET_OPT_IP_NODEFRAG, 17).
%% -define(SOCKET_OPT_IP_OPTIONS, 18). % FreeBSD
-%% -define(SOCKET_OPT_IP_PKTINFO, 19).
+-define(SOCKET_OPT_IP_PKTINFO, 19).
-define(SOCKET_OPT_IP_RECVERR, 20).
-define(SOCKET_OPT_IP_RECVIF, 21).
%% -define(SOCKET_OPT_IP_RECVDSTADDR, 22).
@@ -2246,6 +2246,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, pktinfo, V, _D, _T, _P)
+ when is_boolean(V) ->
+ V;
enc_setopt_value(ip, recverr, V, _D, _T, _P)
when is_boolean(V) ->
V;
@@ -2700,8 +2703,8 @@ enc_sockopt_key(ip = _L, nodefrag = _Opt, _Dir, _D, raw = _T, _P) ->
?SOCKET_OPT_IP_NODEFRAG;
enc_sockopt_key(ip = L, options = Opt, _Dir, _D, _T, _P) ->
not_supported({Opt, L});
-enc_sockopt_key(ip = L, pktinfo = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
+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, recverr = _Opt, _Dir, _D, _T, _P) ->
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 4b032c586c..0ae6bb2dd0 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
+ PktInfo = GIP4(pktinfo), % dgram only
RecvErr4 = GIP4(recverr),
RecvIF = GIP4(recvif), % Only dgram and raw (and FreeBSD)
RecvOPTS = GIP4(recvopts), % Not stream
@@ -677,6 +678,7 @@ handler_init(Manager, ID, Peek, Sock) ->
"~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"
@@ -699,17 +701,28 @@ handler_init(Manager, ID, Peek, Sock) ->
RcvBuf, RcvLW, RcvTO, SndBuf, SndLW, SndTO,
Linger, Timestamp,
FreeBind, MTU, MTUDisc, MALL, MIF4, MLoop4, MTTL,
- NF, RecvErr4, RecvIF, RecvOPTS, RecvTOS, RecvTTL,
+ NF, PktInfo,RecvErr4, RecvIF, RecvOPTS, RecvTOS, RecvTTL,
MHops, MIF6, MLoop6, RecvErr6, RecvPktInfo,
RtHdr, AuthHdr, HopLimit, HopOpts, DstOpts, FlowInfo,
UHops]),
-
+
handler_loop(#handler{peek = Peek,
manager = Manager,
type = Type,
socket = Sock})
end.
+%% 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).
+
+%% soipv6(Sock, Opt, Val) ->
+%% so(Sock, ipv6, Opt, Val).
handler_loop(H) ->
i("try read message"),