NXCP message deserialization fails completely in case of malformed message (instead...
authorVictor Kirhenshtein <victor@netxms.org>
Wed, 4 Oct 2017 14:12:55 +0000 (17:12 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Wed, 4 Oct 2017 14:12:55 +0000 (17:12 +0300)
29 files changed:
include/nxcpapi.h
src/agent/core/config.cpp
src/agent/core/ctrl.cpp
src/agent/core/extagent.cpp
src/agent/core/master.cpp
src/agent/core/nxagentd.h
src/agent/core/register.cpp
src/agent/core/sa.cpp
src/agent/core/session.cpp
src/agent/core/trap.cpp
src/agent/core/tunnel.cpp
src/agent/tools/nxapush/nxapush.cpp
src/client/libnxclient/session.cpp
src/libnetxms/crypto.cpp
src/libnetxms/message.cpp
src/libnetxms/msgrecv.cpp
src/libnetxms/msgwq.cpp
src/libnxcc/comm.cpp
src/server/core/admin.cpp
src/server/core/debug.cpp
src/server/core/isc.cpp
src/server/core/mdsession.cpp
src/server/core/session.cpp
src/server/core/tunnel.cpp
src/server/include/nms_core.h
src/server/libnxsrv/agent.cpp
src/server/libnxsrv/isc.cpp
src/server/tools/nxadm/comm.cpp
tests/test-libnetxms/nxcp.cpp

index 4673193..7479907 100644 (file)
@@ -66,18 +66,21 @@ private:
    BYTE *m_data;           // binary data
    size_t m_dataSize;      // binary data size
 
+   NXCPMessage(const NXCP_MESSAGE *msg, int version);
+
    void *set(UINT32 fieldId, BYTE type, const void *value, bool isSigned = false, size_t size = 0);
    void *get(UINT32 fieldId, BYTE requiredType, BYTE *fieldType = NULL) const;
    NXCP_MESSAGE_FIELD *find(UINT32 fieldId) const;
+   bool isValid() { return m_version != -1; }
 
 public:
    NXCPMessage(int version = NXCP_VERSION);
    NXCPMessage(UINT16 code, UINT32 id, int version = NXCP_VERSION);
    NXCPMessage(NXCPMessage *msg);
-   NXCPMessage(NXCP_MESSAGE *rawMag, int version = NXCP_VERSION);
    ~NXCPMessage();
 
-   NXCP_MESSAGE *createMessage(bool allowCompression = false) const;
+   static NXCPMessage *deserialize(const NXCP_MESSAGE *rawMag, int version = NXCP_VERSION);
+   NXCP_MESSAGE *serialize(bool allowCompression = false) const;
 
    UINT16 getCode() const { return m_code; }
    void setCode(UINT16 code) { m_code = code; }
index 8552a4d..b4e2060 100644 (file)
@@ -98,7 +98,7 @@ BOOL DownloadConfig(TCHAR *pszServer)
          msg.setField(VID_VERSION, NETXMS_VERSION_STRING);
 
          // Send request
-         pRawMsg = msg.createMessage();
+         pRawMsg = msg.serialize();
          nLen = ntohl(pRawMsg->size);
          if (SendEx(hSocket, pRawMsg, nLen, 0, NULL) == nLen)
          {
@@ -110,19 +110,22 @@ BOOL DownloadConfig(TCHAR *pszServer)
                                    &pDummyCtx, NULL, 30000);
             if (nLen >= 16)
             {
-               pResponse = new NXCPMessage(pRawMsg);
-               if ((pResponse->getCode() == CMD_REQUEST_COMPLETED) &&
-                   (pResponse->getId() == 1) &&
-                   (pResponse->getFieldAsUInt32(VID_RCC) == 0))
+               pResponse = NXCPMessage::deserialize(pRawMsg);
+               if (pResponse != NULL)
                {
-                  pszConfig = pResponse->getFieldAsString(VID_CONFIG_FILE);
-                  if (pszConfig != NULL)
+                  if ((pResponse->getCode() == CMD_REQUEST_COMPLETED) &&
+                      (pResponse->getId() == 1) &&
+                      (pResponse->getFieldAsUInt32(VID_RCC) == 0))
                   {
-                     bRet = SaveConfig(pszConfig);
-                     free(pszConfig);
+                     pszConfig = pResponse->getFieldAsString(VID_CONFIG_FILE);
+                     if (pszConfig != NULL)
+                     {
+                        bRet = SaveConfig(pszConfig);
+                        free(pszConfig);
+                     }
                   }
+                  delete pResponse;
                }
-               delete pResponse;
             }
             free(pBuffer);
          }
index 2fb5815..5b04714 100644 (file)
@@ -274,7 +274,7 @@ reconnect:
 #endif
 
    bool success = false;
-       NXCP_MESSAGE *rawMsg = msg->createMessage();
+       NXCP_MESSAGE *rawMsg = msg->serialize();
 #ifdef _WIN32
        DWORD bytes;
        if (!WriteFile(hPipe, rawMsg, ntohl(rawMsg->size), &bytes, NULL))
index 02f418d..a490aab 100644 (file)
@@ -79,7 +79,7 @@ bool ExternalSubagent::sendMessage(NXCPMessage *msg)
        TCHAR buffer[256];
        AgentWriteDebugLog(6, _T("ExternalSubagent::sendMessage(%s): sending message %s"), m_name, NXCPMessageCodeName(msg->getCode(), buffer));
 
-       NXCP_MESSAGE *rawMsg = msg->createMessage();
+       NXCP_MESSAGE *rawMsg = msg->serialize();
        bool success = (m_pipe != NULL) ? m_pipe->write(rawMsg, ntohl(rawMsg->size)) : false;
        free(rawMsg);
        return success;
index fbb840e..b2443b6 100644 (file)
@@ -156,7 +156,7 @@ THREAD_RESULT THREAD_CALL MasterAgentListener(void *arg)
                                delete msg;
 
                                // Send response to pipe
-                               NXCP_MESSAGE *rawMsg = response.createMessage();
+                               NXCP_MESSAGE *rawMsg = response.serialize();
             bool sendSuccess = s_pipe->write(rawMsg, ntohl(rawMsg->size));
             free(rawMsg);
             if (!sendSuccess)
@@ -180,7 +180,7 @@ THREAD_RESULT THREAD_CALL MasterAgentListener(void *arg)
  */
 bool SendMessageToMasterAgent(NXCPMessage *msg)
 {
-   NXCP_MESSAGE *rawMsg = msg->createMessage();
+   NXCP_MESSAGE *rawMsg = msg->serialize();
    bool success = SendRawMessageToMasterAgent(rawMsg);
    free(rawMsg);
    return success;
index 9e03285..999d9a0 100644 (file)
@@ -373,7 +373,7 @@ public:
    void disconnect();
 
    virtual bool sendMessage(NXCPMessage *msg);
-   virtual void postMessage(NXCPMessage *msg) { if (!m_disconnected) m_sendQueue->put(msg->createMessage(m_allowCompression)); }
+   virtual void postMessage(NXCPMessage *msg) { if (!m_disconnected) m_sendQueue->put(msg->serialize(m_allowCompression)); }
    virtual bool sendRawMessage(NXCP_MESSAGE *msg);
    virtual void postRawMessage(NXCP_MESSAGE *msg) { if (!m_disconnected) m_sendQueue->put(nx_memdup(msg, ntohl(msg->size))); }
        virtual bool sendFile(UINT32 requestId, const TCHAR *file, long offset, bool allowCompression);
index 631de72..019987a 100644 (file)
@@ -71,7 +71,7 @@ BOOL RegisterOnServer(const TCHAR *pszServer)
          msg.setField(VID_VERSION_RELEASE, (WORD)NETXMS_VERSION_BUILD);
 
          // Send request
-         pRawMsg = msg.createMessage();
+         pRawMsg = msg.serialize();
          nLen = ntohl(pRawMsg->size);
          if (SendEx(hSocket, pRawMsg, nLen, 0, NULL) == nLen)
          {
@@ -83,14 +83,17 @@ BOOL RegisterOnServer(const TCHAR *pszServer)
                                    &pDummyCtx, NULL, 30000);
             if (nLen >= 16)
             {
-               pResponse = new NXCPMessage(pRawMsg);
-               if ((pResponse->getCode() == CMD_REQUEST_COMPLETED) &&
-                   (pResponse->getId() == 2) &&
-                   (pResponse->getFieldAsUInt32(VID_RCC) == 0))
+               pResponse = NXCPMessage::deserialize(pRawMsg);
+               if (pResponse != NULL)
                {
-                  bRet = TRUE;
+                  if ((pResponse->getCode() == CMD_REQUEST_COMPLETED) &&
+                      (pResponse->getId() == 2) &&
+                      (pResponse->getFieldAsUInt32(VID_RCC) == 0))
+                  {
+                     bRet = TRUE;
+                  }
+                  delete pResponse;
                }
-               delete pResponse;
             }
             free(pBuffer);
          }
index 38722f4..feba0a8 100644 (file)
@@ -117,7 +117,7 @@ void SessionAgentConnector::disconnect()
  */
 bool SessionAgentConnector::sendMessage(NXCPMessage *msg)
 {
-   NXCP_MESSAGE *rawMsg = msg->createMessage();
+   NXCP_MESSAGE *rawMsg = msg->serialize();
    bool success = (SendEx(m_socket, rawMsg, ntohl(rawMsg->size), 0, m_mutex) == ntohl(rawMsg->size));
    free(rawMsg);
    return success;
@@ -156,7 +156,7 @@ void SessionAgentConnector::readThread()
       // Check that actual received packet size is equal to encoded in packet
       if ((int)ntohl(rawMsg->size) != err)
       {
-         DebugPrintf(5, _T("Session agent connector %d: actual message size doesn't match wSize value (%d,%d)"), m_id, err, ntohl(rawMsg->size));
+         DebugPrintf(5, _T("SA-%d: actual message size doesn't match wSize value (%d,%d)"), m_id, err, ntohl(rawMsg->size));
          continue;   // Bad packet, wait for next
       }
 
@@ -170,24 +170,31 @@ void SessionAgentConnector::readThread()
       if (!(flags & MF_BINARY))
       {
          // Create message object from raw message
-         NXCPMessage *msg = new NXCPMessage(rawMsg);
-         if (msg->getCode() == CMD_LOGIN)
+         NXCPMessage *msg = NXCPMessage::deserialize(rawMsg);
+         if (msg != NULL)
          {
-            m_sessionId = msg->getFieldAsUInt32(VID_SESSION_ID);
-            m_sessionState = msg->getFieldAsInt16(VID_SESSION_STATE);
+            if (msg->getCode() == CMD_LOGIN)
+            {
+               m_sessionId = msg->getFieldAsUInt32(VID_SESSION_ID);
+               m_sessionState = msg->getFieldAsInt16(VID_SESSION_STATE);
 
-            safe_free(m_sessionName);
-            m_sessionName = msg->getFieldAsString(VID_NAME);
+               safe_free(m_sessionName);
+               m_sessionName = msg->getFieldAsString(VID_NAME);
 
-            safe_free(m_userName);
-            m_userName = msg->getFieldAsString(VID_USER_NAME);
+               safe_free(m_userName);
+               m_userName = msg->getFieldAsString(VID_USER_NAME);
 
-            delete msg;
-            DebugPrintf(5, _T("Session agent connector %d: login as %s@%s [%d]"), m_id, getUserName(), getSessionName(), m_sessionId);
+               delete msg;
+               DebugPrintf(5, _T("Session agent connector %d: login as %s@%s [%d]"), m_id, getUserName(), getSessionName(), m_sessionId);
+            }
+            else
+            {
+               m_msgQueue.put(msg);
+            }
          }
          else
          {
-            m_msgQueue.put(msg);
+            DebugPrintf(5, _T("SA-%d: message deserialization error"), m_id);
          }
       }
    }
index 639b0de..aaef2dc 100644 (file)
@@ -486,7 +486,7 @@ bool CommSession::sendMessage(NXCPMessage *msg)
    if (m_disconnected)
       return false;
 
-   return sendRawMessage(msg->createMessage(m_allowCompression), m_pCtx);
+   return sendRawMessage(msg->serialize(m_allowCompression), m_pCtx);
 }
 
 /**
@@ -1093,7 +1093,7 @@ UINT32 CommSession::setupProxyConnection(NXCPMessage *pRequest)
             msg.setCode(CMD_REQUEST_COMPLETED);
             msg.setId(pRequest->getId());
             msg.setField(VID_RCC, RCC_SUCCESS);
-            pRawMsg = msg.createMessage();
+            pRawMsg = msg.serialize();
             sendRawMessage(pRawMsg, pSavedCtx);
                                if (pSavedCtx != NULL)
                                        pSavedCtx->decRefCount();
index b757b0f..5b2a696 100644 (file)
@@ -126,7 +126,7 @@ void SendTrap(UINT32 dwEventCode, const TCHAR *eventName, int iNumArgs, TCHAR **
        {
                s_genTrapCount++;
                s_lastTrapTime = time(NULL);
-      s_trapQueue->put(msg.createMessage());
+      s_trapQueue->put(msg.serialize());
        }
 }
 
@@ -232,7 +232,7 @@ void ForwardTrap(NXCPMessage *msg)
        {
                s_genTrapCount++;
                s_lastTrapTime = time(NULL);
-      s_trapQueue->put(msg->createMessage());
+      s_trapQueue->put(msg->serialize());
        }
 }
 
index e380a24..931d734 100644 (file)
@@ -339,7 +339,7 @@ bool Tunnel::sendMessage(const NXCPMessage *msg)
       TCHAR buffer[64];
       debugPrintf(6, _T("Sending message %s"), NXCPMessageCodeName(msg->getCode(), buffer));
    }
-   NXCP_MESSAGE *data = msg->createMessage(false);
+   NXCP_MESSAGE *data = msg->serialize(false);
    bool success = (sslWrite(data, ntohl(data->size)) == ntohl(data->size));
    free(data);
    return success;
index 8429b3b..883fe67 100644 (file)
@@ -109,7 +109,7 @@ static bool Send()
    s_data->fillMessage(&msg, VID_NUM_ITEMS, VID_PUSH_DCI_DATA_BASE);
 
        // Send message to pipe
-       NXCP_MESSAGE *rawMsg = msg.createMessage();
+       NXCP_MESSAGE *rawMsg = msg.serialize();
        bool success = s_pipe->write(rawMsg, ntohl(rawMsg->size));
 
        free(rawMsg);
index 1d23be1..edcba96 100644 (file)
@@ -354,7 +354,7 @@ bool NXCSession::sendMessage(NXCPMessage *msg)
    DebugPrintf(_T("NXCSession::sendMessage(\"%s\", id:%d)"), NXCPMessageCodeName(msg->getCode(), buffer), msg->getId());
 
    bool result;
-   NXCP_MESSAGE *rawMsg = msg->createMessage();
+   NXCP_MESSAGE *rawMsg = msg->serialize();
        MutexLock(m_msgSendLock);
    if (m_encryptionContext != NULL)
    {
index bed222c..859b3c7 100644 (file)
@@ -1,7 +1,7 @@
 /* 
 ** NetXMS - Network Management System
 ** NetXMS Foundation Library
-** Copyright (C) 2003-2015 Victor Kirhenshtein
+** Copyright (C) 2003-2017 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU Lesser General Public License as published
index d19ed00..30e290a 100644 (file)
@@ -142,9 +142,23 @@ NXCPMessage::NXCPMessage(NXCPMessage *msg)
 }
 
 /**
- * Create NXCPMessage object from received message
+ * Create NXCPMessage object from serialized message
+ *
+ * @return message object or NULL on failure
+ */
+NXCPMessage *NXCPMessage::deserialize(const NXCP_MESSAGE *rawMag, int version)
+{
+   NXCPMessage *msg = new NXCPMessage(rawMag, version);
+   if (msg->isValid())
+      return msg;
+   delete msg;
+   return NULL;
+}
+
+/**
+ * Create NXCPMessage object from serialized message
  */
