diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-01-25 14:51:40 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-01-25 14:51:40 +0100 |
commit | 547ffa75e1713d166b43a363afc3ef4c29650fe1 (patch) | |
tree | bcc4666757e5ff1b7d046e1a751adda5f16d181f /src/cadet/gnunet-service-cadet-new_channel.c | |
parent | 5754136c4ab97de7360b2d1d5120c32f2b3b7926 (diff) | |
download | gnunet-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.c | 54 |
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 | ||