コード例 #1
0
void dumpBuffer(unsigned char *buffer, size_t len)
{
  if (buffer == NULL)
  {
    return;
  }
  
  //
  // We will print the buffer 16 characters at a time. For each group
  // of 16 characters will we build two strings. One we call the "hex"
  // string and the other the "ascii" string. They will be formatted
  // as follows:
  //
  //  hex:   "<hex pair> <hex pair> ..."
  //  ascii: "<ascii value><ascii value>..."
  //
  // where each <hex pair> is a 4-character hex representation of
  // 2-bytes and each <ascii value> is 1 character.
  //
  const Int32 CHARS_PER_LINE = 16;
  const Int32 ASCII_BUF_LEN = CHARS_PER_LINE + 1;

  const Int32 HEX_BUF_LEN =
    (2 * CHARS_PER_LINE)     // 2 hex characters per byte of input
    + (CHARS_PER_LINE / 2)   // one space between each <hex pair>
    + 1;                     // null terminator

  //
  // The 100-byte pads in the following two buffers are only used as
  // safeguards to prevent corrupting the stack. The code should work
  // without the padding.
  //
  char hexBuf[HEX_BUF_LEN + 100];
  char asciiBuf[ASCII_BUF_LEN + 100];
  size_t i, j, hexOffset, asciiOffset;
  size_t startingOffset;
  Int32 nCharsWritten;

  //
  // This message will be used for buffer overflow assertion failures
  //  
  const char *msg = "Buffer overflow in dumpBuffer() routine";

  i = 0;
  while (i < len)
  {
    //
    // Initialize the two buffers with blank padding and null
    // terminators
    //
    memset(hexBuf,  ' ', HEX_BUF_LEN);
    memset(asciiBuf, ' ', ASCII_BUF_LEN);
    hexBuf[HEX_BUF_LEN - 1] = '\0';
    asciiBuf[ASCII_BUF_LEN - 1] = '\0';
    hexOffset = 0;
    asciiOffset = 0;
    startingOffset = i;

    //
    // Inside the following for loop hexOffset should be incremented
    // by 2 or 3 and asciiOffset incremented by 1.
    //
    for (j = 0; j < CHARS_PER_LINE && i < len; j++, i++)
    {
      //
      // Write a 2-character hex value to the hex buffer. The %X
      // format expects an int value.
      //
      nCharsWritten = sprintf(&hexBuf[hexOffset], "%02X",
                              (Int32) buffer[i]);
      UDR_ASSERT(nCharsWritten == 2, msg);
      hexOffset += 2;

      //
      // Add a space to the hex buffer following each pair of bytes
      //
      if (j % 2 == 1)
      {
        hexBuf[hexOffset++] = ' ';
      }

      //
      // Write one character to the ascii buffer
      //
      char c;
      if (!isprint(buffer[i]))
      {
        c = '.';
      }
      else
      {
        c = buffer[i];
      }
      asciiBuf[asciiOffset++] = c;

    } // for (j = 0; j < CHARSPERLINE && i < len; j++, i++)

    UDR_ASSERT(hexOffset < HEX_BUF_LEN, msg);
    UDR_ASSERT(asciiOffset < ASCII_BUF_LEN, msg);
    UDR_ASSERT(hexBuf[HEX_BUF_LEN - 1] == '\0', msg);
    UDR_ASSERT(asciiBuf[ASCII_BUF_LEN - 1] == '\0', msg);

    ServerDebug("%08X  %-*s |  %s", (Int32) startingOffset,
                (Int32) (HEX_BUF_LEN - 1), hexBuf, asciiBuf);

  } // while (i < len)

  ServerDebug("");
  
} // dumpBuffer
コード例 #2
0
void UdrServerDataStream::actOnReceive(IpcConnection *conn)
{
  const char *moduleName = "UdrServerDataStream::actOnReceive()";

  IpcMessageObjType t;
  NABoolean somethingArrived = FALSE;

  //
  // A note about control flow in this method. It was originally
  // written under the assumption that only one message arrives at a
  // time. It would call getNextReceiveMsg() only once, then process
  // incoming objects, then return. It turns out this creates a memory
  // leak. Internally within the stream, the incoming message buffer
  // never moved from the "receive" list to the "in use" list and
  // never got cleaned up. Now this method calls getNextReceiveMsg()
  // until it returns FALSE. The result is that after the incoming
  // message has been processed, the next getNextReceiveMsg() call
  // will move the request buffer to the "in use" list where it later
  // gets cleaned up by a call to cleanupBuffers() or
  // releaseBuffers().
  //

  while (getNextReceiveMsg(t))
  {
    somethingArrived = TRUE;

    while (getNextObjType(t))
    {
      switch (t)
      {
        case UDR_MSG_DATA_HEADER:
        {
          // Do nothing for now except extract the object from the stream
          UdrDataHeader *h = new (receiveMsgObj()) UdrDataHeader(this);
          
        } // case UDR_MSG_DATA_HEADER
        break;
        
        case UDR_MSG_CONTINUE_REQUEST:
        {
          // Extract the object from the stream and call SPInfo's work()
          UdrContinueMsg *m = new (receiveMsgObj()) UdrContinueMsg(this);
          
          if(spinfo_->getParamStyle() == COM_STYLE_TM)
            spinfo_->workTM();
          else
            spinfo_->work();
          
        } // case UDR_MSG_CONTINUE_REQUEST
        break;
        
        case UDR_MSG_DATA_REQUEST:
        {
          UdrDataBuffer *request = new (receiveMsgObj()) UdrDataBuffer(this);
          
          if (udrGlob_->verbose_ &&
              udrGlob_->traceLevel_ >= TRACE_DETAILS &&
              udrGlob_->showMain_)
          {
            ServerDebug( "");
            ServerDebug("[UdrServ (%s)] Invoke Request has %ld tupps.",
                        moduleName,
                        request->getSqlBuffer()->getTotalTuppDescs());
            ServerDebug("[UdrServ (%s)] Invoke Request SQL Buffer",
                        moduleName);
            displaySqlBuffer(request->getSqlBuffer(),
                             (Lng32) request->getSqlBufferLength());
          }
          
          udrGlob_->numReqInvokeSP_++;
          
          // Let the SPInfo process the request
	  spinfo_->setCurrentRequest(request);
	  spinfo_->work();

        } // case UDR_MSG_DATA_REQUEST
        break;

        case UDR_MSG_TMUDF_DATA_HEADER:
	{
	  // Extract the object. UDR Handle and RS Handle are
	  // interesting things in this message.
          UdrTmudfDataHeader *h = new (receiveMsgObj()) UdrTmudfDataHeader(this);
	  UdrHandle udrHandle = h->getHandle();

          NABoolean anyMore = getNextObjType(t);
          UDR_ASSERT(anyMore, "DATA_REQUEST must follow TMUDF DATA_HEADER");
          UDR_ASSERT(t == UDR_MSG_DATA_REQUEST,
                     "DATA_REQUEST must follow TMUDF DATA_HEADER");

          UdrDataBuffer *request = new (receiveMsgObj()) 
                                    UdrDataBuffer(this,
                                                  FALSE); //Avoid unpack.

          // Let the SPInfo process the request
	  spinfo_->setCurrentRequest(request);
	  spinfo_->workTM();
	}
        break;

        case UDR_MSG_RS_DATA_HEADER:
	{
	  // Extract the object. UDR Handle and RS Handle are
	  // interesting things in this message.
          UdrRSDataHeader *h = new (receiveMsgObj()) UdrRSDataHeader(this);
	  UdrHandle udrHandle = h->getHandle();
	  RSHandle rsHandle = h->getRSHandle();

          NABoolean anyMore = getNextObjType(t);
          UDR_ASSERT(anyMore, "DATA_REQUEST must follow RS_DATA_HEADER");
          UDR_ASSERT(t == UDR_MSG_DATA_REQUEST,
                     "DATA_REQUEST must follow RS_DATA_HEADER");

          UdrDataBuffer *request = new (receiveMsgObj()) UdrDataBuffer(this);

	  udrGlob_->numReqRSFetch_++;
	  processAnRSFetchMessage(udrGlob_, *this, udrHandle,
                                  rsHandle, request);

          // We need the request buffer in a state where the stream
          // knows it can be freed. We call SqlBuffer::bufferFull() to
          // accomplish this even though the method name is a bit
          // misleading.
          SqlBuffer *sqlBuf = request->getSqlBuffer();
          UDR_ASSERT(sqlBuf,
                     "UDR request buffer is corrupt or contains no data");
          sqlBuf->bufferFull();
	}
        break;

        case UDR_MSG_RS_CONTINUE:
	{
	  UdrRSContinueMsg *rsContinue =
            new (receiveMsgObj()) UdrRSContinueMsg(this);

	  udrGlob_->numReqRSContinue_++;
	  processAnRSContinueMessage(udrGlob_, *this, *rsContinue);
	}
	break;

        default:
        {
          UDR_ASSERT(FALSE,
                     "Unknown message type arrived on UDR data stream");
        } // default
        break;
        
      } // switch (t)
      
    } // while (getNextObjType(t))
  } // while (getNextReceiveMsg(t))

  // Make sure all reply buffers have been given to the connection. If
  // the only objects that arrived during this callback were continue
  // requests, then this action allows reply buffers associated with
  // those continue requests to propagate out of the stream and onto
  // the connection.
  //
  // If numOfInputBuffers() is > 0 then we do not need to do anything
  // at this point. This callback will be invoked again when the
  // incoming message is complete and ready to be processed.
  Lng32 numInputBuffers = numOfInputBuffers();
  if (somethingArrived && numInputBuffers == 0 &&
      spinfo_->getCurrentRequest() == NULL)
  {
    responseDone();

    if (udrGlob_->verbose_ &&
        udrGlob_->traceLevel_ >= TRACE_IPMS &&
        udrGlob_->showMain_)
    {
      ServerDebug("[UdrServ (%s)] All messages marked as replied", moduleName);
    }

    // Cleanup any unpacked message buffers containing only objects
    // that are no longer in use, as determined by the virtual method
    // IpcMessageObj::msgObjIsFree()
    releaseBuffers();  // Do final garbage collection
  }
  
} // UdrServerDataStream::actOnReceive()
コード例 #3
0
NABoolean allocateReplyRow(UdrGlobals *UdrGlob,
  SqlBuffer &replyBuffer,       // [IN]  A reply buffer
  queue_index parentIndex,      // [IN]  Identifies the request queue entry
  Int32 replyRowLen,              // [IN]  Length of reply row
  char *&newReplyRow,           // [OUT] The allocated reply row
  ControlInfo *&newControlInfo, // [OUT] The allocated ControlInfo entry
  ex_queue::up_status upStatus  // [IN]  Q_OK_MMORE, Q_NO_DATA, Q_SQLERROR
  )
{
  const char *moduleName = "allocateReplyRow";

  doMessageBox(UdrGlob, TRACE_SHOW_DIALOGS, UdrGlob->showInvoke_, moduleName);

  NABoolean result = FALSE;
  SqlBufferBase::moveStatus status;
  up_state upState;
  upState.parentIndex = parentIndex;
  upState.downIndex = 0;
  upState.setMatchNo(0);

  upState.status = upStatus;

  tupp_descriptor *tdesc = NULL, **tuppDesc;
  ControlInfo **ctrlInfo;
  NABoolean moveCtrlInfo, moveDataInfo;

  switch (upStatus)
  {
    case ex_queue::Q_OK_MMORE :
    {
      ctrlInfo = &newControlInfo;
      moveCtrlInfo = TRUE;
      moveDataInfo = TRUE;
      tuppDesc = &tdesc;
      break;
    }

    case ex_queue::Q_SQLERROR :
    {
      ctrlInfo = &newControlInfo;
      moveCtrlInfo = TRUE;
      moveDataInfo = FALSE;
      tuppDesc = NULL;
      break;
    }

    case ex_queue::Q_NO_DATA :
    {
      ctrlInfo = NULL;
      moveCtrlInfo = TRUE;
      moveDataInfo = FALSE;
      tuppDesc = NULL;
      break;
    }

    default:
    {
      UDR_ASSERT(FALSE, "Unknown ex_queue::up_status value.");
      return FALSE;
    }
  }

  status = replyBuffer.moveInSendOrReplyData(
    FALSE,                           // [IN] sending? (vs. replying)
    moveCtrlInfo,                    // [IN] force move of ControlInfo?
    moveDataInfo,                    // [IN] move data?
    (void *) &upState,               // [IN] queue state
    sizeof(ControlInfo),             // [IN] length of ControlInfo
    ctrlInfo,                        // [OUT] new ControlInfo
    replyRowLen,                     // [IN] data row length
    tuppDesc,                        // [OUT] new data tupp_desc
    NULL,                            // [IN] diags area
    0                                // [OUT] new diags tupp_desc
    );

  if (status == SqlBufferBase::MOVE_SUCCESS)
  {
    if (upStatus == ex_queue::Q_OK_MMORE)
    {
       newReplyRow = tdesc->getTupleAddress();
       memset(newReplyRow, 0, replyRowLen);
    }
    result = TRUE;
  }
  else
  {
    result = FALSE;
  }
  return result;
}