-NXCPMessage::NXCPMessage(NXCP_MESSAGE *msg, int version)
+NXCPMessage::NXCPMessage(const NXCP_MESSAGE *msg, int version)
 {
    m_flags = ntohs(msg->flags);
    m_code = ntohs(msg->code);
@@ -169,6 +183,7 @@ NXCPMessage::NXCPMessage(NXCP_MESSAGE *msg, int version)
          if (inflateInit(&stream) != Z_OK)
          {
             nxlog_debug(6, _T("NXCPMessage: inflateInit() failed"));
+            m_version = -1;   // error indicator
             return;
          }
 
@@ -181,6 +196,7 @@ NXCPMessage::NXCPMessage(NXCP_MESSAGE *msg, int version)
             inflateEnd(&stream);
             TCHAR buffer[256];
             nxlog_debug(6, _T("NXCPMessage: failed to decompress binary message %s with ID %d"), NXCPMessageCodeName(m_code, buffer), m_id);
+            m_version = -1;   // error indicator
             return;
          }
          inflateEnd(&stream);
@@ -211,6 +227,7 @@ NXCPMessage::NXCPMessage(NXCP_MESSAGE *msg, int version)
          if (inflateInit(&stream) != Z_OK)
          {
             nxlog_debug(6, _T("NXCPMessage: inflateInit() failed"));
+            m_version = -1;   // error indicator
             return;
          }
 
