* generally are NOT virtualized.
*/
+#ifdef _WIN32
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#endif
+
#include "vmware.h"
#include "asyncsocket.h"
#include "asyncSocketBase.h"
#include "loglevel_user.h"
-
-
/*
*----------------------------------------------------------------------------
*
*
* AsyncSocket_UseNodelay --
*
- * Sets or unset TCP_NODELAY on the socket, which disables or
- * enables Nagle's algorithm, respectively.
+ * THIS IS DEPRECATED in favor of AsyncSocket_SetOption(...TCP_NODELAY...).
+ * It exists for now to avoid having to change all existing calling code.
+ * TODO: Remove it fully and fix up all calling code accordingly.
+ *
+ * Sets the setsockopt() value TCP_NODELAY.
+ * asyncSocket may be an AsyncTCPSocket itself
+ * or contain one on which the option will be set.
+ *
+ * This fails if there is no applicable AsyncTCPSocket (asyncSocket or
+ * one inside it).
*
* Results:
* ASOCKERR_SUCCESS on success, ASOCKERR_* otherwise.
+ * There being no applicable AsyncTCPSocket yields ASOCKERR_INVAL.
+ * OS error when setting value yields ASOCKERR_GENERIC.
*
- * Side Effects:
- * Increased bandwidth usage for short messages on this socket
+ * Side effects:
+ * Possibly increased bandwidth usage for short messages on this socket
* due to TCP overhead, in exchange for lower latency.
*
*----------------------------------------------------------------------------
*/
int
-AsyncSocket_UseNodelay(AsyncSocket *asock, // IN/OUT:
- Bool nodelay) // IN:
+AsyncSocket_UseNodelay(AsyncSocket *asyncSocket, // IN/OUT
+ Bool noDelay) // IN
{
+ const int noDelayNative = noDelay ? 1 : 0;
+ return AsyncSocket_SetOption(asyncSocket,
+ IPPROTO_TCP, TCP_NODELAY,
+ &noDelayNative, sizeof noDelayNative);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * AsyncSocket_SetTCPTimeouts --
+ *
+ * Sets setsockopt() TCP_KEEP{INTVL|IDLE|CNT} if available in the OS.
+ * asyncSocket may be an AsyncTCPSocket itself
+ * or contain one on which the option will be set.
+ *
+ * This fails if there is no applicable AsyncTCPSocket (asyncSocket or
+ * one inside it).
+ *
+ * Results:
+ * ASOCKERR_SUCCESS if no error, or OS doesn't support options.
+ * There being no applicable AsyncTCPSocket yields ASOCKERR_INVAL.
+ * OS error when setting any one value yields ASOCKERR_GENERIC.
+ *
+ * Side effects:
+ * None.
+ * Note that in case of error ASOCKERR_GENERIC, 0, 1, or 2 of the values
+ * may have still been successfully set (the successful changes are
+ * not rolled back).
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+AsyncSocket_SetTCPTimeouts(AsyncSocket *asyncSocket, // IN/OUT
+ int keepIdleSec, // IN
+ int keepIntvlSec, // IN
+ int keepCnt) // IN
+{
+ /*
+ * This function is NOT deprecated like the nearby setOption()-wrapping
+ * functions. It's valuable because it: enapsulates OS-dependent logic; and
+ * performs one lock before settong all applicable options together.
+ */
+
+#if defined(__linux__) || defined(VMX86_SERVER)
+ /*
+ * Tempting to call AsyncSocket_SetOption() x 3 instead of worrying about
+ * locking and VT() ourselves, but this way we can reduce amount of
+ * locking/unlocking at the cost of code verbosity.
+ *
+ * Reason for bailing on first error instead of trying all three:
+ * it's what the original code (that this adapts) did. TODO: Find out from
+ * author, explain here.
+ */
+
int ret;
- if (VALID(asock, useNodelay)) {
- AsyncSocketLock(asock);
- ret = VT(asock)->useNodelay(asock, nodelay);
- AsyncSocketUnlock(asock);
+ if (VALID(asyncSocket, setOption)) {
+ AsyncSocketLock(asyncSocket);
+
+ ret = VT(asyncSocket)->setOption
+ (asyncSocket,
+ IPPROTO_TCP, TCP_KEEPIDLE,
+ &keepIdleSec, sizeof keepIdleSec);
+ if (ret == ASOCKERR_SUCCESS) {
+ ret = VT(asyncSocket)->setOption
+ (asyncSocket,
+ IPPROTO_TCP, TCP_KEEPINTVL,
+ &keepIntvlSec, sizeof keepIntvlSec);
+ if (ret == ASOCKERR_SUCCESS) {
+ ret = VT(asyncSocket)->setOption
+ (asyncSocket,
+ IPPROTO_TCP, TCP_KEEPCNT,
+ &keepCnt, sizeof keepCnt);
+ }
+ }
+
+ AsyncSocketUnlock(asyncSocket);
} else {
ret = ASOCKERR_INVAL;
}
return ret;
+#else // #ifndef __linux__
+ return ASOCKERR_SUCCESS;
+#endif
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * AsyncSocket_EstablishMinBufferSizes --
+ *
+ * Meant to be invoked around socket creation time, this tries to ensure
+ * that SO_{SND|RCV}BUF setsockopt() values are set to at least the values
+ * provided as arguments. That is, it sets the given buffer size but only
+ * if the current value reported by the OS is smaller.
+ *
+ * This fails unless asyncSocket is of the "applicable socket type."
+ * Being of "applicable socket type" is defined as supporting the
+ * option:
+ *
+ * layer = SOL_SOCKET,
+ * optID = SO_{SND|RCV}BUF.
+ *
+ * As of this writing, only AsyncTCPSockets (or derivations thereof)
+ * are supported, but (for example) UDP sockets could be added over time.
+ *
+ * Results:
+ * TRUE: on success; FALSE: on failure.
+ * Determining that no setsockopt() is required is considered success.
+ *
+ * Side effects:
+ * None.
+ * Note that in case of a setsockopt() failing, 0 or 1 of the values
+ * may have still been successfully set (the successful changes are
+ * not rolled back).
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+AsyncSocket_EstablishMinBufferSizes(AsyncSocket *asyncSocket, // IN/OUT
+ int sendSz, // IN
+ int recvSz) // IN
+{
+ Bool ok;
+
+ if (VALID(asyncSocket, setOption)) {
+ int curSendSz;
+ socklen_t curSendSzSz = sizeof curSendSz;
+ int curRecvSz;
+ socklen_t curRecvSzSz = sizeof curRecvSz;
+
+ AsyncSocketLock(asyncSocket);
+
+ /*
+ * For each buffer size, see if the current reported size is already
+ * at least as large (in which case we needn't do anything for that one).
+ * Bail out the moment anything fails, but don't worry about undoing any
+ * change already made (as advertised in doc comment).
+ *
+ * Reason for bailing on first error instead of trying everything:
+ * it's what the original code (that this adapts) did. TODO: Find out from
+ * author, explain here.
+ *
+ * Note that depending on the type of socket and the particular
+ * implementation (e.g., the TCP stack), asking for buffer size N might
+ * result in an even larger buffer, like a multiple 2N. It's not an exact
+ * science.
+ */
+
+ ok = (VT(asyncSocket)->getOption(asyncSocket,
+ SOL_SOCKET, SO_SNDBUF,
+ &curSendSz, &curSendSzSz) ==
+ ASOCKERR_SUCCESS) &&
+ (VT(asyncSocket)->getOption(asyncSocket,
+ SOL_SOCKET, SO_RCVBUF,
+ &curRecvSz, &curRecvSzSz) ==
+ ASOCKERR_SUCCESS);
+ if (ok && (curSendSz < sendSz)) {
+ ok = VT(asyncSocket)->setOption(asyncSocket,
+ SOL_SOCKET, SO_SNDBUF,
+ &sendSz, sizeof sendSz) ==
+ ASOCKERR_SUCCESS;
+ }
+ if (ok && (curRecvSz < recvSz)) {
+ ok = VT(asyncSocket)->setOption(asyncSocket,
+ SOL_SOCKET, SO_RCVBUF,
+ &recvSz, sizeof recvSz) ==
+ ASOCKERR_SUCCESS;
+ }
+
+ AsyncSocketUnlock(asyncSocket);
+ } else {
+ ok = FALSE;
+ }
+
+ return ok;
}
/*
*----------------------------------------------------------------------------
*
- * AsyncSocket_SetTCPTimeouts --
+ * AsyncSocket_SetSendLowLatencyMode --
+ *
+ * THIS IS DEPRECATED in favor of
+ * AsyncSocket_SetOption(ASYNC_SOCKET_OPT_SEND_LOW_LATENCY_MODE).
+ * It exists for now to avoid having to change all existing calling code.
+ * TODO: Remove it fully and fix up all calling code accordingly.
*
- * Allow caller to set a number of TCP-specific timeout
- * parameters on the socket for the active connection.
+ * Sets the aforementioned value. See doc comment on
+ * ASYNC_SOCKET_OPT_SEND_LOW_LATENCY_MODE for more info.
*
- * Parameters:
- * keepIdle -- The number of seconds a TCP connection must be idle before
- * keep-alive probes are sent.
- * keepIntvl -- The number of seconds between TCP keep-alive probes once
- * they are being sent.
- * keepCnt -- The number of keep-alive probes to send before killing
- * the connection if no response is received from the peer.
+ * This fails unless asyncSocket is of the "applicable socket type."
+ * Being of "applicable socket type" is defined as supporting the
+ * option:
+ *
+ * layer = ASYNC_SOCKET_OPTS_LAYER_BASE,
+ * optID = ASYNC_SOCKET_OPT_SEND_LOW_LATENCY_MODE.
*
* Results:
* ASOCKERR_SUCCESS on success, ASOCKERR_* otherwise.
+ * asyncSocket being of inapplicable socket type yields ASOCKERR_INVAL.
*
- * Side Effects:
- * None.
+ * Side effects:
+ * See ASYNC_SOCKET_OPT_SEND_LOW_LATENCY_MODE doc comment.
*
*----------------------------------------------------------------------------
*/
int
-AsyncSocket_SetTCPTimeouts(AsyncSocket *asock, // IN/OUT:
- int keepIdle, // IN
- int keepIntvl, // IN
- int keepCnt) // IN
+AsyncSocket_SetSendLowLatencyMode(AsyncSocket *asyncSocket, // IN
+ Bool enable) // IN
{
int ret;
- if (VALID(asock, setTCPTimeouts)) {
- AsyncSocketLock(asock);
- ret = VT(asock)->setTCPTimeouts(asock, keepIdle, keepIntvl, keepCnt);
- AsyncSocketUnlock(asock);
+ if (VALID(asyncSocket, setOption)) {
+ AsyncSocketLock(asyncSocket);
+ ret = VT(asyncSocket)->setOption
+ (asyncSocket, ASYNC_SOCKET_OPTS_LAYER_BASE,
+ ASYNC_SOCKET_OPT_SEND_LOW_LATENCY_MODE,
+ &enable, sizeof enable);
+ AsyncSocketUnlock(asyncSocket);
} else {
ret = ASOCKERR_INVAL;
}
/*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------
*
- * AsyncSocket_SetBufferSizes --
+ * AsyncSocket_SetOption --
*
- * Set socket level recv/send buffer sizes if they are less than given sizes
+ * Sets the value of the given socket option belonging to the given
+ * option layer to the given value. The socket options mechanism is
+ * discussed in more detail in asyncsocket.h.
*
- * Result
- * TRUE: on success
- * FALSE: on failure
+ * The exact behavior and supported options are dependent on the socket
+ * type. See the doc header for the specific implementation for details.
+ * If ->setOption is NULL, all options are invalid for that socket.
+ * Setting an invalid layer+option results in a no-op + error result.
*
- * Side-effects
- * None
+ * For native options, layer = setsockopt() level,
+ * optID = setsockopt() option_name.
*
- *-----------------------------------------------------------------------------
+ * For non-native options, optID is obtained as follows: it is converted
+ * from an enum option ID value for your socket type; for example,
+ * from ASYNC_TCP_SOCKET_OPT_ALLOW_DECREASING_BUFFER_SIZE,
+ * where the latter is of type AsyncTCPSocket_OptID.
+ *
+ * The option's value must reside at the buffer valuePtr that is
+ * inBufLen long. If inBufLen does not match the expected size for
+ * the given option, behavior is undefined.
+ *
+ * Results:
+ * ASOCKERR_SUCCESS on success, ASOCKERR_* otherwise.
+ * Invalid option+layer yields ASOCKERR_INVAL.
+ * Failure to set a native OS option yields ASOCKERR_GENERIC.
+ * inBufLen being wrong (for the given option) yields undefined behavior.
+ *
+ * Side effects:
+ * Depends on option.
+ *
+ *----------------------------------------------------------------------------
*/
-Bool
-AsyncSocket_SetBufferSizes(AsyncSocket *asock, // IN
- int sendSz, // IN
- int recvSz) // IN
+int
+AsyncSocket_SetOption(AsyncSocket *asyncSocket, // IN/OUT
+ AsyncSocketOpts_Layer layer, // IN
+ AsyncSocketOpts_ID optID, // IN
+ const void *valuePtr, // IN
+ socklen_t inBufLen) // IN
{
- Bool ret;
- if (VALID(asock, setBufferSizes)) {
- AsyncSocketLock(asock);
- ret = VT(asock)->setBufferSizes(asock, sendSz, recvSz);
- AsyncSocketUnlock(asock);
+ int ret;
+ /*
+ * Lacking a setOption() implementation is conceptually the same as
+ * ->setOption() existing but determining layer+optID to be invalid
+ * (ASOCKERR_INVAL results).
+ */
+ if (VALID(asyncSocket, setOption)) {
+ AsyncSocketLock(asyncSocket);
+ ret = VT(asyncSocket)->setOption(asyncSocket, layer, optID,
+ valuePtr, inBufLen);
+ AsyncSocketUnlock(asyncSocket);
} else {
- ret = FALSE;
+ ret = ASOCKERR_INVAL;
}
return ret;
}
/*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------
*
- * AsyncSocket_SetSendLowLatencyMode --
+ * AsyncSocket_GetOption --
*
- * Put the socket into a mode where we attempt to issue sends
- * directly from within AsyncSocket_Send(). Ordinarily, we would
- * set up a Poll callback from within AsyncSocket_Send(), which
- * introduces some non-zero latency to the send path. In
- * low-latency-send mode, that delay is potentially avoided. This
- * does introduce a behavioural change; the send completion
- * callback may be triggered before the call to Send() returns. As
- * not all clients may be expecting this, we don't enable this mode
- * unless requested by the client.
+ * Gets the value of the given socket option belonging to the given
+ * option layer. The socket options mechanism is
+ * discussed in more detail in asyncsocket.h.
+ * This is generally symmetrical to ..._SetOption(); most comments applying
+ * to that function apply to this one in common-sense ways.
+ * In particular a layer+optID combo is supported here if and only if it
+ * is supported for ..._SetOption().
*
- * Result
- * ASOCKERR_SUCCESS or ASOCKERR_*
+ * The length of the output buffer at valuePtr must reside at *outBufLen
+ * at entry to this function. If *outBufLen does not match or exceed the
+ * expected size for the given option, behavior is undefined.
+ * At successful return from function, *outBufLen will be set to the
+ * length of the value written to at valuePtr.
*
- * Side-effects
- * See description above.
+ * Results:
+ * ASOCKERR_SUCCESS on success, ASOCKERR_* otherwise.
+ * Invalid option+layer yields ASOCKERR_INVAL.
+ * Failure to get a native OS option yields ASOCKERR_GENERIC.
+ * *outBufLen being wrong (for the given option) yields undefined behavior.
*
- *-----------------------------------------------------------------------------
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
*/
int
-AsyncSocket_SetSendLowLatencyMode(AsyncSocket *asock, // IN
- Bool enable) // IN
+AsyncSocket_GetOption(AsyncSocket *asyncSocket, // IN/OUT
+ AsyncSocketOpts_Layer layer, // IN
+ AsyncSocketOpts_ID optID, // IN
+ void *valuePtr, // OUT
+ socklen_t *outBufLen) // IN/OUT
{
int ret;
- if (VALID(asock, setSendLowLatencyMode)) {
- AsyncSocketLock(asock);
- ret = VT(asock)->setSendLowLatencyMode(asock, enable);
- AsyncSocketUnlock(asock);
+ /*
+ * Lacking a getOption() implementation is conceptually the same as
+ * ->getOption() existing but determining layer+optID to be invalid
+ * (ASOCKERR_INVAL results).
+ */
+ if (VALID(asyncSocket, getOption)) {
+ AsyncSocketLock(asyncSocket);
+ ret = VT(asyncSocket)->getOption(asyncSocket, layer, optID,
+ valuePtr, outBufLen);
+ AsyncSocketUnlock(asyncSocket);
} else {
ret = ASOCKERR_INVAL;
}
*/
typedef struct AsyncSocketVTable {
AsyncSocketState (*getState)(AsyncSocket *sock);
+
+ /*
+ * The socket options mechanism is discussed in asyncsocket.h.
+ * If you're considering adding a new virtual function table entry whose
+ * effect is to call setsockopt() and/or save a value inside the socket
+ * structure and/or forward such a call to a contained AsyncSocket,
+ * strongly consider using this setOption() mechanism instead.
+ * Your life is likely to be made easier by this.
+ */
+ int (*setOption)(AsyncSocket *asyncSocket,
+ AsyncSocketOpts_Layer layer,
+ AsyncSocketOpts_ID optID,
+ const void *valuePtr,
+ socklen_t inBufLen);
+ /*
+ * A setOption() implementation must have a symmetrical getOption()
+ * counterpart.
+ */
+ int (*getOption)(AsyncSocket *asyncSocket,
+ AsyncSocketOpts_Layer layer,
+ AsyncSocketOpts_ID optID,
+ void *valuePtr,
+ socklen_t *outBufLen);
+
int (*getGenericErrno)(AsyncSocket *s);
int (*getFd)(AsyncSocket *asock);
int (*getRemoteIPStr)(AsyncSocket *asock, const char **ipStr);
int (*getINETIPStr)(AsyncSocket *asock, int socketFamily, char **ipRetStr);
unsigned int (*getPort)(AsyncSocket *asock);
- int (*useNodelay)(AsyncSocket *asock, Bool nodelay);
- int (*setTCPTimeouts)(AsyncSocket *asock, int keepIdle, int keepIntvl,
- int keepCnt);
- Bool (*setBufferSizes)(AsyncSocket *asock, int sendSz, int recvSz);
- int (*setSendLowLatencyMode)(AsyncSocket *asock, Bool enable);
int (*setCloseOptions)(AsyncSocket *asock, int flushEnabledMaxWaitMsec,
AsyncSocketCloseFn closeCb);
Bool (*connectSSL)(AsyncSocket *asock, struct _SSLVerifyParam *verifyParam,
#define ADDR_STRING_LEN (INET6_ADDRSTRLEN + 2 + PORT_STRING_LEN)
+/* Local types. */
+
/*
* Output buffer list data type, for the queue of outgoing buffers
*/
static int AsyncTCPSocketGetINETIPStr(AsyncSocket *asock, int socketFamily,
char **ipRetStr);
static unsigned int AsyncTCPSocketGetPort(AsyncSocket *asock);
-static int AsyncTCPSocketUseNodelay(AsyncSocket *asock, Bool nodelay);
-static int AsyncTCPSocketSetTCPTimeouts(AsyncSocket *asock, int keepIdle,
- int keepIntvl, int keepCnt);
-static Bool AsyncTCPSocketSetBufferSizes(AsyncSocket *asock,
- int sendSz, int recvSz);
-static int AsyncTCPSocketSetSendLowLatencyMode(AsyncSocket *asock,
- Bool enable);
static Bool AsyncTCPSocketConnectSSL(AsyncSocket *asock,
struct _SSLVerifyParam *verifyParam,
void *sslContext);
static int AsyncTCPSocketDoOneMsg(AsyncSocket *s, Bool read, int timeoutMS);
static int AsyncTCPSocketWaitForReadMultiple(AsyncSocket **asock, int numSock,
int timeoutMS, int *outIdx);
+static int AsyncTCPSocketSetOption(AsyncSocket *asyncSocket,
+ AsyncSocketOpts_Layer layer,
+ AsyncSocketOpts_ID optID,
+ const void *valuePtr,
+ socklen_t inBufLen);
+static int AsyncTCPSocketGetOption(AsyncSocket *asyncSocket,
+ AsyncSocketOpts_Layer layer,
+ AsyncSocketOpts_ID optID,
+ void *valuePtr,
+ socklen_t *outBufLen);
+
+/* Local constants. */
static const AsyncSocketVTable asyncTCPSocketVTable = {
AsyncSocketGetState,
+ AsyncTCPSocketSetOption,
+ AsyncTCPSocketGetOption,
AsyncTCPSocketGetGenericErrno,
AsyncTCPSocketGetFd,
AsyncTCPSocketGetRemoteIPStr,
AsyncTCPSocketGetINETIPStr,
AsyncTCPSocketGetPort,
- AsyncTCPSocketUseNodelay,
- AsyncTCPSocketSetTCPTimeouts,
- AsyncTCPSocketSetBufferSizes,
- AsyncTCPSocketSetSendLowLatencyMode,
AsyncTCPSocketSetCloseOptions,
AsyncTCPSocketConnectSSL,
AsyncTCPSocketStartSslConnect,
};
+/* Function bodies. */
+
/*
*----------------------------------------------------------------------
*
}
-/*
- *----------------------------------------------------------------------------
- *
- * AsyncTCPSocketUseNodelay --
- *
- * Sets or unset TCP_NODELAY on the socket, which disables or
- * enables Nagle's algorithm, respectively.
- *
- * Results:
- * ASOCKERR_SUCCESS on success, ASOCKERR_GENERIC otherwise.
- *
- * Side Effects:
- * Increased bandwidth usage for short messages on this socket
- * due to TCP overhead, in exchange for lower latency.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-AsyncTCPSocketUseNodelay(AsyncSocket *base, // IN/OUT:
- Bool nodelay) // IN:
-{
- AsyncTCPSocket *asock = TCPSocket(base);
- int flag = nodelay ? 1 : 0;
-
- ASSERT(AsyncTCPSocketIsLocked(asock));
- if (setsockopt(asock->fd, IPPROTO_TCP, TCP_NODELAY,
- (const void *) &flag, sizeof(flag)) != 0) {
- asock->genericErrno = Err_Errno();
- LOG(0, (ASOCKPREFIX "could not set TCP_NODELAY, error %d: %s\n",
- Err_Errno(), Err_ErrString()));
- return ASOCKERR_GENERIC;
- } else {
- return ASOCKERR_SUCCESS;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * AsyncTCPSocketSetTCPTimeouts --
- *
- * Allow caller to set a number of TCP-specific timeout
- * parameters on the socket for the active connection.
- *
- * Parameters:
- * keepIdle -- The number of seconds a TCP connection must be idle before
- * keep-alive probes are sent.
- * keepIntvl -- The number of seconds between TCP keep-alive probes once
- * they are being sent.
- * keepCnt -- The number of keep-alive probes to send before killing
- * the connection if no response is received from the peer.
- *
- * Results:
- * ASOCKERR_SUCCESS on success, ASOCKERR_GENERIC otherwise.
- *
- * Side Effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-AsyncTCPSocketSetTCPTimeouts(AsyncSocket *base, // IN/OUT:
- int keepIdle, // IN
- int keepIntvl, // IN
- int keepCnt) // IN
-{
-#ifdef VMX86_SERVER
- AsyncTCPSocket *asock = TCPSocket(base);
- int val;
- int opt;
-
- ASSERT(AsyncTCPSocketIsLocked(asock));
-
- val = keepIdle;
- opt = TCP_KEEPIDLE;
- if (setsockopt(asock->fd, IPPROTO_TCP, opt,
- &val, sizeof val) != 0) {
- goto error;
- }
-
- val = keepIntvl;
- opt = TCP_KEEPINTVL;
- if (setsockopt(asock->fd, IPPROTO_TCP, opt,
- &val, sizeof val) != 0) {
- goto error;
- }
-
- val = keepCnt;
- opt = TCP_KEEPCNT;
- if (setsockopt(asock->fd, IPPROTO_TCP, opt,
- &val, sizeof val) != 0) {
- goto error;
- }
-
- return ASOCKERR_SUCCESS;
-
-error:
- asock->genericErrno = Err_Errno();
- LOG(0, (ASOCKPREFIX "could not set TCP Timeout %d, error %d: %s\n",
- opt, Err_Errno(), Err_ErrString()));
-#endif
- return ASOCKERR_GENERIC;
-}
-
-
/*
*----------------------------------------------------------------------------
*
* for the socket.
*
* Results:
- * ASOCKERR_SUCESS if everything worked, else ASOCKERR_GENERIC.
+ * ASOCKERR_SUCCESS if everything worked, else ASOCKERR_GENERIC.
*
* Side effects:
* None.
/*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------
*
- * AsyncTCPSocketSetBufferSizes --
+ * AsyncTCPSocketSetOption --
*
- * Set socket level recv/send buffer sizes if they are less than given sizes.
+ * This implementation of ->setOption() supports the following
+ * options. Exact behavior of each cited optID is documented in the
+ * comment header for that enum value declaration (for non-native options),
+ * or `man setsockopt`/equivalent (for native options).
*
- * Result
- * TRUE: on success
- * FALSE: on failure
+ * - layer = SOL_SOCKET, optID =
+ * SO_SNDBUF, SO_RCVBUF.
*
- * Side-effects
- * None
+ * - layer = IPPROTO_TCP, optID =
+ * TCP_NODELAY, TCP_KEEPINTVL, TCP_KEEPIDLE, TCP_KEEPCNT.
*
- *-----------------------------------------------------------------------------
+ * - layer = ASYNC_SOCKET_OPTS_LAYER_BASE, optID (type) =
+ * ASYNC_SOCKET_OPT_SEND_LOW_LATENCY_MODE (Bool).
+ *
+ * Results:
+ * ASOCKERR_SUCCESS on success, ASOCKERR_* otherwise.
+ * Invalid option+layer yields ASOCKERR_INVAL.
+ * Failure to set a native OS option yields ASOCKERR_GENERIC.
+ * inBufLen being wrong (for the given option) yields undefined behavior.
+ *
+ * Side effects:
+ * Depends on option.
+ *
+ *----------------------------------------------------------------------------
*/
-static Bool
-AsyncTCPSocketSetBufferSizes(AsyncSocket *base, // IN
- int sendSz, // IN
- int recvSz) // IN
+static int
+AsyncTCPSocketSetOption(AsyncSocket *asyncSocket, // IN/OUT
+ AsyncSocketOpts_Layer layer, // IN
+ AsyncSocketOpts_ID optID, // IN
+ const void *valuePtr, // IN
+ socklen_t inBufLen) // IN
{
- AsyncTCPSocket *asock = TCPSocket(base);
- int err;
- int buffSz;
- int len = sizeof buffSz;
- int sysErr;
- int fd;
+ /* Maintenance: Keep this in sync with ...GetOption(). */
- fd = asock->fd;
+ AsyncTCPSocket *tcpSocket = TCPSocket(asyncSocket);
+ Bool isSupported;
- err = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&buffSz, &len);
- if (err) {
- sysErr = ASOCK_LASTERROR();
- Warning(ASOCKPREFIX "Could not get recv buffer size for socket %d, "
- "error %d: %s\n", fd, sysErr, Err_Errno2String(sysErr));
- return FALSE;
+ switch ((int)layer)
+ {
+ case SOL_SOCKET:
+ case IPPROTO_TCP:
+ case ASYNC_SOCKET_OPTS_LAYER_BASE:
+ break;
+ default:
+ TCPSOCKLG0(tcpSocket,
+ ("%s: Option layer [%d] (option [%d]) is not "
+ "supported for TCP socket.\n",
+ __FUNCTION__, (int)layer, optID));
+ return ASOCKERR_INVAL;
}
- if (buffSz < recvSz) {
- buffSz = recvSz;
- err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&buffSz, len);
- if (err) {
- sysErr = ASOCK_LASTERROR();
- Warning(ASOCKPREFIX "Could not set recv buffer size for socket %d "
- "to %d, error %d: %s\n", fd, buffSz,
- sysErr, Err_Errno2String(sysErr));
- return FALSE;
+ /*
+ * layer is supported.
+ * Handle non-native options first.
+ */
+
+ if ((layer == ASYNC_SOCKET_OPTS_LAYER_BASE) &&
+ (optID == ASYNC_SOCKET_OPT_SEND_LOW_LATENCY_MODE)) {
+ ASSERT(inBufLen == sizeof(Bool));
+ tcpSocket->sendLowLatency = *((const Bool *)valuePtr);
+ TCPSOCKLG0(tcpSocket,
+ ("%s: sendLowLatencyMode set to [%d].\n",
+ __FUNCTION__, (int)tcpSocket->sendLowLatency));
+ return ASOCKERR_SUCCESS;
+ }
+
+ /*
+ * Handle native (setsockopt()) options from this point on.
+ *
+ * We need the level and option_name arguments for that call.
+ * Our design dictates that, for native options, simply option_name=optID.
+ * So just determine level from our layer enum (for native layers, the enum's
+ * ordinal value is set to the corresponding int level value). Therefore,
+ * level=layer.
+ *
+ * level and option_name are known. However, we only allow the setting of
+ * certain specific options. Anything else is an error.
+ */
+ isSupported = FALSE;
+ if (layer == SOL_SOCKET) {
+ switch (optID) {
+ case SO_SNDBUF:
+ case SO_RCVBUF:
+ isSupported = TRUE;
+ }
+ } else {
+ ASSERT((int)layer == IPPROTO_TCP);
+
+ switch (optID) {
+ /*
+ * Note: All but TCP_KEEPIDLE are available in Mac OS X (at least
+ * 10.11). iOS and Android are TBD. For now, let's keep it simple and
+ * make all these available in the two known OS where all 3 exist
+ * together, as they're typically often set as a group.
+ * TODO: Possibly enable for other OS in more fine-grained fashion.
+ */
+#if defined(__linux__) || defined(VMX86_SERVER)
+ case TCP_KEEPIDLE:
+ case TCP_KEEPINTVL:
+ case TCP_KEEPCNT:
+#endif
+ case TCP_NODELAY:
+ isSupported = TRUE;
}
}
- err = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&buffSz, &len);
- if (err) {
- sysErr = ASOCK_LASTERROR();
- Warning(ASOCKPREFIX "Could not get send buffer size for socket %d, "
- "error %d: %s\n", fd, sysErr, Err_Errno2String(sysErr));
- return FALSE;
+ if (!isSupported) {
+ TCPSOCKLG0(tcpSocket,
+ ("%s: Option layer/level [%d], option/name [%d]: "
+ "could not set OS option for TCP socket; "
+ "option not supported.\n",
+ __FUNCTION__, (int)layer, optID));
+ return ASOCKERR_INVAL;
}
- if (buffSz < sendSz) {
- buffSz = sendSz;
- err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&buffSz, len);
- if (err) {
- sysErr = ASOCK_LASTERROR();
- Warning(ASOCKPREFIX "Could not set send buffer size for socket %d "
- "to %d, error %d: %s\n", fd, buffSz,
- sysErr, Err_Errno2String(sysErr));
- return FALSE;
- }
+ /* All good. Ready to actually set the OS option. */
+
+ if (setsockopt(tcpSocket->fd, layer, optID,
+ valuePtr, inBufLen) != 0) {
+ tcpSocket->genericErrno = Err_Errno();
+ TCPSOCKLG0(tcpSocket,
+ ("%s: Option layer/level [%d], option/name [%d]: "
+ "could not set OS option for TCP socket; "
+ "error [%d: %s].\n",
+ __FUNCTION__, (int)layer, optID,
+ tcpSocket->genericErrno,
+ Err_Errno2String(tcpSocket->genericErrno)));
+ return ASOCKERR_GENERIC;
}
- return TRUE;
+ TCPSOCKLG0(tcpSocket,
+ ("%s: Option layer/level [%d], option/name [%d]: successfully "
+ "set OS option for TCP socket.\n",
+ __FUNCTION__, (int)layer, optID));
+
+ return ASOCKERR_SUCCESS;
}
/*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------
*
- * AsyncTCPSocketSetSendLowLatencyMode --
+ * AsyncTCPSocketGetOption --
*
- * Put the socket into a mode where we attempt to issue sends
- * directly from within AsyncTCPSocket_Send(). Ordinarily, we would
- * set up a Poll callback from within AsyncTCPSocket_Send(), which
- * introduces some non-zero latency to the send path. In
- * low-latency-send mode, that delay is potentially avoided. This
- * does introduce a behavioural change; the send completion
- * callback may be triggered before the call to Send() returns. As
- * not all clients may be expecting this, we don't enable this mode
- * unless requested by the client.
+ * This is the reverse of AsyncTCPSocketSetOption().
*
- * Result
- * ASOCKERR_*
+ * Results:
+ * ASOCKERR_SUCCESS on success, ASOCKERR_* otherwise.
+ * Invalid option+layer yields ASOCKERR_INVAL.
+ * Failure to get a native OS option yields ASOCKERR_GENERIC.
+ * *outBufLen being wrong (for the given option) at entry to function
+ * yields undefined behavior.
*
- * Side-effects
- * See description above.
+ * Side effects:
+ * None.
*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------
*/
static int
-AsyncTCPSocketSetSendLowLatencyMode(AsyncSocket *base, // IN
- Bool enable) // IN
+AsyncTCPSocketGetOption(AsyncSocket *asyncSocket, // IN/OUT
+ AsyncSocketOpts_Layer layer, // IN
+ AsyncSocketOpts_ID optID, // IN
+ void *valuePtr, // OUT
+ socklen_t *outBufLen) // IN/OUT
{
- AsyncTCPSocket *asock = TCPSocket(base);
- asock->sendLowLatency = enable;
+ /*
+ * Maintenance: Keep this in sync with ...GetOption().
+ * Substantive comments are kept light to avoid redundancy (refer to the
+ * other function).
+ */
+
+ AsyncTCPSocket *tcpSocket = TCPSocket(asyncSocket);
+ Bool isSupported;
+
+ switch ((int)layer) {
+ case SOL_SOCKET:
+ case IPPROTO_TCP:
+ case ASYNC_SOCKET_OPTS_LAYER_BASE:
+ break;
+ default:
+ TCPSOCKLG0(tcpSocket,
+ ("%s: Option layer [%d] (option [%d]) is not "
+ "supported for TCP socket.\n",
+ __FUNCTION__, (int)layer, optID));
+ return ASOCKERR_INVAL;
+ }
+
+ if ((layer == ASYNC_SOCKET_OPTS_LAYER_BASE) &&
+ (optID == ASYNC_SOCKET_OPT_SEND_LOW_LATENCY_MODE)) {
+ ASSERT(*outBufLen >= sizeof(Bool));
+ *outBufLen = sizeof(Bool);
+ *((Bool *)valuePtr) = tcpSocket->sendLowLatency;
+ TCPSOCKLG0(tcpSocket,
+ ("%s: sendLowLatencyMode is [%d].\n",
+ __FUNCTION__, (int)tcpSocket->sendLowLatency));
+ return ASOCKERR_SUCCESS;
+ }
+
+ isSupported = FALSE;
+ if (layer == SOL_SOCKET) {
+ switch (optID) {
+ case SO_SNDBUF:
+ case SO_RCVBUF:
+ isSupported = TRUE;
+ }
+ } else {
+ ASSERT((int)layer == IPPROTO_TCP);
+
+ switch (optID) {
+#ifdef __linux__
+ case TCP_KEEPIDLE:
+ case TCP_KEEPINTVL:
+ case TCP_KEEPCNT:
+#endif
+ case TCP_NODELAY:
+ isSupported = TRUE;
+ }
+ }
+
+ if (!isSupported) {
+ TCPSOCKLG0(tcpSocket,
+ ("%s: Option layer/level [%d], option/name [%d]: "
+ "could not get OS option for TCP socket; "
+ "option not supported.\n",
+ __FUNCTION__, (int)layer, optID));
+ return ASOCKERR_INVAL;
+ }
+
+ if (getsockopt(tcpSocket->fd, layer, optID,
+ valuePtr, outBufLen) != 0) {
+ tcpSocket->genericErrno = Err_Errno();
+ TCPSOCKLG0(tcpSocket,
+ ("%s: Option layer/level [%d], option/name [%d]: "
+ "could not get OS option for TCP socket; "
+ "error [%d: %s].\n",
+ __FUNCTION__, (int)layer, optID,
+ tcpSocket->genericErrno,
+ Err_Errno2String(tcpSocket->genericErrno)));
+ return ASOCKERR_GENERIC;
+ }
+
+ TCPSOCKLG0(tcpSocket,
+ ("%s: Option layer/level [%d], option/name [%d]: successfully "
+ "got OS option for TCP socket.\n",
+ __FUNCTION__, (int)layer, optID));
+
return ASOCKERR_SUCCESS;
}
#define INCLUDE_ALLOW_VMCORE
#define INCLUDE_ALLOW_USERLEVEL
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#include <sys/socket.h>
+#endif
+
#include "includeCheck.h"
#if defined(__cplusplus)
double packetLossPercent; /* packet loss percentage */
} AsyncSocketNetworkStats;
+
+/*
+ * The following covers all facilities involving dynamic socket options w.r.t.
+ * various async sockets, excluding the async socket options API on the
+ * sockets themselves, which can be found in asyncSocketVTable.h and those
+ * files implementing that API.
+ *
+ * Potential related future work is covered in
+ * asyncsocket/README-asyncSocketOptions-future-work.txt.
+ *
+ * Summary of dynamic socket options:
+ *
+ * Dynamic socket option = setting settable by the async socket API user
+ * including during the lifetime of the socket. An interface spiritually
+ * similar to setsockopt()'s seemed appropriate.
+ *
+ * The option-setting API looks as follows:
+ *
+ * int ...SetOption(AsyncSocket *asyncSocket,
+ * AsyncSocketOpts_Layer layer, // enum type
+ * AsyncSocketOpts_ID optID, // an integer type
+ * const void *valuePtr,
+ * size_t inBufLen)
+ *
+ * Both native (setsockopt()) and non-native (usually, struct member)
+ * options are supported. layer and optID arguments are conceptually similar
+ * to setsockopt() level and option_name arguments, respectively.
+ *
+ * FOR NATIVE (setsockopt()) OPTIONS:
+ * layer = setsockopt() level value.
+ * optID = setsockopt() option_name value.
+ *
+ * FOR NON-NATIVE (struct member inside socket impl.) OPTIONS:
+ * layer = ..._BASE, ..._TCP, ..._FEC, etc.
+ * (pertains to the various AsyncSocket types);
+ * optID = value from enum type appropriate to the chosen layer.
+ *
+ * Examples (prefixes omitted for space):
+ *
+ * -- NATIVE OPTIONS --
+ * optID | layer | <= | ssopt() level | ssopt() option_name
+ * ---------------+-------------+----+---------------+--------------------
+ * == option_name | == level | <= | SOL_SOCKET | SO_SNDBUF
+ * == option_name | == level | <= | IPPROTO_TCP | TCP_NODELAY
+ *
+ * -- NON-NATIVE OPTIONS --
+ * optID | layer | <= | AsyncSocket type(s)
+ * -------------------------------+-------+----+--------------------
+ * _SEND_LOW_LATENCY_MODE | _BASE | <= | any
+ * (enum AsyncSocket_OptID) | | |
+ * _ALLOW_DECREASING_BUFFER_SIZE | _TCP | <= | AsyncTCPSocket
+ * (enum AsyncTCPSocket_OptID) | | |
+ * _MAX_CWND | _FEC | <= | FECAsyncSocket
+ * (enum FECAsyncSocket_OptID) | | |
+ *
+ * Socket option lists for each non-native layer are just enums. Each socket
+ * type should declare its own socket option enum in its own .h file; e.g., see
+ * AsyncTCPSocket_OptID in this file. Some option lists apply to all async
+ * sockets; these are also here in asyncsocket.h.
+ *
+ * The only way in which different socket option layers coexist in the same
+ * file is the layer enum, AsyncSocketOpts_Layer, in the present file,
+ * which enumerates all possible layers.
+ *
+ * The lack of any other cross-pollution between different non-native option
+ * lists' containing files is a deliberate design choice.
+ */
+
+/*
+ * Integral type used for the optID argument to ->setOption() async socket API.
+ *
+ * For a non-native option, use an enum value for your socket type.
+ * (Example: ASYNC_TCP_SOCKET_OPT_ALLOW_DECREASING_BUFFER_SIZE
+ * of type AsyncTCPSocket_OptID, which would apply to TCP sockets only.)
+ *
+ * For a native (setsockopt()) option, use the setsockopt() integer directly.
+ * (Example: TCP_NODELAY.)
+ *
+ * Let's use a typedef as a small bit of abstraction and to be able to easily
+ * change it to size_t, if (for example) we start indexing arrays with this
+ * thing.
+ */
+typedef int AsyncSocketOpts_ID;
+
+/*
+ * Enum type used for the layer argument to ->setOption() async socket API.
+ * As explained in the summary comment above, this
+ * informs the particular ->setOption() implementation how to interpret
+ * the accompanying optID integer value, as it may refer to one of several
+ * option lists; and possible different socket instances (not as of this
+ * writing).
+ *
+ * If editing, see summary comment above first for background.
+ *
+ * The values explicitly in this enum are for non-native options.
+ * For native options, simply use the level value as for setsockopt().
+ *
+ * Ordinal values for all these non-native layers must not clash
+ * with the native levels; hence the `LEVEL + CONSTANT` trick
+ * just below.
+ */
+typedef enum {
+
+ /*
+ * Used when optID applies to a non-native socket option applicable to ANY
+ * async socket type.
+ */
+ ASYNC_SOCKET_OPTS_LAYER_BASE = SOL_SOCKET + 1000,
+
+ /*
+ * Next enums must follow the above ordinally, so just:
+ * ASYNC_SOCKET_OPTS_LAYER_<layer name 1>,
+ * ASYNC_SOCKET_OPTS_LAYER_<layer name 2>, ...
+ */
+} AsyncSocketOpts_Layer;
+
+/*
+ * Enum type used for the OptId argument to ->setOption() async socket API,
+ * when optID refers to a non-native option of any AsyncSocket regardless
+ * of type.
+ */
+typedef enum {
+ /*
+ * Bool indicating whether to put the socket into a mode where we attempt
+ * to issue sends directly from within ->send(). Ordinarily
+ * (FALSE), we would set up a Poll callback from within ->send(),
+ * which introduces some non-zero latency to the send path. In
+ * low-latency-send mode (TRUE), that delay is potentially avoided. This
+ * does introduce a behavioral change; the send completion
+ * callback may be triggered before the call to ->send() returns. As
+ * not all clients may be expecting this, we don't enable this mode
+ * unless requested by the client.
+ *
+ * Default: FALSE.
+ */
+ ASYNC_SOCKET_OPT_SEND_LOW_LATENCY_MODE
+} AsyncSocket_OptID;
+
+/*
+ * Note: If you need to add a non-native option that applies to AsyncTCPSockets
+ * only, you'd probably introduce an enum here named AsyncTCPSocket_OptID; and
+ * at least one layer named ASYNC_SOCKET_OPTS_LAYER_TCP in the enum
+ * AsyncSocketOpts_Layer.
+ */
+
+
+/* API functions for all AsyncSockets. */
+
AsyncSocketState AsyncSocket_GetState(AsyncSocket *sock);
const char * AsyncSocket_Err2String(int err);
AsyncSocketPollParams *pollParams,
int *error);
-/*
- * Enable or disable TCP_NODELAY on this AsyncSocket.
- */
-int AsyncSocket_UseNodelay(AsyncSocket *asock, Bool nodelay);
-
-/*
- * Set TCP timeout values on this AsyncSocket.
- */
-int AsyncSocket_SetTCPTimeouts(AsyncSocket *asock, int keepIdle,
- int keepIntvl, int keepCnt);
+int AsyncSocket_UseNodelay(AsyncSocket *asyncSocket, Bool nodelay);
+int AsyncSocket_SetTCPTimeouts(AsyncSocket *asyncSocket,
+ int keepIdleSec, int keepIntvlSec, int keepCnt);
+Bool AsyncSocket_EstablishMinBufferSizes(AsyncSocket *asyncSocket,
+ int sendSz,
+ int recvSz);
+int AsyncSocket_SetSendLowLatencyMode(AsyncSocket *asyncSocket, Bool enable);
+int AsyncSocket_SetOption(AsyncSocket *asyncSocket,
+ AsyncSocketOpts_Layer layer,
+ AsyncSocketOpts_ID optID,
+ const void *valuePtr, socklen_t inBufLen);
+int AsyncSocket_GetOption(AsyncSocket *asyncSocket,
+ AsyncSocketOpts_Layer layer,
+ AsyncSocketOpts_ID optID,
+ void *valuePtr, socklen_t *outBufLen);
/*
* Waits until at least one packet is received or times out.
int AsyncSocket_SetErrorFn(AsyncSocket *asock, AsyncSocketErrorFn errorFn,
void *clientData);
-/*
- * Set socket level recv/send buffer sizes if they are less than given sizes.
- */
-Bool AsyncSocket_SetBufferSizes(AsyncSocket *asock, // IN
- int sendSz, // IN
- int recvSz); // IN
-
/*
* Set optional AsyncSocket_Close() behaviors.
*/
*/
uint16 AsyncSocket_GetWebSocketCloseStatus(AsyncSocket *asock);
-/*
- * Set low-latency mode for sends:
- */
-int AsyncSocket_SetSendLowLatencyMode(AsyncSocket *asock, Bool enable);
-
/*
* Get negotiated websocket protocol
*/
// VMX86_DESKTOP must be last because it is the default and is always defined.
#elif defined(VMX86_DESKTOP)
// WORKSTATION_VERSION_NUMBER below has to match this
- #define PRODUCT_VERSION 13,0,0,PRODUCT_BUILD_NUMBER_NUMERIC
+ #define PRODUCT_VERSION 14,0,0,PRODUCT_BUILD_NUMBER_NUMERIC
#else
/* Generic catch-all. */
#define PRODUCT_VERSION 0,0,0,PRODUCT_BUILD_NUMBER_NUMERIC
* ALSO, leave FOO_VERSION at e.x.p on all EXCEPT release branches.
* lmclient.h has a FLEX_VERSION struct so the versionPrefix can't be FLEX
*/
-#define WORKSTATION_VERSION_NUMBER "13.0.0" /* this version number should always match real WS version number */
+#define WORKSTATION_VERSION_NUMBER "14.0.0" /* this version number should always match real WS version number */
#define WORKSTATION_VERSION "e.x.p"
-#define PLAYER_VERSION_NUMBER "13.0.0" /* this version number should always match real Player version number */
+#define PLAYER_VERSION_NUMBER "14.0.0" /* this version number should always match real Player version number */
#define PLAYER_VERSION "e.x.p"
#define VMRC_VERSION_NUMBER "10.0.0" /* this version number should always match real VMRC version number */
#define VMRC_VERSION "10.0.0"
#define SSO_VERSION "1.0.0"
#define WBC_VERSION "5.1.0"
#define SDK_VERSION "4.1.0"
-#define FOUNDRY_VERSION "1.15.0"
-#define FOUNDRY_FILE_VERSION 1,15,0,PRODUCT_BUILD_NUMBER_NUMERIC
+#define FOUNDRY_VERSION "1.17.0"
+#define FOUNDRY_FILE_VERSION 1,17,0,PRODUCT_BUILD_NUMBER_NUMERIC
#define VMLS_VERSION "e.x.p"
#define VLICENSE_VERSION "1.1.5"
#define DDK_VERSION "e.x.p"
# if defined(__APPLE__)
# define PRODUCT_LICENSE_VERSION PRODUCT_MAC_DESKTOP_VERSION_STRING_FOR_LICENSE
# else
-# define PRODUCT_LICENSE_VERSION "12.0"
+# define PRODUCT_LICENSE_VERSION "14.0"
# endif
# else
# define PRODUCT_LICENSE_VERSION "0.0"
goto exit;
}
-
- if (!AsyncSocket_SetBufferSizes(asock, RPCIN_MIN_SEND_BUF_SIZE,
- RPCIN_MIN_RECV_BUF_SIZE)) {
+ if (!AsyncSocket_EstablishMinBufferSizes(asock, RPCIN_MIN_SEND_BUF_SIZE,
+ RPCIN_MIN_RECV_BUF_SIZE)) {
goto exit;
}
goto exit;
}
- if (!AsyncSocket_SetBufferSizes(asock, sendBufSize, recvBufSize)) {
- g_info("Cannot set VSOCK buffer sizes, closing socket %d\n", fd);
+ if (!AsyncSocket_EstablishMinBufferSizes(asock, sendBufSize, recvBufSize)) {
+ g_info("Cannot set VSOCK buffer size minima, closing socket %d\n", fd);
goto exit;
}
goto exit;
}
- if (!AsyncSocket_SetBufferSizes(asock, sendBufSize, recvBufSize)) {
+ if (!AsyncSocket_EstablishMinBufferSizes(asock, sendBufSize, recvBufSize)) {
g_info("Closing socket %d due to error.\n", fd);
goto exit;
}