aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_udp.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2014-04-03 14:42:10 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-04-03 14:42:10 +0000
commitbfd8f09287d9c609607ded19bc10f9dc3469acd3 (patch)
tree67dc8841b3cff553e6a4204a25a63aea8ef3b118 /src/transport/plugin_transport_udp.c
parentc8d735c1386fcb6510b5ec274b67ef9e1c3aa61d (diff)
downloadgnunet-bfd8f09287d9c609607ded19bc10f9dc3469acd3.tar.gz
gnunet-bfd8f09287d9c609607ded19bc10f9dc3469acd3.zip
defragmentation context not freed when session is deleted
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r--src/transport/plugin_transport_udp.c77
1 files changed, 48 insertions, 29 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index b60de7e05..bb3af28dd 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -1201,6 +1201,32 @@ fragmented_message_done (struct UDP_FragmentationContext *fc,
1201 GNUNET_free(fc); 1201 GNUNET_free(fc);
1202} 1202}
1203 1203
1204/**
1205 * Scan the heap for a receive context with the given address.
1206 *
1207 * @param cls the `struct FindReceiveContext`
1208 * @param node internal node of the heap
1209 * @param element value stored at the node (a 'struct ReceiveContext')
1210 * @param cost cost associated with the node
1211 * @return #GNUNET_YES if we should continue to iterate,
1212 * #GNUNET_NO if not.
1213 */
1214static int
1215find_receive_context (void *cls, struct GNUNET_CONTAINER_HeapNode *node,
1216 void *element, GNUNET_CONTAINER_HeapCostType cost)
1217{
1218 struct FindReceiveContext *frc = cls;
1219 struct DefragContext *e = element;
1220
1221 if ((frc->addr_len == e->addr_len)
1222 && (0 == memcmp (frc->addr, e->src_addr, frc->addr_len)))
1223 {
1224 frc->rc = e;
1225 return GNUNET_NO;
1226 }
1227 return GNUNET_YES;
1228}
1229
1204 1230
1205/** 1231/**
1206 * Functions with this signature are called whenever we need 1232 * Functions with this signature are called whenever we need
@@ -1217,6 +1243,7 @@ udp_disconnect_session (void *cls, struct Session *s)
1217 struct Plugin *plugin = cls; 1243 struct Plugin *plugin = cls;
1218 struct UDP_MessageWrapper *udpw; 1244 struct UDP_MessageWrapper *udpw;
1219 struct UDP_MessageWrapper *next; 1245 struct UDP_MessageWrapper *next;
1246 struct FindReceiveContext frc;
1220 1247
1221 GNUNET_assert(GNUNET_YES != s->in_destroy); 1248 GNUNET_assert(GNUNET_YES != s->in_destroy);
1222 LOG(GNUNET_ERROR_TYPE_DEBUG, "Session %p to peer `%s' address ended\n", s, 1249 LOG(GNUNET_ERROR_TYPE_DEBUG, "Session %p to peer `%s' address ended\n", s,
@@ -1234,6 +1261,20 @@ udp_disconnect_session (void *cls, struct Session *s)
1234 fragmented_message_done (s->frag_ctx, GNUNET_SYSERR); 1261 fragmented_message_done (s->frag_ctx, GNUNET_SYSERR);
1235 } 1262 }
1236 1263
1264 frc.rc = NULL;
1265 frc.addr = s->address->address;
1266 frc.addr_len = s->address->address_length;
1267 /* Lookup existing receive context for this address */
1268 GNUNET_CONTAINER_heap_iterate (plugin->defrag_ctxs,
1269 &find_receive_context, &frc);
1270 if (NULL != frc.rc)
1271 {
1272 struct DefragContext *d_ctx = frc.rc;
1273 GNUNET_CONTAINER_heap_remove_node (d_ctx->hnode);
1274 GNUNET_DEFRAGMENT_context_destroy (d_ctx->defrag);
1275 GNUNET_free (d_ctx);
1276 }
1277
1237 next = plugin->ipv4_queue_head; 1278 next = plugin->ipv4_queue_head;
1238 while (NULL != (udpw = next)) 1279 while (NULL != (udpw = next))
1239 { 1280 {
@@ -2016,34 +2057,6 @@ process_udp_message (struct Plugin *plugin,
2016 free_session (s); 2057 free_session (s);
2017} 2058}
2018 2059
2019
2020/**
2021 * Scan the heap for a receive context with the given address.
2022 *
2023 * @param cls the `struct FindReceiveContext`
2024 * @param node internal node of the heap
2025 * @param element value stored at the node (a 'struct ReceiveContext')
2026 * @param cost cost associated with the node
2027 * @return #GNUNET_YES if we should continue to iterate,
2028 * #GNUNET_NO if not.
2029 */
2030static int
2031find_receive_context (void *cls, struct GNUNET_CONTAINER_HeapNode *node,
2032 void *element, GNUNET_CONTAINER_HeapCostType cost)
2033{
2034 struct FindReceiveContext *frc = cls;
2035 struct DefragContext *e = element;
2036
2037 if ((frc->addr_len == e->addr_len)
2038 && (0 == memcmp (frc->addr, e->src_addr, frc->addr_len)))
2039 {
2040 frc->rc = e;
2041 return GNUNET_NO;
2042 }
2043 return GNUNET_YES;
2044}
2045
2046
2047/** 2060/**
2048 * Process a defragmented message. 2061 * Process a defragmented message.
2049 * 2062 *
@@ -2177,8 +2190,14 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg)
2177 s = l_ctx.res; 2190 s = l_ctx.res;
2178 if (NULL == s) 2191 if (NULL == s)
2179 { 2192 {
2180 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Trying to transmit ACK to peer `%s' but not session found!\n", 2193 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2194 "Trying to transmit ACK to peer `%s' but not session found!\n",
2181 GNUNET_a2s(rc->src_addr, rc->addr_len)); 2195 GNUNET_a2s(rc->src_addr, rc->addr_len));
2196
2197 GNUNET_CONTAINER_heap_remove_node (rc->hnode);
2198 GNUNET_DEFRAGMENT_context_destroy (rc->defrag);
2199 GNUNET_free (rc);
2200
2182 return; 2201 return;
2183 } 2202 }
2184 if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX) 2203 if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX)