Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
1.15.0
-
None
Description
If the adaptor rejects an AMQP message containing invalid/corrupted HTTP information in some cases the PN_REJECTED outcome is not propagated. The associated delivery is settled without a terminal outcome.
The root cause is the adaptor is calling qd_message_set_discard(msg, true) in the core_link_deliver adaptor callback. qd_message_set_discard can only be called by the I/O thead that is receiving the AMQP message - NOT the outgoing thread!
Here's a high-level description of the race:
Thread 0: receives an AMQP message from neighboring router. AMQP message contains HTTP message destined to locally attached HTTP endpoint. Message is streaming. Thread hands AMQP message up to core for forwarding
Core: forwards message to HTTP adaptor
Thread 1: runs HTTP adaptor qdr_connection_process() which eventually invokes the core_link_deliver callback. This callback detects an error in the HTTP message, marks the send as complete, sets qd_message_set_discard(msg, true), then returns PN_REJECT. This causes the caller (qdr_link_process_deliveries) to enqueue a delivery update to the core with settled=true and dispo=PN_REJECT.
Thread 0 is scheduled next before the Core thread can process the delivery state update:
Thread 0: runs AMQP rx handler, detects the message has its discard flag set and begins to discard the incoming message. The message happens to complete and thread 0 immediately settled the associated pn_delivery. Disposition is not updated.
Core: processes the delivery update but the proton pn_delivery is gone so the update is lost.