@@ -223,6 +240,7 @@ NXCPMessage::NXCPMessage(NXCP_MESSAGE *msg, int version)
             inflateEnd(&stream);
             TCHAR buffer[256];
             nxlog_debug(6, _T("NXCPMessage: failed to decompress message %s with ID %d"), NXCPMessageCodeName(m_code, buffer), m_id);
+            m_version = -1;   // error indicator
             return;
          }
          inflateEnd(&stream);
@@ -241,15 +259,24 @@ NXCPMessage::NXCPMessage(NXCP_MESSAGE *msg, int version)
 
          // Validate position inside message
          if (pos > msgDataSize - 8)
+         {
+            m_version = -1;   // error indicator
             break;
+         }
          if ((pos > msgDataSize - 12) &&
              ((field->type == NXCP_DT_STRING) || (field->type == NXCP_DT_BINARY)))
+         {
+            m_version = -1;   // error indicator
             break;
+         }
 
          // Calculate and validate field size
          size_t fieldSize = CalculateFieldSize(field, true);
          if (pos + fieldSize > msgDataSize)
+         {
+            m_version = -1;   // error indicator
             break;
+         }
 
          // Create new entry
          MessageField *entry = CreateMessageField(fieldSize);
@@ -826,7 +853,7 @@ uuid NXCPMessage::getFieldAsGUID(UINT32 fieldId) const
 /**
  * Build protocol message ready to be send over the wire
  */
