summaryrefslogtreecommitdiffhomepage
path: root/src/hashtables.c
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-08-01 15:59:37 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-08-03 00:14:18 +0200
commit9f4cc375561f34a6512f3789edbbd3d7a900145f (patch)
tree06c28c1a36d2b03c79fa6bbffb1a39cd49858dac /src/hashtables.c
parent7dbb9eec2638b41a0b95f3ca196d3c3a8550173c (diff)
peer: ensure destruction doesn't race
Completely rework peer removal to ensure peers don't jump between contexts and create races. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/hashtables.c')
-rw-r--r--src/hashtables.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/hashtables.c b/src/hashtables.c
index 03b9e21..ac6df59 100644
--- a/src/hashtables.c
+++ b/src/hashtables.c
@@ -152,7 +152,7 @@ void index_hashtable_remove(struct index_hashtable *table, struct index_hashtabl
}
/* Returns a strong reference to a entry->peer */
-struct index_hashtable_entry *index_hashtable_lookup(struct index_hashtable *table, const enum index_hashtable_type type_mask, const __le32 index)
+struct index_hashtable_entry *index_hashtable_lookup(struct index_hashtable *table, const enum index_hashtable_type type_mask, const __le32 index, struct wireguard_peer **peer)
{
struct index_hashtable_entry *iter_entry, *entry = NULL;
@@ -166,7 +166,9 @@ struct index_hashtable_entry *index_hashtable_lookup(struct index_hashtable *tab
}
if (likely(entry)) {
entry->peer = peer_get_maybe_zero(entry->peer);
- if (unlikely(!entry->peer))
+ if (likely(entry->peer))
+ *peer = entry->peer;
+ else
entry = NULL;
}
rcu_read_unlock_bh();