diff options
author | Micael Karlberg <[email protected]> | 2018-07-23 10:57:25 +0200 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2018-09-18 14:50:18 +0200 |
commit | 31ef72ceda0bf5bba902bf18f3b445950516d6af (patch) | |
tree | 30a33b29731cb246554ba90ac07527151a22939e | |
parent | 1c26ae984a79224ce64b40dbc7239bf9721bb096 (diff) | |
download | otp-31ef72ceda0bf5bba902bf18f3b445950516d6af.tar.gz otp-31ef72ceda0bf5bba902bf18f3b445950516d6af.tar.bz2 otp-31ef72ceda0bf5bba902bf18f3b445950516d6af.zip |
[socket-nif] Add support for socket (level ip) option recvopts
Added support for ip level socket option RECVOPTS.
OTP-14831
-rw-r--r-- | erts/doc/src/socket_usage.xml | 7 | ||||
-rw-r--r-- | erts/emulator/nifs/common/socket_nif.c | 91 | ||||
-rw-r--r-- | erts/preloaded/ebin/socket.beam | bin | 56564 -> 56604 bytes | |||
-rw-r--r-- | erts/preloaded/src/socket.erl | 9 | ||||
-rw-r--r-- | lib/kernel/test/socket_server.erl | 8 |
5 files changed, 109 insertions, 6 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml index a286171a1b..eb1cbf6984 100644 --- a/erts/doc/src/socket_usage.xml +++ b/erts/doc/src/socket_usage.xml @@ -359,6 +359,13 @@ <cell>type = dgram | raw</cell> </row> <row> + <cell>recvopts</cell> + <cell>boolean()</cell> + <cell>yes</cell> + <cell>yes</cell> + <cell>type =/= stream</cell> + </row> + <row> <cell>recvttl</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 f319f171ad..7e4504cd2d 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -527,6 +527,7 @@ typedef union { #define SOCKET_OPT_IP_MULTICAST_TTL 16 #define SOCKET_OPT_IP_NODEFRAG 17 #define SOCKET_OPT_IP_RECVIF 21 +#define SOCKET_OPT_IP_RECVOPTS 23 #define SOCKET_OPT_IP_RECVTOS 25 #define SOCKET_OPT_IP_RECVTTL 26 #define SOCKET_OPT_IP_ROUTER_ALERT 28 @@ -1127,6 +1128,16 @@ static ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env, SocketDescriptor* descP, ERL_NIF_TERM eVal); #endif +#if defined(IP_RECVIF) +static ERL_NIF_TERM nsetopt_lvl_ip_recvif(ErlNifEnv* env, + SocketDescriptor* descP, + ERL_NIF_TERM eVal); +#endif +#if defined(IP_RECVOPTS) +static ERL_NIF_TERM nsetopt_lvl_ip_recvopts(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, @@ -1450,6 +1461,14 @@ static ERL_NIF_TERM ngetopt_lvl_ip_multicast_ttl(ErlNifEnv* env, static ERL_NIF_TERM ngetopt_lvl_ip_nodefrag(ErlNifEnv* env, SocketDescriptor* descP); #endif +#if defined(IP_RECVIF) +static ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env, + SocketDescriptor* descP); +#endif +#if defined(IP_RECVOPTS) +static ERL_NIF_TERM ngetopt_lvl_ip_recvopts(ErlNifEnv* env, + SocketDescriptor* descP); +#endif #if defined(IP_RECVTOS) static ERL_NIF_TERM ngetopt_lvl_ip_recvtos(ErlNifEnv* env, SocketDescriptor* descP); @@ -4802,6 +4821,12 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env, break; #endif +#if defined(IP_RECVOPTS) + case SOCKET_OPT_IP_RECVOPTS: + result = nsetopt_lvl_ip_recvopts(env, descP, eVal); + break; +#endif + #if defined(IP_RECVTOS) case SOCKET_OPT_IP_RECVTOS: result = nsetopt_lvl_ip_recvtos(env, descP, eVal); @@ -5148,7 +5173,7 @@ ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env, #endif -/* nsetopt_lvl_ip_recvif - Level IP RECVIFxs option +/* nsetopt_lvl_ip_recvif - Level IP RECVIF option */ #if defined(IP_RECVIF) static @@ -5167,6 +5192,25 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvif(ErlNifEnv* env, #endif +/* nsetopt_lvl_ip_recvopts - Level IP RECVOPTS option + */ +#if defined(IP_RECVOPTS) +static +ERL_NIF_TERM nsetopt_lvl_ip_recvopts(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_RECVOPTS, eVal); +} +#endif + + /* nsetopt_lvl_ip_recvtos - Level IP RECVTOS option */ #if defined(IP_RECVTOS) @@ -6672,6 +6716,11 @@ ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env, { ERL_NIF_TERM result; + SSDBG( descP, + ("SOCKET", "ngetopt_opt -> entry with" + "\r\n eOpt: %d" + "\r\n", eOpt) ); + switch (eOpt) { case SOCKET_OPT_OTP_DEBUG: result = ngetopt_otp_debug(env, descP); @@ -6686,6 +6735,11 @@ ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env, break; } + SSDBG( descP, + ("SOCKET", "ngetopt_opt -> done when" + "\r\n result: %T" + "\r\n", result) ); + return result; } @@ -7409,6 +7463,11 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env, { ERL_NIF_TERM result; + SSDBG( descP, + ("SOCKET", "ngetopt_lvl_ip -> entry with" + "\r\n eOpt: %d" + "\r\n", eOpt) ); + switch (eOpt) { #if defined(IP_FREEBIND) case SOCKET_OPT_IP_FREEBIND: @@ -7470,6 +7529,12 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env, break; #endif +#if defined(IP_RECVOPTS) + case SOCKET_OPT_IP_RECVOPTS: + result = ngetopt_lvl_ip_recvopts(env, descP); + break; +#endif + #if defined(IP_RECVTOS) case SOCKET_OPT_IP_RECVTOS: result = ngetopt_lvl_ip_recvtos(env, descP); @@ -7501,10 +7566,16 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env, #endif default: + SSDBG( descP, ("SOCKET", "ngetopt_lvl_ip -> unknown opt %d\r\n", eOpt) ); result = esock_make_error(env, esock_atom_einval); break; } + SSDBG( descP, + ("SOCKET", "ngetopt_lvl_ip -> done when" + "\r\n result: %T" + "\r\n", result) ); + return result; } @@ -7742,6 +7813,24 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env, #endif +/* ngetopt_lvl_ip_recvopt - Level IP RECVOPTS option + */ +#if defined(IP_RECVOPTS) +static +ERL_NIF_TERM ngetopt_lvl_ip_recvopts(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_RECVOPTS); +} +#endif + + /* ngetopt_lvl_ip_recvttl - Level IP RECVTTL option */ #if defined(IP_RECVTTL) diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam Binary files differindex 3657212f81..54cc44db54 100644 --- a/erts/preloaded/ebin/socket.beam +++ b/erts/preloaded/ebin/socket.beam diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index 329223c443..49c7a3f56d 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -614,7 +614,7 @@ %% -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_RECVOPTS, 23). %% -define(SOCKET_OPT_IP_RECVORIGDSTADDR, 24). -define(SOCKET_OPT_IP_RECVTOS, 25). -define(SOCKET_OPT_IP_RECVTTL, 26). @@ -2210,6 +2210,9 @@ enc_setopt_value(ip, nodefrag, V, _D, _T, _P) enc_setopt_value(ip, recvif, V, _D, _T, _P) when is_boolean(V) -> V; +enc_setopt_value(ip, recvopts, V, _D, _T, _P) + when is_boolean(V) -> + V; enc_setopt_value(ip, recvtos, V, _D, _T, _P) when is_boolean(V) -> V; @@ -2619,8 +2622,8 @@ enc_sockopt_key(ip = _L, recvif = _Opt, _Dir, _D, T, _P) ?SOCKET_OPT_IP_RECVIF; enc_sockopt_key(ip = L, recvdstaddr = Opt, _Dir, _D, _T, _P) -> not_supported({L, Opt}); -enc_sockopt_key(ip = L, recvopts = Opt, _Dir, _D, T, _P) when (T =/= stream) -> - not_supported({L, Opt}); +enc_sockopt_key(ip = _L, recvopts = _Opt, _Dir, _D, T, _P) when (T =/= stream) -> + ?SOCKET_OPT_IP_RECVOPTS; enc_sockopt_key(ip = L, recvorigdstaddr = Opt, _Dir, _D, _T, _P) -> not_supported({L, Opt}); enc_sockopt_key(ip, recvtos = _Opt, _Dir, _D, _T, _P) -> diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl index 971ceb2093..aa577b6289 100644 --- a/lib/kernel/test/socket_server.erl +++ b/lib/kernel/test/socket_server.erl @@ -612,6 +612,8 @@ handler_init(Manager, ID, Peek, Sock) -> MLoop = GIP(multicast_loop), MTTL = GIP(multicast_ttl), NF = GIP(nodefrag), % raw only + RecvIF = GIP(recvif), % Only dgram and raw (and FreeBSD) + RecvOPTS = GIP(recvopts), % Not stream RecvTOS = GIP(recvtos), RecvTTL = GIP(recvttl), % not stream i("got continue when: " @@ -638,6 +640,8 @@ handler_init(Manager, ID, Peek, Sock) -> "~n (ip) Multicast Loop: ~s" "~n (ip) Multicast TTL: ~s" "~n (ip) Node Frag: ~s" + "~n (ip) Recv IF: ~s" + "~n (ip) Recv OPTS: ~s" "~n (ip) Recv TOS: ~s" "~n (ip) Recv TTL: ~s", [Domain, Type, Proto, @@ -645,8 +649,8 @@ handler_init(Manager, ID, Peek, Sock) -> RcvBuf, RcvLW, RcvTO, SndBuf, SndLW, SndTO, Linger, Timestamp, FreeBind, MTU, MTUDisc, MALL, MIF, MLoop, MTTL, - NF, RecvTOS, RecvTTL]), - + NF, RecvIF, RecvOPTS, RecvTOS, RecvTTL]), + handler_loop(#handler{peek = Peek, manager = Manager, type = Type, |