static int on_io_recv()

in adapters/tlsio_mbedtls.c [301:389]


static int on_io_recv(void *context, unsigned char *buf, size_t sz)
{
    int result;
    if (context == NULL)
    {
        LogError("Invalid context NULL value passed");
        result = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }
    else
    {
        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)context;
        unsigned char *new_socket_io_read_bytes;
        int pending = 0;

        while (tls_io_instance->socket_io_read_byte_count == 0)
        {
            xio_dowork(tls_io_instance->socket_io);

            if (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN)
            {
                break;
            }
            else if (tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN ||
                     tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING ||
                     tls_io_instance->tlsio_state == TLSIO_STATE_ERROR)
            {
                // Underlying io error, exit.
                return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
            }
            else
            {
                // Handkshake
                if (tls_io_instance->socket_io_read_byte_count == 0)
                {
                    if (pending++ >= HANDSHAKE_TIMEOUT_MS / HANDSHAKE_WAIT_INTERVAL_MS)
                    {
                        // The connection is close from server side and no response.
                        LogError("Tlsio_Failure: encountered unknow connection issue, the connection will be restarted.");
                        indicate_error(tls_io_instance);
                        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
                    }
                    ThreadAPI_Sleep(HANDSHAKE_WAIT_INTERVAL_MS);
                }
            }
        }

        result = (int) tls_io_instance->socket_io_read_byte_count;
        if (result > (int)sz)
        {
            result = (int)sz;
        }

        if (result > 0)
        {
            size_t read_byte_count = safe_subtract_size_t(tls_io_instance->socket_io_read_byte_count, (size_t)result);
            if (read_byte_count != SIZE_MAX)
            {
                (void)memcpy((void*)buf, tls_io_instance->socket_io_read_bytes, result);
                (void)memmove(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_bytes + result, read_byte_count);

                tls_io_instance->socket_io_read_byte_count = read_byte_count;
                if (tls_io_instance->socket_io_read_byte_count > 0)
                {
                    new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count);
                    if (new_socket_io_read_bytes != NULL)
                    {
                        tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes;
                    }
                }
                else
                {
                    free(tls_io_instance->socket_io_read_bytes);
                    tls_io_instance->socket_io_read_bytes = NULL;
                }
            }
            else
            {
                LogError("Tlsio_Failure: memmove invalid size.");
                return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
            }
        }

        if ((result == 0) && (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN))
        {
            result = MBEDTLS_ERR_SSL_WANT_READ;
        }
    }
    return result;
}