]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
HGFS: cleanup server request and header unpacking part II
authorVMware, Inc <>
Fri, 12 Apr 2013 19:46:52 +0000 (12:46 -0700)
committerDmitry Torokhov <dtor@vmware.com>
Wed, 17 Apr 2013 19:16:53 +0000 (12:16 -0700)
After the first cleanup and extracting the header details by individual
routines and now we have the session information and routines separated.

1) Cleanup the unpack params routine:
- Make it just do the unpacking of the headers and validate the fields.
- Make any bad header sizes or incorrect values of the header fiels untrusted
data and we drop the packet by returning internal error. It makes no sense
to try and reply if the data in the header is not valid.
- Move the transport/server Hgfs packet handling, the session info and the
input params back to the hgfs server main file into a parent function of the
unpack params. The new parent function HgfsServerGetRequest is called from
the server receive message routine now instead.
- Make the input request handling variables const as the input data is not
modified.

2) Cleanup the processing a little more in the new HgfsServerGetRequest
function by doing the can fail processing first: Hgfs Packet, and unpack
packet params first. If we have valid data, determine the session and
then allocate and set the input params. Saves a potential processing
with the input params not initialized to anything but zero.

3) Remove the useless and duplicated function HgfsValidatePacket.

4) Move HgfsPackReplyHeaderV4 function declaration to the correct header file.

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/hgfsServer/hgfsServerParameters.h

index 38f68aa4dee032b9b3fb00fb33d6c2821c71c50b..3407895d28d97034ec2c00caed23b58cd1b1494f 100644 (file)
 #define HGFS_ASSERT_CLIENT(op)
 #endif
 
