aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-07-10 13:42:28 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commit8936b71f13b37559600afb5536ff7d7878b9ab0e (patch)
treeb128f2ffac826378b624e2e5c635e7ce1f11e1ff
parent9110ba256099e6fa55461fc4ca90da5ec4b2966b (diff)
downloadotp-8936b71f13b37559600afb5536ff7d7878b9ab0e.tar.gz
otp-8936b71f13b37559600afb5536ff7d7878b9ab0e.tar.bz2
otp-8936b71f13b37559600afb5536ff7d7878b9ab0e.zip
[socket-nif] Add support for socket (level ip) option multicast_loop
Added support for the IP option MULTICAST_LOOP. OTP-14831
-rw-r--r--erts/emulator/nifs/common/socket_nif.c89
-rw-r--r--erts/preloaded/ebin/socket.beambin43748 -> 43784 bytes
-rw-r--r--erts/preloaded/src/socket.erl127
-rw-r--r--lib/kernel/test/socket_server.erl18
4 files changed, 198 insertions, 36 deletions
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index 82468c6e8f..95f29f3dd8 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -342,9 +342,9 @@ typedef union {
#define SOCKET_OPT_LEVEL_UDP 5
#define SOCKET_OPT_LEVEL_SCTP 6
-#define SOCKET_OPT_OTP_DEBUG 0
-#define SOCKET_OPT_OTP_IOW 1
-#define SOCKET_OPT_OTP_CTRL_PROC 2
+#define SOCKET_OPT_OTP_DEBUG 1
+#define SOCKET_OPT_OTP_IOW 2
+#define SOCKET_OPT_OTP_CTRL_PROC 3
#define SOCKET_OPT_SOCK_ACCEPTCONN 1
#define SOCKET_OPT_SOCK_BROADCAST 4
@@ -362,22 +362,23 @@ typedef union {
#define SOCKET_OPT_SOCK_SNDBUF 27
#define SOCKET_OPT_SOCK_TYPE 32
-#define SOCKET_OPT_IP_RECVTOS 25
-#define SOCKET_OPT_IP_ROUTER_ALERT 28
-#define SOCKET_OPT_IP_TOS 30
-#define SOCKET_OPT_IP_TTL 32
+#define SOCKET_OPT_IP_MULTICAST_LOOP 15
+#define SOCKET_OPT_IP_RECVTOS 25
+#define SOCKET_OPT_IP_ROUTER_ALERT 28
+#define SOCKET_OPT_IP_TOS 30
+#define SOCKET_OPT_IP_TTL 32
#define SOCKET_OPT_IPV6_HOPLIMIT 12
-#define SOCKET_OPT_TCP_CONGESTION 0
-#define SOCKET_OPT_TCP_CORK 1
-#define SOCKET_OPT_TCP_MAXSEG 2
-#define SOCKET_OPT_TCP_NODELAY 3
+#define SOCKET_OPT_TCP_CONGESTION 1
+#define SOCKET_OPT_TCP_CORK 2
+#define SOCKET_OPT_TCP_MAXSEG 3
+#define SOCKET_OPT_TCP_NODELAY 4
-#define SOCKET_OPT_UDP_CORK 0
+#define SOCKET_OPT_UDP_CORK 1
-#define SOCKET_OPT_SCTP_AUTOCLOSE 7
-#define SOCKET_OPT_SCTP_NODELAY 22
+#define SOCKET_OPT_SCTP_AUTOCLOSE 8
+#define SOCKET_OPT_SCTP_NODELAY 23
/* =================================================================== *
@@ -843,6 +844,11 @@ static ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
SocketDescriptor* descP,
int eOpt,
ERL_NIF_TERM eVal);
+#if defined(IP_MULTICAST_LOOP)
+static ERL_NIF_TERM nsetopt_lvl_ip_multicast_loop(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,
@@ -1011,6 +1017,10 @@ static ERL_NIF_TERM ngetopt_lvl_sock_type(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
SocketDescriptor* descP,
int eOpt);
+#if defined(IP_MULTICAST_LOOP)
+static ERL_NIF_TERM ngetopt_lvl_ip_multicast_loop(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IP_RECVTOS)
static ERL_NIF_TERM ngetopt_lvl_ip_recvtos(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -3936,6 +3946,12 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
ERL_NIF_TERM result;
switch (eOpt) {
+#if defined(IP_MULTICAST_LOOP)
+ case SOCKET_OPT_IP_MULTICAST_LOOP:
+ result = nsetopt_lvl_ip_multicast_loop(env, descP, eVal);
+ break;
+#endif
+
#if defined(IP_RECVTOS)
case SOCKET_OPT_IP_RECVTOS:
result = nsetopt_lvl_ip_recvtos(env, descP, eVal);
@@ -3969,6 +3985,25 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
}
+/* nsetopt_lvl_ip_multicast_loop - Level IP MULTICAST_LOOP option
+ */
+#if defined(IP_MULTICAST_LOOP)
+static
+ERL_NIF_TERM nsetopt_lvl_ip_multicast_loop(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_MULTICAST_LOOP, eVal);
+}
+#endif
+
+
/* nsetopt_lvl_ip_recvtos - Level IP RECVTOS option
*/
#if defined(IP_RECVTOS)
@@ -5022,7 +5057,7 @@ ERL_NIF_TERM ngetopt_lvl_sock_linger(ErlNifEnv* env,
if (res != 0) {
result = esock_make_error_errno(env, res);
} else {
- ERL_NIF_TERM lOnOff = MKI(env, val.l_onoff);
+ ERL_NIF_TERM lOnOff = ((val.l_onoff) ? atom_true : atom_false);
ERL_NIF_TERM lSecs = MKI(env, val.l_linger);
ERL_NIF_TERM linger = MKT2(env, lOnOff, lSecs);
@@ -5196,6 +5231,12 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
ERL_NIF_TERM result;
switch (eOpt) {
+#if defined(IP_MULTICAST_LOOP)
+ case SOCKET_OPT_IP_MULTICAST_LOOP:
+ result = ngetopt_lvl_ip_multicast_loop(env, descP);
+ break;
+#endif
+
#if defined(IP_RECVTOS)
case SOCKET_OPT_IP_RECVTOS:
result = ngetopt_lvl_ip_recvtos(env, descP);
@@ -5229,6 +5270,24 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
}
+/* ngetopt_lvl_ip_multicast_loop - Level IP MULTICAST_LOOP option
+ */
+#if defined(IP_RECVTOS)
+static
+ERL_NIF_TERM ngetopt_lvl_ip_multicast_loop(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_MULTICAST_LOOP);
+}
+#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 4e8c848539..0f49c421fa 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 278a3f17ad..d2ed733b3c 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -460,9 +460,9 @@
-define(SOCKET_OPT_LEVEL_UDP, 5).
-define(SOCKET_OPT_LEVEL_SCTP, 6).
--define(SOCKET_OPT_OTP_DEBUG, 0).
--define(SOCKET_OPT_OTP_IOW, 1).
--define(SOCKET_OPT_OTP_CTRL_PROC, 2).
+-define(SOCKET_OPT_OTP_DEBUG, 1).
+-define(SOCKET_OPT_OTP_IOW, 2).
+-define(SOCKET_OPT_OTP_CTRL_PROC, 3).
-define(SOCKET_OPT_SOCK_ACCEPTCONN, 1).
%% -define(SOCKET_OPT_SOCK_ACCEPTFILTER, 2).
@@ -497,22 +497,112 @@
%% -define(SOCKET_OPT_SOCK_TIMESTAMP, 31).
-define(SOCKET_OPT_SOCK_TYPE, 32).
--define(SOCKET_OPT_IP_RECVTOS, 25).
--define(SOCKET_OPT_IP_ROUTER_ALERT, 28).
--define(SOCKET_OPT_IP_TOS, 30).
--define(SOCKET_OPT_IP_TTL, 32).
-
--define(SOCKET_OPT_IPV6_HOPLIMIT, 12).
-
--define(SOCKET_OPT_TCP_CONGESTION, 0).
+%% -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_DONT_FRAG, 4).
+%% -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_MTU, 11).
+%% -define(SOCKET_OPT_IP_MTU_DISCOVER, 12).
+%% -define(SOCKET_OPT_IP_MULTICAST_ALL, 13).
+%% -define(SOCKET_OPT_IP_MULTICAST_IF, 14).
+-define(SOCKET_OPT_IP_MULTICAST_LOOP, 15).
+%% -define(SOCKET_OPT_IP_MULTICAST_TTL, 16).
+%% -define(SOCKET_OPT_IP_NODEFRAG, 17).
+%% -define(SOCKET_OPT_IP_OPTIONS, 18).
+%% -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_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).
+-define(SOCKET_OPT_IP_ROUTER_ALERT, 28).
+%% -define(SOCKET_OPT_IP_SNDSRCADDR, 29).
+-define(SOCKET_OPT_IP_TOS, 30).
+%% -define(SOCKET_OPT_IP_TRANSPARENT, 31).
+-define(SOCKET_OPT_IP_TTL, 32).
+-define(SOCKET_OPT_IP_UNBLOCK_SOURCE, 33).
+
+%% -define(SOCKET_OPT_IPV6_ADDFORM, 1).
+%% -define(SOCKET_OPT_IPV6_ADD_MEMBERSHIP, 2).
+%% -define(SOCKET_OPT_IPV6_AUTHHDR, 3).
+%% -define(SOCKET_OPT_IPV6_AUTH_LEVEL, 4).
+%% -define(SOCKET_OPT_IPV6_CHECKSUM, 5).
+%% -define(SOCKET_OPT_IPV6_DROP_MEMBERSHIP, 6).
+%% -define(SOCKET_OPT_IPV6_DSTOPTS, 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_HOPLIMIT, 12).
+%% -define(SOCKET_OPT_IPV6_HOPOPTS, 13).
+%% -define(SOCKET_OPT_IPV6_IPCOMP_LEVEL, 14).
+%% -define(SOCKET_OPT_IPV6_JOIN_GROUP, 15).
+%% -define(SOCKET_OPT_IPV6_LEAVE_GROUP, 16).
+%% -define(SOCKET_OPT_IPV6_MTU, 17).
+%% -define(SOCKET_OPT_IPV6_MTU_DISCOVER, 18).
+%% -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_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_TCP_CONGESTION, 1).
-define(SOCKET_OPT_TCP_CORK, 2).
-define(SOCKET_OPT_TCP_MAXSEG, 3).
-define(SOCKET_OPT_TCP_NODELAY, 4).
--define(SOCKET_OPT_UDP_CORK, 0).
-
--define(SOCKET_OPT_SCTP_AUTOCLOSE, 7).
--define(SOCKET_OPT_SCTP_NODELAY, 22).
+-define(SOCKET_OPT_UDP_CORK, 1).
+
+%% -define(SOCKET_OPT_SCTP_ADAPTION_LAYER, 1).
+%% -define(SOCKET_OPT_SCTP_ASSOCINFO, 2).
+%% -define(SOCKET_OPT_SCTP_AUTH_ACTIVE_KEY, 3).
+%% -define(SOCKET_OPT_SCTP_AUTH_ASCONF, 4).
+%% -define(SOCKET_OPT_SCTP_AUTH_CHUNK, 5).
+%% -define(SOCKET_OPT_SCTP_AUTH_KEY, 6).
+%% -define(SOCKET_OPT_SCTP_AUTH_DELETE_KEY, 7).
+-define(SOCKET_OPT_SCTP_AUTOCLOSE, 8).
+%% -define(SOCKET_OPT_SCTP_CONTEXT, 9).
+%% -define(SOCKET_OPT_SCTP_DEFAULT_SEND_PARAMS, 10).
+%% -define(SOCKET_OPT_SCTP_DELAYED_ACK_TIME, 11).
+%% -define(SOCKET_OPT_SCTP_DISABLE_FRAGMENTS, 12).
+%% -define(SOCKET_OPT_SCTP_HMAC_IDENT, 13).
+%% -define(SOCKET_OPT_SCTP_EXPLICIT_EOR, 14).
+%% -define(SOCKET_OPT_SCTP_FRAGMENT_INTERLEAVE, 15).
+%% -define(SOCKET_OPT_SCTP_GET_PEER_ADDR_INFO, 16).
+%% -define(SOCKET_OPT_SCTP_INITMSG, 17).
+%% -define(SOCKET_OPT_SCTP_I_WANT_MAPPED_V4_ADDR, 18).
+%% -define(SOCKET_OPT_SCTP_LOCAL_AUTH_CHUNKS, 19).
+%% -define(SOCKET_OPT_SCTP_MAXSEG, 20).
+%% -define(SOCKET_OPT_SCTP_MAXBURST, 21).
+-define(SOCKET_OPT_SCTP_NODELAY, 22).
+%% -define(SOCKET_OPT_SCTP_PARTIAL_DELIVERY_POINT, 23).
+%% -define(SOCKET_OPT_SCTP_PEER_ADDR_PARAMS, 24).
+%% -define(SOCKET_OPT_SCTP_PEER_AUTH_CHUNKS, 25).
+%% -define(SOCKET_OPT_SCTP_PRIMARY_ADDR, 26).
+%% -define(SOCKET_OPT_SCTP_RESET_STREAMS, 27).
+%% -define(SOCKET_OPT_SCTP_RTOINFO, 28).
+%% -define(SOCKET_OPT_SCTP_SET_PEER_PRIMARY_ADDR, 29).
+%% -define(SOCKET_OPT_SCTP_STATUS, 30).
+%% -define(SOCKET_OPT_SCTP_USE_EXT_RECVINFO, 31).
-define(SOCKET_SHUTDOWN_HOW_READ, 0).
-define(SOCKET_SHUTDOWN_HOW_WRITE, 1).
@@ -1865,6 +1955,9 @@ enc_setopt_value(socket, sndbuf, V, _D, _T, _P) when is_integer(V) ->
enc_setopt_value(socket = L, Opt, V, _D, _T, _P) ->
not_supported({L, Opt, V});
+enc_setopt_value(ip, multicast_loop, V, _D, _T, _P)
+ when is_boolean(V) ->
+ V;
enc_setopt_value(ip, recvtos, V, _D, _T, _P)
when is_boolean(V) ->
V;
@@ -2157,8 +2250,8 @@ enc_sockopt_key(ip = L, multicast_all = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ip = L, multicast_if = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
-enc_sockopt_key(ip = L, multicast_loop = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
+enc_sockopt_key(ip = _L, multicast_loop = _Opt, _Dir, _D, _T, _P) ->
+ ?SOCKET_OPT_IP_MULTICAST_LOOP;
enc_sockopt_key(ip = L, multicast_ttl = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
enc_sockopt_key(ip = L, nodefrag = Opt, _Dir, _D, raw = _T, _P) ->
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index da5a2ca905..9c6ef47fbc 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -439,11 +439,21 @@ handler_init(Manager, ID, Peek, Sock) ->
{ok, Type} = socket:getopt(Sock, socket, type),
{ok, Proto} = socket:getopt(Sock, socket, protocol),
{ok, OOBI} = socket:getopt(Sock, socket, oobinline),
+ {ok, SndBuf} = socket:getopt(Sock, socket, sndbuf),
+ {ok, RcvBuf} = socket:getopt(Sock, socket, rcvbuf),
+ {ok, Linger} = socket:getopt(Sock, socket, linger),
+ {ok, ML} = socket:getopt(Sock, ip, multicast_loop),
i("got continue when: "
- "~n Domain: ~p"
- "~n Type: ~p"
- "~n Protocol: ~p"
- "~n OOBInline: ~p", [Domain, Type, Proto, OOBI]),
+ "~n (socket) Domain: ~p"
+ "~n (socket) Type: ~p"
+ "~n (socket) Protocol: ~p"
+ "~n (socket) OOBInline: ~p"
+ "~n (socket) SndBuf: ~p"
+ "~n (socket) RcvBuf: ~p"
+ "~n (socket) Linger: ~p"
+ "~n (ip) Multicast Loop: ~p",
+ [Domain, Type, Proto,
+ OOBI, SndBuf, RcvBuf, Linger, ML]),
%% socket:setopt(Sock, otp, debug, true),
handler_loop(#handler{peek = Peek,
manager = Manager,