aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-07-25 11:28:49 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commit5d9de1cdc46c75117f15f1ab17f017cdb700eb4c (patch)
tree9f86c5e9f9593e395a08d844f13b6ff4b8d65904 /erts/preloaded
parent4e24993aff4c5a0cb2bec96e5499131a660a79f9 (diff)
downloadotp-5d9de1cdc46c75117f15f1ab17f017cdb700eb4c.tar.gz
otp-5d9de1cdc46c75117f15f1ab17f017cdb700eb4c.tar.bz2
otp-5d9de1cdc46c75117f15f1ab17f017cdb700eb4c.zip
[socket-nif] Add support for socket (level ip) option msfilter
Added support for ip level socket option MSFILTER. This option has not been tested *in any way*... OTP-14831
Diffstat (limited to 'erts/preloaded')
-rw-r--r--erts/preloaded/ebin/socket.beambin58080 -> 59008 bytes
-rw-r--r--erts/preloaded/src/socket.erl40
2 files changed, 36 insertions, 4 deletions
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 8ca75307bc..14ee41257b 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 5695e45ac5..acda4e3811 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -94,6 +94,8 @@
ip_mreq/0,
ip_mreq_source/0,
ip_pmtudisc/0,
+ ip_msfilter_mode/0,
+ ip_msfilter/0,
ipv6_mreq/0,
ipv6_pmtudisc/0,
sctp_event_subscribe/0,
@@ -196,6 +198,17 @@
-type ip_pmtudisc() :: want | dont | do | probe.
+%% multiaddr: Multicast group address
+%% interface: Address of local interface
+%% mode: Filter mode
+%% slist: List of source addresses
+-type ip_msfilter_mode() :: include | exclude.
+
+-type ip_msfilter() :: #{multiaddr => ip4_address(),
+ interface => ip4_address(),
+ mode => ip_msfilter_mode(),
+ slist => [ip4_address()]}.
+
-type ipv6_mreq() :: #{multiaddr := ip6_address(),
interface := non_neg_integer()}.
@@ -604,13 +617,13 @@
-define(SOCKET_OPT_IP_ADD_MEMBERSHIP, 1).
-define(SOCKET_OPT_IP_ADD_SOURCE_MEMBERSHIP, 2).
-define(SOCKET_OPT_IP_BLOCK_SOURCE, 3).
-%% -define(SOCKET_OPT_IP_DONTFRAG, 4).
+%% -define(SOCKET_OPT_IP_DONTFRAG, 4). % FreeBSD
-define(SOCKET_OPT_IP_DROP_MEMBERSHIP, 5).
-define(SOCKET_OPT_IP_DROP_SOURCE_MEMBERSHIP, 6).
-define(SOCKET_OPT_IP_FREEBIND, 7).
%% -define(SOCKET_OPT_IP_HDRINCL, 8).
-define(SOCKET_OPT_IP_MINTTL, 9).
-%% -define(SOCKET_OPT_IP_MSFILTER, 10).
+-define(SOCKET_OPT_IP_MSFILTER, 10).
-define(SOCKET_OPT_IP_MTU, 11).
-define(SOCKET_OPT_IP_MTU_DISCOVER, 12).
-define(SOCKET_OPT_IP_MULTICAST_ALL, 13).
@@ -2197,6 +2210,18 @@ enc_setopt_value(ip, freebind, V, _D, _T, _P) when is_boolean(V) ->
V;
enc_setopt_value(ip, minttl, V, _D, _T, _P) when is_integer(V) ->
V;
+enc_setopt_value(ip, msfilter, null = V, _D, _T, _P) ->
+ V;
+enc_setopt_value(ip, msfilter, #{multiaddr := MA,
+ interface := IF,
+ fmode := FMode,
+ slist := SL} = V, _D, _T, _P)
+ when (is_tuple(MA) andalso (size(MA) =:= 4)) andalso
+ (is_tuple(IF) andalso (size(IF) =:= 4)) andalso
+ ((FMode =:= include) orelse (FMode =:= exclude)) andalso
+ is_list(SL) ->
+ ensure_ip_msfilter_slist(SL),
+ V;
enc_setopt_value(ip, mtu_discover, V, _D, _T, _P)
when (V =:= want) orelse
(V =:= dont) orelse
@@ -2656,8 +2681,8 @@ enc_sockopt_key(ip = L, hdrincl = Opt, _Dir, _D, raw = _T, _P) ->
%% FreeBSD only?
enc_sockopt_key(ip = _L, minttl = _Opt, _Dir, _D, raw = _T, _P) ->
?SOCKET_OPT_IP_MINTTL;
-enc_sockopt_key(ip = L, msfilter = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
+enc_sockopt_key(ip = _L, msfilter = _Opt, set = _Dir, _D, _T, _P) ->
+ ?SOCKET_OPT_IP_MSFILTER;
enc_sockopt_key(ip = _L, mtu = _Opt, get = _Dir, _D, _T, _P) ->
?SOCKET_OPT_IP_MTU;
enc_sockopt_key(ip = _L, mtu_discover = _Opt, _Dir, _D, _T, _P) ->
@@ -2922,6 +2947,13 @@ enc_shutdown_how(read_write) ->
%%
%% ===========================================================================
+ensure_ip_msfilter_slist(SL) ->
+ EnsureSA = fun(SA) when is_tuple(SA) andalso (size(SA) =:= 4) -> ok;
+ (_) -> einval()
+ end,
+ lists:foreach(EnsureSA, SL).
+
+
ensure_sockaddr(#{family := inet} = SockAddr) ->
maps:merge(?SOCKADDR_IN4_DEFAULTS, SockAddr);
ensure_sockaddr(#{family := inet6} = SockAddr) ->