AsyncSSLSocket::performRead(void** buf, size_t* buflen, size_t* offset) {
  VLOG(4) << "AsyncSSLSocket::performRead() this=" << this << ", buf=" << *buf
          << ", buflen=" << *buflen;

  if (sslState_ == STATE_UNENCRYPTED) {
    return AsyncSocket::performRead(buf, buflen, offset);
  }

  int numToRead = 0;
  if (*buflen > std::numeric_limits<int>::max()) {
    numToRead = std::numeric_limits<int>::max();
    VLOG(4) << "Clamping SSL_read to " << numToRead;
  } else {
    numToRead = int(*buflen);
  }
  int bytes = SSL_read(ssl_.get(), *buf, numToRead);

  if (server_ && renegotiateAttempted_) {
    LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
               << ", sslstate=" << sslState_ << ", events=" << eventFlags_
               << "): client intitiated SSL renegotiation not permitted";
    return ReadResult(
        READ_ERROR,
        std::make_unique<SSLException>(SSLError::CLIENT_RENEGOTIATION));
  }
  if (bytes <= 0) {
    int error = SSL_get_error(ssl_.get(), bytes);
    if (error == SSL_ERROR_WANT_READ) {
      // The caller will register for read event if not already.
      if (errno == EWOULDBLOCK || errno == EAGAIN) {
        return ReadResult(READ_BLOCKING);
      } else {
        return ReadResult(READ_ERROR);
      }
    } else if (error == SSL_ERROR_WANT_WRITE) {
      // TODO: Even though we are attempting to read data, SSL_read() may
      // need to write data if renegotiation is being performed.  We currently
      // don't support this and just fail the read.
      LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
                 << ", sslState=" << sslState_ << ", events=" << eventFlags_
                 << "): unsupported SSL renegotiation during read";
      return ReadResult(
          READ_ERROR,
          std::make_unique<SSLException>(SSLError::INVALID_RENEGOTIATION));
    } else {
      if (zero_return(error, bytes, errno)) {
        return ReadResult(bytes);
      }
      auto errError = ERR_get_error();
      VLOG(6) << "AsyncSSLSocket(fd=" << fd_ << ", "
              << "state=" << state_ << ", "
              << "sslState=" << sslState_ << ", "
              << "events=" << std::hex << eventFlags_ << "): "
              << "bytes: " << bytes << ", "
              << "error: " << error << ", "
              << "errno: " << errno << ", "
              << "func: " << ERR_func_error_string(errError) << ", "
              << "reason: " << ERR_reason_error_string(errError);
      return ReadResult(
          READ_ERROR,
          std::make_unique<SSLException>(error, errError, bytes, errno));
    }
  } else {
    appBytesReceived_ += bytes;
    return ReadResult(bytes);
  }
}
AsyncSSLSocket::performRead(void** buf, size_t* buflen, size_t* offset) {
  VLOG(4) << "AsyncSSLSocket::performRead() this=" << this << ", buf=" << *buf
          << ", buflen=" << *buflen;

  if (sslState_ == STATE_UNENCRYPTED) {
    return AsyncSocket::performRead(buf, buflen, offset);
  }

  int numToRead = 0;
  if (*buflen > std::numeric_limits<int>::max()) {
    numToRead = std::numeric_limits<int>::max();
    VLOG(4) << "Clamping SSL_read to " << numToRead;
  } else {
    numToRead = int(*buflen);
  }
  int bytes = SSL_read(ssl_.get(), *buf, numToRead);

  if (server_ && renegotiateAttempted_) {
    LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
               << ", sslstate=" << sslState_ << ", events=" << eventFlags_
               << "): client intitiated SSL renegotiation not permitted";
    return ReadResult(
        READ_ERROR,
        std::make_unique<SSLException>(SSLError::CLIENT_RENEGOTIATION));
  }
  if (bytes <= 0) {
    int error = SSL_get_error(ssl_.get(), bytes);
    if (error == SSL_ERROR_WANT_READ) {
       
      if (errno == EWOULDBLOCK || errno == EAGAIN) {
        return ReadResult(READ_BLOCKING);
      } else {
        return ReadResult(READ_ERROR);
      }
    } else if (error == SSL_ERROR_WANT_WRITE) {
       
       
       
      LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
                 << ", sslState=" << sslState_ << ", events=" << eventFlags_
                 << "): unsupported SSL renegotiation during read";
      return ReadResult(
          READ_ERROR,
          std::make_unique<SSLException>(SSLError::INVALID_RENEGOTIATION));
    } else {
      if (zero_return(error, bytes, errno)) {
        return ReadResult(bytes);
      }
      auto errError = ERR_get_error();
      VLOG(6) << "AsyncSSLSocket(fd=" << fd_ << ", "
              << "state=" << state_ << ", "
              << "sslState=" << sslState_ << ", "
              << "events=" << std::hex << eventFlags_ << "): "
              << "bytes: " << bytes << ", "
              << "error: " << error << ", "
              << "errno: " << errno << ", "
              << "func: " << ERR_func_error_string(errError) << ", "
              << "reason: " << ERR_reason_error_string(errError);
      return ReadResult(
          READ_ERROR,
          std::make_unique<SSLException>(error, errError, bytes, errno));
    }
  } else {
    appBytesReceived_ += bytes;
    return ReadResult(bytes);
  }
}