-NXCP_MESSAGE *NXCPMessage::createMessage(bool allowCompression) const
+NXCP_MESSAGE *NXCPMessage::serialize(bool allowCompression) const
 {
    // Calculate message size
    size_t size = NXCP_HEADER_SIZE;
index dc0a491..98f6d8e 100644 (file)
@@ -73,13 +73,17 @@ NXCPMessage *AbstractMessageReceiver::getMessageFromBuffer(bool *protocolError)
                   m_decryptionBuffer = (BYTE *)malloc(m_size);
                if (m_encryptionContext->decryptMessage((NXCP_ENCRYPTED_MESSAGE *)m_buffer, m_decryptionBuffer))
                {
-                  msg = new NXCPMessage((NXCP_MESSAGE *)m_buffer);
+                  msg = NXCPMessage::deserialize(reinterpret_cast<NXCP_MESSAGE*>(m_buffer));
+                  if (msg == NULL)
+                     *protocolError = true;  // message deserialization error
                }
             }
          }
          else
          {
-            msg = new NXCPMessage((NXCP_MESSAGE *)m_buffer);
+            msg = NXCPMessage::deserialize(reinterpret_cast<NXCP_MESSAGE*>(m_buffer));
+            if (msg == NULL)
+               *protocolError = true;  // message deserialization error
          }
          m_dataSize -= msgSize;
          if (m_dataSize > 0)
