/*
   * On input, we hash messages one at a time since servers may need
   * to access an intermediate hash to validate a CertificateVerify
   * message.
   *
   * Note that many handshake messages can come in one record (and often
   * do, to reduce network resource utilization), and one message can also
   * require multiple records (e.g. very large Certificate messages).
   */
  void processLoop() throws IOException {

    // need to read off 4 bytes at least to get the handshake
    // message type and length.
    while (input.available() >= 4) {
      byte messageType;
      int messageLen;

      /*
       * See if we can read the handshake message header, and
       * then the entire handshake message.  If not, wait till
       * we can read and process an entire message.
       */
      input.mark(4);

      messageType = (byte) input.getInt8();
      messageLen = input.getInt24();

      if (input.available() < messageLen) {
        input.reset();
        return;
      }

      /*
       * Process the messsage.  We require
       * that processMessage() consumes the entire message.  In
       * lieu of explicit error checks (how?!) we assume that the
       * data will look like garbage on encoding/processing errors,
       * and that other protocol code will detect such errors.
       *
       * Note that digesting is normally deferred till after the
       * message has been processed, though to process at least the
       * client's Finished message (i.e. send the server's) we need
       * to acccelerate that digesting.
       *
       * Also, note that hello request messages are never hashed;
       * that includes the hello request header, too.
       */
      if (messageType == HandshakeMessage.ht_hello_request) {
        input.reset();
        processMessage(messageType, messageLen);
        input.ignore(4 + messageLen);
      } else {
        input.mark(messageLen);
        processMessage(messageType, messageLen);
        input.digestNow();
      }
    }
  }