aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet-new_channel.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-25 14:51:40 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-25 14:51:40 +0100
commit547ffa75e1713d166b43a363afc3ef4c29650fe1 (patch)
treebcc4666757e5ff1b7d046e1a751adda5f16d181f /src/cadet/gnunet-service-cadet-new_channel.c
parent5754136c4ab97de7360b2d1d5120c32f2b3b7926 (diff)
downloadgnunet-547ffa75e1713d166b43a363afc3ef4c29650fe1.tar.gz
gnunet-547ffa75e1713d166b43a363afc3ef4c29650fe1.zip
handle duplicate DATA packets
Diffstat (limited to 'src/cadet/gnunet-service-cadet-new_channel.c')
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c
index b681dfedc..753634c62 100644
--- a/src/cadet/gnunet-service-cadet-new_channel.c
+++ b/src/cadet/gnunet-service-cadet-new_channel.c
@@ -1039,10 +1039,7 @@ GCCH_handle_channel_open_ack (struct CadetChannel *ch)
1039/** 1039/**
1040 * Test if element @a e1 comes before element @a e2. 1040 * Test if element @a e1 comes before element @a e2.
1041 * 1041 *
1042 * TODO: use opportunity to create generic list insertion sort 1042 * @param cls closure, to a flag where we indicate duplicate packets
1043 * logic in container!
1044 *
1045 * @param cls closure, our `struct CadetChannel`
1046 * @param e1 an element of to sort 1043 * @param e1 an element of to sort
1047 * @param e2 another element to sort 1044 * @param e2 another element to sort
1048 * @return #GNUNET_YES if @e1 < @e2, otherwise #GNUNET_NO 1045 * @return #GNUNET_YES if @e1 < @e2, otherwise #GNUNET_NO
@@ -1052,12 +1049,14 @@ is_before (void *cls,
1052 struct CadetOutOfOrderMessage *m1, 1049 struct CadetOutOfOrderMessage *m1,
1053 struct CadetOutOfOrderMessage *m2) 1050 struct CadetOutOfOrderMessage *m2)
1054{ 1051{
1052 int *duplicate = cls;
1055 uint32_t v1 = ntohl (m1->mid.mid); 1053 uint32_t v1 = ntohl (m1->mid.mid);
1056 uint32_t v2 = ntohl (m2->mid.mid); 1054 uint32_t v2 = ntohl (m2->mid.mid);
1057 uint32_t delta; 1055 uint32_t delta;
1058 1056
1059 delta = v2 - v1; 1057 delta = v2 - v1;
1060 GNUNET_assert (0 != delta); 1058 if (0 == delta)
1059 *duplicate = GNUNET_YES;
1061 if (delta > (uint32_t) INT_MAX) 1060 if (delta > (uint32_t) INT_MAX)
1062 { 1061 {
1063 /* in overflow range, we can safely assume we wrapped around */ 1062 /* in overflow range, we can safely assume we wrapped around */
@@ -1097,7 +1096,6 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
1097 struct GNUNET_MQ_Envelope *env; 1096 struct GNUNET_MQ_Envelope *env;
1098 struct GNUNET_CADET_LocalData *ld; 1097 struct GNUNET_CADET_LocalData *ld;
1099 struct CadetChannelClient *ccc; 1098 struct CadetChannelClient *ccc;
1100 struct CadetOutOfOrderMessage *com;
1101 size_t payload_size; 1099 size_t payload_size;
1102 1100
1103 GNUNET_assert (GNUNET_NO == ch->is_loopback); 1101 GNUNET_assert (GNUNET_NO == ch->is_loopback);
@@ -1141,30 +1139,48 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
1141 } 1139 }
1142 else 1140 else
1143 { 1141 {
1142 struct CadetOutOfOrderMessage *com;
1143 int duplicate;
1144
1144 /* FIXME-SECURITY: if the element is WAY too far ahead, 1145 /* FIXME-SECURITY: if the element is WAY too far ahead,
1145 drop it (can't buffer too much!) */ 1146 drop it (can't buffer too much!) */
1146 /* FIXME-SECURITY: if element is a BIT in the past and/or
1147 duplicate, just drop it! */
1148 LOG (GNUNET_ERROR_TYPE_DEBUG,
1149 "Queuing %s payload of %u bytes on %s (mid %u, need %u first)\n",
1150 (GNUNET_YES == ccc->client_ready)
1151 ? "out-of-order"
1152 : "client-not-ready",
1153 (unsigned int) payload_size,
1154 GCCH_2s (ch),
1155 ntohl (msg->mid.mid),
1156 ntohl (ch->mid_recv.mid));
1157 1147
1158 com = GNUNET_new (struct CadetOutOfOrderMessage); 1148 com = GNUNET_new (struct CadetOutOfOrderMessage);
1159 com->mid = msg->mid; 1149 com->mid = msg->mid;
1160 com->env = env; 1150 com->env = env;
1161 1151 duplicate = GNUNET_NO;
1162 GNUNET_CONTAINER_DLL_insert_sorted (struct CadetOutOfOrderMessage, 1152 GNUNET_CONTAINER_DLL_insert_sorted (struct CadetOutOfOrderMessage,
1163 is_before, 1153 is_before,
1164 NULL, 1154 &duplicate,
1165 ccc->head_recv, 1155 ccc->head_recv,
1166 ccc->tail_recv, 1156 ccc->tail_recv,
1167 com); 1157 com);
1158 if (GNUNET_YES == duplicate)
1159 {
1160 LOG (GNUNET_ERROR_TYPE_DEBUG,
1161 "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1162 (unsigned int) payload_size,
1163 GCCH_2s (ch),
1164 ntohl (msg->mid.mid));
1165 GNUNET_STATISTICS_update (stats,
1166 "# duplicate DATA",
1167 1,
1168 GNUNET_NO);
1169 GNUNET_CONTAINER_DLL_remove (ccc->head_recv,
1170 ccc->tail_recv,
1171 com);
1172 GNUNET_free (com);
1173 return;
1174 }
1175 LOG (GNUNET_ERROR_TYPE_DEBUG,
1176 "Queued %s payload of %u bytes on %s (mid %u, need %u first)\n",
1177 (GNUNET_YES == ccc->client_ready)
1178 ? "out-of-order"
1179 : "client-not-ready",
1180 (unsigned int) payload_size,
1181 GCCH_2s (ch),
1182 ntohl (msg->mid.mid),
1183 ntohl (ch->mid_recv.mid));
1168 } 1184 }
1169} 1185}
1170 1186