Commit 5b76361
committed
Fix routing for empty binding key to topic exchange
Fixes #16221
## What?
Fix a bug in the Khepri v4 topic trie projection where
messages published with an empty routing key to a topic exchange
were incorrectly routed to queues bound to other topic exchanges
with an empty binding key.
## Why?
The MQTT 5.0 spec states:
> All Topic Names and Topic Filters MUST be at least one character long
In contrast, the AMQP 0.9.1 spec state:
> The routing key used for a topic exchange MUST consist of **zero** or more words
delimited by dots. Each word may contain the letters A-Z and a-z and digits 0-9.
The routing pattern follows the same rules as the routing key with the addition
that * matches a single word, and # matches zero or more words
Hence zero words, i.e. empty routing keys and empty binding keys, are expliclity
allowed for the topic exchange type.
In the Khepri v4 projection, the topic trie used a global `root` atom
as the initial node ID for all topic exchanges. When a binding was
created with an empty binding key (`<<>>`), `split_topic_key_binary/1`
returned an empty list (`[]`). The trie traversal stopped immediately
at the root, meaning the binding was inserted into the
`rabbit_khepri_topic_binding_v4` ETS table with the global `root` atom
as the `LeafNodeId`.
Because the `LeafNodeId` lacked any exchange-specific context, all
empty bindings across all topic exchanges were
attached to the exact same global `root` node. Consequently, when a
message was published with an empty routing key to any topic exchange,
the routing logic (`trie_bindings/3`) would scan the ETS table starting
at the global `root` node and incorrectly match bindings belonging to
completely unrelated topic exchanges.
## How?
To fix this and ensure exchange isolation, the conceptual root of the
trie was changed from the global `root` atom to an exchange-specific
tuple: `{root, XSrc}` (where `XSrc` is `{VHost, ExchangeName}`).
- `rabbit_khepri:trie_follow_down_create/3` and `trie_follow_down_get_path/3`
now initialize their trie traversal with `{root, XSrc}`.
- `rabbit_db_topic_exchange:trie_match/5` now initiates routing from
`{root, {VHost, XName}}`.
This structural change guarantees that empty bindings are isolated per
exchange in the bindings ETS table, completely resolving the cross-exchange
leakage while fully supporting AMQP 0-9-1's allowance for empty binding
keys without breaking backward compatibility.1 parent b1f3d4b commit 5b76361
3 files changed
Lines changed: 70 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| 42 | + | |
42 | 43 | | |
43 | | - | |
| 44 | + | |
44 | 45 | | |
45 | 46 | | |
46 | 47 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1733 | 1733 | | |
1734 | 1734 | | |
1735 | 1735 | | |
1736 | | - | |
| 1736 | + | |
1737 | 1737 | | |
1738 | 1738 | | |
1739 | 1739 | | |
| |||
1757 | 1757 | | |
1758 | 1758 | | |
1759 | 1759 | | |
1760 | | - | |
| 1760 | + | |
1761 | 1761 | | |
1762 | 1762 | | |
1763 | 1763 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
| 49 | + | |
49 | 50 | | |
50 | 51 | | |
51 | 52 | | |
| |||
706 | 707 | | |
707 | 708 | | |
708 | 709 | | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
709 | 775 | | |
710 | 776 | | |
711 | 777 | | |
| |||
0 commit comments