static CURLcode bearssl_run_until(struct Curl_easy *data,
                                  struct connectdata *conn, int sockindex,
                                  unsigned target)
{
  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  struct ssl_backend_data *backend = connssl->backend;
  curl_socket_t sockfd = conn->sock[sockindex];
  unsigned state;
  unsigned char *buf;
  size_t len;
  ssize_t ret;
  int err;

  for(;;) {
    state = br_ssl_engine_current_state(&backend->ctx.eng);
    if(state & BR_SSL_CLOSED) {
      err = br_ssl_engine_last_error(&backend->ctx.eng);
      switch(err) {
      case BR_ERR_OK:
        /* TLS close notify */
        if(connssl->state != ssl_connection_complete) {
          failf(data, "SSL: connection closed during handshake");
          return CURLE_SSL_CONNECT_ERROR;
        }
        return CURLE_OK;
      case BR_ERR_X509_EXPIRED:
        failf(data, "SSL: X.509 verification: "
              "certificate is expired or not yet valid");
        return CURLE_PEER_FAILED_VERIFICATION;
      case BR_ERR_X509_BAD_SERVER_NAME:
        failf(data, "SSL: X.509 verification: "
              "expected server name was not found in the chain");
        return CURLE_PEER_FAILED_VERIFICATION;
      case BR_ERR_X509_NOT_TRUSTED:
        failf(data, "SSL: X.509 verification: "
              "chain could not be linked to a trust anchor");
        return CURLE_PEER_FAILED_VERIFICATION;
      }
      /* X.509 errors are documented to have the range 32..63 */
      if(err >= 32 && err < 64)
        return CURLE_PEER_FAILED_VERIFICATION;
      return CURLE_SSL_CONNECT_ERROR;
    }
    if(state & target)
      return CURLE_OK;
    if(state & BR_SSL_SENDREC) {
      buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len);
      ret = swrite(sockfd, buf, len);
      if(ret == -1) {
        if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
          if(connssl->state != ssl_connection_complete)
            connssl->connecting_state = ssl_connect_2_writing;
          return CURLE_AGAIN;
        }
        return CURLE_WRITE_ERROR;
      }
      br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret);
    }
    else if(state & BR_SSL_RECVREC) {
      buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len);
      ret = sread(sockfd, buf, len);
      if(ret == 0) {
        failf(data, "SSL: EOF without close notify");
        return CURLE_READ_ERROR;
      }
      if(ret == -1) {
        if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
          if(connssl->state != ssl_connection_complete)
            connssl->connecting_state = ssl_connect_2_reading;
          return CURLE_AGAIN;
        }
        return CURLE_READ_ERROR;
      }
      br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret);
    }
  }
}
static CURLcode bearssl_run_until(struct Curl_easy *data,
                                  struct connectdata *conn, int sockindex,
                                  unsigned target)
{
  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  struct ssl_backend_data *backend = connssl->backend;
  curl_socket_t sockfd = conn->sock[sockindex];
  unsigned state;
  unsigned char *buf;
  size_t len;
  ssize_t ret;
  int err;

  for(;;) {
    state = br_ssl_engine_current_state(&backend->ctx.eng);
    if(state & BR_SSL_CLOSED) {
      err = br_ssl_engine_last_error(&backend->ctx.eng);
      switch(err) {
      case BR_ERR_OK:
         
        if(connssl->state != ssl_connection_complete) {
          failf(data, "SSL: connection closed during handshake");
          return CURLE_SSL_CONNECT_ERROR;
        }
        return CURLE_OK;
      case BR_ERR_X509_EXPIRED:
        failf(data, "SSL: X.509 verification: "
              "certificate is expired or not yet valid");
        return CURLE_PEER_FAILED_VERIFICATION;
      case BR_ERR_X509_BAD_SERVER_NAME:
        failf(data, "SSL: X.509 verification: "
              "expected server name was not found in the chain");
        return CURLE_PEER_FAILED_VERIFICATION;
      case BR_ERR_X509_NOT_TRUSTED:
        failf(data, "SSL: X.509 verification: "
              "chain could not be linked to a trust anchor");
        return CURLE_PEER_FAILED_VERIFICATION;
      }
       
      if(err >= 32 && err < 64)
        return CURLE_PEER_FAILED_VERIFICATION;
      return CURLE_SSL_CONNECT_ERROR;
    }
    if(state & target)
      return CURLE_OK;
    if(state & BR_SSL_SENDREC) {
      buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len);
      ret = swrite(sockfd, buf, len);
      if(ret == -1) {
        if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
          if(connssl->state != ssl_connection_complete)
            connssl->connecting_state = ssl_connect_2_writing;
          return CURLE_AGAIN;
        }
        return CURLE_WRITE_ERROR;
      }
      br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret);
    }
    else if(state & BR_SSL_RECVREC) {
      buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len);
      ret = sread(sockfd, buf, len);
      if(ret == 0) {
        failf(data, "SSL: EOF without close notify");
        return CURLE_READ_ERROR;
      }
      if(ret == -1) {
        if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
          if(connssl->state != ssl_connection_complete)
            connssl->connecting_state = ssl_connect_2_reading;
          return CURLE_AGAIN;
        }
        return CURLE_READ_ERROR;
      }
      br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret);
    }
  }
}