aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-05-08 16:49:58 +0200
committerMicael Karlberg <[email protected]>2018-09-18 13:01:37 +0200
commit83dd8317ea3534fb9353f0d5159a0b1cb485f38c (patch)
tree04c39e17a2ef0dea4ed4db6cf5c11c737028cec1
parent0f2b8a76edaa462fca388a55eaf449a36296820a (diff)
downloadotp-83dd8317ea3534fb9353f0d5159a0b1cb485f38c.tar.gz
otp-83dd8317ea3534fb9353f0d5159a0b1cb485f38c.tar.bz2
otp-83dd8317ea3534fb9353f0d5159a0b1cb485f38c.zip
[socket-nif] setopt for socket option(s) rcvbuf and sndnuf
-rw-r--r--erts/emulator/nifs/common/socket_nif.c30
-rw-r--r--erts/preloaded/src/socket.erl27
2 files changed, 48 insertions, 9 deletions
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index f9727d41b1..eee96ee844 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -364,7 +364,9 @@ typedef union {
#define SOCKET_OPT_SOCK_KEEPALIVE 9
#define SOCKET_OPT_SOCK_LINGER 10
#define SOCKET_OPT_SOCK_PRIORITY 16
+#define SOCKET_OPT_SOCK_RCVBUF 17
#define SOCKET_OPT_SOCK_REUSEADDR 21
+#define SOCKET_OPT_SOCK_SNDBUF 27
#define SOCKET_OPT_IP_RECVTOS 25
#define SOCKET_OPT_IP_ROUTER_ALERT 28
@@ -3486,6 +3488,20 @@ BOOLEAN_T eoptval2optval_socket(ErlNifEnv* env,
break;
#endif
+#if defined(SO_RCVBUF)
+ case SOCKET_OPT_SOCK_RCVBUF:
+ if (GET_INT(env, eVal, &valP->u.intVal)) {
+ valP->tag = SOCKET_OPT_VALUE_INT;
+ *opt = SO_RCVBUF;
+ return TRUE;
+ } else {
+ *opt = -1;
+ valP->tag = SOCKET_OPT_VALUE_UNDEF;
+ return FALSE;
+ }
+ break;
+#endif
+
#if defined(SO_REUSEADDR)
case SOCKET_OPT_SOCK_REUSEADDR:
{
@@ -3505,6 +3521,20 @@ BOOLEAN_T eoptval2optval_socket(ErlNifEnv* env,
break;
#endif
+#if defined(SO_SNDBUF)
+ case SOCKET_OPT_SOCK_SNDBUF:
+ if (GET_INT(env, eVal, &valP->u.intVal)) {
+ valP->tag = SOCKET_OPT_VALUE_INT;
+ *opt = SO_SNDBUF;
+ return TRUE;
+ } else {
+ *opt = -1;
+ valP->tag = SOCKET_OPT_VALUE_UNDEF;
+ return FALSE;
+ }
+ break;
+#endif
+
default:
*opt = -1;
valP->tag = SOCKET_OPT_VALUE_UNDEF;
diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl
index f40fd81d36..7b53f271ef 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -199,12 +199,14 @@
%% Read-only options:
%% mtu
%%
+%% Options only valid on FreeBSD?:
+%% dontfrag
%% Options only valid for RAW sockets:
-%% nodefrag
+%% nodefrag (linux only?)
-type ip_socket_option() :: add_membership |
add_source_membership |
block_source |
- dont_frag |
+ dontfrag |
drop_membership |
drop_source_membership |
freebind |
@@ -437,7 +439,9 @@
-define(SOCKET_OPT_SOCK_KEEPALIVE, 9).
-define(SOCKET_OPT_SOCK_LINGER, 10).
-define(SOCKET_OPT_SOCK_PRIORITY, 16).
+-define(SOCKET_OPT_SOCK_RCVBUF, 17).
-define(SOCKET_OPT_SOCK_REUSEADDR, 21).
+-define(SOCKET_OPT_SOCK_SNDBUF, 27).
-define(SOCKET_OPT_IP_RECVTOS, 25).
-define(SOCKET_OPT_IP_ROUTER_ALERT, 28).
@@ -1600,9 +1604,10 @@ enc_setopt_key(Level, Opt, Domain, Type, Protocol) ->
%% +++ Encode setopt value +++
%%
-%% For the most part this function does *not* do an actually encode,
-%% it simply validates the value type. But in some cases it actually
-%% encodes the value into an more manageable type.
+%% For the most part this function does *not* do an actual encode,
+%% it simply validates the value type. But in some cases it will
+%% encode the value into an more "manageable" type.
+%% It also handles "aliases" (see linger).
enc_setopt_value(otp, debug, V, _, _, _) when is_boolean(V) ->
V;
@@ -1622,8 +1627,12 @@ enc_setopt_value(socket, linger, {OnOff, Secs} = V, _D, _T, _P)
V;
enc_setopt_value(socket, priority, V, _D, _T, _P) when is_integer(V) ->
V;
+enc_setopt_value(socket, rcvbuf, V, _D, _T, _P) when is_integer(V) ->
+ V;
enc_setopt_value(socket, reuseaddr, V, _D, _T, _P) when is_boolean(V) ->
V;
+enc_setopt_value(socket, sndbuf, V, _D, _T, _P) when is_integer(V) ->
+ V;
enc_setopt_value(socket = L, Opt, V, _D, _T, _P) ->
not_supported({L, Opt, V});
@@ -1830,8 +1839,8 @@ enc_sockopt_key(socket, peek_cred = Opt, get = _Dir, _D, _T, _P) ->
not_supported(Opt);
enc_sockopt_key(socket, priority = _Opt, _Dir, _D, _T, _P) ->
?SOCKET_OPT_SOCK_PRIORITY;
-enc_sockopt_key(socket, rcvbuf = Opt, _Dir, _D, _T, _P) ->
- not_supported(Opt);
+enc_sockopt_key(socket, rcvbuf = _Opt, _Dir, _D, _T, _P) ->
+ ?SOCKET_OPT_SOCK_RCVBUF;
enc_sockopt_key(socket, rcvbufforce = Opt, _Dir, _D, _T, _P) ->
not_supported(Opt);
%% May not work on linux.
@@ -1848,8 +1857,8 @@ enc_sockopt_key(socket, rxq_ovfl = Opt, _Dir, _D, _T, _P) ->
not_supported(Opt);
enc_sockopt_key(socket, setfib = Opt, set = _Dir, _D, _T, _P) ->
not_supported(Opt);
-enc_sockopt_key(socket, sndbuf = Opt, _Dir, _D, _T, _P) ->
- not_supported(Opt);
+enc_sockopt_key(socket, sndbuf = _Opt, _Dir, _D, _T, _P) ->
+ ?SOCKET_OPT_SOCK_SNDBUF;
enc_sockopt_key(socket, sndbufforce = Opt, _Dir, _D, _T, _P) ->
not_supported(Opt);
%% Not changeable on linux.