aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-07-23 18:26:42 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commitde82310c32063b8556add3fe7cf62b26eef27841 (patch)
tree7f07bf03f590fabe32b482a2c1a7ff2739dbe071
parent4d14b84183c3c17f0ec03bf3631f1fd8575f07b9 (diff)
downloadotp-de82310c32063b8556add3fe7cf62b26eef27841.tar.gz
otp-de82310c32063b8556add3fe7cf62b26eef27841.tar.bz2
otp-de82310c32063b8556add3fe7cf62b26eef27841.zip
[socket-nif] Add support for socket (level ipv6) option recvpktinfo
Added support for the IPv6 socket option RECVPKTINFO. This option is called PKTINFO on FreeBSD, so that value will also be accepted. OTP-14831.
-rw-r--r--erts/doc/src/socket_usage.xml7
-rw-r--r--erts/emulator/nifs/common/socket_nif.c56
-rw-r--r--erts/preloaded/ebin/socket.beambin56980 -> 57144 bytes
-rw-r--r--erts/preloaded/src/socket.erl36
-rw-r--r--lib/kernel/test/socket_server.erl10
5 files changed, 88 insertions, 21 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index af21806243..78662e7d0d 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -468,6 +468,13 @@
<cell>none</cell>
</row>
<row>
+ <cell>recvpktinfo | pktinfo</cell>
+ <cell>boolean()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>type = dgram | raw</cell>
+ </row>
+ <row>
<cell>v6only</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 218ed66f52..35997c359d 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -543,7 +543,8 @@ typedef union {
#define SOCKET_OPT_IPV6_MULTICAST_HOPS 19
#define SOCKET_OPT_IPV6_MULTICAST_IF 20
#define SOCKET_OPT_IPV6_MULTICAST_LOOP 21
-#define SOCKET_OPT_IPV6_V6ONLY 33
+#define SOCKET_OPT_IPV6_RECVPKTINFO 25 // PKTINFO on FreeBSD
+#define SOCKET_OPT_IPV6_V6ONLY 32
#define SOCKET_OPT_TCP_CONGESTION 1
#define SOCKET_OPT_TCP_CORK 2
@@ -1234,6 +1235,11 @@ static ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
+static ERL_NIF_TERM nsetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(IPV6_V6ONLY)
static ERL_NIF_TERM nsetopt_lvl_ipv6_v6only(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1535,6 +1541,10 @@ static ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_if(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
+static ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IPV6_V6ONLY)
static ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -5556,6 +5566,12 @@ ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env,
break;
#endif
+#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
+ case SOCKET_OPT_IPV6_RECVPKTINFO:
+ result = nsetopt_lvl_ipv6_recvpktinfo(env, descP, eVal);
+ break;
+#endif
+
#if defined(IPV6_V6ONLY)
case SOCKET_OPT_IPV6_V6ONLY:
result = nsetopt_lvl_ipv6_v6only(env, descP, eVal);
@@ -5688,6 +5704,22 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
#endif
+#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
+static
+ERL_NIF_TERM nsetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+#if defined(IPV6_RECVPKTINFO)
+ int opt = IPV6_RECVPKTINFO;
+#else
+ int opt = IPV6_PKTINFO;
+#endif
+
+ return nsetopt_bool_opt(env, descP, SOL_IPV6, opt, eVal);
+}
+#endif
+
#if defined(IPV6_V6ONLY)
static
@@ -8052,6 +8084,12 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env,
break;
#endif
+#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
+ case SOCKET_OPT_IPV6_RECVPKTINFO:
+ result = ngetopt_lvl_ipv6_recvpktinfo(env, descP);
+ break;
+#endif
+
#if defined(IPV6_V6ONLY)
case SOCKET_OPT_IPV6_V6ONLY:
result = ngetopt_lvl_ipv6_v6only(env, descP);
@@ -8151,6 +8189,22 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env,
#endif
+#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO)
+static
+ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+#if defined(IPV6_RECVPKTINFO)
+ int opt = IPV6_RECVPKTINFO;
+#else
+ int opt = IPV6_PKTINFO;
+#endif
+
+ return ngetopt_bool_opt(env, descP, SOL_IPV6, opt);
+}
+#endif
+
+
#if defined(IPV6_V6ONLY)
static
ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env,
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 5decdd72c2..15bc762ae9 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 7f160207b1..7e9b61ba8f 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -376,10 +376,9 @@
multicast_if |
multicast_loop |
portrange |
- pktinfo |
pktoptions |
recverr |
- recvpktinfo |
+ recvpktinfo | pktinfo |
recvtclass |
router_alert |
rthdr |
@@ -653,17 +652,16 @@
-define(SOCKET_OPT_IPV6_MULTICAST_IF, 20).
-define(SOCKET_OPT_IPV6_MULTICAST_LOOP, 21).
%% -define(SOCKET_OPT_IPV6_PORTRANGE, 22).
-%% -define(SOCKET_OPT_IPV6_PKTINFO, 23).
-%% -define(SOCKET_OPT_IPV6_PKTOPTIONS, 24).
-%% -define(SOCKET_OPT_IPV6_RECVERR, 25).
-%% -define(SOCKET_OPT_IPV6_RECVPKTINFO, 26).
-%% -define(SOCKET_OPT_IPV6_RECVTCLASS, 27).
-%% -define(SOCKET_OPT_IPV6_ROUTER_ALERT, 28).
-%% -define(SOCKET_OPT_IPV6_RTHDR, 29).
-%% -define(SOCKET_OPT_IPV6_TCLASS, 30).
-%% -define(SOCKET_OPT_IPV6_UNICAST_HOPS, 31).
-%% -define(SOCKET_OPT_IPV6_USE_MIN_MTU, 32).
--define(SOCKET_OPT_IPV6_V6ONLY, 33).
+%% -define(SOCKET_OPT_IPV6_PKTOPTIONS, 23).
+%% -define(SOCKET_OPT_IPV6_RECVERR, 24).
+-define(SOCKET_OPT_IPV6_RECVPKTINFO, 25). % On FreeBSD: PKTINFO
+%% -define(SOCKET_OPT_IPV6_RECVTCLASS, 26).
+%% -define(SOCKET_OPT_IPV6_ROUTER_ALERT, 27).
+%% -define(SOCKET_OPT_IPV6_RTHDR, 28).
+%% -define(SOCKET_OPT_IPV6_TCLASS, 29).
+%% -define(SOCKET_OPT_IPV6_UNICAST_HOPS, 30).
+%% -define(SOCKET_OPT_IPV6_USE_MIN_MTU, 31).
+-define(SOCKET_OPT_IPV6_V6ONLY, 32).
-define(SOCKET_OPT_TCP_CONGESTION, 1).
-define(SOCKET_OPT_TCP_CORK, 2).
@@ -2280,6 +2278,10 @@ enc_setopt_value(ipv6, multicast_if, V, _D, _T, _P)
enc_setopt_value(ipv6, multicast_loop, V, _D, _T, _P)
when is_boolean(V) ->
V;
+enc_setopt_value(ipv6, Opt, V, _D, _T, _P)
+ when ((Opt =:= recvpktinfo) orelse (Opt =:= pktinfo)) andalso
+ is_boolean(V) ->
+ V;
enc_setopt_value(ipv6, v6only, V, _D, _T, _P) when is_boolean(V) ->
V;
enc_setopt_value(ipv6 = L, Opt, V, _D, _T, _P) ->
@@ -2713,14 +2715,14 @@ enc_sockopt_key(ipv6 = _L, multicast_loop = _Opt, _Dir, _D, _T, _P) ->
?SOCKET_OPT_IPV6_MULTICAST_LOOP;
enc_sockopt_key(ipv6 = L, portrange = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
-enc_sockopt_key(ipv6 = L, pktinfo = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
enc_sockopt_key(ipv6 = L, pktoptions = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ipv6 = L, recverr = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
-enc_sockopt_key(ipv6 = L, recvpktinfo = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
+enc_sockopt_key(ipv6 = _L, Opt, _Dir, _D, T, _P)
+ when ((Opt =:= recvpktinfo) orelse (Opt =:= pktinfo)) andalso
+ ((T =:= dgram) orelse (T =:= raw)) ->
+ ?SOCKET_OPT_IPV6_RECVPKTINFO;
enc_sockopt_key(ipv6 = L, recvtclass = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ipv6 = L, router_alert = Opt, _Dir, _D, _T, _P) ->
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index f3f397aa20..ba74964ed1 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -154,7 +154,7 @@ do_manager_init(Domain, dgram = Type, Proto, Peek) ->
addr => Addr},
i("try bind to: "
"~n ~p", [Addr]),
- case socket:bind(Sock, any) of
+ case socket:bind(Sock, SA) of
{ok, _P} ->
ok;
{error, BReason} ->
@@ -620,6 +620,7 @@ handler_init(Manager, ID, Peek, Sock) ->
MHops = GIP6(multicast_hops),
MIF6 = GIP6(multicast_if), % Only dgram and raw
MLoop6 = GIP6(multicast_loop),
+ RecvPktInfo = GIP6(recvpktinfo),
i("got continue when: "
"~n (socket) Domain: ~p"
"~n (socket) Type: ~p"
@@ -650,14 +651,16 @@ handler_init(Manager, ID, Peek, Sock) ->
"~n (ip) Recv TTL: ~s"
"~n (ipv6) Multicast Hops: ~s"
"~n (ipv6) Multicast IF: ~s"
- "~n (ipv6) Multicast Loop: ~s",
+ "~n (ipv6) Multicast Loop: ~s"
+ "~n (ipv6) Recv Pkt Info: ~s",
[Domain, Type, Proto,
RA, RP, B2D, OOBI,
RcvBuf, RcvLW, RcvTO, SndBuf, SndLW, SndTO,
Linger, Timestamp,
FreeBind, MTU, MTUDisc, MALL, MIF4, MLoop4, MTTL,
NF, RecvIF, RecvOPTS, RecvTOS, RecvTTL,
- MHops, MIF6, MLoop6]),
+ MHops, MIF6, MLoop6,
+ RecvPktInfo]),
handler_loop(#handler{peek = Peek,
manager = Manager,
@@ -665,6 +668,7 @@ handler_init(Manager, ID, Peek, Sock) ->
socket = Sock})
end.
+
handler_loop(H) ->
i("try read message"),
case recv(H) of