index 6a4a2e8..231298e 100644 (file)
@@ -1,7 +1,7 @@
 /* 
 ** NetXMS - Network Management System
 ** NetXMS Foundation Library
-** Copyright (C) 2003-2016 Victor Kirhenshtein
+** Copyright (C) 2003-2017 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU Lesser General Public License as published
index 65f9c51..7adccdb 100644 (file)
@@ -372,7 +372,7 @@ static THREAD_RESULT THREAD_CALL ClusterKeepaliveThread(void *arg)
    NXCPMessage msg;
    msg.setCode(CMD_KEEPALIVE);
    msg.setField(VID_NODE_ID, g_nxccNodeId);
-   NXCP_MESSAGE *rawMsg = msg.createMessage();
+   NXCP_MESSAGE *rawMsg = msg.serialize();
 
    while(!g_nxccShutdown)
    {
@@ -416,7 +416,7 @@ void ClusterSendMessage(ClusterNodeInfo *node, NXCPMessage *msg)
                 NXCPMessageCodeName(msg->getCode(), buffer), msg->getId(),
                 node->m_id, (const TCHAR *)node->m_addr->toString());
 
-   NXCP_MESSAGE *rawMsg = msg->createMessage();
+   NXCP_MESSAGE *rawMsg = msg->serialize();
    MutexLock(node->m_mutex);
    if (node->m_socket != INVALID_SOCKET)
    {
@@ -455,7 +455,7 @@ void LIBNXCC_EXPORTABLE ClusterNotify(INT16 code)
  */
 void LIBNXCC_EXPORTABLE ClusterNotify(NXCPMessage *msg)
 {
-   NXCP_MESSAGE *rawMsg = msg->createMessage();
+   NXCP_MESSAGE *rawMsg = msg->serialize();
 
    for(int i = 0; i < CLUSTER_MAX_NODE_ID; i++)
    {
@@ -527,7 +527,7 @@ int LIBNXCC_EXPORTABLE ClusterSendCommand(NXCPMessage *msg)
 
    UINT32 requestId = (UINT32)InterlockedIncrement(&s_commandId);
    msg->setId(requestId);
-   NXCP_MESSAGE *rawMsg = msg->createMessage();
+   NXCP_MESSAGE *rawMsg = msg->serialize();
 
    bool waitFlags[CLUSTER_MAX_NODE_ID];
    memset(waitFlags, 0, sizeof(waitFlags));
@@ -634,7 +634,7 @@ NXCPMessage LIBNXCC_EXPORTABLE *ClusterSendDirectCommandEx(UINT32 nodeId, NXCPMe
 
    UINT32 requestId = (UINT32)InterlockedIncrement(&s_commandId);
    msg->setId(requestId);
-   NXCP_MESSAGE *rawMsg = msg->createMessage();
+   NXCP_MESSAGE *rawMsg = msg->serialize();
 
    TCHAR buffer[64];
    ClusterDebug(7, _T("ClusterSendDirectCommandEx: sending message %s (%d) to peer %d [%s]"),
index 2d0470d..01dfda0 100644 (file)
@@ -93,7 +93,7 @@ static THREAD_RESULT THREAD_CALL ProcessingThread(void *pArg)
       }
 
       response.setCode(CMD_REQUEST_COMPLETED);
-      NXCP_MESSAGE *rawMsgOut = response.createMessage();
+      NXCP_MESSAGE *rawMsgOut = response.serialize();
                SendEx(sock, rawMsgOut, ntohl(rawMsgOut->size), 0, ctx.socketMutex);
       free(rawMsgOut);
       delete request;
index 2571476..78a93a9 100644 (file)
@@ -100,7 +100,7 @@ void ConsolePrintf(CONSOLE_CTX console, const TCHAR *pszFormat, ...)
                }
                else
                {
-                       NXCP_MESSAGE *pRawMsg = console->pMsg->createMessage();
+                       NXCP_MESSAGE *pRawMsg = console->pMsg->serialize();
                        SendEx(console->hSocket, pRawMsg, ntohl(pRawMsg->size), 0, console->socketMutex);
                        free(pRawMsg);
                }
@@ -149,7 +149,7 @@ void ConsoleWrite(CONSOLE_CTX console, const TCHAR *text)
                }
                else
                {
-                       NXCP_MESSAGE *pRawMsg = console->pMsg->createMessage();
+                       NXCP_MESSAGE *pRawMsg = console->pMsg->serialize();
                        SendEx(console->hSocket, pRawMsg, ntohl(pRawMsg->size), 0, console->socketMutex);
                        free(pRawMsg);
                }
index 3066808..127ad25 100644 (file)
@@ -110,7 +110,13 @@ static THREAD_RESULT THREAD_CALL ProcessingThread(void *arg)
       }
                else
                {
-                       pRequest = new NXCPMessage(pRawMsg);
+                       pRequest = NXCPMessage::deserialize(pRawMsg);
+                       if (pRequest == NULL)
+                       {
+                DbgPrintf(5, _T("%s message deserialization error"), dbgPrefix);
+                          continue;
+                       }
+
                        DbgPrintf(5, _T("%s message %s received"), dbgPrefix, NXCPMessageCodeName(pRequest->getCode(), buffer));
                        if (pRequest->getCode() == CMD_KEEPALIVE)
                        {
@@ -170,7 +176,7 @@ static THREAD_RESULT THREAD_CALL ProcessingThread(void *arg)
                        
                        response.setId(pRequest->getId());
                        response.setCode(CMD_REQUEST_COMPLETED);
-                       pRawMsgOut = response.createMessage();
+                       pRawMsgOut = response.serialize();
                        DbgPrintf(5, _T("%s sending message %s"), dbgPrefix, NXCPMessageCodeName(response.getCode(), buffer));
                        if (SendEx(sock, pRawMsgOut, ntohl(pRawMsgOut->size), 0, NULL) != (int)ntohl(pRawMsgOut->size))
                                DbgPrintf(5, _T("%s SendEx() failed in ProcessingThread(): %s"), dbgPrefix, strerror(WSAGetLastError()));
index 7a4e884..783b8aa 100644 (file)
@@ -384,7 +384,7 @@ void MobileDeviceSession::sendMessage(NXCPMessage *msg)
    BOOL bResult;
 
        debugPrintf(6, _T("Sending message %s"), NXCPMessageCodeName(msg->getCode(), szBuffer));
-       NXCP_MESSAGE *pRawMsg = msg->createMessage();
+       NXCP_MESSAGE *pRawMsg = msg->serialize();
    if (nxlog_get_debug_level() >= 8)
    {
       String msgDump = NXCPMessage::dump(pRawMsg, NXCP_VERSION);
index b95a060..e2fe0db 100644 (file)
@@ -1430,7 +1430,7 @@ bool ClientSession::sendMessage(NXCPMessage *msg)
    if (isTerminated())
       return false;
 
-       NXCP_MESSAGE *rawMsg = msg->createMessage((m_dwFlags & CSF_COMPRESSION_ENABLED) != 0);
+       NXCP_MESSAGE *rawMsg = msg->serialize((m_dwFlags & CSF_COMPRESSION_ENABLED) != 0);
 
    if ((nxlog_get_debug_level() >= 6) && (msg->getCode() != CMD_ADM_MESSAGE))
    {
@@ -5996,7 +5996,7 @@ void ClientSession::onActionDBUpdate(UINT32 dwCode, NXC_ACTION *pAction)
       if (dwCode != NX_NOTIFY_ACTION_DELETED)
          FillActionInfoMessage(&msg, pAction);
       ThreadPoolExecute(g_mainThreadPool, this, &ClientSession::sendActionDBUpdateMessage,
-               msg.createMessage((m_dwFlags & CSF_COMPRESSION_ENABLED) != 0));
+               msg.serialize((m_dwFlags & CSF_COMPRESSION_ENABLED) != 0));
    }
 }
 
index 5c7223f..6c42976 100644 (file)
@@ -400,7 +400,7 @@ bool AgentTunnel::sendMessage(NXCPMessage *msg)
       TCHAR buffer[64];
       debugPrintf(6, _T("Sending message %s"), NXCPMessageCodeName(msg->getCode(), buffer));
    }
