Bluetooth: Mesh: Improve Network Message Cache behavior
The implementation of the Network Message Cache has so far been suboptimal, since it has treated the same packet with different TTL values as different packets. Since one of the purposes of this cache is to prevent unnecessary relaying, it's important that we don't let the TTL value influence the "hash" that's used for matching messages. This patch changes the hash to consist of most of the IV Index (three least significant bytes of it), the sequence number and the source address, which should give fairly optimal matching behavior. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
bd4c87584b
commit
c2f0dad29d
2 changed files with 16 additions and 27 deletions
|
@ -104,30 +104,23 @@ static bool check_dup(struct net_buf_simple *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
static u64_t msg_hash(struct net_buf_simple *pdu)
|
||||
static u64_t msg_hash(struct bt_mesh_net_rx *rx, struct net_buf_simple *pdu)
|
||||
{
|
||||
u8_t *tpdu_last;
|
||||
u64_t hash;
|
||||
u32_t hash1, hash2;
|
||||
|
||||
/* Last byte of TransportPDU */
|
||||
tpdu_last = net_buf_simple_tail(pdu) - (CTL(pdu->data) ? 8 : 4) - 1;
|
||||
/* Three least significant bytes of IVI + first byte of SEQ */
|
||||
hash1 = (BT_MESH_NET_IVI_RX(rx) << 8) | pdu->data[2];
|
||||
|
||||
((u8_t *)(&hash))[0] = pdu->data[0];
|
||||
((u8_t *)(&hash))[1] = (pdu->data[1] & 0xc0);
|
||||
((u8_t *)(&hash))[2] = *tpdu_last;
|
||||
memcpy(&((u8_t *)&hash)[3], &pdu->data[2], 5);
|
||||
/* Two last bytes of SEQ + SRC */
|
||||
memcpy(&hash2, &pdu->data[3], 4);
|
||||
|
||||
return hash;
|
||||
return (u64_t)hash1 << 32 | (u64_t)hash2;
|
||||
}
|
||||
|
||||
static void msg_cache_add(u64_t new_hash)
|
||||
{
|
||||
msg_cache[msg_cache_next++] = new_hash;
|
||||
msg_cache_next %= ARRAY_SIZE(msg_cache);
|
||||
}
|
||||
|
||||
static bool msg_is_known(u64_t hash)
|
||||
static bool msg_cache_match(struct bt_mesh_net_rx *rx,
|
||||
struct net_buf_simple *pdu)
|
||||
{
|
||||
u64_t hash = msg_hash(rx, pdu);
|
||||
u16_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(msg_cache); i++) {
|
||||
|
@ -136,6 +129,10 @@ static bool msg_is_known(u64_t hash)
|
|||
}
|
||||
}
|
||||
|
||||
/* Add to the cache */
|
||||
msg_cache[msg_cache_next++] = hash;
|
||||
msg_cache_next %= ARRAY_SIZE(msg_cache);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -929,7 +926,8 @@ static int net_decrypt(struct bt_mesh_subnet *sub, u8_t idx, const u8_t *data,
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (msg_is_known(rx->hash)) {
|
||||
if (rx->net_if == BT_MESH_NET_IF_ADV && msg_cache_match(rx, buf)) {
|
||||
BT_WARN("Duplicate found in Network Message Cache");
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
|
@ -1111,10 +1109,6 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if,
|
|||
|
||||
rx->net_if = net_if;
|
||||
|
||||
if (net_if == BT_MESH_NET_IF_ADV) {
|
||||
rx->hash = msg_hash(data);
|
||||
}
|
||||
|
||||
if (!net_find_and_decrypt(data->data, data->len, rx, buf)) {
|
||||
BT_DBG("Unable to find matching net for packet");
|
||||
return -ENOENT;
|
||||
|
@ -1161,10 +1155,6 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if,
|
|||
return -EBADMSG;
|
||||
}
|
||||
|
||||
if (net_if == BT_MESH_NET_IF_ADV) {
|
||||
msg_cache_add(rx->hash);
|
||||
}
|
||||
|
||||
BT_DBG("src 0x%04x dst 0x%04x ttl %u", rx->ctx.addr, rx->dst,
|
||||
rx->ctx.recv_ttl);
|
||||
BT_DBG("PDU: %s", bt_hex(buf->data, buf->len));
|
||||
|
|
|
@ -202,7 +202,6 @@ enum bt_mesh_net_if {
|
|||
struct bt_mesh_net_rx {
|
||||
struct bt_mesh_subnet *sub;
|
||||
struct bt_mesh_msg_ctx ctx;
|
||||
u64_t hash; /* Hash for the relay cache */
|
||||
u32_t seq; /* Sequence Number */
|
||||
u16_t dst; /* Destination address */
|
||||
u8_t old_iv:1, /* iv_index - 1 was used */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue