From 15597be9268d8b60ec37402615fd88820ef50ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Narajowski?= Date: Thu, 9 Nov 2017 11:58:33 +0100 Subject: [PATCH] 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. X-Original-Commit: 311263736dbe417f254413ab63dcd3f99aca32a8 --- nimble/host/mesh/src/net.c | 46 +++++++++++++------------------------- nimble/host/mesh/src/net.h | 1 - 2 files changed, 16 insertions(+), 31 deletions(-) diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 032abed83..26c5cc935 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -99,32 +99,23 @@ static bool check_dup(struct os_mbuf *data) return false; } -static u64_t msg_hash(struct os_mbuf *pdu) +static u64_t msg_hash(struct bt_mesh_net_rx *rx, struct os_mbuf *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->om_data) ? 8 : 4) - 1; + /* Three least significant bytes of IVI + first byte of SEQ */ + hash1 = (BT_MESH_NET_IVI_RX(rx) << 8) | pdu->om_data[2]; - ((u8_t *)(&hash))[0] = pdu->om_data[0]; - ((u8_t *)(&hash))[1] = (pdu->om_data[1] & 0xc0); - ((u8_t *)(&hash))[2] = *tpdu_last; - memcpy(&((u8_t *)&hash)[3], &pdu->om_data[2], 5); + /* Two last bytes of SEQ + SRC */ + memcpy(&hash2, &pdu->om_data[3], 4); - BT_DBG("hash=%llx", hash) - - 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 os_mbuf *pdu) { + u64_t hash = msg_hash(rx, pdu); u16_t i; for (i = 0; i < ARRAY_SIZE(msg_cache); i++) { @@ -133,6 +124,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; } @@ -944,8 +939,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)) { - BT_DBG("Message is already in cache; hash=%llx", 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; } @@ -1132,10 +1127,6 @@ int bt_mesh_net_decode(struct os_mbuf *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->om_data, data->om_len, rx, buf)) { BT_DBG("Unable to find matching net for packet"); return -ENOENT; @@ -1183,11 +1174,6 @@ int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if, return -EBADMSG; } - if (net_if == BT_MESH_NET_IF_ADV) { - BT_DBG("Add message to cache; hash=%llx", rx->hash); - 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->om_data, buf->om_len)); diff --git a/nimble/host/mesh/src/net.h b/nimble/host/mesh/src/net.h index 77923c5e2..557e4420f 100644 --- a/nimble/host/mesh/src/net.h +++ b/nimble/host/mesh/src/net.h @@ -216,7 +216,6 @@ 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 */