-   NXCP_MESSAGE *data = msg->createMessage(true);
+   NXCP_MESSAGE *data = msg->serialize(true);
    bool success = (sslWrite(data, ntohl(data->size)) == ntohl(data->size));
    free(data);
    return success;
index a6f30e8..affa5b0 100644 (file)
@@ -365,7 +365,7 @@ public:
 
    void run();
 
-   void postMessage(NXCPMessage *pMsg) { m_pSendQueue->put(pMsg->createMessage()); }
+   void postMessage(NXCPMessage *pMsg) { m_pSendQueue->put(pMsg->serialize()); }
    void sendMessage(NXCPMessage *pMsg);
 
        int getId() { return m_id; }
@@ -758,7 +758,7 @@ public:
 
    void run();
 
-   void postMessage(NXCPMessage *pMsg) { if (!isTerminated()) m_sendQueue->put(pMsg->createMessage((m_dwFlags & CSF_COMPRESSION_ENABLED) != 0)); }
+   void postMessage(NXCPMessage *pMsg) { if (!isTerminated()) m_sendQueue->put(pMsg->serialize((m_dwFlags & CSF_COMPRESSION_ENABLED) != 0)); }
    bool sendMessage(NXCPMessage *pMsg);
    void sendRawMessage(NXCP_MESSAGE *pMsg);
    void sendPollerMsg(UINT32 dwRqId, const TCHAR *pszMsg);
