From: VMware, Inc <> Date: Fri, 12 Apr 2013 19:37:24 +0000 (-0700) Subject: HGFS: Fix server channel characteristics for HGFS sessions X-Git-Tag: 2013.04.16-1098359~98 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b04809b5e14b7139976c8b42feb69d2e7e1ae1da;p=thirdparty%2Fopen-vm-tools.git HGFS: Fix server channel characteristics for HGFS sessions Currently the HGFS session had hardcoded constants specific to VMCI set in the HGFS session object and which is returned to the client on a HGFS create session protocol request. The constant was not used by any client that was released but will be in the future releases. The HGFS session also can be used with the backdoor channel too, so this first change is to move the constant (maximum packet size) from the HGFS server into the channel specific code which passes it to the HGFS server on a connect call. The HGFS server connect call will create the HGFS server transport session object which will be used when creating the HGFS session object. Later changes will deal with the backward compatibility issues by updating the HGFS session protocol request to allow newer clients that use the session field for maximum packet size to determine the version of the server and correctness of the session reply field. Signed-off-by: Dmitry Torokhov --- diff --git a/open-vm-tools/lib/hgfsServer/hgfsServer.c b/open-vm-tools/lib/hgfsServer/hgfsServer.c index c88e9ee61..6e0c2915b 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServer.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServer.c @@ -177,7 +177,7 @@ static void HgfsServerSessionReceive(HgfsPacket *packet, void *clientData); static Bool HgfsServerSessionConnect(void *transportData, HgfsServerChannelCallbacks *channelCbTable, - uint32 channelCapabililies, + HgfsServerChannelData *channelCapabililies, void **clientData); static void HgfsServerSessionDisconnect(void *clientData); static void HgfsServerSessionClose(void *clientData); @@ -224,13 +224,6 @@ typedef struct HgfsSharedFolderProperties { static void HgfsServerTransportRemoveSessionFromList(HgfsTransportSessionInfo *transportSession, HgfsSessionInfo *sessionInfo); -/* - * Limit payload to 16M + header. - * This limit ensures that list of shared pages fits into VMCI datagram. - * Client may impose a lower limit in create session request. - */ -#define MAX_SERVER_PACKET_SIZE_V4 (0x1000000 + sizeof(HgfsHeader)) - /* Local functions. */ static void HgfsInvalidateSessionObjects(DblLnkLst_Links *shares, HgfsSessionInfo *session); @@ -3697,7 +3690,7 @@ HgfsServerEnumerateSharedFolders(void) static Bool HgfsServerSessionConnect(void *transportData, // IN: transport session context HgfsServerChannelCallbacks *channelCbTable, // IN: Channel callbacks - uint32 channelCapabilities, // IN: channel capabilities + HgfsServerChannelData *channelCapabilities, // IN: channel capabilities void **transportSessionData) // OUT: server session context { HgfsTransportSessionInfo *transportSession; @@ -3709,10 +3702,9 @@ HgfsServerSessionConnect(void *transportData, // IN: tra transportSession = Util_SafeCalloc(1, sizeof *transportSession); transportSession->transportData = transportData; transportSession->channelCbTable = channelCbTable; - transportSession->maxPacketSize = MAX_SERVER_PACKET_SIZE_V4; transportSession->type = HGFS_SESSION_TYPE_REGULAR; transportSession->state = HGFS_SESSION_STATE_OPEN; - transportSession->channelCapabilities = channelCapabilities; + transportSession->channelCapabilities = *channelCapabilities; transportSession->numSessions = 0; transportSession->sessionArrayLock = @@ -3759,7 +3751,6 @@ HgfsServerSessionConnect(void *transportData, // IN: tra Bool HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, // IN: - uint32 channelCapabilities, // IN: HgfsSessionInfo **sessionData) // OUT: { int i; @@ -3806,7 +3797,7 @@ HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, // IN: session->sessionId = HgfsGenerateSessionId(); session->state = HGFS_SESSION_STATE_OPEN; DblLnkLst_Init(&session->links); - session->maxPacketSize = MAX_SERVER_PACKET_SIZE_V4; + session->maxPacketSize = transportSession->channelCapabilities.maxPacketSize; session->activeNotification = FALSE; session->isInactive = TRUE; session->transportSession = transportSession; @@ -3860,7 +3851,7 @@ HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, // IN: HgfsServerGetDefaultCapabilities(session->hgfsSessionCapabilities, &session->numberOfCapabilities); - if (channelCapabilities & HGFS_CHANNEL_SHARED_MEM) { + if (transportSession->channelCapabilities.flags & HGFS_CHANNEL_SHARED_MEM) { HgfsServerSetSessionCapability(HGFS_OP_READ_FAST_V4, HGFS_REQUEST_SUPPORTED, session); HgfsServerSetSessionCapability(HGFS_OP_WRITE_FAST_V4, @@ -7801,7 +7792,6 @@ HgfsServerCreateSession(HgfsInputParam *input) // IN: Input params LOG(4, ("%s: create session\n", __FUNCTION__)); if (!HgfsServerAllocateSession(input->transportSession, - input->transportSession->channelCapabilities, &session)) { status = HGFS_ERROR_NOT_ENOUGH_MEMORY; goto abort; diff --git a/open-vm-tools/lib/hgfsServer/hgfsServerInt.h b/open-vm-tools/lib/hgfsServer/hgfsServerInt.h index a2a63f2ce..5aba0c2f5 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServerInt.h +++ b/open-vm-tools/lib/hgfsServer/hgfsServerInt.h @@ -38,6 +38,7 @@ struct DirectoryEntry; #include "hgfsUtil.h" // for HgfsInternalStatus #include "vm_atomic.h" #include "userlock.h" +#include "hgfsServer.h" // for the server public types #define HGFS_DEBUG_ASYNC (0) @@ -285,7 +286,7 @@ typedef struct HgfsTransportSessionInfo { Atomic_uint32 refCount; /* Reference count for session. */ - uint32 channelCapabilities; + HgfsServerChannelData channelCapabilities; } HgfsTransportSessionInfo; typedef struct HgfsSessionInfo { @@ -604,7 +605,6 @@ HgfsServerRestartSearchVirtualDir(HgfsGetNameFunc *getName, // IN: Name enum /* Allocate/Add sessions helper functions. */ Bool HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, - uint32 channelCapabilities, HgfsSessionInfo **sessionData); void HgfsServerSessionGet(HgfsSessionInfo *session); diff --git a/open-vm-tools/lib/hgfsServer/hgfsServerParameters.c b/open-vm-tools/lib/hgfsServer/hgfsServerParameters.c index 53cf01398..c9da1be18 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServerParameters.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServerParameters.c @@ -376,7 +376,6 @@ HgfsParseRequest(HgfsPacket *packet, // IN: request packet * Create a new session if the default session doesn't exist. */ if (!HgfsServerAllocateSession(transportSession, - transportSession->channelCapabilities, &session)) { result = HGFS_ERROR_NOT_ENOUGH_MEMORY; } else { diff --git a/open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c b/open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c index 933299d60..ce49573d1 100644 --- a/open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c +++ b/open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c @@ -344,6 +344,10 @@ static Bool HgfsChannelGuestConnConnect(HgfsGuestConn *connData) // IN: our connection data { Bool result; + static HgfsServerChannelData HgfsBdCapData = { + 0, + HGFS_LARGE_PACKET_MAX + }; connData->channelCbTable.getWriteVa = NULL; connData->channelCbTable.getReadVa = NULL; @@ -351,7 +355,7 @@ HgfsChannelGuestConnConnect(HgfsGuestConn *connData) // IN: our connection data connData->channelCbTable.send = HgfsChannelGuestBdSend; result = connData->serverCbTable->connect(connData, &connData->channelCbTable, - 0, + &HgfsBdCapData, &connData->serverSession); if (result) { HgfsChannelGuestConnGet(connData); diff --git a/open-vm-tools/lib/include/hgfsServer.h b/open-vm-tools/lib/include/hgfsServer.h index 20859cc39..f3d22da15 100644 --- a/open-vm-tools/lib/include/hgfsServer.h +++ b/open-vm-tools/lib/include/hgfsServer.h @@ -113,9 +113,15 @@ typedef uint32 HgfsSendFlags; #define HGFS_SEND_NO_COMPLETE (1 << 1) // Channel capability flags +typedef uint32 HgfsChannelFlags; #define HGFS_CHANNEL_SHARED_MEM (1 << 0) #define HGFS_CHANNEL_ASYNC (1 << 1) +typedef struct HgfsServerChannelData { + HgfsChannelFlags flags; + uint32 maxPacketSize; +}HgfsServerChannelData; + typedef Bool HgfsSessionSendFunc(void *opaqueSession, // IN char *buffer, // IN @@ -144,7 +150,7 @@ typedef struct HgfsServerChannelCallbacks { }HgfsServerChannelCallbacks; typedef struct HgfsServerSessionCallbacks { - Bool (*connect)(void *, HgfsServerChannelCallbacks *, uint32 ,void **); + Bool (*connect)(void *, HgfsServerChannelCallbacks *, HgfsServerChannelData *,void **); void (*disconnect)(void *); void (*close)(void *); void (*receive)(HgfsPacket *packet, void *);