int SSLconnect::sslRead()

in nlsCppSdk/transport/SSLconnect.cpp [275:371]


int SSLconnect::sslRead(uint8_t *buffer, size_t len) {
  MUTEX_LOCK(_mtxSSL);

  if (_ssl == NULL) {
    LOG_ERROR("SSL(%p) ssl has been closed.", this);
    MUTEX_UNLOCK(_mtxSSL);
    return -(SslReadFailed);
  }

  int rLen = SSL_read(_ssl, (void *)buffer, (int)len);
  if (rLen <= 0) {
    int sslError = SSL_get_error(_ssl, rLen);
    int errno_code = utility::getLastErrorCode();
    char sslErrMsg[MaxSslErrorLength] = {0};
    const char *SSL_read_ret = "return of SSL_read: ";
    const int SSL_read_str_size = strnlen(SSL_read_ret, 64);
    // LOG_WARN("Read maybe failed, get_ssl_error:%d", sslError);
    if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE ||
        sslError == SSL_ERROR_WANT_X509_LOOKUP) {
      // LOG_DEBUG("SSL(%p) Read could not complete. Will be invoked later.",
      // this);
      MUTEX_UNLOCK(_mtxSSL);
      return 0;
    } else if (sslError == SSL_ERROR_SYSCALL) {
      LOG_INFO("SSL(%p) SSL_read error_syscall failed, errno:%d.", this,
               errno_code);

      if (NLS_ERR_CONNECT_RETRIABLE(errno_code) ||
          NLS_ERR_RW_RETRIABLE(errno_code)) {
        LOG_WARN("SSL(%p) Retry read...", this);
        MUTEX_UNLOCK(_mtxSSL);
        return 0;
      } else if (errno_code == 0) {
        LOG_DEBUG("SSL(%p) SSL_read syscall success.", this);
        MUTEX_UNLOCK(_mtxSSL);
        return 0;
#ifdef _MSC_VER
      } else if (errno_code == WSAECONNRESET) {
#else
      } else if (errno_code == ECONNRESET) {
#endif
        memset(_errorMsg, 0x0, MaxSslErrorLength);
        memcpy(sslErrMsg, SSL_read_ret, SSL_read_str_size);
        ERR_error_string_n(ERR_get_error(), sslErrMsg + SSL_read_str_size,
                           MaxSslErrorLength - SSL_read_str_size - 1);
        snprintf(_errorMsg, MaxSslErrorLength,
                 "%s. It's mean the remote end was "
                 "closed because of bad network. errno_code:%d, ssl_eCode:%d.",
                 sslErrMsg, errno_code, sslError);
        LOG_ERROR("SSL(%p) SSL_ERROR_SYSCALL Read failed, %s.", this,
                  _errorMsg);
        MUTEX_UNLOCK(_mtxSSL);
        return -(SslReadSysError);
      } else {
        memset(_errorMsg, 0x0, MaxSslErrorLength);
        memcpy(sslErrMsg, SSL_read_ret, SSL_read_str_size);
        ERR_error_string_n(ERR_get_error(), sslErrMsg + SSL_read_str_size,
                           MaxSslErrorLength - SSL_read_str_size - 1);
        snprintf(_errorMsg, MaxSslErrorLength,
                 "%s. errno_code:%d, ssl_eCode:%d.", sslErrMsg, errno_code,
                 sslError);
        LOG_ERROR("SSL(%p) SSL_ERROR_SYSCALL Read failed, %s.", this,
                  _errorMsg);
        MUTEX_UNLOCK(_mtxSSL);
        return -(SslReadSysError);
      }
    } else {
      memset(_errorMsg, 0x0, MaxSslErrorLength);
      memcpy(sslErrMsg, SSL_read_ret, strnlen(SSL_read_ret, 64));
      ERR_error_string_n(ERR_get_error(), sslErrMsg + SSL_read_str_size,
                         MaxSslErrorLength - SSL_read_str_size - 1);
      if (sslError == SSL_ERROR_ZERO_RETURN && errno_code == 0 &&
          ++_sslTryAgain <= MaxSslTryAgain) {
        snprintf(
            _errorMsg, MaxSslErrorLength,
            "%s. errno_code:%d ssl_eCode:%d. It's mean this connection was "
            "closed or shutdown because of bad network, Try again ...",
            sslErrMsg, errno_code, sslError);
        LOG_WARN("SSL(%p) SSL_read failed: %s.", this, _errorMsg);
        MUTEX_UNLOCK(_mtxSSL);
        return 0;
      } else {
        snprintf(_errorMsg, MaxSslErrorLength,
                 "%s. errno_code:%d ssl_eCode:%d.", sslErrMsg, errno_code,
                 sslError);
      }
      LOG_ERROR("SSL(%p) SSL_read failed: %s.", this, _errorMsg);
      MUTEX_UNLOCK(_mtxSSL);
      return -(SslReadFailed);
    }
  }

  _sslTryAgain = 0;

  MUTEX_UNLOCK(_mtxSSL);
  return rLen;
}