index 7ab4d4a..063f214 100644 (file)
@@ -363,89 +363,96 @@ void AgentConnection::receiverThread()
       else
       {
          // Create message object from raw message
-         NXCPMessage *msg = new NXCPMessage(rawMsg, m_nProtocolVersion);
-         if (nxlog_get_debug_level() >= 6)
+         NXCPMessage *msg = NXCPMessage::deserialize(rawMsg, m_nProtocolVersion);
+         if (msg != NULL)
          {
-            TCHAR buffer[64];
-            debugPrintf(6, _T("Received message %s (%d) from agent at %s"),
-               NXCPMessageCodeName(msg->getCode(), buffer), msg->getId(), (const TCHAR *)m_addr.toString());
+            if (nxlog_get_debug_level() >= 6)
+            {
+               TCHAR buffer[64];
+               debugPrintf(6, _T("Received message %s (%d) from agent at %s"),
+                  NXCPMessageCodeName(msg->getCode(), buffer), msg->getId(), (const TCHAR *)m_addr.toString());
+            }
+            switch(msg->getCode())
+            {
+               case CMD_REQUEST_COMPLETED:
+               case CMD_SESSION_KEY:
+                  m_pMsgWaitQueue->put(msg);
+                  break;
+               case CMD_TRAP:
+                  if (g_agentConnectionThreadPool != NULL)
+                  {
+                     incInternalRefCount();
+                     ThreadPoolExecute(g_agentConnectionThreadPool, this, &AgentConnection::onTrapCallback, msg);
+                  }
+                  else
+                  {
+                     delete msg;
+                  }
+                  break;
+               case CMD_SYSLOG_RECORDS:
+                  if (g_agentConnectionThreadPool != NULL)
+                  {
+                     incInternalRefCount();
+                     ThreadPoolExecute(g_agentConnectionThreadPool, this, &AgentConnection::onSyslogMessageCallback, msg);
+                  }
+                  else
+                  {
+                     delete msg;
+                  }
+                  break;
+               case CMD_PUSH_DCI_DATA:
+                  if (g_agentConnectionThreadPool != NULL)
+                  {
+                     incInternalRefCount();
+                     ThreadPoolExecute(g_agentConnectionThreadPool, this, &AgentConnection::onDataPushCallback, msg);
+                  }
+                  else
+                  {
+                     delete msg;
+                  }
+                  break;
+               case CMD_DCI_DATA:
+                  if (g_agentConnectionThreadPool != NULL)
+                  {
+                     incInternalRefCount();
+                     ThreadPoolExecute(g_agentConnectionThreadPool, this, &AgentConnection::processCollectedDataCallback, msg);
+                  }
+                  else
+                  {
+                     NXCPMessage response;
+                     response.setCode(CMD_REQUEST_COMPLETED);
+                     response.setId(msg->getId());
+                     response.setField(VID_RCC, ERR_INTERNAL_ERROR);
+                     sendMessage(&response);
+                     delete msg;
+                  }
+                  break;
+               case CMD_FILE_MONITORING:
+                  onFileMonitoringData(msg);
+                  delete msg;
+                  break;
+               case CMD_SNMP_TRAP:
+                  if (g_agentConnectionThreadPool != NULL)
+                  {
+                     incInternalRefCount();
+                     ThreadPoolExecute(g_agentConnectionThreadPool, this, &AgentConnection::onSnmpTrapCallback, msg);
+                  }
+                  else
+                  {
+                     delete msg;
+                  }
+                  break;
+               default:
+                  if (processCustomMessage(msg))
+                     delete msg;
+                  else
+                     m_pMsgWaitQueue->put(msg);
+                  break;
+            }
          }
-         switch(msg->getCode())
+         else
          {
-            case CMD_REQUEST_COMPLETED:
-            case CMD_SESSION_KEY:
-               m_pMsgWaitQueue->put(msg);
-               break;
-            case CMD_TRAP:
-               if (g_agentConnectionThreadPool != NULL)
-               {
-                  incInternalRefCount();
-                  ThreadPoolExecute(g_agentConnectionThreadPool, this, &AgentConnection::onTrapCallback, msg);
-               }
-               else
-               {
-                  delete msg;
-               }
-               break;
-            case CMD_SYSLOG_RECORDS:
-               if (g_agentConnectionThreadPool != NULL)
-               {
-                  incInternalRefCount();
-                  ThreadPoolExecute(g_agentConnectionThreadPool, this, &AgentConnection::onSyslogMessageCallback, msg);
-               }
-               else
-               {
-                  delete msg;
-               }
-               break;
-            case CMD_PUSH_DCI_DATA:
-               if (g_agentConnectionThreadPool != NULL)
-               {
-                  incInternalRefCount();
-                  ThreadPoolExecute(g_agentConnectionThreadPool, this, &AgentConnection::onDataPushCallback, msg);
-               }
-               else
-               {
-                  delete msg;
-               }
-               break;
-            case CMD_DCI_DATA:
-               if (g_agentConnectionThreadPool != NULL)
-               {
-                  incInternalRefCount();
-                  ThreadPoolExecute(g_agentConnectionThreadPool, this, &AgentConnection::processCollectedDataCallback, msg);
-               }
-               else
-               {
-                  NXCPMessage response;
-                  response.setCode(CMD_REQUEST_COMPLETED);
-                  response.setId(msg->getId());
-                  response.setField(VID_RCC, ERR_INTERNAL_ERROR);
-                  sendMessage(&response);
-                  delete msg;
-               }
-               break;
-            case CMD_FILE_MONITORING:
-               onFileMonitoringData(msg);
-               delete msg;
-               break;
-            case CMD_SNMP_TRAP:
-               if (g_agentConnectionThreadPool != NULL)
-               {
-                  incInternalRefCount();
-                  ThreadPoolExecute(g_agentConnectionThreadPool, this, &AgentConnection::onSnmpTrapCallback, msg);
-               }
-               else
-               {
-                  delete msg;
-               }
-               break;
-            default:
-               if (processCustomMessage(msg))
-                  delete msg;
-               else
-                  m_pMsgWaitQueue->put(msg);
-               break;
+            debugPrintf(6, _T("RecvMsg: message deserialization error"));
          }
       }
    }