-#define HGFS_ASSERT_INPUT(input) ASSERT(input && input->packet && input->metaPacket && \
-                                        ((!input->v4header && input->session) || \
-                                         (input->v4header && \
-                                          (input->op == HGFS_OP_CREATE_SESSION_V4 || input->session))) && \
-                                        (!input->payloadSize || input->payload))
+#define HGFS_ASSERT_INPUT(input) \
+   ASSERT(input && input->packet && input->metaPacket && \
+          ((!input->sessionEnabled && input->session) || \
+          (input->sessionEnabled && \
+          (input->op == HGFS_OP_CREATE_SESSION_V4 || input->session))) && \
+          (!input->payloadSize || input->payload))
 
 /*
  * Define this to enable an ASSERT if server gets an op lower than
@@ -283,6 +284,9 @@ static void HgfsServerDirWatchEvent(HgfsSharedFolderHandle sharedFolder,
                                     struct HgfsSessionInfo *session);
 static void HgfsFreeSearchDirents(HgfsSearch *search);
 
+static HgfsInternalStatus
+HgfsServerTransportGetDefaultSession(HgfsTransportSessionInfo *transportSession,
+                                     HgfsSessionInfo **session);
 
 /*
  * Opcode handlers
@@ -2837,6 +2841,160 @@ static struct {
 };
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerInputAllocInit --
+ *
+ *    Allocates and initializes the input params object with the operation parameters.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+HgfsServerInputAllocInit(HgfsPacket *packet,                        // IN: packet
+                         HgfsTransportSessionInfo *transportSession,// IN: session
+                         HgfsSessionInfo *session,                  // IN: session Id
+                         void const *request,                       // IN: HGFS packet
+                         size_t requestSize,                        // IN: request packet size
+                         Bool sessionEnabled,                       // IN: session enabled request
+                         uint32 requestId,                          // IN: unique request id
+                         HgfsOp requestOp,                          // IN: op
+                         size_t requestOpArgsSize,                  // IN: op args size
+                         const void *requestOpArgs,                 // IN: op args
+                         HgfsInputParam **params)                   // OUT: parameters
+{
+   HgfsInputParam *localParams;
+
+   localParams = Util_SafeCalloc(1, sizeof *localParams);
+
+   localParams->packet = packet;
+   localParams->metaPacket = request;
+   localParams->metaPacketSize = requestSize;
+   localParams->transportSession = transportSession;
+   localParams->session = session;
+   localParams->id = requestId;
+   localParams->sessionEnabled = sessionEnabled;
+   localParams->op = requestOp;
+   localParams->payload = requestOpArgs;
+   localParams->payloadSize = requestOpArgsSize;
+
+   if (NULL != localParams->payload) {
+      localParams->payloadOffset = (char *)localParams->payload -
+                                   (char *)localParams->metaPacket;
+   }
+   *params = localParams;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerGetRequest --
+ *
+ *    Takes the Hgfs packet and extracts the operation parameters.
+ *    This validates the incoming packet as part of the processing.
+ *
+ * Results:
+ *    HGFS_ERROR_SUCCESS if all the request parameters are successfully extracted.
+ *    HGFS_ERROR_INTERNAL if an error occurs without sufficient request data to be
+ *    able to send a reply to the client.
+ *    Any other appropriate error if the incoming packet has errors and there is
+ *    sufficient information to send a response.
+ *
+ * Side effects:
+ *    None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static HgfsInternalStatus
+HgfsServerGetRequest(HgfsPacket *packet,                        // IN: packet
+                     HgfsTransportSessionInfo *transportSession,// IN: session
+                     HgfsInputParam **input)                    // OUT: parameters
+{
+   HgfsSessionInfo *session = NULL;
+   uint64 sessionId = HGFS_INVALID_SESSION_ID;
+   Bool sessionEnabled = FALSE;
+   uint32 requestId;
+   HgfsOp opcode;
+   const void *request;
+   size_t requestSize;
+   const void *requestOpArgs;
+   size_t requestOpArgsSize;
+   HgfsInternalStatus parseStatus = HGFS_ERROR_SUCCESS;
+
+   request = HSPU_GetMetaPacket(packet, &requestSize, transportSession);
+   ASSERT_DEVEL(request);
+
+   if (NULL == request) {
+      /*
+       * How can I return error back to the client, clearly the client is either broken or
+       * malicious? We cannot continue from here.
+       */
+      parseStatus = HGFS_ERROR_INTERNAL;
+      goto exit;
+   }
+
+   parseStatus = HgfsUnpackPacketParams(request,
+                                        requestSize,
+                                        &sessionEnabled,
+                                        &sessionId,
+                                        &requestId,
+                                        &opcode,
+                                        &requestOpArgsSize,
+                                        &requestOpArgs);
+   if (HGFS_ERROR_INTERNAL == parseStatus) {
+      /* The packet was malformed and we cannot reply. */
+      goto exit;
+   }
+
+   /*
+    * Every request must be processed within an HGFS session, except create session.
+    * If we don't already have an HGFS session for processing this request,
+    * then use or create the default session.
+    */
+   if (sessionEnabled) {
+      if (opcode != HGFS_OP_CREATE_SESSION_V4) {
+         session = HgfsServerTransportGetSessionInfo(transportSession,
+                                                     sessionId);
+         if (NULL == session || session->state != HGFS_SESSION_STATE_OPEN) {
+            LOG(4, ("%s: HGFS packet with invalid session id!\n", __FUNCTION__));
+            parseStatus = HGFS_ERROR_STALE_SESSION;
+         }
+      }
+   } else {
+      parseStatus = HgfsServerTransportGetDefaultSession(transportSession,
+                                                         &session);
+   }
+
+   if (NULL != session) {
+      session->isInactive = FALSE;
+   }
+
+   HgfsServerInputAllocInit(packet,
+                            transportSession,
+                            session,
+                            request,
+                            requestSize,
+                            sessionEnabled,
+                            requestId,
+                            opcode,
+                            requestOpArgsSize,
+                            requestOpArgs,
+                            input);
+
+exit:
+   return parseStatus;
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -2871,7 +3029,7 @@ HgfsServerCompleteRequest(HgfsInternalStatus status,   // IN: Status of the requ
       ASSERT(input);
    }
 
