aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-07-24 12:05:00 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commite54642b537177941ff361b1eebdec10e02cfc22d (patch)
tree26f0b90fcc6387f1cb19f10e1b0afd9b04b34825
parent9ca6de6efbe844bcf7dc996cfcf51bcd50325007 (diff)
downloadotp-e54642b537177941ff361b1eebdec10e02cfc22d.tar.gz
otp-e54642b537177941ff361b1eebdec10e02cfc22d.tar.bz2
otp-e54642b537177941ff361b1eebdec10e02cfc22d.zip
[socket-nif] Add support for socket (level ipv6) option flowinfo
Added support for the IPv6 socket option(s) FLOWINFO. The option returns with einval when calling setsockopt, so either you need to be a privileged user to update, or its not actually possible to update this option (even though it says nothing about that in the man page. It only talks about set). This is the same behaviour as with DSTOPTS. Needs furher checking. OTP-14831.
-rw-r--r--erts/doc/src/socket_usage.xml7
-rw-r--r--erts/emulator/nifs/common/socket_nif.c43
-rw-r--r--erts/preloaded/ebin/socket.beambin57468 -> 57524 bytes
-rw-r--r--erts/preloaded/src/socket.erl9
-rw-r--r--lib/kernel/test/socket_server.erl8
5 files changed, 61 insertions, 6 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index 87b44f139f..09a65c7152 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -440,6 +440,13 @@
<cell>type = dgram | raw, requires superuser privileges to update</cell>
</row>
<row>
+ <cell>flowinfo</cell>
+ <cell>boolean()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>type = dgram | raw, requires superuser privileges to update</cell>
+ </row>
+ <row>
<cell>hoplimit</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 9504643cb8..6a2904f75f 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -539,6 +539,7 @@ typedef union {
#define SOCKET_OPT_IPV6_AUTHHDR 3
#define SOCKET_OPT_IPV6_DROP_MEMBERSHIP 6
#define SOCKET_OPT_IPV6_DSTOPTS 7
+#define SOCKET_OPT_IPV6_FLOWINFO 11
#define SOCKET_OPT_IPV6_HOPLIMIT 12
#define SOCKET_OPT_IPV6_HOPOPTS 13
#define SOCKET_OPT_IPV6_MTU 17
@@ -1219,6 +1220,11 @@ static ERL_NIF_TERM nsetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IPV6_FLOWINFO)
+static ERL_NIF_TERM nsetopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(IPV6_HOPLIMIT)
static ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1549,6 +1555,10 @@ static ERL_NIF_TERM ngetopt_lvl_ipv6_authhdr(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(IPV6_FLOWINFO)
+static ERL_NIF_TERM ngetopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IPV6_HOPLIMIT)
static ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -5597,6 +5607,12 @@ ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env,
break;
#endif
+#if defined(IPV6_FLOWINFO)
+ case SOCKET_OPT_IPV6_FLOWINFO:
+ result = nsetopt_lvl_ipv6_flowinfo(env, descP, eVal);
+ break;
+#endif
+
#if defined(IPV6_HOPLIMIT)
case SOCKET_OPT_IPV6_HOPLIMIT:
result = nsetopt_lvl_ipv6_hoplimit(env, descP, eVal);
@@ -5719,6 +5735,17 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
#endif
+#if defined(IPV6_FLOWINFO)
+static
+ERL_NIF_TERM nsetopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ return nsetopt_bool_opt(env, descP, SOL_IPV6, IPV6_FLOWINFO, eVal);
+}
+#endif
+
+
#if defined(IPV6_HOPLIMIT)
static
ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
@@ -8190,6 +8217,12 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
break;
#endif
+#if defined(IPV6_FLOWINFO)
+ case SOCKET_OPT_IPV6_FLOWINFO:
+ result = ngetopt_lvl_ipv6_flowinfo(env, descP);
+ break;
+#endif
+
#if defined(IPV6_HOPLIMIT)
case SOCKET_OPT_IPV6_HOPLIMIT:
result = ngetopt_lvl_ipv6_hoplimit(env, descP);
@@ -8284,6 +8317,16 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_dstopts(ErlNifEnv* env,
#endif
+#if defined(IPV6_FLOWINFO)
+static
+ERL_NIF_TERM ngetopt_lvl_ipv6_flowinfo(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ return ngetopt_bool_opt(env, descP, SOL_IPV6, IPV6_FLOWINFO);
+}
+#endif
+
+
#if defined(IPV6_HOPLIMIT)
static
ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env,
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 17622c5341..f0788f2378 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 2bab42267a..95bd5ce094 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -640,7 +640,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_FLOWINFO, 11).
+-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).
@@ -2263,6 +2263,9 @@ enc_setopt_value(ipv6, drop_membership, #{multiaddr := MA,
when ((is_tuple(MA) andalso (size(MA) =:= 8)) andalso
(is_integer(IF) andalso (IF >= 0))) ->
V;
+enc_setopt_value(ipv6, flowinfo, V, _D, T, _P)
+ when is_boolean(V) andalso ((T =:= dgram) orelse (T =:= raw)) ->
+ V;
enc_setopt_value(ipv6, hoplimit, V, _D, T, _P)
when is_boolean(V) andalso ((T =:= dgram) orelse (T =:= raw)) ->
V;
@@ -2702,9 +2705,9 @@ enc_sockopt_key(ipv6 = L, esp_trans_level = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ipv6 = L, esp_network_level = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
-enc_sockopt_key(ipv6 = L, flowinfo = Opt, _Dir, _D, T, _P)
+enc_sockopt_key(ipv6 = _L, flowinfo = _Opt, _Dir, _D, T, _P)
when (T =:= dgram) orelse (T =:= raw) ->
- not_supported({L, Opt});
+ ?SOCKET_OPT_IPV6_DSTOPTS;
enc_sockopt_key(ipv6, hoplimit = _Opt, _Dir, _D, T, _P)
when (T =:= dgram) orelse (T =:= raw) ->
?SOCKET_OPT_IPV6_HOPLIMIT;
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 8436b39372..a1be73593b 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -166,7 +166,7 @@ do_manager_init(Domain, dgram = Type, Proto, Peek) ->
addr => Addr},
i("try bind to: "
"~n ~p", [Addr]),
- case socket:bind(Sock, SA) of
+ case socket:bind(Sock, any) of
{ok, _P} ->
ok;
{error, BReason} ->
@@ -638,6 +638,7 @@ handler_init(Manager, ID, Peek, Sock) ->
HopLimit = GIP6(hoplimit),
HopOpts = GIP6(hopopts),
DstOpts = GIP6(dstopts),
+ FlowInfo = GIP6(flowinfo),
i("got continue when: "
"~n (socket) Domain: ~p"
"~n (socket) Type: ~p"
@@ -674,7 +675,8 @@ handler_init(Manager, ID, Peek, Sock) ->
"~n (ipv6) Auth Hdr: ~s"
"~n (ipv6) Hop Limit: ~s"
"~n (ipv6) Hop Opts: ~s"
- "~n (ipv6) Dst Opts: ~s",
+ "~n (ipv6) Dst Opts: ~s"
+ "~n (ipv6) Flow Info: ~s",
[Domain, Type, Proto,
RA, RP, B2D, OOBI,
RcvBuf, RcvLW, RcvTO, SndBuf, SndLW, SndTO,
@@ -682,7 +684,7 @@ handler_init(Manager, ID, Peek, Sock) ->
FreeBind, MTU, MTUDisc, MALL, MIF4, MLoop4, MTTL,
NF, RecvIF, RecvOPTS, RecvTOS, RecvTTL,
MHops, MIF6, MLoop6, RecvPktInfo,
- RtHdr, AuthHdr, HopLimit, HopOpts, DstOpts]),
+ RtHdr, AuthHdr, HopLimit, HopOpts, DstOpts, FlowInfo]),
handler_loop(#handler{peek = Peek,
manager = Manager,