]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Implement separate HgfsSessions for Transport layer and Sessions layer.
authorVMware, Inc <>
Mon, 21 Nov 2011 22:57:41 +0000 (14:57 -0800)
committerMarcelo Vanzin <mvanzin@vmware.com>
Mon, 21 Nov 2011 22:57:41 +0000 (14:57 -0800)
To make the hgFileCopy more robust, we have decided to implement
separate sessions in the transport layer and the session layer. I
implemented a list of sessions in the transport layer. Moved the necessary
attributes from HgfsTransportSessionInfo to HgfsSessionInfo. Modified
all the necessary server connect|disconnect|receive|... functions to handle
the packets properly.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/lib/hgfsServer/hgfsServer.c
open-vm-tools/lib/hgfsServer/hgfsServerInt.h
open-vm-tools/lib/hgfsServer/hgfsServerPacketUtil.c
open-vm-tools/lib/hgfsServer/hgfsServerParameters.c
open-vm-tools/lib/include/mutexRankLib.h

index 0a89e5b178464c75af179228f4f29cb053a0cb4c..787a4b15ff62f9fa97fb82e59a486e5552396780 100644 (file)
@@ -222,6 +222,11 @@ typedef struct HgfsSharedFolderProperties {
    Bool markedForDeletion;
 } HgfsSharedFolderProperties;
 
+static void HgfsServerTransportRemoveSessionFromList(HgfsTransportSessionInfo *transportSession,
+                                                     HgfsSessionInfo *sessionInfo);
+
+static void HgfsServerTransportAddSessionToList(HgfsTransportSessionInfo *transportSession,
+                                                HgfsSessionInfo *sessionInfo);
 /*
  *    Limit payload to 16M + header.
  *    This limit ensures that list of shared pages fits into VMCI datagram.
@@ -231,6 +236,9 @@ typedef struct HgfsSharedFolderProperties {
 
 /* Local functions. */
 
+static Bool HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession,
+                                      uint32 channelCapabilities,
+                                      HgfsSessionInfo **sessionData);
 static void HgfsInvalidateSessionObjects(DblLnkLst_Links *shares,
                                          HgfsSessionInfo *session);
 static Bool HgfsAddToCacheInternal(HgfsHandle handle,
@@ -361,12 +369,75 @@ static void
 HgfsServerSessionPut(HgfsSessionInfo *session)   // IN: session context
 {
    ASSERT(session);
+
    if (Atomic_FetchAndDec(&session->refCount) == 1) {
       HgfsServerExitSessionInternal(session);
    }
 }
 
 
+/*
+ *----------------------------------------------------------------------------
+ *
+ * HgfsServerTransportSessionGet --
+ *
+ *      Increment transport session reference count.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+HgfsServerTransportSessionGet(HgfsTransportSessionInfo *transportSession)   // IN: session context
+{
+   ASSERT(transportSession);
+   Atomic_Inc(&transportSession->refCount);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * HgfsServerTransportSessionPut --
+ *
+ *      Decrement transport session reference count.
+ *
+ *      Free session info data if no reference.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static void
+HgfsServerTransportSessionPut(HgfsTransportSessionInfo *transportSession)   // IN: transport session context
+{
+   ASSERT(transportSession);
+   if (Atomic_FetchAndDec(&transportSession->refCount) == 1) {
+      DblLnkLst_Links *curr, *next;
+
+      MXUser_AcquireExclLock(transportSession->sessionArrayLock);
+
+      DblLnkLst_ForEachSafe(curr, next,  &transportSession->sessionArray) {
+         HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links);
+         HgfsServerTransportRemoveSessionFromList(transportSession, session);
+         HgfsServerSessionPut(session);
+      }
+
+      MXUser_ReleaseExclLock(transportSession->sessionArrayLock);
+   }
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -2861,7 +2932,7 @@ HgfsServerCompleteRequest(HgfsInternalStatus status,   // IN: Status of the requ
       replySize = sizeof *header + replyPayloadSize;
       replyPacketSize = replySize;
       header = HSPU_GetReplyPacket(input->packet, &replyPacketSize,
-                                   input->session);
+                                   input->transportSession);
       packetOut = (char *)header;
 
       ASSERT_DEVEL(header && (replySize <= replyPacketSize));
@@ -2882,7 +2953,7 @@ HgfsServerCompleteRequest(HgfsInternalStatus status,   // IN: Status of the requ
       }
       replyPacketSize = replySize;
       reply = HSPU_GetReplyPacket(input->packet, &replyPacketSize,
-                                  input->session);
+                                  input->transportSession);
       packetOut = (char *)reply;
 
       ASSERT_DEVEL(reply && (replySize <= replyPacketSize));
@@ -2892,12 +2963,13 @@ HgfsServerCompleteRequest(HgfsInternalStatus status,   // IN: Status of the requ
       }
    }
    if (!HgfsPacketSend(input->packet, packetOut, replySize,
-                       input->session, 0)) {
+                       input->transportSession, 0)) {
       /* Send failed. Drop the reply. */
       LOG(4, ("Error sending reply\n"));
    }
 
    HgfsServerSessionPut(input->session);
+   HgfsServerTransportSessionPut(input->transportSession);
    free(input);
 }
 
@@ -2925,7 +2997,7 @@ HgfsServerProcessRequest(void *context)
    if (!input->metaPacket) {
       input->metaPacket = HSPU_GetMetaPacket(input->packet,
                                              &input->metaPacketSize,
-                                             input->session);
+                                             input->transportSession);
    }
 
    input->payload = (char *)input->metaPacket + input->payloadOffset;
