From ebd626e7b4259bdfb4ddb34ce2d298d0feb0a1c8 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 18 Jul 2018 11:33:50 +0200 Subject: [socket-nif] Add support for socket (level ipv6) option mtu Added support for the VPv6 socket option MTU. OTP-14831. --- erts/doc/src/socket_usage.xml | 14 +++++++++++ erts/emulator/nifs/common/socket_nif.c | 44 +++++++++++++++++++++++++++++++++ erts/preloaded/ebin/socket.beam | Bin 51436 -> 51480 bytes erts/preloaded/src/socket.erl | 8 +++--- lib/kernel/test/socket_client.erl | 2 +- lib/kernel/test/socket_server.erl | 30 ++++++++++++++++++---- 6 files changed, 89 insertions(+), 9 deletions(-) diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml index b4880c3989..cdd98090e8 100644 --- a/erts/doc/src/socket_usage.xml +++ b/erts/doc/src/socket_usage.xml @@ -369,6 +369,20 @@ no type = dgram | raw + + mtu + boolean() + yes + yes + Get: Only after the socket has been connected + + + v6only + boolean() + yes + no + none +

Options for level tcp:

diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index 15d43da9da..0222d58e6d 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -388,6 +388,7 @@ typedef union { #define SOCKET_OPT_IPV6_ADD_MEMBERSHIP 2 #define SOCKET_OPT_IPV6_DROP_MEMBERSHIP 6 #define SOCKET_OPT_IPV6_HOPLIMIT 12 +#define SOCKET_OPT_IPV6_MTU 17 #define SOCKET_OPT_IPV6_V6ONLY 33 #define SOCKET_OPT_TCP_CONGESTION 1 @@ -1008,6 +1009,11 @@ static ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env, SocketDescriptor* descP, ERL_NIF_TERM eVal); #endif +#if defined(IPV6_MTU) +static ERL_NIF_TERM nsetopt_lvl_ipv6_mtu(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, @@ -1227,12 +1233,17 @@ static ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env, static ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env, SocketDescriptor* descP); #endif +#if defined(IPV6_MTU) +static ERL_NIF_TERM ngetopt_lvl_ipv6_mtu(ErlNifEnv* env, + SocketDescriptor* descP); +#endif #if defined(IPV6_V6ONLY) static ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env, SocketDescriptor* descP); #endif #endif // defined(SOL_IPV6) + static ERL_NIF_TERM ngetopt_lvl_tcp(ErlNifEnv* env, SocketDescriptor* descP, int eOpt); @@ -4960,6 +4971,12 @@ ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env, break; #endif +#if defined(IPV6_MTU) + case SOCKET_OPT_IPV6_MTU: + result = nsetopt_lvl_ipv6_mtu(env, descP, eVal); + break; +#endif + #if defined(IPV6_V6ONLY) case SOCKET_OPT_IPV6_V6ONLY: result = nsetopt_lvl_ipv6_v6only(env, descP, eVal); @@ -5010,6 +5027,17 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env, #endif +#if defined(IPV6_MTU) +static +ERL_NIF_TERM nsetopt_lvl_ipv6_mtu(ErlNifEnv* env, + SocketDescriptor* descP, + ERL_NIF_TERM eVal) +{ + return nsetopt_int_opt(env, descP, SOL_IPV6, IPV6_MTU, eVal); +} +#endif + + #if defined(IPV6_V6ONLY) static ERL_NIF_TERM nsetopt_lvl_ipv6_v6only(ErlNifEnv* env, @@ -6697,6 +6725,12 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env, break; #endif +#if defined(IPV6_MTU) + case SOCKET_OPT_IPV6_MTU: + result = ngetopt_lvl_ipv6_mtu(env, descP); + break; +#endif + #if defined(IPV6_V6ONLY) case SOCKET_OPT_IPV6_V6ONLY: result = ngetopt_lvl_ipv6_v6only(env, descP); @@ -6727,6 +6761,16 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env, #endif +#if defined(IPV6_MTU) +static +ERL_NIF_TERM ngetopt_lvl_ipv6_mtu(ErlNifEnv* env, + SocketDescriptor* descP) +{ + return ngetopt_int_opt(env, descP, SOL_IPV6, IPV6_MTU); +} +#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 307a94be4e..7ab8b0b3c4 100644 Binary files a/erts/preloaded/ebin/socket.beam and b/erts/preloaded/ebin/socket.beam differ diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index 3e31326759..41df672ef5 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -586,7 +586,7 @@ %% -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, 17). %% -define(SOCKET_OPT_IPV6_MTU_DISCOVER, 18). %% -define(SOCKET_OPT_IPV6_MULTICAST_HOPS, 19). %% -define(SOCKET_OPT_IPV6_MULTICAST_IF, 20). @@ -2105,6 +2105,8 @@ enc_setopt_value(ipv6, drop_membership, #{multiaddr := MA, enc_setopt_value(ipv6, hoplimit, V, _D, T, _P) when is_boolean(V) andalso ((T =:= dgram) orelse (T =:= raw)) -> V; +enc_setopt_value(ipv6, mtu, V, _D, _T, _P) when is_integer(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) -> @@ -2458,8 +2460,8 @@ enc_sockopt_key(ipv6 = L, join_group = Opt, _Dir, _D, _T, _P) -> not_supported({L, Opt}); enc_sockopt_key(ipv6 = L, leave_group = Opt, _Dir, _D, _T, _P) -> not_supported({L, Opt}); -enc_sockopt_key(ipv6 = L, mtu = Opt, _Dir, _D, _T, _P) -> - not_supported({L, Opt}); +enc_sockopt_key(ipv6 = _L, mtu = _Opt, _Dir, _D, _T, _P) -> + ?SOCKET_OPT_IPV6_MTU; enc_sockopt_key(ipv6 = L, mtu_discover = Opt, _Dir, _D, _T, _P) -> not_supported({L, Opt}); enc_sockopt_key(ipv6 = L, multicast_hops = Opt, _Dir, _D, _T, _P) -> diff --git a/lib/kernel/test/socket_client.erl b/lib/kernel/test/socket_client.erl index 8ec9a02374..0d332e8439 100644 --- a/lib/kernel/test/socket_client.erl +++ b/lib/kernel/test/socket_client.erl @@ -21,7 +21,7 @@ -module(socket_client). -export([ - start/1, + start/1, start/5, start_tcp/1, start_tcp/2, start_tcp6/1, start_udp/1, start_udp/2, start_udp6/1 ]). diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl index 8a77b9b3c9..65069df60b 100644 --- a/lib/kernel/test/socket_server.erl +++ b/lib/kernel/test/socket_server.erl @@ -22,8 +22,10 @@ -export([ start/0, start/4, - start_tcp/0, start_tcp/1, - start_udp/0, start_udp/1 + start_tcp/0, start_tcp/1, start_tcp/2, + start_tcp4/1, start_tcp6/1, + start_udp/0, start_udp/1, start_udp/2, + start_udp4/1, start_udp6/1 ]). -define(LIB, socket_lib). @@ -41,13 +43,31 @@ start_tcp() -> start_tcp(false). start_tcp(Peek) -> - start(inet, stream, tcp, Peek). + start_tcp4(Peek). + +start_tcp4(Peek) -> + start_tcp(inet, Peek). + +start_tcp6(Peek) -> + start_tcp(inet6, Peek). + +start_tcp(Domain, Peek) when is_boolean(Peek) -> + start(Domain, stream, tcp, Peek). start_udp() -> start_udp(false). -start_udp(Peek) when is_boolean(Peek) -> - start(inet, dgram, udp, Peek). +start_udp(Peek) -> + start_udp4(Peek). + +start_udp4(Peek) -> + start_udp(inet, Peek). + +start_udp6(Peek) -> + start_udp(inet6, Peek). + +start_udp(Domain, Peek) when is_boolean(Peek) -> + start(Domain, dgram, udp, Peek). start(Domain, Type, Proto, Peek) -> put(sname, "starter"), -- cgit v1.2.3