aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLutz Kresge <LutzKr@protonmail.ch>2018-03-01 16:25:40 +0200
committerAnders Broman <a.broman58@gmail.com>2018-03-02 06:24:17 +0000
commit68e16ab05b7d6e726bd6adb7fab48875f28a6631 (patch)
treea00a3749cbc165552a65316c455ad71bf79d4fa2
parent1fa2781b7a2e97a77b8ef7ddb3b3c48a93f2516d (diff)
RLC: Fix duplication check after sqn reset
When rlc sequence number wrapped around, duplicate frames wouldn't be marked because they were compared to the sqn from the first round. Change-Id: Ia57aac9b86b4cc84dd8ec411fe0a94972acb9526 Reviewed-on: https://code.wireshark.org/review/26208 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--epan/dissectors/packet-umts_rlc.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/epan/dissectors/packet-umts_rlc.c b/epan/dissectors/packet-umts_rlc.c
index 250d958efe..bd39bf0faf 100644
--- a/epan/dissectors/packet-umts_rlc.c
+++ b/epan/dissectors/packet-umts_rlc.c
@@ -1237,6 +1237,8 @@ rlc_is_duplicate(enum rlc_mode mode, packet_info *pinfo, guint16 seq,
struct rlc_seqlist lookup, *list;
struct rlc_seq seq_item, *seq_new;
guint16 snmod;
+ nstime_t delta;
+ gboolean is_duplicate,is_unseen;
if (rlc_channel_assign(&lookup.ch, mode, pinfo, atm) == -1)
return FALSE;
@@ -1262,26 +1264,39 @@ rlc_is_duplicate(enum rlc_mode mode, packet_info *pinfo, guint16 seq,
}
}
+ is_duplicate = FALSE;
+ is_unseen = TRUE;
element = g_list_find_custom(list->list, &seq_item, rlc_cmp_seq);
- if (element) {
+ while(element) {
+ /* Check if this is a different frame (by comparing frame numbers) which arrived less than */
+ /* RLC_RETRANSMISSION_TIMEOUT seconds ago */
seq_new = (struct rlc_seq *)element->data;
- if (seq_new->frame_num != seq_item.frame_num) {
- nstime_t delta;
+ if (seq_new->frame_num < seq_item.frame_num) {
nstime_delta(&delta, &pinfo->abs_ts, &seq_new->arrival);
if (delta.secs < RLC_RETRANSMISSION_TIMEOUT) {
- if (original)
+ /* This is a duplicate. */
+ if (original) {
+ /* Save the frame number where our sequence number was previously seen */
*original = seq_new->frame_num;
- return TRUE;
+ }
+ is_duplicate = TRUE;
}
- return FALSE;
}
- return FALSE; /* we revisit the seq that was already seen */
+ else if (seq_new->frame_num == seq_item.frame_num) {
+ /* Check if our frame is already in the list and this is a secondary check.*/
+ /* in this case raise a flag so the frame isn't entered more than once to the list */
+ is_unseen = FALSE;
+ }
+ element = g_list_find_custom(element->next, &seq_item, rlc_cmp_seq);
}
- seq_new = (struct rlc_seq *)wmem_alloc0(wmem_file_scope(), sizeof(struct rlc_seq));
- *seq_new = seq_item;
- seq_new->arrival = pinfo->abs_ts;
- list->list = g_list_append(list->list, seq_new); /* insert in order of arrival */
- return FALSE;
+ if(is_unseen) {
+ /* Add to list for the first time this frame is checked */
+ seq_new = (struct rlc_seq *)wmem_alloc0(wmem_file_scope(), sizeof(struct rlc_seq));
+ *seq_new = seq_item;
+ seq_new->arrival = pinfo->abs_ts;
+ list->list = g_list_append(list->list, seq_new); /* insert in order of arrival */
+ }
+ return is_duplicate;
}
static void