-   if (input->v4header) {
+   if (input->sessionEnabled) {
       HgfsHeader *header;
       replySize = sizeof *header + replyPayloadSize;
       replyPacketSize = replySize;
@@ -3005,7 +3163,7 @@ HgfsServerSessionReceive(HgfsPacket *packet,      // IN: Hgfs Packet
 
    HgfsServerTransportSessionGet(transportSession);
 
-   status = HgfsUnpackPacketParams(packet, transportSession, &input);
+   status = HgfsServerGetRequest(packet, transportSession, &input);
    if (HGFS_ERROR_INTERNAL == status) {
       LOG(4, ("%s: %d: Error: packet invalid and cannot reply %d.\n ",
               __FUNCTION__, __LINE__, status));
@@ -3017,9 +3175,7 @@ HgfsServerSessionReceive(HgfsPacket *packet,      // IN: Hgfs Packet
    HGFS_ASSERT_MINIMUM_OP(input->op);
    if (HGFS_ERROR_SUCCESS == status) {
       HGFS_ASSERT_INPUT(input);
-      if (HgfsValidatePacket(input->metaPacket, input->metaPacketSize,
-                             input->v4header) &&
-          (input->op < ARRAYSIZE(handlers)) &&
+      if ((input->op < ARRAYSIZE(handlers)) &&
           (handlers[input->op].handler != NULL) &&
           (input->metaPacketSize >= handlers[input->op].minReqSize)) {
          /* Initial validation passed, process the client request now. */
@@ -3120,6 +3276,65 @@ HgfsServerTransportGetSessionInfo(HgfsTransportSessionInfo *transportSession,
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerTransportGetDefaultSession --
+ *
+ *    Returns default session if there is one, otherwise creates it.
+ *    XXX - this function should be moved to the HgfsServer file.
+ *
+ * Results:
+ *    HGFS_ERROR_SUCCESS and the session if found or created successfully
+ *    or an appropriate error if no memory or cannot add to the list of sessions.
+ *
+ * Side effects:
+ *    None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static HgfsInternalStatus
+HgfsServerTransportGetDefaultSession(HgfsTransportSessionInfo *transportSession, // IN: transport
+                                     HgfsSessionInfo **session)                  // OUT: session
+{
+   HgfsInternalStatus status = HGFS_ERROR_SUCCESS;
+   HgfsSessionInfo *defaultSession;
+
+   defaultSession = HgfsServerTransportGetSessionInfo(transportSession,
+                                                      transportSession->defaultSessionId);
+   if (NULL != defaultSession) {
+      /* The default session already exists, we are done. */
+      goto exit;
+   }
+
+   /*
+    * Create a new session if the default session doesn't exist.
+    */
+   if (!HgfsServerAllocateSession(transportSession,
+                                  &defaultSession)) {
+      status = HGFS_ERROR_NOT_ENOUGH_MEMORY;
+      goto exit;
+   }
+
+   status = HgfsServerTransportAddSessionToList(transportSession,
+                                                defaultSession);
+   if (HGFS_ERROR_SUCCESS != status) {
+      LOG(4, ("%s: Could not add session to the list.\n", __FUNCTION__));
+      HgfsServerSessionPut(defaultSession);
+      defaultSession = NULL;
+      goto exit;
+   }
+
+   transportSession->defaultSessionId = defaultSession->sessionId;
+   HgfsServerSessionGet(defaultSession);
+
+exit:
+   *session = defaultSession;
+   return status;
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
index 03dc24c22381eb559b444b04baf1a1e1457dcd52..d5225bb70b7e146695a4ed284227cdab7d64382b 100644 (file)
@@ -477,17 +477,17 @@ typedef struct HgfsCreateSessionInfo {
 
 
 typedef struct HgfsInputParam {
-   const char *metaPacket;
-   size_t metaPacketSize;
-   HgfsSessionInfo *session;
+   const char *metaPacket;       /* Hgfs header followed by operation request */
+   size_t metaPacketSize;        /* Size of Hgfs header and operation request */
+   HgfsSessionInfo *session;     /* Hgfs session data */
    HgfsTransportSessionInfo *transportSession;
-   HgfsPacket *packet;
-   void const *payload;
-   uint32 payloadOffset;
-   size_t payloadSize;
-   HgfsOp op;
-   uint32 id;
-   Bool v4header;
+   HgfsPacket *packet;           /* Public (server/transport) Hgfs packet */
+   void const *payload;          /* Hgfs operation request */
+   uint32 payloadOffset;         /* Offset to start of Hgfs operation request */
+   size_t payloadSize;           /* Hgfs operation request size */
+   HgfsOp op;                    /* Hgfs operation command code */
+   uint32 id;                    /* Request ID to be matched with the reply */
+   Bool sessionEnabled;          /* Requests have session enabled headers */
 } HgfsInputParam;
 
 Bool
@@ -834,18 +834,6 @@ HgfsPlatformVDirStatsFs(HgfsSessionInfo *session,  // IN: session info
                         VolumeInfoType infoType,   // IN:
                         uint64 *outFreeBytes,      // OUT:
                         uint64 *outTotalBytes);    // OUT:
-Bool
-HgfsValidatePacket(char const *packetIn, // IN: HGFS packet
-                   size_t packetSize,    // IN: HGFS packet size
-                   Bool v4header);       // IN: HGFS header type
-void
-HgfsPackReplyHeaderV4(HgfsInternalStatus status,  // IN: platfrom independent HGFS status code
-                      uint32 payloadSize,         // IN: size of HGFS operational packet
-                      HgfsOp op,                  // IN: request type
-                      uint64 sessionId,           // IN: session id
-                      uint32 requestId,           // IN: request id
-                      uint32 hdrFlags,            // IN: header flags
-                      HgfsHeader *header);        // OUT: packet header
 
 HgfsInternalStatus
 HgfsPlatformGetFd(HgfsHandle hgfsHandle,    // IN:  HGFS file handle
index bbe25722a57282baf3f584bc7d8b3ab818d3d82c..7f2326053fa0830cf00a111010f1b53d5a72880e 100644 (file)
@@ -125,52 +125,6 @@ static HgfsCapability hgfsDefaultCapabilityTable[] =
    {HGFS_OP_SET_EAS_V4,            HGFS_REQUEST_NOT_SUPPORTED},
 };
 
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsValidatePacket --
- *
- *    Validates that packet is not malformed. Checks consistency of various
- *    fields and sizes.
- *
- * Results:
- *    TRUE if the packet is correct.
- *    FALSE if the packet is malformed.
- *
- * Side effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-HgfsValidatePacket(char const *packetIn,  // IN: request packet
-                   size_t packetSize,     // IN: request packet size
-                   Bool v4header)         // IN: HGFS header type
-{
-   const HgfsRequest *request = (const HgfsRequest *)packetIn;
-   Bool result = TRUE;
-   if (packetSize < sizeof *request) {
-      LOG(4, ("%s: Malformed HGFS packet received - packet too small!\n", __FUNCTION__));
-      return FALSE;
-   }
-   if (v4header) {
-      const HgfsHeader *header = (const HgfsHeader *)packetIn;
-      ASSERT(packetSize >= header->packetSize);
-      ASSERT(header->packetSize >= header->headerSize);
-      result = packetSize >= offsetof(HgfsHeader, requestId) &&
-               header->headerSize >= offsetof(HgfsHeader, reserved) &&
-               header->packetSize >= header->headerSize &&
-               packetSize >= header->packetSize;
-   } else {
-      result = packetSize >= sizeof *request;
-   }
-   if (!result) {
-      LOG(4, ("%s: Malformed HGFS packet received!\n", __FUNCTION__));
-   }
-   return result;
-}
-
 
 /*
  *-----------------------------------------------------------------------------
@@ -248,62 +202,6 @@ HgfsGetPayloadSize(char const *packetIn,        // IN: request packet
 }
 
 
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsServerTransportGetDefaultSession --
- *
- *    Returns default session if there is one, otherwise creates it.
- *    XXX - this function should be moved to the HgfsServer file.
- *
- * Results:
- *    HGFS_ERROR_SUCCESS and the session if found or created successfully
- *    or an appropriate error if no memory or cannot add to the list of sessions.
- *
- * Side effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-static HgfsInternalStatus
-HgfsServerTransportGetDefaultSession(HgfsTransportSessionInfo *transportSession, // IN: transport
-                                     HgfsSessionInfo **session)                  // OUT: session
-{
-   HgfsInternalStatus status = HGFS_ERROR_SUCCESS;
-   HgfsSessionInfo *defaultSession;
-
-   defaultSession = HgfsServerTransportGetSessionInfo(transportSession,
-                                                      transportSession->defaultSessionId);
-   if (NULL != defaultSession) {
-      /* The default session already exists, we are done. */
-      goto exit;
-   }
-
-   /*
-    * Create a new session if the default session doesn't exist.
-    */
-   if (!HgfsServerAllocateSession(transportSession,
-                                  &defaultSession)) {
-      status = HGFS_ERROR_NOT_ENOUGH_MEMORY;
-      goto exit;
-   }
-
-   status = HgfsServerTransportAddSessionToList(transportSession,
-                                                defaultSession);
-   if (HGFS_ERROR_SUCCESS != status) {
-      LOG(4, ("%s: Could not add session to the list.\n", __FUNCTION__));
-      goto exit;
-   }
-
-   transportSession->defaultSessionId = defaultSession->sessionId;
-   HgfsServerSessionGet(defaultSession);
-
-exit:
-   *session = defaultSession;
-   return status;
-}
-
-
 /*
  *-----------------------------------------------------------------------------
  *
@@ -323,7 +221,7 @@ exit:
  */
 
 static HgfsInternalStatus
-HgfsUnpackHeaderV1V2(HgfsRequest *request,        // IN: request header
+HgfsUnpackHeaderV1V2(const HgfsRequest *request,  // IN: request header
                      size_t requestSize,          // IN: request data size
                      uint32 *requestId,           // OUT: unique request id
                      HgfsOp *opcode,              // OUT: request opcode
@@ -358,7 +256,7 @@ HgfsUnpackHeaderV1V2(HgfsRequest *request,        // IN: request header
  */
 
 static HgfsInternalStatus
-HgfsUnpackHeaderV3(HgfsRequest *request,        // IN: request header
+HgfsUnpackHeaderV3(const HgfsRequest *request,  // IN: request header
                    size_t requestSize,          // IN: request data size
                    uint32 *requestId,           // OUT: unique request id
                    HgfsOp *opcode,              // OUT: request opcode
@@ -390,7 +288,7 @@ HgfsUnpackHeaderV3(HgfsRequest *request,        // IN: request header
  *
  * Results:
  *    HGFS_ERROR_SUCCESS if successful or
- *    HGFS_STATUS_PROTOCOL_ERROR for a malformed reply.
+ *    HGFS_ERROR_INTERNAL for a malformed request, and we cannot trust the data.
  *
  * Side effects:
  *    None.
@@ -399,22 +297,22 @@ HgfsUnpackHeaderV3(HgfsRequest *request,        // IN: request header
  */
 
 static HgfsInternalStatus
-HgfsUnpackHeaderV4(HgfsHeader *requestHeader,   // IN: request header
-                   size_t requestSize,          // IN: request data size
-                   uint64 *sessionId,           // OUT: session Id
-                   uint32 *requestId,           // OUT: unique request id
-                   uint32 *hdrFlags,            // OUT: header flags
-                   uint32 *information,         // OUT: generic information
-                   HgfsOp *opcode,              // OUT: request opcode
-                   size_t *payloadSize,         // OUT: size of the payload
-                   const void **payload)        // OUT: pointer to the payload
+HgfsUnpackHeaderV4(const HgfsHeader *requestHeader,   // IN: request header
+                   size_t requestSize,                // IN: request data size
+                   uint64 *sessionId,                 // OUT: session Id
+                   uint32 *requestId,                 // OUT: unique request id
+                   uint32 *hdrFlags,                  // OUT: header flags
+                   uint32 *information,               // OUT: generic information
+                   HgfsOp *opcode,                    // OUT: request opcode
+                   size_t *payloadSize,               // OUT: size of the payload
+                   const void **payload)              // OUT: pointer to the payload
 {
    HgfsInternalStatus status = HGFS_ERROR_SUCCESS;
 
    if (requestSize < sizeof *requestHeader) {
       LOG(4, ("%s: Malformed HGFS packet received - header is too small!\n",
               __FUNCTION__));
-      status = HGFS_ERROR_PROTOCOL;
+      status = HGFS_ERROR_INTERNAL;
       goto exit;
    }
 
@@ -422,17 +320,19 @@ HgfsUnpackHeaderV4(HgfsHeader *requestHeader,   // IN: request header
        requestHeader->packetSize < requestHeader->headerSize) {
       LOG(4, ("%s: Malformed HGFS packet received - inconsistent header"
               " and packet sizes!\n", __FUNCTION__));
-      status = HGFS_ERROR_PROTOCOL;
+      status = HGFS_ERROR_INTERNAL;
       goto exit;
    }
 
    if (HGFS_HEADER_VERSION_1 > requestHeader->version) {
       LOG(4, ("%s: Malformed HGFS packet received - invalid header version!\n",
               __FUNCTION__));
-      status = HGFS_ERROR_PROTOCOL;
+      status = HGFS_ERROR_INTERNAL;
       goto exit;
    }
 
+   ASSERT(HGFS_V4_LEGACY_OPCODE == requestHeader->dummy);
+
    /* The basics of the header are validated, get the remaining parameters. */
    *sessionId   = requestHeader->sessionId;
    *requestId   = requestHeader->requestId;
@@ -475,85 +375,66 @@ exit:
  */
 
 HgfsInternalStatus
-HgfsUnpackPacketParams(HgfsPacket *packet,                        // IN: packet
-                       HgfsTransportSessionInfo *transportSession,// IN: session
-                       HgfsInputParam **input)                    // OUT: parameters
+HgfsUnpackPacketParams(void const *packet,      // IN: HGFS packet
+                       size_t packetSize,       // IN: request packet size
+                       Bool *sessionEnabled,    // OUT: session enabled request
+                       uint64 *sessionId,       // OUT: session Id
+                       uint32 *requestId,       // OUT: unique request id
+                       HgfsOp *opcode,          // OUT: request opcode
+                       size_t *payloadSize,     // OUT: size of the opcode request
+                       const void **payload)    // OUT: pointer to the opcode request
 {
-   HgfsRequest *request;
-   size_t packetSize;
-   HgfsInputParam *localInput;
-   uint64 sessionId = HGFS_INVALID_SESSION_ID;
-   HgfsSessionInfo *session = NULL;
-   HgfsInternalStatus parseStatus = HGFS_ERROR_SUCCESS;
-
-   request = HSPU_GetMetaPacket(packet, &packetSize, transportSession);
-   ASSERT_DEVEL(request);
+   const HgfsRequest *request;
+   HgfsInternalStatus unpackStatus = HGFS_ERROR_SUCCESS;
 
-   if (NULL == request) {
-      /*
-       * How can I return error back to the client, clearly the client is either broken or
-       * malicious? We cannot continue from here.
-       */
-      parseStatus = HGFS_ERROR_INTERNAL;
-      goto exit;
-   }
+   ASSERT(NULL != packet);
 
+   request = packet;
    LOG(4, ("%s: Received a request with opcode %d.\n", __FUNCTION__, (int) request->op));
 
-   *input = Util_SafeMalloc(sizeof *localInput);
-   localInput = *input;
-
-   memset(localInput, 0, sizeof *localInput);
-   localInput->metaPacket = (char *)request;
-   localInput->metaPacketSize = packetSize;
-   localInput->transportSession = transportSession;
-   localInput->packet = packet;
-   localInput->session = NULL;
-
    /*
     * Error out if less than HgfsRequest size.
     * We cannot continue any further with this packet.
     */
    if (packetSize < sizeof *request) {
-      if (packetSize >= sizeof request->id) {
-         localInput->id = request->id;
-      }
       ASSERT_DEVEL(0);
-      parseStatus = HGFS_ERROR_INTERNAL;
+      unpackStatus = HGFS_ERROR_INTERNAL;
       goto exit;
    }
 
+   *sessionEnabled = FALSE;
+
    if (request->op < HGFS_OP_OPEN_V3) {
-      parseStatus = HgfsUnpackHeaderV1V2(request,
-                                         packetSize,
-                                         &localInput->id,
-                                         &localInput->op,
-                                         &localInput->payloadSize,
-                                         &localInput->payload);
+      unpackStatus = HgfsUnpackHeaderV1V2(request,
+                                          packetSize,
+                                          requestId,
+                                          opcode,
+                                          payloadSize,
+                                          payload);
    } else if (request->op < HGFS_OP_CREATE_SESSION_V4) {
-      parseStatus = HgfsUnpackHeaderV3(request,
-                                       packetSize,
-                                       &localInput->id,
-                                       &localInput->op,
-                                       &localInput->payloadSize,
-                                       &localInput->payload);
+      unpackStatus = HgfsUnpackHeaderV3(request,
+                                        packetSize,
+                                        requestId,
+                                        opcode,
+                                        payloadSize,
+                                        payload);
    } else if (HGFS_V4_LEGACY_OPCODE == request->op) {
       /* The legacy op means a new header but we can have V3 and newer opcodes. */
-      HgfsHeader *requestHdr = (HgfsHeader *)request;
+      const HgfsHeader *requestHdr = packet;
       uint32 hdrFlags = 0;
       uint32 information;
 
-      localInput->v4header = TRUE;
+      *sessionEnabled = TRUE;
 
-      parseStatus = HgfsUnpackHeaderV4(requestHdr,
-                                       packetSize,
-                                       &sessionId,
-                                       &localInput->id,
-                                       &hdrFlags,
-                                       &information,
-                                       &localInput->op,
-                                       &localInput->payloadSize,
-                                       &localInput->payload);
+      unpackStatus = HgfsUnpackHeaderV4(requestHdr,
+                                        packetSize,
+                                        sessionId,
+                                        requestId,
+                                        &hdrFlags,
+                                        &information,
+                                        opcode,
+                                        payloadSize,
+                                        payload);
 
       /* XXX - TBD analyze flags and information. */
       ASSERT(0 == hdrFlags ||
@@ -562,47 +443,11 @@ HgfsUnpackPacketParams(HgfsPacket *packet,                        // IN: packet
    } else {
       LOG(4, ("%s: HGFS packet - unknown opcode == newer client or malformed!\n",
               __FUNCTION__));
-      parseStatus = HGFS_ERROR_PROTOCOL;
+      unpackStatus = HGFS_ERROR_INTERNAL;
    }
 
-   /*
-    * Check for any header parsing issues, and if so bail.
-    */
-   if (HGFS_ERROR_SUCCESS != parseStatus) {
-      goto exit;
-   }
-
-   /*
-    * Every request must be processed within an HGFS session, except create session.
-    * If we don't already have an HGFS session for processing this request,
-    * then use or create the default session.
-    */
-   if (localInput->v4header) {
-      if (localInput->op != HGFS_OP_CREATE_SESSION_V4) {
-         session = HgfsServerTransportGetSessionInfo(transportSession,
-                                                     sessionId);
-         if (NULL == session || session->state != HGFS_SESSION_STATE_OPEN) {
-            LOG(4, ("%s: HGFS packet with invalid session id!\n", __FUNCTION__));
-            parseStatus = HGFS_ERROR_STALE_SESSION;
-         }
-      }
-   } else {
-      ASSERT(NULL == session);
-      parseStatus = HgfsServerTransportGetDefaultSession(transportSession,
-                                                         &session);
-   }
-
-   if (NULL != session) {
-      session->isInactive = FALSE;
-   }
-
-   localInput->session = session;
-   if (NULL != localInput->payload) {
-      localInput->payloadOffset = (char *)localInput->payload -
-                                  (char *)localInput->metaPacket;
-   }
 exit:
-   return parseStatus;
+   return unpackStatus;
 }
 
 
index 013c703562ec4725f217c4ed6b6365c79d7167d4..75d099fe9dd6164e2b6f939f1a50325098410c3d 100644 (file)
 
 
 HgfsInternalStatus
-HgfsUnpackPacketParams(HgfsPacket *packet,                         // IN: request packet
-                       HgfsTransportSessionInfo *transportSession, // IN: current session
-                       HgfsInputParam **input);                    // OUT: request parameters
+HgfsUnpackPacketParams(void const *packet,      // IN: HGFS packet
+                       size_t packetSize,       // IN: request packet size
+                       Bool *sessionEnabled,    // OUT: session enabled request
+                       uint64 *sessionId,       // OUT: session Id
+                       uint32 *requestId,       // OUT: unique request id
+                       HgfsOp *opcode,          // OUT: request opcode
+                       size_t *payloadSize,     // OUT: size of the opcode request
+                       const void **payload);    // OUT: pointer to the opcode request
 
 void
+HgfsPackReplyHeaderV4(HgfsInternalStatus status,  // IN: platfrom independent HGFS status code
+                      uint32 payloadSize,         // IN: size of HGFS operational packet
+                      HgfsOp op,                  // IN: request type
+                      uint64 sessionId,           // IN: session id
+                      uint32 requestId,           // IN: request id
+                      uint32 hdrFlags,            // IN: header flags
+                      HgfsHeader *header);        // OUT: packet header
+void
 HgfsPackLegacyReplyHeader(HgfsInternalStatus status,    // IN: reply status
                           HgfsHandle id,                // IN: original packet id
                           HgfsReply *header);           // OUT: outgoing packet header
+
 Bool
 HgfsUnpackOpenRequest(void const *packet,          // IN: incoming packet
                       size_t packetSize,           // IN: size of packet