@@ -2968,24 +3040,24 @@ static void
 HgfsServerSessionReceive(HgfsPacket *packet,      // IN: Hgfs Packet
                          void *clientData)        // IN: session info
 {
-   HgfsSessionInfo *session = (HgfsSessionInfo *)clientData;
+   HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData;
    HgfsInternalStatus status;
    HgfsInputParam *input = NULL;
 
-   ASSERT(session);
+   ASSERT(transportSession);
 
-   if (session->state == HGFS_SESSION_STATE_CLOSED) {
+   if (transportSession->state == HGFS_SESSION_STATE_CLOSED) {
       LOG(4, ("%s: %d: Received packet after disconnected.\n", __FUNCTION__,
               __LINE__));
       return;
    }
 
-   HgfsServerSessionGet(session);
+   HgfsServerTransportSessionGet(transportSession);
 
-   if (!HgfsParseRequest(packet, session, &input, &status)) {
+   if (!HgfsParseRequest(packet, transportSession, &input, &status)) {
       LOG(4, ("%s: %d: Can't generate any response for the guest, just exit.\n ",
               __FUNCTION__, __LINE__));
-      HgfsServerSessionPut(session);
+      HgfsServerTransportSessionPut(transportSession);
       return;
    }
 
@@ -3008,7 +3080,7 @@ HgfsServerSessionReceive(HgfsPacket *packet,      // IN: Hgfs Packet
              * Asynchronous processing is supported by the transport.
              * We can release mappings here and reacquire when needed.
              */
-            HSPU_PutMetaPacket(packet, session);
+            HSPU_PutMetaPacket(packet, transportSession);
             input->metaPacket = NULL;
             Atomic_Inc(&gHgfsAsyncCounter);
 
@@ -3048,6 +3120,111 @@ HgfsServerSessionReceive(HgfsPacket *packet,      // IN: Hgfs Packet
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerTransportGetSessionInfo --
+ *
+ *   Scans the list of sessions and return the session with the specified
+ *   session id.
+ *
+ * Results:
+ *    A valid pointer to HgfsSessionInfo if there is a session with the
+ *    specified session id. NULL, otherwise.
+ *
+ * Side effects:
+ *    None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+HgfsSessionInfo *
+HgfsServerTransportGetSessionInfo(HgfsTransportSessionInfo *transportSession,       // IN: transport session info
+                                  uint64 sessionId)                                 // IN: session id
+{
+   DblLnkLst_Links *curr;
+   HgfsSessionInfo *session = NULL;
+
+   ASSERT(transportSession);
+
+   MXUser_AcquireExclLock(transportSession->sessionArrayLock);
+
+   DblLnkLst_ForEach(curr, &transportSession->sessionArray) {
+      session = DblLnkLst_Container(curr, HgfsSessionInfo, links);
+      if (session->sessionId == sessionId) {
+         HgfsServerSessionGet(session);
+         break;
+      }
+      session = NULL;
+   }
+
+   MXUser_ReleaseExclLock(transportSession->sessionArrayLock);
+
+   return session;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerTransportRemoveSessionFromList --
+ *
+ *   Unlinks the specified session info from the list.
+ *
+ *   Note: The caller must acquire the sessionArrayLock in transportSession
+ *   before calling this function.
+ *
+ * Results:
+ *    None
+ *
+ * Side effects:
+ *    None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+HgfsServerTransportRemoveSessionFromList(HgfsTransportSessionInfo *transportSession,   // IN: transport session info
+                                         HgfsSessionInfo *session)                     // IN: session info
+{
+   ASSERT(transportSession);
+   ASSERT(session);
+
+   DblLnkLst_Unlink1(&session->links);
+   HgfsServerSessionPut(session);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerTransportAddSessionToList --
+ *
+ *   Links the specified session info to the list.
+ *
+ * Results:
+ *    None
+ *
+ * Side effects:
+ *    None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+HgfsServerTransportAddSessionToList(HgfsTransportSessionInfo *transportSession,       // IN: transport session info
+                                    HgfsSessionInfo *session)                         // IN: session info
+{
+   ASSERT(transportSession);
+   ASSERT(session);
+
+   MXUser_AcquireExclLock(transportSession->sessionArrayLock);
+   DblLnkLst_LinkLast(&transportSession->sessionArray, &session->links);
+   HgfsServerSessionGet(session);
+   MXUser_ReleaseExclLock(transportSession->sessionArrayLock);
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -3508,6 +3685,79 @@ HgfsServerEnumerateSharedFolders(void)
  *
  *    Initialize a new client session.
  *
+ *    Allocate HgfsTransportSessionInfo and initialize it.
+ *
+ * Results:
+ *    TRUE on success, FALSE otherwise.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static Bool
+HgfsServerSessionConnect(void *transportData,                         // IN: transport session context
+                         HgfsServerChannelCallbacks *channelCbTable,  // IN: Channel callbacks
+                         uint32 channelCapabilities,                  // IN: channel capabilities
+                         void **transportSessionData)                 // OUT: server session context
+{
+   HgfsTransportSessionInfo *transportSession;
+   HgfsSessionInfo *defaultSession;
+
+   ASSERT(transportSessionData);
+
+   LOG(4, ("%s: initting.\n", __FUNCTION__));
+
+   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->sessionArrayLock =
+         MXUser_CreateExclLock("HgfsSessionArrayLock",
+                               RANK_hgfsSessionArrayLock);
+   if (transportSession->sessionArrayLock == NULL) {
+      LOG(4, ("%s: Could not create session sync mutex.\n", __FUNCTION__));
+      free(transportSession);
+      return FALSE;
+   }
+
+   DblLnkLst_Init(&transportSession->sessionArray);
+
+   if (!HgfsServerAllocateSession(transportSession,
+                                  channelCapabilities,
+                                  &defaultSession)) {
+      MXUser_DestroyExclLock(transportSession->sessionArrayLock);
+      free(transportSession);
+      return FALSE;
+   }
+
+   defaultSession->type = HGFS_SESSION_TYPE_INTERNAL;
+   HgfsServerTransportAddSessionToList(transportSession, defaultSession);
+
+   transportSession->defaultSessionId = defaultSession->sessionId;
+
+   Atomic_Write(&transportSession->refCount, 0);
+
+   /* Give our session a reference to hold while we are open. */
+   HgfsServerTransportSessionGet(transportSession);
+
+   *transportSessionData = transportSession;
+   return TRUE;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerAllocateSession --
+ *
+ *    Initialize a new Hgfs session.
+ *
  *    Allocate HgfsSessionInfo and initialize it. Create the nodeArray and
  *    searchArray for the session.
  *
@@ -3521,17 +3771,16 @@ HgfsServerEnumerateSharedFolders(void)
  */
 
 static Bool
-HgfsServerSessionConnect(void *transportData,                         // IN: transport session context
-                         HgfsServerChannelCallbacks *channelCbTable,  // IN: Channel callbacks
-                         uint32 channelCapabililies,                  // IN: channel capabilities
-                         void **sessionData)                          // OUT: server session context
+HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, // IN:
+                          uint32 channelCapabilities,                 // IN:
+                          HgfsSessionInfo **sessionData)              // OUT:
 {
    int i;
-   HgfsSessionInfo *session = Util_SafeMalloc(sizeof *session);
+   HgfsSessionInfo *session;
 
-   ASSERT(sessionData);
+   ASSERT(transportSession);
 
-   LOG(4, ("%s: initting.\n", __FUNCTION__));
+   session = Util_SafeCalloc(1, sizeof *session);
 
    /*
     * Initialize all our locks first as these can fail.
@@ -3540,9 +3789,8 @@ HgfsServerSessionConnect(void *transportData,                         // IN: tra
    session->fileIOLock = MXUser_CreateExclLock("HgfsFileIOLock",
                                                RANK_hgfsFileIOLock);
    if (session->fileIOLock == NULL) {
-      free(session);
       LOG(4, ("%s: Could not create node array sync mutex.\n", __FUNCTION__));
-
+      free(session);
       return FALSE;
    }
 
@@ -3550,9 +3798,8 @@ HgfsServerSessionConnect(void *transportData,                         // IN: tra
                                                   RANK_hgfsNodeArrayLock);
    if (session->nodeArrayLock == NULL) {
       MXUser_DestroyExclLock(session->fileIOLock);
-      free(session);
       LOG(4, ("%s: Could not create node array sync mutex.\n", __FUNCTION__));
-
+      free(session);
       return FALSE;
    }
 
@@ -3561,16 +3808,20 @@ HgfsServerSessionConnect(void *transportData,                         // IN: tra
    if (session->searchArrayLock == NULL) {
       MXUser_DestroyExclLock(session->fileIOLock);
       MXUser_DestroyExclLock(session->nodeArrayLock);
-      free(session);
       LOG(4, ("%s: Could not create search array sync mutex.\n",
               __FUNCTION__));
-
+      free(session);
       return FALSE;
    }
 
    session->sessionId = HgfsGenerateSessionId();
+   session->type = HGFS_SESSION_TYPE_REGULAR;
+   session->state = HGFS_SESSION_STATE_OPEN;
+   DblLnkLst_Init(&session->links);
    session->maxPacketSize = MAX_SERVER_PACKET_SIZE_V4;
    session->activeNotification = FALSE;
+   session->transportSession = transportSession;
+
    /*
     * Initialize the node handling components.
     */
@@ -3598,6 +3849,11 @@ HgfsServerSessionConnect(void *transportData,                         // IN: tra
    /* Initialize search freelist. */
    DblLnkLst_Init(&session->searchFreeList);
 
+   Atomic_Write(&session->refCount, 0);
+
+   /* Give our session a reference to hold while we are open. */
+   HgfsServerSessionGet(session);
+
    /* Allocate array of searches and add them to free list. */
    session->numSearches = NUM_SEARCHES;
    session->searchArray = Util_SafeCalloc(session->numSearches,
@@ -3610,25 +3866,11 @@ HgfsServerSessionConnect(void *transportData,                         // IN: tra
                          &session->searchArray[i].links);
    }
 
-   /*
-    * Initialize the general session stuff.
-    */
-
-   session->type = HGFS_SESSION_TYPE_REGULAR;
-   session->state = HGFS_SESSION_STATE_OPEN;
-   session->transportData = transportData;
-   session->channelCbTable = channelCbTable;
-   Atomic_Write(&session->refCount, 0);
-
    /* Get common to all sessions capabiities. */
    HgfsServerGetDefaultCapabilities(session->hgfsSessionCapabilities,
                                     &session->numberOfCapabilities);
 
-   /* Give our session a reference to hold while we are open. */
-   HgfsServerSessionGet(session);
-   *sessionData = session;
-
-   if (channelCapabililies & HGFS_CHANNEL_SHARED_MEM) {
+   if (channelCapabilities & HGFS_CHANNEL_SHARED_MEM) {
       HgfsServerSetSessionCapability(HGFS_OP_READ_FAST_V4,
                                      HGFS_REQUEST_SUPPORTED, session);
       HgfsServerSetSessionCapability(HGFS_OP_WRITE_FAST_V4,
@@ -3651,6 +3893,8 @@ HgfsServerSessionConnect(void *transportData,                         // IN: tra
                                      HGFS_REQUEST_SUPPORTED, session);
    }
 
+   *sessionData = session;
+
    return TRUE;
 }
 
@@ -3658,7 +3902,7 @@ HgfsServerSessionConnect(void *transportData,                         // IN: tra
 /*
  *-----------------------------------------------------------------------------
  *
- * HgfsServerSessionDisconnect --
+ * HgfsDisconnectSessionInt --
  *
  *    Disconnect a client session.
  *
@@ -3676,9 +3920,8 @@ HgfsServerSessionConnect(void *transportData,                         // IN: tra
  */
 
 static void
-HgfsServerSessionDisconnect(void *clientData)    // IN: session context
+HgfsDisconnectSessionInt(HgfsSessionInfo *session)    // IN: session context
 {
-   HgfsSessionInfo *session = (HgfsSessionInfo *)clientData;
 
    ASSERT(session);
    ASSERT(session->nodeArray);
@@ -3686,8 +3929,48 @@ HgfsServerSessionDisconnect(void *clientData)    // IN: session context
    if (session->activeNotification) {
       HgfsNotify_CleanupSession(session);
    }
+}
 
-   session->state = HGFS_SESSION_STATE_CLOSED;
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerSessionDisconnect --
+ *
+ *    Disconnect a client session.
+ *
+ *    Mark the session as closed as we are in the process of teardown
+ *    of the session. No more new requests should be processed. We would
+ *    start draining any outstanding pending operations at this point.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+HgfsServerSessionDisconnect(void *clientData)    // IN: session context
+{
+   HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData;
+   DblLnkLst_Links *curr, *next;
+
+   ASSERT(transportSession);
+
+   MXUser_AcquireExclLock(transportSession->sessionArrayLock);
+
+   DblLnkLst_ForEachSafe(curr, next, &transportSession->sessionArray) {
+      HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links);
+
+      HgfsDisconnectSessionInt(session);
+   }
+
+   MXUser_ReleaseExclLock(transportSession->sessionArrayLock);
+
+   transportSession->state = HGFS_SESSION_STATE_CLOSED;
 }
 
 
@@ -3713,16 +3996,13 @@ HgfsServerSessionDisconnect(void *clientData)    // IN: session context
 static void
 HgfsServerSessionClose(void *clientData)    // IN: session context
 {
-   HgfsSessionInfo *session = (HgfsSessionInfo *)clientData;
-
-   ASSERT(session);
-   ASSERT(session->nodeArray);
-   ASSERT(session->searchArray);
+   HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData;
 
-   ASSERT(session->state == HGFS_SESSION_STATE_CLOSED);
+   ASSERT(transportSession);
+   ASSERT(transportSession->state == HGFS_SESSION_STATE_CLOSED);
 
    /* Remove, typically, the last reference, will teardown everything. */
-   HgfsServerSessionPut(session);
+   HgfsServerTransportSessionPut(transportSession);
 }
 
 
@@ -3797,6 +4077,7 @@ HgfsServerExitSessionInternal(HgfsSessionInfo *session)    // IN: session contex
    MXUser_DestroyExclLock(session->nodeArrayLock);
    MXUser_DestroyExclLock(session->searchArrayLock);
    MXUser_DestroyExclLock(session->fileIOLock);
+
    free(session);
 }
 
@@ -3864,19 +4145,20 @@ HgfsServer_SetHandleCounter(uint32 newHandleCounter)
  * Side effects:
  *    Frees the packet buffer.
  *
- *----------------------------------------------------------------------------
+ *---------------------------------------------------------------------------
  */
 
 void
 HgfsServerSessionSendComplete(HgfsPacket *packet,   // IN/OUT: Hgfs packet
                               void *clientData)     // IN: session info
 {
-   HgfsSessionInfo *session = (HgfsSessionInfo *)clientData;
+   HgfsTransportSessionInfo *transportSession =
+         (HgfsTransportSessionInfo *)clientData;
 
    if (packet->guestInitiated) {
-      HSPU_PutMetaPacket(packet, session);
-      HSPU_PutReplyPacket(packet, session);
-      HSPU_PutDataPacketBuf(packet, session);
+      HSPU_PutMetaPacket(packet, transportSession);
+      HSPU_PutReplyPacket(packet, transportSession);
+      HSPU_PutDataPacketBuf(packet, transportSession);
    } else {
       free(packet->metaPacket);
       free(packet);
@@ -3981,19 +4263,19 @@ Bool
 HgfsPacketSend(HgfsPacket *packet,            // IN/OUT: Hgfs Packet
                char *packetOut,               // IN: output buffer
                size_t packetOutLen,           // IN: packet size
-               HgfsSessionInfo *session,      // IN: session info
+               HgfsTransportSessionInfo *transportSession,      // IN: session info
                HgfsSendFlags flags)           // IN: flags for how to process
 {
    Bool result = FALSE;
    Bool notificationNeeded = packet->guestInitiated && packet->processedAsync;
 
    ASSERT(packet);
-   ASSERT(session);
+   ASSERT(transportSession);
 
-   if (session->state == HGFS_SESSION_STATE_OPEN) {
+   if (transportSession->state == HGFS_SESSION_STATE_OPEN) {
       packet->replyPacketSize = packetOutLen;
-      ASSERT(session->type == HGFS_SESSION_TYPE_REGULAR);
-      result = session->channelCbTable->send(session->transportData,
+      ASSERT(transportSession->type == HGFS_SESSION_TYPE_REGULAR);
+      result = transportSession->channelCbTable->send(transportSession->transportData,
                                              packet, packetOut,
                                              packetOutLen, flags);
    }
@@ -4146,11 +4428,23 @@ HgfsInvalidateSessionObjects(DblLnkLst_Links *shares,  // IN: List of new shares
 
 void
 HgfsServerSessionInvalidateObjects(void *clientData,         // IN:
-                                    DblLnkLst_Links *shares)  // IN: List of new shares
+                                   DblLnkLst_Links *shares)  // IN: List of new shares
 {
-   HgfsSessionInfo *session = (HgfsSessionInfo *)clientData;
+   HgfsTransportSessionInfo *transportSession =
+         (HgfsTransportSessionInfo *)clientData;
+   DblLnkLst_Links *curr;
+
+   ASSERT(transportSession);
+   MXUser_AcquireExclLock(transportSession->sessionArrayLock);
 
-   HgfsInvalidateSessionObjects(shares, session);
+   DblLnkLst_ForEach(curr, &transportSession->sessionArray) {
+      HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links);
+      HgfsServerSessionGet(session);
+      HgfsInvalidateSessionObjects(shares, session);
+      HgfsServerSessionPut(session);
+   }
+
+   MXUser_ReleaseExclLock(transportSession->sessionArrayLock);
 }
 
 
@@ -5206,7 +5500,7 @@ HgfsAllocInitReply(HgfsPacket *packet,           // IN/OUT: Hgfs Packet
       headerSize = sizeof(HgfsReply);
    }
    replyPacketSize = headerSize + payloadSize;
-   reply = HSPU_GetReplyPacket(packet, &replyPacketSize, session);
+   reply = HSPU_GetReplyPacket(packet, &replyPacketSize, session->transportSession);
 
    if (reply && (replyPacketSize >= headerSize + payloadSize)) {
       memset(reply, 0, headerSize + payloadSize);
@@ -5273,7 +5567,7 @@ HgfsServerRead(HgfsInputParam *input)  // IN: Input params
                   payload = &reply->payload[0];
                } else {
                   payload = HSPU_GetDataPacketBuf(input->packet, BUF_WRITEABLE,
-                                                  input->session);
+                                                  input->transportSession);
                }
                if (payload) {
                   status = HgfsPlatformReadFile(file, input->session, offset,
@@ -7689,7 +7983,7 @@ HgfsServerSearchRead(HgfsInputParam *input)  // IN: Input params
 
          if (inlineDataSize == 0) {
             info.replyPayload = HSPU_GetDataPacketBuf(input->packet, BUF_WRITEABLE,
-                                                      input->session);
+                                                      input->transportSession);
          } else {
             info.replyPayload = (char *)info.reply + baseReplySize;
          }
@@ -7793,20 +8087,23 @@ HgfsServerCreateSession(HgfsInputParam *input)  // IN: Input params
 
    if (HgfsUnpackCreateSessionRequest(input->payload, input->payloadSize,
                                       input->op, &info)) {
+      HgfsSessionInfo *session;
       LOG(4, ("%s: create session\n", __FUNCTION__));
+
+      if (!HgfsServerAllocateSession(input->transportSession,
+                                     input->transportSession->channelCapabilities,
+                                     &session)) {
+         status = HGFS_ERROR_NOT_ENOUGH_MEMORY;
+         goto abort;
+      } else {
+         HgfsServerTransportAddSessionToList(input->transportSession, session);
+      }
+
       if (info.maxPacketSize < input->session->maxPacketSize) {
          input->session->maxPacketSize = info.maxPacketSize;
       }
       if (HgfsPackCreateSessionReply(input->packet, input->metaPacket,
-                                     &replyPayloadSize, input->session)) {
-
-         /*
-          * XXX - TO BE RESTORED on session support implementation
-          * completion.
-          */
-#if defined HGFS_SESSION_SUPPORT
-         HgfsServerSessionGet(input->session);
-#endif
+                                     &replyPayloadSize, session)) {
          status = HGFS_ERROR_SUCCESS;
       } else {
          status = HGFS_ERROR_INTERNAL;
@@ -7815,6 +8112,7 @@ HgfsServerCreateSession(HgfsInputParam *input)  // IN: Input params
       status = HGFS_ERROR_PROTOCOL;
    }
 
+abort:
    HgfsServerCompleteRequest(status, replyPayloadSize, input);
 }
 
@@ -7838,16 +8136,41 @@ HgfsServerCreateSession(HgfsInputParam *input)  // IN: Input params
 static void
 HgfsServerDestroySession(HgfsInputParam *input)  // IN: Input params
 {
+   HgfsTransportSessionInfo *transportSession;
+   HgfsSessionInfo *session;
+
    HGFS_ASSERT_INPUT(input);
 
-   HgfsServerCompleteRequest(HGFS_ERROR_SUCCESS, 0, input);
+   transportSession = input->transportSession;
+   session = input->session;
+
+   if ((session->sessionId == transportSession->defaultSessionId) ||
+       (session->type != HGFS_SESSION_TYPE_REGULAR)) {
+
+      /*
+       * In each transport session, there will be a default session. This
+       * default session should be in opened state till the end of the
+       * transport session. If we receive a destroy session request for
+       * default session, then we are receiving the requests for a malformed
+       * client. Return an error.
+       */
+      HgfsServerCompleteRequest(HGFS_STATUS_PROTOCOL_ERROR, 0, input);
+      return;
+   }
+
+   session->state = HGFS_SESSION_STATE_CLOSED;
+
    /*
-    * XXX - TO BE RESTORED on session support implementation
-    * completion.
-      */
-#if defined HGFS_SESSION_SUPPORT
-   HgfsServerSessionPut(input->session);
-#endif
+    * Remove the session from the list. By doing that, the refcount of
+    * the session will be decremented. Later, we will be invoking
+    * HgfsServerCompleteRequest which will decrement the session's
+    * refcount and cleanup the session
+    */
+   MXUser_AcquireExclLock(transportSession->sessionArrayLock);
+   HgfsServerTransportRemoveSessionFromList(transportSession, session);
+   MXUser_ReleaseExclLock(transportSession->sessionArrayLock);
+   HgfsServerCompleteRequest(HGFS_ERROR_SUCCESS, 0, input);
+   HgfsServerSessionPut(session);
 }
 
 
@@ -8000,7 +8323,7 @@ Hgfs_NotificationCallback(HgfsSharedFolderHandle sharedFolder, // IN: shared fol
 
       HgfsPackChangeNotificationRequest(packetHeader, subscriber, shareName, fileName, mask,
                                         flags, session, &sizeNeeded);
-      if (!HgfsPacketSend(packet, (char *)packetHeader,  sizeNeeded, session, 0)) {
+      if (!HgfsPacketSend(packet, (char *)packetHeader,  sizeNeeded, session->transportSession, 0)) {
          LOG(4, ("%s: failed to send notification to the host\n", __FUNCTION__));
       }
 
index 79744a59d677ef2f37a744e33bc78ba2c11d9b99..1a6b9290f9ff00939a27f7f1a9890a5577bc21f5 100644 (file)
@@ -278,15 +278,21 @@ typedef enum {
    HGFS_SESSION_TYPE_INTERNAL,     /* This is a static session. */
 } HgfsSessionInfoType;
 
-/* HgfsTransportSessionState, used for session status. */
+/* HgfsSessionState, used for session status. */
 typedef enum {
    HGFS_SESSION_STATE_OPEN,
    HGFS_SESSION_STATE_CLOSED,
 } HgfsSessionInfoState;
 
-typedef struct HgfsSessionInfo {
-   /* Unique session id. */
-   uint64 sessionId;
+typedef struct HgfsTransportSessionInfo {
+   /* Default session id. */
+   uint64 defaultSessionId;
+
+   /* Lock to manipulate the list of sessions */
+   MXUserExclLock *sessionArrayLock;
+
+   /* List of sessions */
+   DblLnkLst_Links sessionArray;
 
    /* Max packet size that is supported by both client and server. */
    uint32 maxPacketSize;
@@ -303,6 +309,30 @@ typedef struct HgfsSessionInfo {
    /* Function callbacks into Hgfs Channels. */
    HgfsServerChannelCallbacks *channelCbTable;
 
+   Atomic_uint32 refCount;    /* Reference count for session. */
+
+   uint32 channelCapabilities;
+} HgfsTransportSessionInfo;
+
+typedef struct HgfsSessionInfo {
+
+   DblLnkLst_Links links;
+
+   /* Unique session id. */
+   uint64 sessionId;
+
+   /* Max packet size that is supported by both client and server. */
+   uint32 maxPacketSize;
+
+   /* Transport session context. */
+   HgfsTransportSessionInfo *transportSession;
+
+   /* Current state of the session. */
+   HgfsSessionInfoState state;
+
+   /* Session is dynamic or internal. */
+   HgfsSessionInfoType type;
+
    /* Lock to ensure some fileIO requests are atomic for a handle. */
    MXUserExclLock *fileIOLock;
 
@@ -359,10 +389,8 @@ typedef struct HgfsSessionInfo {
    uint32 numberOfCapabilities;
 
    Bool activeNotification;
-
 } HgfsSessionInfo;
 
-
 /*
  * These structs represent information about file open requests, file
  * attributes, and directory creation requests.
@@ -474,6 +502,7 @@ typedef struct HgfsInputParam {
    const char *metaPacket;
    size_t metaPacketSize;
    HgfsSessionInfo *session;
+   HgfsTransportSessionInfo *transportSession;
    HgfsPacket *packet;
    void const *payload;
    uint32 payloadOffset;
@@ -568,7 +597,7 @@ HgfsServerSearchVirtualDir(HgfsGetNameFunc *getName,     // IN: Name enumerator
 
 Bool
 HgfsParseRequest(HgfsPacket *packet,          // IN: request packet
-                 HgfsSessionInfo *session,    // IN: current session
+                 HgfsTransportSessionInfo *transportSession,    // IN: current session
                  HgfsInputParam **input,      // OUT: request parameters
                  HgfsInternalStatus *status); // OUT: error code
 
@@ -1032,14 +1061,19 @@ HgfsPackAndSendPacket(HgfsPacket *packet,           // IN/OUT: Hgfs Packet
                       size_t packetOutLen,          // IN: Output packet size
                       HgfsInternalStatus status,    // IN: status
                       HgfsHandle id,                // IN: id of the request packet
-                      HgfsSessionInfo *session,     // IN: session info
+                      HgfsTransportSessionInfo *transportSession,     // IN: session info
                       HgfsSendFlags flags);         // IN: flags how to send
 
+/* Get the session with a specific session id */
+HgfsSessionInfo *
+HgfsServerTransportGetSessionInfo(HgfsTransportSessionInfo *transportSession,   // IN: transport session info
+                                  uint64 sessionId);                            // IN: session id
+
 Bool
 HgfsPacketSend(HgfsPacket *packet,            // IN/OUT: Hgfs Packet
                char *packetOut,               // IN: Output packet buffer
                size_t packetOutLen,           // IN: Output packet size
-               HgfsSessionInfo *session,      // IN: session info
+               HgfsTransportSessionInfo *transportSession,      // IN: session info
                HgfsSendFlags flags);          // IN: flags how to send
 
 Bool
@@ -1163,8 +1197,6 @@ HgfsPlatformValidateOpen(HgfsFileOpenInfo *openInfo, // IN: Open info struct
                          HgfsSessionInfo *session,   // IN: Session info
                          HgfsLocalId *localId,       // OUT: Local unique file ID
                          fileDesc *newHandle);       // OUT: Handle to the file
-void HgfsServerSessionGet(HgfsSessionInfo *session); // IN: session context
-
 void *
 HSPU_GetBuf(HgfsPacket *packet,           // IN/OUT: Hgfs Packet
             uint32 startIndex,            // IN: start index of iov
@@ -1172,21 +1204,21 @@ HSPU_GetBuf(HgfsPacket *packet,           // IN/OUT: Hgfs Packet
             size_t bufSize,               // IN: Size of buffer
             Bool *isAllocated,            // OUT: Was buffer allocated ?
             MappingType mappingType,      // IN: Readable/ Writeable ?
-            HgfsSessionInfo *session);    // IN: Session Info
+            HgfsTransportSessionInfo *transportSession);    // IN: Session Info
 
 void *
 HSPU_GetMetaPacket(HgfsPacket *packet,          // IN/OUT: Hgfs Packet
                    size_t *metaPacketSize,      // OUT: Size of metaPacket
-                   HgfsSessionInfo *session);   // IN: Session Info
+                   HgfsTransportSessionInfo *transportSession);   // IN: Session Info
 
 void *
 HSPU_GetDataPacketBuf(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
                       MappingType mappingType,   // IN: Readable/ Writeable ?
-                      HgfsSessionInfo *session); // IN: Session Info
+                      HgfsTransportSessionInfo *transportSession); // IN: Session Info
 
 void
 HSPU_PutPacket(HgfsPacket *packet,         // IN/OUT: Hgfs Packet
-               HgfsSessionInfo *session);  // IN: Session Info
+               HgfsTransportSessionInfo *transportSession);  // IN: Session Info
 
 void
 HSPU_PutBuf(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
@@ -1195,33 +1227,33 @@ HSPU_PutBuf(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
             size_t *bufSize,           // IN: Size of the buffer
             Bool *isAllocated,         // IN: Was buffer allocated ?
             MappingType mappingType,   // IN: Readable/ Writeable ?
-            HgfsSessionInfo *session); // IN: Session info
+            HgfsTransportSessionInfo *transportSession); // IN: Session info
 
 void
 HSPU_PutDataPacketBuf(HgfsPacket *packet,         // IN/OUT: Hgfs Packet
-                      HgfsSessionInfo *session);  // IN: Session Info
+                      HgfsTransportSessionInfo *transportSession);  // IN: Session Info
 
 void
 HSPU_PutMetaPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
-                   HgfsSessionInfo *session); // IN: Session Info
+                   HgfsTransportSessionInfo *transportSession); // IN: Session Info
 
 void
 HSPU_CopyBufToDataIovec(HgfsPacket *packet,       // IN/OUT: Hgfs packet
                         void *buf,                // IN: Buffer to copy from
                         uint32 bufSize,           // IN: Size of buffer
-                        HgfsSessionInfo *session);// IN: Session Info
+                        HgfsTransportSessionInfo *transportSession);// IN: Session Info
 void
 HSPU_CopyBufToIovec(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
                     uint32 startIndex,        // IN: start index into iov
                     void *buf,                // IN: Buffer
                     size_t bufSize,           // IN: Size of buffer
-                    HgfsSessionInfo *session); // IN: Session Info
+                    HgfsTransportSessionInfo *transportSession); // IN: Session Info
 void *
 HSPU_GetReplyPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
                     size_t *replyPacketSize,   //IN/OUT: Size of reply Packet
-                    HgfsSessionInfo *session); // IN: Session Info
+                    HgfsTransportSessionInfo *transportSession); // IN: Session Info
 
 void
 HSPU_PutReplyPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
-                    HgfsSessionInfo *session); // IN: Session Info
+                    HgfsTransportSessionInfo *transportSession); // IN: Session Info
 #endif /* __HGFS_SERVER_INT_H__ */
index b0e61511b0893032f6818c388e9c5b408ff763e7..cf436a798bb58d3e1863ccf01902ac8c3365e716 100644 (file)
@@ -53,9 +53,9 @@
 void *
 HSPU_GetReplyPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
                     size_t *replyPacketSize,   // IN/OUT: Size of reply Packet
-                    HgfsSessionInfo *session)  // IN: Session Info
+                    HgfsTransportSessionInfo *transportSession)  // IN: Session Info
 {
-   ASSERT(session);
+   ASSERT(transportSession);
    if (packet->replyPacket) {
       /*
        * When we are transferring packets over backdoor, reply packet
@@ -64,7 +64,7 @@ HSPU_GetReplyPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
       LOG(4, ("Exising reply packet %s %Zu %Zu\n", __FUNCTION__,
               *replyPacketSize, packet->replyPacketSize));
       ASSERT_DEVEL(*replyPacketSize <= packet->replyPacketSize);
-   } else if (session->channelCbTable && session->channelCbTable->getWriteVa) {
+   } else if (transportSession->channelCbTable && transportSession->channelCbTable->getWriteVa) {
      /* Can we write directly into guest memory ? */
       ASSERT_DEVEL(packet->metaPacket);
       if (packet->metaPacket) {
@@ -79,7 +79,7 @@ HSPU_GetReplyPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
                                            packet->metaPacketSize,
                                            &packet->metaPacketIsAllocated,
                                            BUF_WRITEABLE,
-                                           session);
+                                           transportSession);
          /*
           * Really this can never happen, we would have caught bad physical address
           * during getMetaPacket.
@@ -117,7 +117,7 @@ HSPU_GetReplyPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
 
 void
 HSPU_PutReplyPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
-                    HgfsSessionInfo *session)  // IN: Session Info
+                    HgfsTransportSessionInfo *transportSession)  // IN: Session Info
 {
    if (packet->replyPacketIsAllocated) {
       LOG(10, ("%s Freeing reply packet", __FUNCTION__));
@@ -148,13 +148,13 @@ HSPU_PutReplyPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
 void *
 HSPU_GetMetaPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
                    size_t *metaPacketSize,    // OUT: Size of metaPacket
-                   HgfsSessionInfo *session)  // IN: Session Info
+                   HgfsTransportSessionInfo *transportSession)  // IN: Session Info
 {
    *metaPacketSize = packet->metaPacketSize;
    return HSPU_GetBuf(packet, 0, &packet->metaPacket,
                       packet->metaPacketSize,
                       &packet->metaPacketIsAllocated,
-                      BUF_READWRITEABLE, session);
+                      BUF_READWRITEABLE, transportSession);
 }
 
 
@@ -176,7 +176,7 @@ HSPU_GetMetaPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
 
 void *
 HSPU_GetDataPacketIov(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
-                      HgfsSessionInfo *session, // IN: Session Info
+                      HgfsTransportSessionInfo *transportSession, // IN: Session Info
                       HgfsVaIov iov)            // OUT: I/O vector
 {
    NOT_IMPLEMENTED();
@@ -204,12 +204,12 @@ HSPU_GetDataPacketIov(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
 void *
 HSPU_GetDataPacketBuf(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
                       MappingType mappingType,  // IN: Writeable/Readable
-                      HgfsSessionInfo *session) // IN: Session Info
+                      HgfsTransportSessionInfo *transportSession) // IN: Session Info
 {
    packet->dataMappingType = mappingType;
    return HSPU_GetBuf(packet, packet->dataPacketIovIndex,
                       &packet->dataPacket, packet->dataPacketSize,
-                      &packet->dataPacketIsAllocated, mappingType, session);
+                      &packet->dataPacketIsAllocated, mappingType, transportSession);
 }
 
 
@@ -236,7 +236,7 @@ HSPU_GetBuf(HgfsPacket *packet,           // IN/OUT: Hgfs Packet
             size_t  bufSize,              // IN: Size of buffer
             Bool *isAllocated,            // OUT: Was buffer allocated ?
             MappingType mappingType,      // IN: Readable/Writeable ?
-            HgfsSessionInfo *session)     // IN: Session Info
+            HgfsTransportSessionInfo *transportSession)     // IN: Session Info
 {
    uint32 iovCount;
    uint32 iovMapped = 0;
@@ -251,16 +251,16 @@ HSPU_GetBuf(HgfsPacket *packet,           // IN/OUT: Hgfs Packet
       return NULL;
    }
 
-   if (!session->channelCbTable) {
+   if (!transportSession->channelCbTable) {
       return NULL;
    }
 
    if (mappingType == BUF_WRITEABLE ||
        mappingType == BUF_READWRITEABLE) {
-      func = session->channelCbTable->getWriteVa;
+      func = transportSession->channelCbTable->getWriteVa;
    } else {
       ASSERT(mappingType == BUF_READABLE);
-      func = session->channelCbTable->getReadVa;
+      func = transportSession->channelCbTable->getReadVa;
    }
 
    /* Looks like we are in the middle of poweroff. */
@@ -329,7 +329,7 @@ HSPU_GetBuf(HgfsPacket *packet,           // IN/OUT: Hgfs Packet
 
 freeMem:
    for (i = startIndex; i < iovCount; i++) {
-      session->channelCbTable->putVa(&packet->iov[i].token);
+      transportSession->channelCbTable->putVa(&packet->iov[i].token);
       packet->iov[i].va = NULL;
    }
 
@@ -355,13 +355,13 @@ freeMem:
 
 void
 HSPU_PutMetaPacket(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
-                   HgfsSessionInfo *session) // IN: Session Info
+                   HgfsTransportSessionInfo *transportSession) // IN: Session Info
 {
    LOG(4, ("%s Hgfs Putting Meta packet\n", __FUNCTION__));
    HSPU_PutBuf(packet, 0, &packet->metaPacket,
                &packet->metaPacketSize,
                &packet->metaPacketIsAllocated,
-               BUF_WRITEABLE, session);
+               BUF_WRITEABLE, transportSession);
 }
 
 
@@ -405,14 +405,14 @@ HSPU_PutDataPacketIov()
 
 void
 HSPU_PutDataPacketBuf(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
-                      HgfsSessionInfo *session)  // IN: Session Info
+                      HgfsTransportSessionInfo *transportSession)  // IN: Session Info
 {
 
    LOG(4, ("%s Hgfs Putting Data packet\n", __FUNCTION__));
    HSPU_PutBuf(packet, packet->dataPacketIovIndex,
                &packet->dataPacket, &packet->dataPacketSize,
                &packet->dataPacketIsAllocated,
-               packet->dataMappingType, session);
+               packet->dataMappingType, transportSession);
 }
 
 
@@ -438,23 +438,23 @@ HSPU_PutBuf(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
             size_t *bufSize,           // IN: Size of the buffer
             Bool *isAllocated,         // IN: Was buffer allocated ?
             MappingType mappingType,   // IN: Readable / Writeable ?
-            HgfsSessionInfo *session)  // IN: Session info
+            HgfsTransportSessionInfo *transportSession)  // IN: Session info
 {
    uint32 iovCount = 0;
    int size = *bufSize;
    ASSERT(buf);
 
-   if (!session->channelCbTable) {
+   if (!transportSession->channelCbTable) {
       return;
    }
 
-   if (!session->channelCbTable->putVa || *buf == NULL) {
+   if (!transportSession->channelCbTable->putVa || *buf == NULL) {
       return;
    }
 
    if (*isAllocated) {
       if (mappingType == BUF_WRITEABLE) {
-         HSPU_CopyBufToIovec(packet, startIndex, *buf, *bufSize, session);
+         HSPU_CopyBufToIovec(packet, startIndex, *buf, *bufSize, transportSession);
       }
       LOG(10, ("%s: Hgfs Freeing buffer \n", __FUNCTION__));
       free(*buf);
@@ -464,7 +464,7 @@ HSPU_PutBuf(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
            iovCount < packet->iovCount && size > 0;
            iovCount++) {
          ASSERT_DEVEL(packet->iov[iovCount].token);
-         session->channelCbTable->putVa(&packet->iov[iovCount].token);
+         transportSession->channelCbTable->putVa(&packet->iov[iovCount].token);
          size -= packet->iov[iovCount].len;
       }
       LOG(10, ("%s: Hgfs bufSize = %d \n", __FUNCTION__, size));
@@ -493,9 +493,9 @@ void
 HSPU_CopyBufToMetaIovec(HgfsPacket *packet,      // IN/OUT: Hgfs packet
                         void *buf,               // IN: Buffer to copy from
                         size_t bufSize,          // IN: Size of buffer
-                        HgfsSessionInfo *session)// IN: Session Info
+                        HgfsTransportSessionInfo *transportSession)// IN: Session Info
 {
-   HSPU_CopyBufToIovec(packet, 0, buf, bufSize, session);
+   HSPU_CopyBufToIovec(packet, 0, buf, bufSize, transportSession);
 }
 
 
@@ -518,10 +518,10 @@ void
 HSPU_CopyBufToDataIovec(HgfsPacket *packet,   // IN: Hgfs packet
                         void *buf,            // IN: Buffer to copy from
                         uint32 bufSize,       // IN: Size of buffer
-                        HgfsSessionInfo *session)
+                        HgfsTransportSessionInfo *transportSession)
 {
    HSPU_CopyBufToIovec(packet, packet->dataPacketIovIndex, buf, bufSize,
-                       session);
+                       transportSession);
 }
 
 
@@ -545,7 +545,7 @@ HSPU_CopyBufToIovec(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
                     uint32 startIndex,        // IN: start index into iov
                     void *buf,                // IN: Contigous Buffer
                     size_t bufSize,           // IN: Size of buffer
-                    HgfsSessionInfo *session) // IN: Session Info
+                    HgfsTransportSessionInfo *transportSession) // IN: Session Info
 {
    uint32 iovCount;
    size_t remainingSize = bufSize;
@@ -555,12 +555,12 @@ HSPU_CopyBufToIovec(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
    ASSERT(packet);
    ASSERT(buf);
 
-   if (!session->channelCbTable) {
+   if (!transportSession->channelCbTable) {
       return;
    }
 
-   ASSERT_DEVEL(session->channelCbTable->getWriteVa);
-   if (!session->channelCbTable->getWriteVa) {
+   ASSERT_DEVEL(transportSession->channelCbTable->getWriteVa);
+   if (!transportSession->channelCbTable->getWriteVa) {
       return;
    }
 
@@ -575,13 +575,13 @@ HSPU_CopyBufToIovec(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
       ASSERT_DEVEL(packet->iov[iovCount].len <=
                   (PAGE_SIZE - PAGE_OFFSET(packet->iov[iovCount].pa)));
 
-      packet->iov[iovCount].va = session->channelCbTable->getWriteVa(packet->iov[iovCount].pa,
+      packet->iov[iovCount].va = transportSession->channelCbTable->getWriteVa(packet->iov[iovCount].pa,
                                                      packet->iov[iovCount].len,
                                                      &packet->iov[iovCount].token);
       ASSERT_DEVEL(packet->iov[iovCount].va);
       if (packet->iov[iovCount].va != NULL) {
          memcpy(packet->iov[iovCount].va, (char *)buf + copiedAmount, copyAmount);
-         session->channelCbTable->putVa(&packet->iov[iovCount].token);
+         transportSession->channelCbTable->putVa(&packet->iov[iovCount].token);
          remainingSize -= copyAmount;
          copiedAmount += copyAmount;
       } else {
index 1a9f1c215a2aff09d55edecbf49cd3622cc30394..fe6c777ffd820db121beb6a5cdbf345ba1bd3bd8 100644 (file)
@@ -267,7 +267,7 @@ HgfsGetPayloadSize(char const *packetIn,        // IN: request packet
 
 Bool
 HgfsParseRequest(HgfsPacket *packet,         // IN: request packet
-                 HgfsSessionInfo *session,   // IN: current session
+                 HgfsTransportSessionInfo *transportSession,   // IN: current session
                  HgfsInputParam **input,     // OUT: request parameters
                  HgfsInternalStatus *status) // OUT: error code
 {
@@ -275,10 +275,13 @@ HgfsParseRequest(HgfsPacket *packet,         // IN: request packet
    size_t packetSize;
    HgfsInternalStatus result = HGFS_ERROR_SUCCESS;
    HgfsInputParam *localInput;
+   HgfsSessionInfo *session = NULL;
 
-   request = (HgfsRequest *) HSPU_GetMetaPacket(packet, &packetSize, session);
+   request = (HgfsRequest *) HSPU_GetMetaPacket(packet, &packetSize, transportSession);
    ASSERT_DEVEL(request);
 
+   LOG(4, ("%s: Recieved a request with opcode %d.\n", __FUNCTION__, (int) request->op));
+
    if (!request) {
       /*
        * How can I return error back to the client, clearly the client is either broken or
@@ -293,8 +296,9 @@ HgfsParseRequest(HgfsPacket *packet,         // IN: request packet
    memset(localInput, 0, sizeof *localInput);
    localInput->metaPacket = (char *)request;
    localInput->metaPacketSize = packetSize;
-   localInput->session = session;
+   localInput->transportSession = transportSession;
    localInput->packet = packet;
+   localInput->session = NULL;
 
    /*
     * Error out if less than HgfsRequest size.
@@ -329,15 +333,18 @@ HgfsParseRequest(HgfsPacket *packet,         // IN: request packet
       localInput->id = header->requestId;
 
       if (packetSize >= offsetof(HgfsHeader, sessionId) + sizeof header->sessionId) {
-         if (header->sessionId != session->sessionId &&
-            header->op != HGFS_OP_CREATE_SESSION_V4) {
+         if (header->op != HGFS_OP_CREATE_SESSION_V4) {
+            session = HgfsServerTransportGetSessionInfo(transportSession,
+                                                        header->sessionId);
+            if (!session || session->state != HGFS_SESSION_STATE_OPEN) {
                LOG(4, ("%s: HGFS packet with invalid session id!\n", __FUNCTION__));
                result = HGFS_ERROR_STALE_SESSION;
+            }
          } else if (packetSize < header->packetSize ||
             header->packetSize < header->headerSize) {
-               LOG(4, ("%s: Malformed HGFS packet received - inconsistent header"
-                  " and packet sizes!\n", __FUNCTION__));
-               result = HGFS_ERROR_PROTOCOL;
+            LOG(4, ("%s: Malformed HGFS packet received - inconsistent header"
+               " and packet sizes!\n", __FUNCTION__));
+            result = HGFS_ERROR_PROTOCOL;
          }
       } else {
          LOG(4, ("%s: Malformed HGFS packet received - header is too small!\n",
@@ -359,6 +366,13 @@ HgfsParseRequest(HgfsPacket *packet,         // IN: request packet
       LOG(4, ("%s: Malformed HGFS packet received!\n", __FUNCTION__));
    }
 
+   if (!session) {
+      session = HgfsServerTransportGetSessionInfo(transportSession,
+                                                  transportSession->defaultSessionId);
+   }
+   ASSERT(session);
+
+   localInput->session = session;
    localInput->payloadOffset = (char *)localInput->payload -
                                (char *)localInput->metaPacket;
    *status = result;
@@ -4321,7 +4335,7 @@ HgfsUnpackWriteRequest(HgfsInputParam *input,   // IN: Input params
          if (result) {
             *data = HSPU_GetDataPacketBuf(input->packet,
                                           BUF_READABLE,
-                                          input->session);
+                                          input->transportSession);
             if (NULL == *data) {
                LOG(4, ("%s: Failed to get data in guest memory\n", __FUNCTION__));
                result = FALSE;
index 3ce5541fb0911252f7ff36a0f3fb1042bdaa54bc..2d5adb01208fb667ac97612c1005f083c4bb1926 100644 (file)
 /*
  * hgfs locks
  */
-#define RANK_hgfsSharedFolders       (RANK_libLockBase + 0x4003)
-#define RANK_hgfsNotifyLock          (RANK_libLockBase + 0x4005)
-#define RANK_hgfsFileIOLock          (RANK_libLockBase + 0x4010)
-#define RANK_hgfsSearchArrayLock     (RANK_libLockBase + 0x4020)
-#define RANK_hgfsNodeArrayLock       (RANK_libLockBase + 0x4030)
+#define RANK_hgfsSessionArrayLock    (RANK_libLockBase + 0x4010)
+#define RANK_hgfsSharedFolders       (RANK_libLockBase + 0x4030)
+#define RANK_hgfsNotifyLock          (RANK_libLockBase + 0x4040)
+#define RANK_hgfsFileIOLock          (RANK_libLockBase + 0x4050)
+#define RANK_hgfsSearchArrayLock     (RANK_libLockBase + 0x4060)
+#define RANK_hgfsNodeArrayLock       (RANK_libLockBase + 0x4070)
 
 /*
  * SLPv2 global lock