@@ -1101,7 +1108,7 @@ bool AgentConnection::sendMessage(NXCPMessage *pMsg)
    }
 
    bool success;
-   NXCP_MESSAGE *rawMsg = pMsg->createMessage(m_allowCompression);
+   NXCP_MESSAGE *rawMsg = pMsg->serialize(m_allowCompression);
        NXCPEncryptionContext *pCtx = acquireEncryptionContext();
    if (pCtx != NULL)
    {
index 519430f..42e0400 100644 (file)
@@ -227,16 +227,23 @@ void ISC::receiverThread()
                else
                {
                        // Create message object from raw message
-                       pMsg = new NXCPMessage(pRawMsg, m_protocolVersion);
-         if (onMessage(pMsg))
-         {
-            // message was consumed by handler
-            delete pMsg;
-         }
-         else
-         {
-                          m_msgWaitQueue->put(pMsg);
-         }
+                       pMsg = NXCPMessage::deserialize(pRawMsg, m_protocolVersion);
+                       if (pMsg != NULL)
+                       {
+            if (onMessage(pMsg))
+            {
+               // message was consumed by handler
+               delete pMsg;
+            }
+            else
+            {
+               m_msgWaitQueue->put(pMsg);
+            }
+                       }
+                       else
+                       {
+                printMessage(_T("RecvMsg: message deserialization error"));
+                       }
                }
    }
 
@@ -427,7 +434,7 @@ BOOL ISC::sendMessage(NXCPMessage *pMsg)
       pMsg->setId((UINT32)InterlockedIncrement(&m_requestId));
    }
 
-   pRawMsg = pMsg->createMessage();
+   pRawMsg = pMsg->serialize();
    if (m_ctx != NULL)
    {
       pEnMsg = m_ctx->encryptMessage(pRawMsg);
index f063e53..1426c7d 100644 (file)
@@ -95,7 +95,7 @@ void SendMsg(NXCPMessage *pMsg)
 {
    NXCP_MESSAGE *pRawMsg;
 
-   pRawMsg = pMsg->createMessage();
+   pRawMsg = pMsg->serialize();
    SendEx(g_hSocket, pRawMsg, ntohl(pRawMsg->size), 0, NULL);
    free(pRawMsg);
 }
index f33b4ae..9ff32b0 100644 (file)
@@ -74,11 +74,12 @@ void TestMessageClass()
    StartTest(_T("NXCP message compression"));
 
    msg.setField(100, longText);
-   NXCP_MESSAGE *binMsg = msg.createMessage(true);
+   NXCP_MESSAGE *binMsg = msg.serialize(true);
    AssertNotNull(binMsg);
    AssertTrue((ntohs(binMsg->flags) & MF_COMPRESSED) != 0);
 
-   NXCPMessage *dmsg = new NXCPMessage(binMsg);
+   NXCPMessage *dmsg = NXCPMessage::deserialize(binMsg);
+   AssertNotNull(dmsg);
    TCHAR *longTextOut = dmsg->getFieldAsString(100);
    AssertNotNull(longTextOut);
    AssertTrue(!_tcscmp(longTextOut, longText));