aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-09-28 18:40:08 +0200
committerMicael Karlberg <[email protected]>2018-09-28 18:40:08 +0200
commit1c412c62ba3be17b7a818f264049a7ee7942351e (patch)
tree675494d373a04c6b15ff0fc19b24725d5f95c986 /erts/emulator
parent0b56a98366fc152c0fa5d5398220ac31866114d5 (diff)
downloadotp-1c412c62ba3be17b7a818f264049a7ee7942351e.tar.gz
otp-1c412c62ba3be17b7a818f264049a7ee7942351e.tar.bz2
otp-1c412c62ba3be17b7a818f264049a7ee7942351e.zip
[socket-nif] Add support for socket (level otp) buffer options
Add support for otp level socket options rcvbuf, rcvctrlbuf and sndctrlbuf. These options define default sizes for these buffers. The 'rcvbuf' is used when receiving messages when calling the recv, recvfrom and recvmsg functions. The 'rcvctrlbuf' is used for the control message header info when calling the recvmsg function. The 'sndctrlbuf' is used for the control message header info when calling the sendmsg function. OTP-14831
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/nifs/common/socket_nif.c146
-rw-r--r--erts/emulator/nifs/common/socket_util.c29
-rw-r--r--erts/emulator/nifs/common/socket_util.h6
3 files changed, 181 insertions, 0 deletions
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index ccbcf63ece..876bed3135 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -501,6 +501,9 @@ typedef union {
#define SOCKET_OPT_OTP_DEBUG 1
#define SOCKET_OPT_OTP_IOW 2
#define SOCKET_OPT_OTP_CTRL_PROC 3
+#define SOCKET_OPT_OTP_RCVBUF 4
+#define SOCKET_OPT_OTP_RCVCTRLBUF 6
+#define SOCKET_OPT_OTP_SNDCTRLBUF 7
#define SOCKET_OPT_SOCK_ACCEPTCONN 1
#define SOCKET_OPT_SOCK_BINDTODEVICE 3
@@ -1004,6 +1007,15 @@ static ERL_NIF_TERM nsetopt_otp_iow(ErlNifEnv* env,
static ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
+static ERL_NIF_TERM nsetopt_otp_rcvbuf(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+static ERL_NIF_TERM nsetopt_otp_rcvctrlbuf(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+static ERL_NIF_TERM nsetopt_otp_sndctrlbuf(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
static ERL_NIF_TERM nsetopt_native(ErlNifEnv* env,
SocketDescriptor* descP,
int level,
@@ -1492,6 +1504,12 @@ static ERL_NIF_TERM ngetopt_otp_iow(ErlNifEnv* env,
SocketDescriptor* descP);
static ERL_NIF_TERM ngetopt_otp_ctrl_proc(ErlNifEnv* env,
SocketDescriptor* descP);
+static ERL_NIF_TERM ngetopt_otp_rcvbuf(ErlNifEnv* env,
+ SocketDescriptor* descP);
+static ERL_NIF_TERM ngetopt_otp_rcvctrlbuf(ErlNifEnv* env,
+ SocketDescriptor* descP);
+static ERL_NIF_TERM ngetopt_otp_sndctrlbuf(ErlNifEnv* env,
+ SocketDescriptor* descP);
static ERL_NIF_TERM ngetopt_native(ErlNifEnv* env,
SocketDescriptor* descP,
int level,
@@ -5001,6 +5019,18 @@ ERL_NIF_TERM nsetopt_otp(ErlNifEnv* env,
result = nsetopt_otp_ctrl_proc(env, descP, eVal);
break;
+ case SOCKET_OPT_OTP_RCVBUF:
+ result = nsetopt_otp_rcvbuf(env, descP, eVal);
+ break;
+
+ case SOCKET_OPT_OTP_RCVCTRLBUF:
+ result = nsetopt_otp_rcvctrlbuf(env, descP, eVal);
+ break;
+
+ case SOCKET_OPT_OTP_SNDCTRLBUF:
+ result = nsetopt_otp_sndctrlbuf(env, descP, eVal);
+ break;
+
default:
result = esock_make_error(env, esock_atom_einval);
break;
@@ -5079,6 +5109,74 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env,
+/* nsetopt_otp_rcvbuf - Handle the OTP (level) rcvbuf option
+ */
+static
+ERL_NIF_TERM nsetopt_otp_rcvbuf(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ size_t val;
+ char* xres;
+
+ if ((xres = esock_decode_bufsz(env,
+ eVal,
+ SOCKET_RECV_BUFFER_SIZE_DEFAULT, &val)) != NULL)
+ return esock_make_error_str(env, xres);
+
+ descP->rBufSz = val;
+
+ return esock_atom_ok;
+}
+
+
+
+/* nsetopt_otp_rcvctrlbuf - Handle the OTP (level) rcvctrlbuf option
+ */
+static
+ERL_NIF_TERM nsetopt_otp_rcvctrlbuf(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ size_t val;
+ char* xres;
+
+ if ((xres = esock_decode_bufsz(env,
+ eVal,
+ SOCKET_RECV_CTRL_BUFFER_SIZE_DEFAULT,
+ &val)) != NULL)
+ return esock_make_error_str(env, xres);
+
+ descP->rCtrlSz = val;
+
+ return esock_atom_ok;
+}
+
+
+
+/* nsetopt_otp_sndctrlbuf - Handle the OTP (level) sndctrlbuf option
+ */
+static
+ERL_NIF_TERM nsetopt_otp_sndctrlbuf(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ size_t val;
+ char* xres;
+
+ if ((xres = esock_decode_bufsz(env,
+ eVal,
+ SOCKET_SEND_CTRL_BUFFER_SIZE_DEFAULT,
+ &val)) != NULL)
+ return esock_make_error_str(env, xres);
+
+ descP->wCtrlSz = val;
+
+ return esock_atom_ok;
+}
+
+
+
/* The option has *not* been encoded. Instead it has been provided
* in "native mode" (option is provided as is and value as a binary).
*/
@@ -8169,6 +8267,18 @@ ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env,
result = ngetopt_otp_ctrl_proc(env, descP);
break;
+ case SOCKET_OPT_OTP_RCVBUF:
+ result = ngetopt_otp_rcvbuf(env, descP);
+ break;
+
+ case SOCKET_OPT_OTP_RCVCTRLBUF:
+ result = ngetopt_otp_rcvctrlbuf(env, descP);
+ break;
+
+ case SOCKET_OPT_OTP_SNDCTRLBUF:
+ result = ngetopt_otp_sndctrlbuf(env, descP);
+ break;
+
default:
result = esock_make_error(env, esock_atom_einval);
break;
@@ -8220,6 +8330,42 @@ ERL_NIF_TERM ngetopt_otp_ctrl_proc(ErlNifEnv* env,
+/* ngetopt_otp_rcvbuf - Handle the OTP (level) rcvbuf options
+ */
+static
+ERL_NIF_TERM ngetopt_otp_rcvbuf(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ ERL_NIF_TERM eVal = MKI(env, descP->rBufSz);
+
+ return esock_make_ok2(env, eVal);
+}
+
+
+/* ngetopt_otp_rcvctrlbuf - Handle the OTP (level) rcvctrlbuf options
+ */
+static
+ERL_NIF_TERM ngetopt_otp_rcvctrlbuf(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ ERL_NIF_TERM eVal = MKI(env, descP->rCtrlSz);
+
+ return esock_make_ok2(env, eVal);
+}
+
+
+/* ngetopt_otp_sndctrlbuf - Handle the OTP (level) sndctrlbuf options
+ */
+static
+ERL_NIF_TERM ngetopt_otp_sndctrlbuf(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ ERL_NIF_TERM eVal = MKI(env, descP->wCtrlSz);
+
+ return esock_make_ok2(env, eVal);
+}
+
+
/* The option has *not* been encoded. Instead it has been provided
* in "native mode" (option is provided as is). In this case it will have the
* format: {NativeOpt :: integer(), ValueSize :: non_neg_integer()}
diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c
index 8bb725fb5b..ff50fd2384 100644
--- a/erts/emulator/nifs/common/socket_util.c
+++ b/erts/emulator/nifs/common/socket_util.c
@@ -1261,6 +1261,35 @@ char* esock_decode_protocol(ErlNifEnv* env,
+/* +++ esock_decode_bufsz +++
+ *
+ * Decode an buffer size. The size of a buffer is:
+ *
+ * Sz > 0 => Use provided value
+ * Sz => Use provided default
+ *
+ */
+extern
+char* esock_decode_bufsz(ErlNifEnv* env,
+ ERL_NIF_TERM eVal,
+ size_t defSz,
+ size_t* sz)
+{
+ int val;
+
+ if (!GET_INT(env, eVal, &val))
+ return ESOCK_STR_EINVAL;
+
+ if (val > 0)
+ *sz = (size_t) val;
+ else
+ *sz = defSz;
+
+ return NULL;
+}
+
+
+
/* *** esock_decode_string ***
*
* Decode a string value. A successful decode results in an
diff --git a/erts/emulator/nifs/common/socket_util.h b/erts/emulator/nifs/common/socket_util.h
index a38453e238..1b5d003155 100644
--- a/erts/emulator/nifs/common/socket_util.h
+++ b/erts/emulator/nifs/common/socket_util.h
@@ -158,6 +158,12 @@ char* esock_encode_protocol(ErlNifEnv* env,
ERL_NIF_TERM* eProtocol);
extern
+char* esock_decode_bufsz(ErlNifEnv* env,
+ ERL_NIF_TERM eVal,
+ size_t defSz,
+ size_t* sz);
+
+extern
BOOLEAN_T esock_decode_string(ErlNifEnv* env,
const ERL_NIF_TERM eString,
char** stringP);