From: Oliver Kurth Date: Fri, 15 Sep 2017 18:23:42 +0000 (-0700) Subject: Dynamic socket options API for async sockets X-Git-Tag: stable-10.2.0~182 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ec6c1f40fb15ffb0d8d6658b9a99c21c706ccb59;p=thirdparty%2Fopen-vm-tools.git Dynamic socket options API for async sockets lib/asyncsocket/asyncsocket.c: lib/asyncsocket/asyncSocketInterface.c: lib/asyncsocket/asyncSocketVTable.h: lib/include/asyncsocket.h: - Add AsyncTCPSocketSetOption(), AsyncTCPSocketGetOption() and AsyncSocket_EstablishMinBufferSizes functions. - Remove/deprecate specific option set functions to be subsumed by ->setOption(). - ->useNodelay() (TCP_NODELAY), ->setTCPTimeouts (3x TCP_... options), ->setBufferSize (SO_{SND|RCV}BUF), ->setSendLowLatencyMode() (non-native option regarding buffering/callback behavior). lib/rpcIn/rpcin.c: services/plugins/grabbitmqProxy/grabbitmqProxyPlugin.c: - replace AsyncSocket_SetBufferSizes() calls with AsyncSocket_EstablishMinBufferSizes() calls. Common header file change: not applicable to open-vm-tools. --- diff --git a/open-vm-tools/lib/asyncsocket/asyncSocketInterface.c b/open-vm-tools/lib/asyncsocket/asyncSocketInterface.c index e0e1becc5..92e216397 100644 --- a/open-vm-tools/lib/asyncsocket/asyncSocketInterface.c +++ b/open-vm-tools/lib/asyncsocket/asyncSocketInterface.c @@ -49,6 +49,14 @@ * generally are NOT virtualized. */ +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif + #include "vmware.h" #include "asyncsocket.h" #include "asyncSocketBase.h" @@ -59,8 +67,6 @@ #include "loglevel_user.h" - - /* *---------------------------------------------------------------------------- * @@ -314,71 +320,257 @@ AsyncSocket_GetPort(AsyncSocket *asock) // IN * * 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; } @@ -387,72 +579,117 @@ AsyncSocket_SetTCPTimeouts(AsyncSocket *asock, // IN/OUT: /* - *----------------------------------------------------------------------------- + *---------------------------------------------------------------------------- * - * 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; } diff --git a/open-vm-tools/lib/asyncsocket/asyncSocketVTable.h b/open-vm-tools/lib/asyncsocket/asyncSocketVTable.h index c1216e039..afb5e544b 100644 --- a/open-vm-tools/lib/asyncsocket/asyncSocketVTable.h +++ b/open-vm-tools/lib/asyncsocket/asyncSocketVTable.h @@ -51,16 +51,35 @@ */ 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, diff --git a/open-vm-tools/lib/asyncsocket/asyncsocket.c b/open-vm-tools/lib/asyncsocket/asyncsocket.c index a997a2f3c..d2086fc67 100644 --- a/open-vm-tools/lib/asyncsocket/asyncsocket.c +++ b/open-vm-tools/lib/asyncsocket/asyncsocket.c @@ -152,6 +152,8 @@ #define ADDR_STRING_LEN (INET6_ADDRSTRLEN + 2 + PORT_STRING_LEN) +/* Local types. */ + /* * Output buffer list data type, for the queue of outgoing buffers */ @@ -307,13 +309,6 @@ static int AsyncTCPSocketGetRemoteIPStr(AsyncSocket *asock, const char **ipStr); 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); @@ -359,19 +354,29 @@ static int AsyncTCPSocketSendBlocking(AsyncSocket *s, void *buf, int len, 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, @@ -405,6 +410,8 @@ static const AsyncSocketVTable asyncTCPSocketVTable = { }; +/* Function bodies. */ + /* *---------------------------------------------------------------------- * @@ -2256,114 +2263,6 @@ AsyncSocket_AttachToSSLSock(SSLSock sslSock, // IN } -/* - *---------------------------------------------------------------------------- - * - * 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; -} - - /* *---------------------------------------------------------------------------- * @@ -3535,7 +3434,7 @@ AsyncTCPSocketDispatchSentBuffer(AsyncTCPSocket *s) // IN * for the socket. * * Results: - * ASOCKERR_SUCESS if everything worked, else ASOCKERR_GENERIC. + * ASOCKERR_SUCCESS if everything worked, else ASOCKERR_GENERIC. * * Side effects: * None. @@ -5655,110 +5554,258 @@ AsyncTCPSocketStartSslAccept(AsyncSocket *base, // IN /* - *----------------------------------------------------------------------------- + *---------------------------------------------------------------------------- * - * 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; } diff --git a/open-vm-tools/lib/include/asyncsocket.h b/open-vm-tools/lib/include/asyncsocket.h index 7939b54ad..533d61428 100644 --- a/open-vm-tools/lib/include/asyncsocket.h +++ b/open-vm-tools/lib/include/asyncsocket.h @@ -47,6 +47,14 @@ #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_USERLEVEL + +#ifdef _WIN32 +#include +#include +#else +#include +#endif + #include "includeCheck.h" #if defined(__cplusplus) @@ -191,6 +199,154 @@ typedef struct AsyncSocketNetworkStats { 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_, + * ASYNC_SOCKET_OPTS_LAYER_, ... + */ +} 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); @@ -404,16 +560,21 @@ AsyncSocket *AsyncSocket_AttachToSSLSock(struct SSLSockStruct *sslSock, 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. @@ -500,13 +661,6 @@ int AsyncSocket_CancelCbForClose(AsyncSocket *asock); 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. */ @@ -542,11 +696,6 @@ int AsyncSocket_SetWebSocketCookie(AsyncSocket *asock, // IN */ uint16 AsyncSocket_GetWebSocketCloseStatus(AsyncSocket *asock); -/* - * Set low-latency mode for sends: - */ -int AsyncSocket_SetSendLowLatencyMode(AsyncSocket *asock, Bool enable); - /* * Get negotiated websocket protocol */ diff --git a/open-vm-tools/lib/include/vm_product_versions.h b/open-vm-tools/lib/include/vm_product_versions.h index d45ee7528..6460a73d1 100644 --- a/open-vm-tools/lib/include/vm_product_versions.h +++ b/open-vm-tools/lib/include/vm_product_versions.h @@ -56,7 +56,7 @@ // 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 @@ -160,9 +160,9 @@ * 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" @@ -249,8 +249,8 @@ #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" @@ -423,7 +423,7 @@ # 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" diff --git a/open-vm-tools/lib/rpcIn/rpcin.c b/open-vm-tools/lib/rpcIn/rpcin.c index 1a1aa3fc9..f5a9974b8 100644 --- a/open-vm-tools/lib/rpcIn/rpcin.c +++ b/open-vm-tools/lib/rpcIn/rpcin.c @@ -1107,9 +1107,8 @@ RpcInConnectDone(AsyncSocket *asock, // IN 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; } diff --git a/open-vm-tools/services/plugins/grabbitmqProxy/grabbitmqProxyPlugin.c b/open-vm-tools/services/plugins/grabbitmqProxy/grabbitmqProxyPlugin.c index f0fc0e105..f7fb0f8e4 100644 --- a/open-vm-tools/services/plugins/grabbitmqProxy/grabbitmqProxyPlugin.c +++ b/open-vm-tools/services/plugins/grabbitmqProxy/grabbitmqProxyPlugin.c @@ -1012,8 +1012,8 @@ VmxListenSockConnectedCb(AsyncSocket *asock, // IN 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; } @@ -1419,7 +1419,7 @@ RmqListenSockConnectedCb(AsyncSocket *asock, // IN 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; }