]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
HGFS: Fix server channel characteristics for HGFS sessions
authorVMware, Inc <>
Fri, 12 Apr 2013 19:37:24 +0000 (12:37 -0700)
committerDmitry Torokhov <dtor@vmware.com>
Wed, 17 Apr 2013 19:16:32 +0000 (12:16 -0700)
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 <dtor@vmware.com>
open-vm-tools/lib/hgfsServer/hgfsServer.c
open-vm-tools/lib/hgfsServer/hgfsServerInt.h
open-vm-tools/lib/hgfsServer/hgfsServerParameters.c
open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c
open-vm-tools/lib/include/hgfsServer.h

index c88e9ee61fddada7e212357e8846250da9fe2840..6e0c2915b2dd7387bc47de338b0933c89a71c14e 100644 (file)
@@ -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;
index a2a63f2cea866dd5608138b89f5d619fdedfc4af..5aba0c2f5d4e59d675ce3514b743d491d9fafb63 100644 (file)
@@ -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);
index 53cf01398800afee5c7f003eecd9c8bd17d4a5d0..c9da1be18eeeb9a8564fcda28bf305e4ad7a08c6 100644 (file)
@@ -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 {
index 933299d60831c11edfb81ead56ae7eb1c5b5dde6..ce49573d160dd82b79fa37bb7899d585fffce38b 100644 (file)
@@ -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);
index 20859cc3958bc66997208de1008c7110941c0017..f3d22da15e8993ce07685fa864ab05c961962482 100644 (file)
@@ -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 *);