Azure / azure-uamqp-c

AMQP library for C
Other
58 stars 62 forks source link

Reset link credit on last transfer legally received #465

Closed ewertons closed 2 months ago

ewertons commented 2 months ago

This is a problematic code, since if the current credit is already zero, the sender will not have sent another transfer.

else if (is_transfer_type_by_descriptor(descriptor))
{
    if (link_instance->on_transfer_received != NULL)
    {
        TRANSFER_HANDLE transfer_handle;
        if (amqpvalue_get_transfer(performative, &transfer_handle) != 0)
        {
            LogError("Cannot get transfer performative");
        }
        else
        {
            AMQP_VALUE delivery_state;
            bool more;
            bool is_error;

            if (link_instance->current_link_credit == 0)

That can be verified in the AMQP 1.0 spec in "2.6.7 Flow Control": "If the link-credit is less than or equal to zero, i.e. the delivery-count is the same as or greater than the delivery-limit, it is illegal to send more messages."

Here the code is already automatically replenishing the link credit if it gets "too low". In such case, it should check if the link credit gets down to 1 or less (for the last message that the sender can legally send) and then replenish, also sending a new flow to the sender.

Btw, this is a new bug caused by this change: https://github.com/Azure/azure-uamqp-c/pull/383/files

The current issue that best matches this bug is https://github.com/Azure/azure-uamqp-c/issues/461

ericwolz commented 2 months ago

UT needed?

ewertons commented 2 months ago

UT needed?

Added.