-
Notifications
You must be signed in to change notification settings - Fork 148
Description
AMQP 1.0 section 2.7.4 states for FLOW field next-incoming-id:
This value MUST be set if the peer has received the begin frame for the session, and MUST NOT be set if it has not.
However, this client always sets field next-incoming-id irrespective whether it has received the server's BEGIN frame.
Reproduction steps:
In root folder of https://github.com/ansd/rabbitmq-server/tree/native-amqp-dotnet-bug, run
make -C deps/rabbitmq_amqp1_0 ct-system t=dotnet:redelivery
The test case fails with error
Amqp.AmqpException: next-incoming-id from FLOW (0) leads next-outgoing-id (4294967292)
Here is an easier example:
Start latest RabbitMQ server https://github.com/rabbitmq/rabbitmq-server/tree/v3.12.8 (probably any other server will do it as well):
make run-broker PLUGINS="rabbitmq_amqp1_0 rabbitmq_management"
Create a C# project:
dotnet new console
Modify the .csproj file to contain
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>rabbit_dot_net</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AmqpNetLite" Version="2.4.7" />
</ItemGroup>
</Project>
and the Program.cs file to contain
using Amqp;
Trace.TraceLevel = TraceLevel.Frame;
Trace.TraceListener = (l, f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:mm:ss.fff]") + " " + string.Format(f, a));
Address address = new Address("amqp://guest:guest@localhost:5672");
Connection connection = new Connection(address);
Session session = new Session(connection);
ReceiverLink receiver = new ReceiverLink(session, "receiver-link", "q1");
Message response = receiver.Receive();Start the client:
dotnet run
[05:08:26.761] SEND AMQP 3 1 0 0
[05:08:26.804] RECV sasl-mechanisms(sasl-server-mechanisms:[ANONYMOUS,PLAIN,AMQPLAIN])
[05:08:26.806] SEND sasl-init(mechanism:PLAIN,initial-response:...,hostname:localhost)
[05:08:26.807] RECV sasl-outcome(code:Ok)
[05:08:26.808] SEND AMQP 0 1.0.0
[05:08:26.809] SEND (ch=0) open(container-id:AMQPNetLite-7ec36d4f,host-name:localhost,max-frame-size:262144,channel-max:255,idle-time-out:1073741823)
[05:08:26.809] RECV AMQP 0 1 0 0
[05:08:26.810] SEND (ch=0) begin(next-outgoing-id:4294967293,incoming-window:2048,outgoing-window:2048,handle-max:1023)
[05:08:26.811] SEND (ch=0) attach(name:receiver-link,handle:0,role:True,source:source(address:q1),target:target())
[05:08:26.812] SEND (ch=0) flow(next-in-id:0,in-window:2048,next-out-id:4294967293,out-window:2048,handle:0,delivery-count:0,link-credit:200,drain:False)
[05:08:26.815] RECV (ch=0) open(container-id:rabbit@myhost,max-frame-size:262144,channel-max:255,idle-time-out:60000,properties:[cluster_name:rabbit@myhost,copyright:Copyright (c) 2007-2023 VMware, Inc. or its affiliates.,information:Licensed under the MPL 2.0. Website: https://rabbitmq.com,platform:Erlang/OTP 26.1.2,product:RabbitMQ,version:3.12.8])
[05:08:26.818] RECV (ch=0) begin(remote-channel:0,next-outgoing-id:0,incoming-window:65535,outgoing-window:65535,handle-max:1023)
[05:08:26.819] RECV (ch=0) attach(name:receiver-link,handle:0,role:False,snd-settle-mode:Unsettled,source:source(address:q1,default-outcome:released(),outcomes:[amqp:accepted:list,amqp:rejected:list,amqp:released:list,amqp:modified:list]),initial-delivery-count:0)
[05:08:26.820] RECV (ch=0) flow(next-in-id:4294967293,in-window:65535,next-out-id:0,out-window:65535,handle:0,delivery-count:0,link-credit:200,available:0,drain:False)
As seen in the trace output, the client sends flow(next-in-id:0 before it receives the begin.
Instead of setting next-in-id to 0, the correct behaviour is to not set that field.