summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2016-10-26 04:20:44 +0000
committerBart Polot <bart@net.in.tum.de>2016-10-26 04:20:44 +0000
commit98d657cd445d60e793484594449c643655b23df5 (patch)
tree4498b35271cf38d55e587722d23d6fd7e0f51ef0 /src
parentf98d6a1587d1c3d0207f708cd0c1eec9f516cd9e (diff)
downloadgnunet-98d657cd445d60e793484594449c643655b23df5.tar.gz
gnunet-98d657cd445d60e793484594449c643655b23df5.zip
- add queue control in peer and connection to cancel MQ_env when those are destroyed, since callbacks could dereference freed memory
Diffstat (limited to 'src')
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c106
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c2126
2 files changed, 1147 insertions, 1085 deletions
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c
index 12cabec21..47e728ed0 100644
--- a/src/cadet/gnunet-service-cadet_connection.c
+++ b/src/cadet/gnunet-service-cadet_connection.c
@@ -54,6 +54,37 @@
54/******************************************************************************/ 54/******************************************************************************/
55 55
56/** 56/**
57 * Handle for messages queued but not yet sent.
58 */
59struct CadetConnectionQueue
60{
61
62 struct CadetConnectionQueue *next;
63 struct CadetConnectionQueue *prev;
64
65 /**
66 * Peer queue handle, to cancel if necessary.
67 */
68 struct CadetPeerQueue *peer_q;
69
70 /**
71 * Continuation to call once sent.
72 */
73 GCC_sent cont;
74
75 /**
76 * Closure for @e cont.
77 */
78 void *cont_cls;
79
80 /**
81 * Was this a forced message? (Do not account for it)
82 */
83 int forced;
84};
85
86
87/**
57 * Struct to encapsulate all the Flow Control information to a peer to which 88 * Struct to encapsulate all the Flow Control information to a peer to which
58 * we are directly connected (on a core level). 89 * we are directly connected (on a core level).
59 */ 90 */
@@ -64,6 +95,9 @@ struct CadetFlowControl
64 */ 95 */
65 struct CadetConnection *c; 96 struct CadetConnection *c;
66 97
98 struct CadetConnectionQueue *q_head;
99 struct CadetConnectionQueue *q_tail;
100
67 /** 101 /**
68 * How many messages are in the queue on this connection. 102 * How many messages are in the queue on this connection.
69 */ 103 */
@@ -265,32 +299,6 @@ struct CadetConnection
265}; 299};
266 300
267 301
268/**
269 * Handle for messages queued but not yet sent.
270 */
271struct CadetConnectionQueue
272{
273 /**
274 * Peer queue handle, to cancel if necessary.
275 */
276 struct CadetPeerQueue *peer_q;
277
278 /**
279 * Continuation to call once sent.
280 */
281 GCC_sent cont;
282
283 /**
284 * Closure for @e cont.
285 */
286 void *cont_cls;
287
288 /**
289 * Was this a forced message? (Do not account for it)
290 */
291 int forced;
292};
293
294/******************************************************************************/ 302/******************************************************************************/
295/******************************* GLOBALS ***********************************/ 303/******************************* GLOBALS ***********************************/
296/******************************************************************************/ 304/******************************************************************************/
@@ -694,6 +702,7 @@ conn_message_sent (void *cls,
694 int forced; 702 int forced;
695 703
696 GCC_check_connections (); 704 GCC_check_connections ();
705 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection message_sent\n");
697 706
698 /* If c is NULL, nothing to update. */ 707 /* If c is NULL, nothing to update. */
699 if (NULL == c) 708 if (NULL == c)
@@ -708,16 +717,17 @@ conn_message_sent (void *cls,
708 return; 717 return;
709 } 718 }
710 719
711 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection message_sent\n"); 720 LOG (GNUNET_ERROR_TYPE_DEBUG, " %ssent %s %s pid %u\n",
721 sent ? "" : "not ", GC_f2s (fwd),
722 GC_m2s (type), GC_m2s (payload_type), pid);
712 GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG); 723 GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG);
713 724
714 /* Update flow control info. */ 725 /* Update flow control info. */
715 fc = fwd ? &c->fwd_fc : &c->bck_fc; 726 fc = fwd ? &c->fwd_fc : &c->bck_fc;
716 LOG (GNUNET_ERROR_TYPE_DEBUG, " %ssent %s %s pid %u\n", 727
717 sent ? "" : "not ", GC_f2s (fwd),
718 GC_m2s (type), GC_m2s (payload_type), pid);
719 if (NULL != q) 728 if (NULL != q)
720 { 729 {
730 GNUNET_CONTAINER_DLL_remove (fc->q_head, fc->q_tail, q);
721 forced = q->forced; 731 forced = q->forced;
722 if (NULL != q->cont) 732 if (NULL != q->cont)
723 { 733 {
@@ -728,12 +738,14 @@ conn_message_sent (void *cls,
728 } 738 }
729 else if (type == GNUNET_MESSAGE_TYPE_CADET_AX) 739 else if (type == GNUNET_MESSAGE_TYPE_CADET_AX)
730 { 740 {
731 /* If NULL == q and ENCRYPTED == type, message must have been ch_mngmnt */ 741 /* SHOULD NO LONGER HAPPEN FIXME: REMOVE CASE */
742 // If NULL == q and ENCRYPTED == type, message must have been ch_mngmnt
732 forced = GNUNET_YES; 743 forced = GNUNET_YES;
744 GNUNET_assert (0); // FIXME
733 } 745 }
734 else 746 else /* CONN_CREATE or CONN_ACK */
735 { 747 {
736 forced = GNUNET_NO; 748 forced = GNUNET_YES;
737 } 749 }
738 750
739 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P- %p %u\n", c, c->pending_messages); 751 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P- %p %u\n", c, c->pending_messages);
@@ -1091,22 +1103,21 @@ send_broken_unknown (const struct GNUNET_CADET_Hash *connection_id,
1091 const struct GNUNET_PeerIdentity *id2, 1103 const struct GNUNET_PeerIdentity *id2,
1092 struct CadetPeer *neighbor) 1104 struct CadetPeer *neighbor)
1093{ 1105{
1094 struct GNUNET_CADET_ConnectionBroken *msg; 1106 struct GNUNET_CADET_ConnectionBroken msg;
1095 1107
1096 GCC_check_connections (); 1108 GCC_check_connections ();
1097 LOG (GNUNET_ERROR_TYPE_INFO, "--> BROKEN on unknown connection %s\n", 1109 LOG (GNUNET_ERROR_TYPE_INFO, "--> BROKEN on unknown connection %s\n",
1098 GNUNET_h2s (GC_h2hc (connection_id))); 1110 GNUNET_h2s (GC_h2hc (connection_id)));
1099 1111
1100 msg = GNUNET_new (struct GNUNET_CADET_ConnectionBroken); 1112 msg.header.size = htons (sizeof (struct GNUNET_CADET_ConnectionBroken));
1101 msg->header.size = htons (sizeof (struct GNUNET_CADET_ConnectionBroken)); 1113 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
1102 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); 1114 msg.cid = *connection_id;
1103 msg->cid = *connection_id; 1115 msg.peer1 = *id1;
1104 msg->peer1 = *id1;
1105 if (NULL != id2) 1116 if (NULL != id2)
1106 msg->peer2 = *id2; 1117 msg.peer2 = *id2;
1107 else 1118 else
1108 memset (&msg->peer2, 0, sizeof (msg->peer2)); 1119 memset (&msg.peer2, 0, sizeof (msg.peer2));
1109 GNUNET_assert (NULL != GCP_send (neighbor, &msg->header, 1120 GNUNET_assert (NULL != GCP_send (neighbor, &msg.header,
1110 UINT16_MAX, 2, 1121 UINT16_MAX, 2,
1111 NULL, GNUNET_SYSERR, /* connection, fwd */ 1122 NULL, GNUNET_SYSERR, /* connection, fwd */
1112 NULL, NULL)); /* continuation */ 1123 NULL, NULL)); /* continuation */
@@ -1382,6 +1393,11 @@ connection_cancel_queues (struct CadetConnection *c,
1382 GCC_cancel (fc->poll_msg); 1393 GCC_cancel (fc->poll_msg);
1383 LOG (GNUNET_ERROR_TYPE_DEBUG, " cancelled POLL msg for fc %p\n", fc); 1394 LOG (GNUNET_ERROR_TYPE_DEBUG, " cancelled POLL msg for fc %p\n", fc);
1384 } 1395 }
1396
1397 while (NULL != fc->q_head)
1398 {
1399 GCC_cancel (fc->q_head);
1400 }
1385 GCC_check_connections (); 1401 GCC_check_connections ();
1386} 1402}
1387 1403
@@ -2849,6 +2865,11 @@ GCC_destroy (struct CadetConnection *c)
2849 { 2865 {
2850 connection_cancel_queues (c, GNUNET_YES); 2866 connection_cancel_queues (c, GNUNET_YES);
2851 connection_cancel_queues (c, GNUNET_NO); 2867 connection_cancel_queues (c, GNUNET_NO);
2868 if (NULL != c->maintenance_q)
2869 {
2870 GCP_send_cancel (c->maintenance_q);
2871 c->maintenance_q = NULL;
2872 }
2852 } 2873 }
2853 unregister_neighbors (c); 2874 unregister_neighbors (c);
2854 path_destroy (c->path); 2875 path_destroy (c->path);
@@ -3354,6 +3375,7 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
3354 } 3375 }
3355 q->cont = cont; 3376 q->cont = cont;
3356 q->cont_cls = cont_cls; 3377 q->cont_cls = cont_cls;
3378 GNUNET_CONTAINER_DLL_insert (fc->q_head, fc->q_tail, q);
3357 GCC_check_connections (); 3379 GCC_check_connections ();
3358 return (NULL == cont) ? NULL : q; 3380 return (NULL == cont) ? NULL : q;
3359} 3381}
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c
index 9fa25a1fa..5dbf0c209 100644
--- a/src/cadet/gnunet-service-cadet_peer.c
+++ b/src/cadet/gnunet-service-cadet_peer.c
@@ -44,145 +44,150 @@
44/******************************** STRUCTS **********************************/ 44/******************************** STRUCTS **********************************/
45/******************************************************************************/ 45/******************************************************************************/
46 46
47
48/** 47/**
49 * Struct containing all information regarding a given peer 48 * Information about a queued message on the peer level.
50 */ 49 */
51struct CadetPeer 50struct CadetPeerQueue {
52{ 51
53 /** 52 struct CadetPeerQueue *next;
54 * ID of the peer 53 struct CadetPeerQueue *prev;
55 */ 54
56 GNUNET_PEER_Id id; 55 /**
57 56 * Envelope to cancel message before MQ sends it.
58 /** 57 */
59 * Last time we heard from this peer 58 struct GNUNET_MQ_Envelope *env;
60 */ 59
61 struct GNUNET_TIME_Absolute last_contact; 60 /**
62 61 * Peer (neighbor) this message is being sent to.
63 /** 62 */
64 * Paths to reach the peer, ordered by ascending hop count 63 struct CadetPeer *peer;
65 */
66 struct CadetPeerPath *path_head;
67
68 /**
69 * Paths to reach the peer, ordered by ascending hop count
70 */
71 struct CadetPeerPath *path_tail;
72
73 /**
74 * Handle to stop the DHT search for paths to this peer
75 */
76 struct GCD_search_handle *search_h;
77
78 /**
79 * Handle to stop the DHT search for paths to this peer
80 */
81 struct GNUNET_SCHEDULER_Task *search_delayed;
82
83 /**
84 * Tunnel to this peer, if any.
85 */
86 struct CadetTunnel *tunnel;
87
88 /**
89 * Connections that go through this peer; indexed by tid.
90 */
91 struct GNUNET_CONTAINER_MultiHashMap *connections;
92
93 /**
94 * Handle for core transmissions.
95 */
96 struct GNUNET_MQ_Handle *core_mq;
97
98 /**
99 * How many messages are in the queue to this peer.
100 */
101 unsigned int queue_n;
102
103 /**
104 * Hello message.
105 */
106 struct GNUNET_HELLO_Message* hello;
107
108 /**
109 * Handle to us offering the HELLO to the transport.
110 */
111 struct GNUNET_TRANSPORT_OfferHelloHandle *hello_offer;
112
113 /**
114 * Handle to our ATS request asking ATS to suggest an address
115 * to TRANSPORT for this peer (to establish a direct link).
116 */
117 struct GNUNET_ATS_ConnectivitySuggestHandle *connectivity_suggestion;
118 64
65 /**
66 * Continuation to call to notify higher layers about message sent.
67 */
68 GCP_sent cont;
69
70 /**
71 * Closure for @a cont.
72 */
73 void *cont_cls;
74
75 /**
76 * Time when message was queued for sending.
77 */
78 struct GNUNET_TIME_Absolute queue_timestamp;
79
80 /**
81 * #GNUNET_YES if message was management traffic (POLL, ACK, ...).
82 */
83 int management_traffic;
84
85 /**
86 * Message type.
87 */
88 uint16_t type;
89
90 /**
91 * Message size.
92 */
93 uint16_t size;
94
95 /**
96 * Type of the message's payload, if it was encrypted data.
97 */
98 uint16_t payload_type;
99
100 /**
101 *ID of the payload (PID, ACK #, ...).
102 */
103 uint16_t payload_id;
104
105 /**
106 * Connection this message was sent on.
107 */
108 struct CadetConnection *c;
109
110 /**
111 * Direction in @a c this message was send on (#GNUNET_YES = FWD).
112 */
113 int c_fwd;
119}; 114};
120 115
121 116
122/** 117/**
123 * Information about a queued message on the peer level. 118 * Struct containing all information regarding a given peer
124 */ 119 */
125struct CadetPeerQueue { 120struct CadetPeer
121{
122 /**
123 * ID of the peer
124 */
125 GNUNET_PEER_Id id;
126
127 struct CadetPeerQueue *q_head;
128 struct CadetPeerQueue *q_tail;
129
130 /**
131 * Last time we heard from this peer
132 */
133 struct GNUNET_TIME_Absolute last_contact;
134
135 /**
136 * Paths to reach the peer, ordered by ascending hop count
137 */
138 struct CadetPeerPath *path_head;
139
140 /**
141 * Paths to reach the peer, ordered by ascending hop count
142 */
143 struct CadetPeerPath *path_tail;
144
145 /**
146 * Handle to stop the DHT search for paths to this peer
147 */
148 struct GCD_search_handle *search_h;
149
150 /**
151 * Handle to stop the DHT search for paths to this peer
152 */
153 struct GNUNET_SCHEDULER_Task *search_delayed;
154
155 /**
156 * Tunnel to this peer, if any.
157 */
158 struct CadetTunnel *tunnel;
159
160 /**
161 * Connections that go through this peer; indexed by tid.
162 */
163 struct GNUNET_CONTAINER_MultiHashMap *connections;
164
165 /**
166 * Handle for core transmissions.
167 */
168 struct GNUNET_MQ_Handle *core_mq;
169
170 /**
171 * How many messages are in the queue to this peer.
172 */
173 unsigned int queue_n;
174
175 /**
176 * Hello message.
177 */
178 struct GNUNET_HELLO_Message* hello;
179
180 /**
181 * Handle to us offering the HELLO to the transport.
182 */
183 struct GNUNET_TRANSPORT_OfferHelloHandle *hello_offer;
184
185 /**
186 * Handle to our ATS request asking ATS to suggest an address
187 * to TRANSPORT for this peer (to establish a direct link).
188 */
189 struct GNUNET_ATS_ConnectivitySuggestHandle *connectivity_suggestion;
126 190
127 /**
128 * Envelope to cancel message before MQ sends it.
129 */
130 struct GNUNET_MQ_Envelope *env;
131
132 /**
133 * Peer (neighbor) this message is being sent to.
134 */
135 struct CadetPeer *peer;
136
137 /**
138 * Continuation to call to notify higher layers about message sent.
139 */
140 GCP_sent cont;
141
142 /**
143 * Closure for @a cont.
144 */
145 void *cont_cls;
146
147 /**
148 * Time when message was queued for sending.
149 */
150 struct GNUNET_TIME_Absolute queue_timestamp;
151
152 /**
153 * #GNUNET_YES if message was management traffic (POLL, ACK, ...).
154 */
155 int management_traffic;
156
157 /**
158 * Message type.
159 */
160 uint16_t type;
161
162 /**
163 * Message size.
164 */
165 uint16_t size;
166
167 /**
168 * Type of the message's payload, if it was encrypted data.
169 */
170 uint16_t payload_type;
171
172 /**
173 *ID of the payload (PID, ACK #, ...).
174 */
175 uint16_t payload_id;
176
177 /**
178 * Connection this message was sent on.
179 */
180 struct CadetConnection *c;
181
182 /**
183 * Direction in @a c this message was send on (#GNUNET_YES = FWD).
184 */
185 int c_fwd;
186}; 191};
187 192
188 193
@@ -261,14 +266,14 @@ notify_broken (void *cls,
261 const struct GNUNET_HashCode *key, 266 const struct GNUNET_HashCode *key,
262 void *value) 267 void *value)
263{ 268{
264 struct CadetPeer *peer = cls; 269 struct CadetPeer *peer = cls;
265 struct CadetConnection *c = value; 270 struct CadetConnection *c = value;
266 271
267 LOG (GNUNET_ERROR_TYPE_DEBUG, 272 LOG (GNUNET_ERROR_TYPE_DEBUG,
268 "Notifying %s due to %s disconnect\n", 273 "Notifying %s due to %s disconnect\n",
269 GCC_2s (c), GCP_2s (peer)); 274 GCC_2s (c), GCP_2s (peer));
270 GCC_neighbor_disconnected (c, peer); 275 GCC_neighbor_disconnected (c, peer);
271 return GNUNET_YES; 276 return GNUNET_YES;
272} 277}
273 278
274 279
@@ -280,21 +285,32 @@ notify_broken (void *cls,
280static struct CadetPeerPath * 285static struct CadetPeerPath *
281pop_direct_path (struct CadetPeer *peer) 286pop_direct_path (struct CadetPeer *peer)
282{ 287{
283 struct CadetPeerPath *iter; 288 struct CadetPeerPath *iter;
284 289
285 for (iter = peer->path_head; NULL != iter; iter = iter->next) 290 for (iter = peer->path_head; NULL != iter; iter = iter->next)
286 {
287 if (2 >= iter->length)
288 { 291 {
289 GNUNET_CONTAINER_DLL_remove (peer->path_head, 292 if (2 >= iter->length)
290 peer->path_tail, 293 {
291 iter); 294 GNUNET_CONTAINER_DLL_remove (peer->path_head,
292 return iter; 295 peer->path_tail,
296 iter);
297 return iter;
298 }
293 } 299 }
294 } 300 return NULL;
295 return NULL;
296} 301}
297 302
303/**
304 * Call the continuation after a message has been sent or dropped.
305 *
306 * This funcion removes the message from the queue.
307 *
308 * @param q Queue handle.
309 * @param sent #GNUNET_YES if was sent to CORE, #GNUNET_NO if dropped.
310 */
311static void
312call_peer_cont (struct CadetPeerQueue *q, int sent);
313
298 314
299/******************************************************************************/ 315/******************************************************************************/
300/***************************** CORE CALLBACKS *********************************/ 316/***************************** CORE CALLBACKS *********************************/
@@ -315,57 +331,57 @@ core_connect_handler (void *cls,
315 const struct GNUNET_PeerIdentity *peer, 331 const struct GNUNET_PeerIdentity *peer,
316 struct GNUNET_MQ_Handle *mq) 332 struct GNUNET_MQ_Handle *mq)
317{ 333{
318 struct CadetPeer *neighbor; 334 struct CadetPeer *neighbor;
319 struct CadetPeerPath *path; 335 struct CadetPeerPath *path;
320 char own_id[16]; 336 char own_id[16];
321 337
322 GCC_check_connections (); 338 GCC_check_connections ();
323 GNUNET_snprintf (own_id, 339 GNUNET_snprintf (own_id,
324 sizeof (own_id), 340 sizeof (own_id),
325 "%s", 341 "%s",
326 GNUNET_i2s (&my_full_id)); 342 GNUNET_i2s (&my_full_id));
343
344 /* Save a path to the neighbor */
345 neighbor = GCP_get (peer, GNUNET_YES);
346 if (myid == neighbor->id)
347 {
348 LOG (GNUNET_ERROR_TYPE_INFO,
349 "CONNECTED %s (self)\n",
350 own_id);
351 path = path_new (1);
352 }
353 else
354 {
355 LOG (GNUNET_ERROR_TYPE_INFO,
356 "CONNECTED %s <= %s\n",
357 own_id,
358 GNUNET_i2s (peer));
359 path = path_new (2);
360 path->peers[1] = neighbor->id;
361 GNUNET_PEER_change_rc (neighbor->id, 1);
362 GNUNET_assert (NULL == neighbor->core_mq);
363 neighbor->core_mq = mq;
364 }
365 path->peers[0] = myid;
366 GNUNET_PEER_change_rc (myid, 1);
367 GCP_add_path (neighbor, path, GNUNET_YES);
368
369 /* Create the connections hashmap */
370 GNUNET_assert (NULL == neighbor->connections);
371 neighbor->connections = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO);
372 GNUNET_STATISTICS_update (stats,
373 "# peers",
374 1,
375 GNUNET_NO);
327 376
328 /* Save a path to the neighbor */ 377 if ( (NULL != GCP_get_tunnel (neighbor)) &&
329 neighbor = GCP_get (peer, GNUNET_YES); 378 (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, peer)) )
330 if (myid == neighbor->id) 379 {
331 { 380 GCP_connect (neighbor);
332 LOG (GNUNET_ERROR_TYPE_INFO, 381 }
333 "CONNECTED %s (self)\n", 382 GCC_check_connections ();
334 own_id); 383
335 path = path_new (1); 384 return neighbor;
336 }
337 else
338 {
339 LOG (GNUNET_ERROR_TYPE_INFO,
340 "CONNECTED %s <= %s\n",
341 own_id,
342 GNUNET_i2s (peer));
343 path = path_new (2);
344 path->peers[1] = neighbor->id;
345 GNUNET_PEER_change_rc (neighbor->id, 1);
346 GNUNET_assert (NULL == neighbor->core_mq);
347 neighbor->core_mq = mq;
348 }
349 path->peers[0] = myid;
350 GNUNET_PEER_change_rc (myid, 1);
351 GCP_add_path (neighbor, path, GNUNET_YES);
352
353 /* Create the connections hashmap */
354 GNUNET_assert (NULL == neighbor->connections);
355 neighbor->connections = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO);
356 GNUNET_STATISTICS_update (stats,
357 "# peers",
358 1,
359 GNUNET_NO);
360
361 if ( (NULL != GCP_get_tunnel (neighbor)) &&
362 (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, peer)) )
363 {
364 GCP_connect (neighbor);
365 }
366 GCC_check_connections ();
367
368 return neighbor;
369} 385}
370 386
371 387
@@ -381,41 +397,41 @@ core_disconnect_handler (void *cls,
381 const struct GNUNET_PeerIdentity *peer, 397 const struct GNUNET_PeerIdentity *peer,
382 void *internal_cls) 398 void *internal_cls)
383{ 399{
384 struct CadetPeer *p = internal_cls; 400 struct CadetPeer *p = internal_cls;
385 struct CadetPeerPath *direct_path; 401 struct CadetPeerPath *direct_path;
386 char own_id[16]; 402 char own_id[16];
387 403
388 GCC_check_connections (); 404 GCC_check_connections ();
389 strncpy (own_id, GNUNET_i2s (&my_full_id), 16); 405 strncpy (own_id, GNUNET_i2s (&my_full_id), 16);
390 own_id[15] = '\0'; 406 own_id[15] = '\0';
391 if (myid == p->id) 407 if (myid == p->id)
392 { 408 {
393 LOG (GNUNET_ERROR_TYPE_INFO, 409 LOG (GNUNET_ERROR_TYPE_INFO,
394 "DISCONNECTED %s (self)\n", 410 "DISCONNECTED %s (self)\n",
395 own_id); 411 own_id);
396 } 412 }
397 else 413 else
398 { 414 {
399 LOG (GNUNET_ERROR_TYPE_INFO, 415 LOG (GNUNET_ERROR_TYPE_INFO,
400 "DISCONNECTED %s <= %s\n", 416 "DISCONNECTED %s <= %s\n",
401 own_id, GNUNET_i2s (peer)); 417 own_id, GNUNET_i2s (peer));
402 p->core_mq = NULL; 418 p->core_mq = NULL;
403 } 419 }
404 direct_path = pop_direct_path (p); 420 direct_path = pop_direct_path (p);
405 if (NULL != p->connections) 421 if (NULL != p->connections)
406 { 422 {
407 GNUNET_CONTAINER_multihashmap_iterate (p->connections, 423 GNUNET_CONTAINER_multihashmap_iterate (p->connections,
408 &notify_broken, 424 &notify_broken,
409 p); 425 p);
410 GNUNET_CONTAINER_multihashmap_destroy (p->connections); 426 GNUNET_CONTAINER_multihashmap_destroy (p->connections);
411 p->connections = NULL; 427 p->connections = NULL;
412 } 428 }
413 GNUNET_STATISTICS_update (stats, 429 GNUNET_STATISTICS_update (stats,
414 "# peers", 430 "# peers",
415 -1, 431 -1,
416 GNUNET_NO); 432 GNUNET_NO);
417 path_destroy (direct_path); 433 path_destroy (direct_path);
418 GCC_check_connections (); 434 GCC_check_connections ();
419} 435}
420 436
421 437
@@ -436,15 +452,15 @@ core_disconnect_handler (void *cls,
436static int 452static int
437check_create (void *cls, const struct GNUNET_CADET_ConnectionCreate *msg) 453check_create (void *cls, const struct GNUNET_CADET_ConnectionCreate *msg)
438{ 454{
439 uint16_t size; 455 uint16_t size;
440 456
441 size = ntohs (msg->header.size); 457 size = ntohs (msg->header.size);
442 if (size < sizeof (*msg)) 458 if (size < sizeof (*msg))
443 { 459 {
444 GNUNET_break_op (0); 460 GNUNET_break_op (0);
445 return GNUNET_NO; 461 return GNUNET_NO;
446 } 462 }
447 return GNUNET_YES; 463 return GNUNET_YES;
448} 464}
449 465
450/** 466/**
@@ -456,8 +472,8 @@ check_create (void *cls, const struct GNUNET_CADET_ConnectionCreate *msg)
456static void 472static void
457handle_create (void *cls, const struct GNUNET_CADET_ConnectionCreate *msg) 473handle_create (void *cls, const struct GNUNET_CADET_ConnectionCreate *msg)
458{ 474{
459 struct CadetPeer *peer = cls; 475 struct CadetPeer *peer = cls;
460 GCC_handle_create (peer, msg); 476 GCC_handle_create (peer, msg);
461} 477}
462 478
463 479
@@ -470,8 +486,8 @@ handle_create (void *cls, const struct GNUNET_CADET_ConnectionCreate *msg)
470static void 486static void
471handle_confirm (void *cls, const struct GNUNET_CADET_ConnectionACK *msg) 487handle_confirm (void *cls, const struct GNUNET_CADET_ConnectionACK *msg)
472{ 488{
473 struct CadetPeer *peer = cls; 489 struct CadetPeer *peer = cls;
474 GCC_handle_confirm (peer, msg); 490 GCC_handle_confirm (peer, msg);
475} 491}
476 492
477 493
@@ -484,8 +500,8 @@ handle_confirm (void *cls, const struct GNUNET_CADET_ConnectionACK *msg)
484static void 500static void
485handle_broken (void *cls, const struct GNUNET_CADET_ConnectionBroken *msg) 501handle_broken (void *cls, const struct GNUNET_CADET_ConnectionBroken *msg)
486{ 502{
487 struct CadetPeer *peer = cls; 503 struct CadetPeer *peer = cls;
488 GCC_handle_broken (peer, msg); 504 GCC_handle_broken (peer, msg);
489} 505}
490 506
491 507
@@ -498,8 +514,8 @@ handle_broken (void *cls, const struct GNUNET_CADET_ConnectionBroken *msg)
498static void 514static void
499handle_destroy (void *cls, const struct GNUNET_CADET_ConnectionDestroy *msg) 515handle_destroy (void *cls, const struct GNUNET_CADET_ConnectionDestroy *msg)
500{ 516{
501 struct CadetPeer *peer = cls; 517 struct CadetPeer *peer = cls;
502 GCC_handle_destroy (peer, msg); 518 GCC_handle_destroy (peer, msg);
503} 519}
504 520
505 521
@@ -512,8 +528,8 @@ handle_destroy (void *cls, const struct GNUNET_CADET_ConnectionDestroy *msg)
512static void 528static void
513handle_ack (void *cls, const struct GNUNET_CADET_ACK *msg) 529handle_ack (void *cls, const struct GNUNET_CADET_ACK *msg)
514{ 530{
515 struct CadetPeer *peer = cls; 531 struct CadetPeer *peer = cls;
516 GCC_handle_ack (peer, msg); 532 GCC_handle_ack (peer, msg);
517} 533}
518 534
519 535
@@ -526,8 +542,8 @@ handle_ack (void *cls, const struct GNUNET_CADET_ACK *msg)
526static void 542static void
527handle_poll (void *cls, const struct GNUNET_CADET_Poll *msg) 543handle_poll (void *cls, const struct GNUNET_CADET_Poll *msg)
528{ 544{
529 struct CadetPeer *peer = cls; 545 struct CadetPeer *peer = cls;
530 GCC_handle_poll (peer, msg); 546 GCC_handle_poll (peer, msg);
531} 547}
532 548
533 549
@@ -542,19 +558,19 @@ handle_poll (void *cls, const struct GNUNET_CADET_Poll *msg)
542static int 558static int
543check_kx (void *cls, const struct GNUNET_CADET_KX *msg) 559check_kx (void *cls, const struct GNUNET_CADET_KX *msg)
544{ 560{
545 uint16_t size; 561 uint16_t size;
546 uint16_t expected_size; 562 uint16_t expected_size;
547 563
548 size = ntohs (msg->header.size); 564 size = ntohs (msg->header.size);
549 expected_size = sizeof (struct GNUNET_CADET_KX) 565 expected_size = sizeof (struct GNUNET_CADET_KX)
550 + sizeof (struct GNUNET_MessageHeader); 566 + sizeof (struct GNUNET_MessageHeader);
551 567
552 if (size < expected_size) 568 if (size < expected_size)
553 { 569 {
554 GNUNET_break_op (0); 570 GNUNET_break_op (0);
555 return GNUNET_NO; 571 return GNUNET_NO;
556 } 572 }
557 return GNUNET_YES; 573 return GNUNET_YES;
558} 574}
559 575
560/** 576/**
@@ -566,8 +582,8 @@ check_kx (void *cls, const struct GNUNET_CADET_KX *msg)
566static void 582static void
567handle_kx (void *cls, const struct GNUNET_CADET_KX *msg) 583handle_kx (void *cls, const struct GNUNET_CADET_KX *msg)
568{ 584{
569 struct CadetPeer *peer = cls; 585 struct CadetPeer *peer = cls;
570 GCC_handle_kx (peer, msg); 586 GCC_handle_kx (peer, msg);
571} 587}
572 588
573 589
@@ -582,19 +598,19 @@ handle_kx (void *cls, const struct GNUNET_CADET_KX *msg)
582static int 598static int
583check_encrypted (void *cls, const struct GNUNET_CADET_AX *msg) 599check_encrypted (void *cls, const struct GNUNET_CADET_AX *msg)
584{ 600{
585 uint16_t size; 601 uint16_t size;
586 uint16_t minimum_size; 602 uint16_t minimum_size;
587 603
588 size = ntohs (msg->header.size); 604 size = ntohs (msg->header.size);
589 minimum_size = sizeof (struct GNUNET_CADET_AX) 605 minimum_size = sizeof (struct GNUNET_CADET_AX)
590 + sizeof (struct GNUNET_MessageHeader); 606 + sizeof (struct GNUNET_MessageHeader);
591 607
592 if (size < minimum_size) 608 if (size < minimum_size)
593 { 609 {
594 GNUNET_break_op (0); 610 GNUNET_break_op (0);
595 return GNUNET_NO; 611 return GNUNET_NO;
596 } 612 }
597 return GNUNET_YES; 613 return GNUNET_YES;
598} 614}
599 615
600/** 616/**
@@ -606,8 +622,8 @@ check_encrypted (void *cls, const struct GNUNET_CADET_AX *msg)
606static void 622static void
607handle_encrypted (void *cls, const struct GNUNET_CADET_AX *msg) 623handle_encrypted (void *cls, const struct GNUNET_CADET_AX *msg)
608{ 624{
609 struct CadetPeer *peer = cls; 625 struct CadetPeer *peer = cls;
610 GCC_handle_encrypted (peer, msg); 626 GCC_handle_encrypted (peer, msg);
611} 627}
612 628
613 629
@@ -625,46 +641,46 @@ core_init_notify (void *cls,
625static void 641static void
626connect_to_core (const struct GNUNET_CONFIGURATION_Handle *c) 642connect_to_core (const struct GNUNET_CONFIGURATION_Handle *c)
627{ 643{
628 struct GNUNET_MQ_MessageHandler core_handlers[] = { 644 struct GNUNET_MQ_MessageHandler core_handlers[] = {
629 GNUNET_MQ_hd_var_size (create, 645 GNUNET_MQ_hd_var_size (create,
630 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE, 646 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE,
631 struct GNUNET_CADET_ConnectionCreate, 647 struct GNUNET_CADET_ConnectionCreate,
632 NULL), 648 NULL),
633 GNUNET_MQ_hd_fixed_size (confirm, 649 GNUNET_MQ_hd_fixed_size (confirm,
634 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK, 650 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK,
635 struct GNUNET_CADET_ConnectionACK, 651 struct GNUNET_CADET_ConnectionACK,
636 NULL), 652 NULL),
637 GNUNET_MQ_hd_fixed_size (broken, 653 GNUNET_MQ_hd_fixed_size (broken,
638 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN, 654 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
639 struct GNUNET_CADET_ConnectionBroken, 655 struct GNUNET_CADET_ConnectionBroken,
640 NULL), 656 NULL),
641 GNUNET_MQ_hd_fixed_size (destroy, 657 GNUNET_MQ_hd_fixed_size (destroy,
642 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY, 658 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY,
643 struct GNUNET_CADET_ConnectionDestroy, 659 struct GNUNET_CADET_ConnectionDestroy,
644 NULL), 660 NULL),
645 GNUNET_MQ_hd_fixed_size (ack, 661 GNUNET_MQ_hd_fixed_size (ack,
646 GNUNET_MESSAGE_TYPE_CADET_ACK, 662 GNUNET_MESSAGE_TYPE_CADET_ACK,
647 struct GNUNET_CADET_ACK, 663 struct GNUNET_CADET_ACK,
648 NULL), 664 NULL),
649 GNUNET_MQ_hd_fixed_size (poll, 665 GNUNET_MQ_hd_fixed_size (poll,
650 GNUNET_MESSAGE_TYPE_CADET_POLL, 666 GNUNET_MESSAGE_TYPE_CADET_POLL,
651 struct GNUNET_CADET_Poll, 667 struct GNUNET_CADET_Poll,
652 NULL), 668 NULL),
653 GNUNET_MQ_hd_var_size (kx, 669 GNUNET_MQ_hd_var_size (kx,
654 GNUNET_MESSAGE_TYPE_CADET_KX, 670 GNUNET_MESSAGE_TYPE_CADET_KX,
655 struct GNUNET_CADET_KX, 671 struct GNUNET_CADET_KX,
656 NULL), 672 NULL),
657 GNUNET_MQ_hd_var_size (encrypted, 673 GNUNET_MQ_hd_var_size (encrypted,
658 GNUNET_MESSAGE_TYPE_CADET_AX, 674 GNUNET_MESSAGE_TYPE_CADET_AX,
659 struct GNUNET_CADET_AX, 675 struct GNUNET_CADET_AX,
660 NULL), 676 NULL),
661 GNUNET_MQ_handler_end () 677 GNUNET_MQ_handler_end ()
662 }; 678 };
663 core_handle = GNUNET_CORE_connecT (c, NULL, 679 core_handle = GNUNET_CORE_connecT (c, NULL,
664 &core_init_notify, 680 &core_init_notify,
665 &core_connect_handler, 681 &core_connect_handler,
666 &core_disconnect_handler, 682 &core_disconnect_handler,
667 core_handlers); 683 core_handlers);
668} 684}
669 685
670/******************************************************************************/ 686/******************************************************************************/
@@ -683,19 +699,19 @@ static void
683core_init_notify (void *cls, 699core_init_notify (void *cls,
684 const struct GNUNET_PeerIdentity *core_identity) 700 const struct GNUNET_PeerIdentity *core_identity)
685{ 701{
686 const struct GNUNET_CONFIGURATION_Handle *c = cls; 702 const struct GNUNET_CONFIGURATION_Handle *c = cls;
687 703
688 LOG (GNUNET_ERROR_TYPE_DEBUG, "Core init\n"); 704 LOG (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
689 if (0 != memcmp (core_identity, &my_full_id, sizeof (my_full_id))) 705 if (0 != memcmp (core_identity, &my_full_id, sizeof (my_full_id)))
690 { 706 {
691 LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n")); 707 LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
692 LOG (GNUNET_ERROR_TYPE_ERROR, " core id %s\n", GNUNET_i2s (core_identity)); 708 LOG (GNUNET_ERROR_TYPE_ERROR, " core id %s\n", GNUNET_i2s (core_identity));
693 LOG (GNUNET_ERROR_TYPE_ERROR, " my id %s\n", GNUNET_i2s (&my_full_id)); 709 LOG (GNUNET_ERROR_TYPE_ERROR, " my id %s\n", GNUNET_i2s (&my_full_id));
694 GNUNET_CORE_disconnecT (core_handle); 710 GNUNET_CORE_disconnecT (core_handle);
695 connect_to_core (c); 711 connect_to_core (c);
696 return; 712 return;
697 } 713 }
698 GML_start (); 714 GML_start ();
699} 715}
700 716
701 717
@@ -717,31 +733,50 @@ core_init_notify (void *cls,
717enum GNUNET_CORE_Priority 733enum GNUNET_CORE_Priority
718get_priority (struct CadetPeerQueue *q) 734get_priority (struct CadetPeerQueue *q)
719{ 735{
720 enum GNUNET_CORE_Priority low; 736 enum GNUNET_CORE_Priority low;
721 enum GNUNET_CORE_Priority high; 737 enum GNUNET_CORE_Priority high;
738
739 if (NULL == q)
740 {
741 GNUNET_break (0);
742 return GNUNET_CORE_PRIO_BACKGROUND;
743 }
744
745 /* Relayed traffic has lower priority, our own traffic has higher */
746 if (NULL == q->c || GNUNET_NO == GCC_is_origin (q->c, q->c_fwd))
747 {
748 low = GNUNET_CORE_PRIO_BEST_EFFORT;
749 high = GNUNET_CORE_PRIO_URGENT;
750 }
751 else
752 {
753 low = GNUNET_CORE_PRIO_URGENT;
754 high = GNUNET_CORE_PRIO_CRITICAL_CONTROL;
755 }
756
757 /* Bulky payload has lower priority, control traffic has higher. */
758 if (GNUNET_MESSAGE_TYPE_CADET_AX == q->type)
759 return low;
760 return high;
761}
722 762
723 if (NULL == q)
724 {
725 GNUNET_break (0);
726 return GNUNET_CORE_PRIO_BACKGROUND;
727 }
728 763
729 /* Relayed traffic has lower priority, our own traffic has higher */ 764/**
730 if (NULL == q->c || GNUNET_NO == GCC_is_origin (q->c, q->c_fwd)) 765 * Cancel all messages queued to CORE MQ towards this peer.
731 { 766 *
732 low = GNUNET_CORE_PRIO_BEST_EFFORT; 767 * @param peer Peer towards which to cancel all messages.
733 high = GNUNET_CORE_PRIO_URGENT; 768 */
734 } 769static void
735 else 770cancel_queued_messages (struct CadetPeer *peer)
736 { 771{
737 low = GNUNET_CORE_PRIO_URGENT; 772 while (NULL != peer->q_head)
738 high = GNUNET_CORE_PRIO_CRITICAL_CONTROL; 773 {
739 } 774 struct CadetPeerQueue *q;
740 775
741 /* Bulky payload has lower priority, control traffic has higher. */ 776 q = peer->q_head;
742 if (GNUNET_MESSAGE_TYPE_CADET_AX == q->type) 777 call_peer_cont (q, GNUNET_NO);
743 return low; 778 GNUNET_free (q);
744 return high; 779 }
745} 780}
746 781
747 782
@@ -754,56 +789,57 @@ get_priority (struct CadetPeerQueue *q)
754static int 789static int
755peer_destroy (struct CadetPeer *peer) 790peer_destroy (struct CadetPeer *peer)
756{ 791{
757 struct GNUNET_PeerIdentity id; 792 struct GNUNET_PeerIdentity id;
758 struct CadetPeerPath *p; 793 struct CadetPeerPath *p;
759 struct CadetPeerPath *nextp; 794 struct CadetPeerPath *nextp;
760 795
761 GNUNET_PEER_resolve (peer->id, &id); 796 GNUNET_PEER_resolve (peer->id, &id);
762 GNUNET_PEER_change_rc (peer->id, -1); 797 GNUNET_PEER_change_rc (peer->id, -1);
763
764 LOG (GNUNET_ERROR_TYPE_INFO,
765 "destroying peer %s\n",
766 GNUNET_i2s (&id));
767
768 if (GNUNET_YES !=
769 GNUNET_CONTAINER_multipeermap_remove (peers, &id, peer))
770 {
771 GNUNET_break (0);
772 LOG (GNUNET_ERROR_TYPE_WARNING, " peer not in peermap!!\n");
773 }
774 GCP_stop_search (peer);
775 p = peer->path_head;
776 while (NULL != p)
777 {
778 nextp = p->next;
779 GNUNET_CONTAINER_DLL_remove (peer->path_head,
780 peer->path_tail,
781 p);
782 path_destroy (p);
783 p = nextp;
784 }
785 if (NULL != peer->tunnel)
786 GCT_destroy_empty (peer->tunnel);
787 if (NULL != peer->connections)
788 {
789 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (peer->connections));
790 GNUNET_CONTAINER_multihashmap_destroy (peer->connections);
791 peer->connections = NULL;
792 }
793 if (NULL != peer->hello_offer)
794 {
795 GNUNET_TRANSPORT_offer_hello_cancel (peer->hello_offer);
796 peer->hello_offer = NULL;
797 }
798 if (NULL != peer->connectivity_suggestion)
799 {
800 GNUNET_ATS_connectivity_suggest_cancel (peer->connectivity_suggestion);
801 peer->connectivity_suggestion = NULL;
802 }
803 798
804 GNUNET_free_non_null (peer->hello); 799 LOG (GNUNET_ERROR_TYPE_INFO,
805 GNUNET_free (peer); 800 "destroying peer %s\n",
806 return GNUNET_OK; 801 GNUNET_i2s (&id));
802
803 if (GNUNET_YES !=
804 GNUNET_CONTAINER_multipeermap_remove (peers, &id, peer))
805 {
806 GNUNET_break (0);
807 LOG (GNUNET_ERROR_TYPE_WARNING, " peer not in peermap!!\n");
808 }
809 GCP_stop_search (peer);
810 p = peer->path_head;
811 while (NULL != p)
812 {
813 nextp = p->next;
814 GNUNET_CONTAINER_DLL_remove (peer->path_head,
815 peer->path_tail,
816 p);
817 path_destroy (p);
818 p = nextp;
819 }
820 if (NULL != peer->tunnel)
821 GCT_destroy_empty (peer->tunnel);
822 if (NULL != peer->connections)
823 {
824 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (peer->connections));
825 GNUNET_CONTAINER_multihashmap_destroy (peer->connections);
826 peer->connections = NULL;
827 }
828 if (NULL != peer->hello_offer)
829 {
830 GNUNET_TRANSPORT_offer_hello_cancel (peer->hello_offer);
831 peer->hello_offer = NULL;
832 }
833 if (NULL != peer->connectivity_suggestion)
834 {
835 GNUNET_ATS_connectivity_suggest_cancel (peer->connectivity_suggestion);
836 peer->connectivity_suggestion = NULL;
837 }
838 cancel_queued_messages (peer);
839
840 GNUNET_free_non_null (peer->hello);
841 GNUNET_free (peer);
842 return GNUNET_OK;
807} 843}
808 844
809 845
@@ -821,15 +857,15 @@ shutdown_peer (void *cls,
821 const struct GNUNET_PeerIdentity *key, 857 const struct GNUNET_PeerIdentity *key,
822 void *value) 858 void *value)
823{ 859{
824 struct CadetPeer *p = value; 860 struct CadetPeer *p = value;
825 struct CadetTunnel *t = p->tunnel; 861 struct CadetTunnel *t = p->tunnel;
826 862
827 LOG (GNUNET_ERROR_TYPE_DEBUG, " shutting down %s\n", GCP_2s (p)); 863 LOG (GNUNET_ERROR_TYPE_DEBUG, " shutting down %s\n", GCP_2s (p));
828 if (NULL != t) 864 if (NULL != t)
829 GCT_destroy (t); 865 GCT_destroy (t);
830 p->tunnel = NULL; 866 p->tunnel = NULL;
831 peer_destroy (p); 867 peer_destroy (p);
832 return GNUNET_YES; 868 return GNUNET_YES;
833} 869}
834 870
835 871
@@ -843,9 +879,9 @@ shutdown_peer (void *cls,
843static int 879static int
844is_searching (const struct CadetPeer *peer) 880is_searching (const struct CadetPeer *peer)
845{ 881{
846 return ( (NULL == peer->search_h) && 882 return ( (NULL == peer->search_h) &&
847 (NULL == peer->search_delayed) ) ? 883 (NULL == peer->search_delayed) ) ?
848 GNUNET_NO : GNUNET_YES; 884 GNUNET_NO : GNUNET_YES;
849} 885}
850 886
851 887
@@ -857,12 +893,12 @@ is_searching (const struct CadetPeer *peer)
857static void 893static void
858delayed_search (void *cls) 894delayed_search (void *cls)
859{ 895{
860 struct CadetPeer *peer = cls; 896 struct CadetPeer *peer = cls;
861 897
862 peer->search_delayed = NULL; 898 peer->search_delayed = NULL;
863 GCC_check_connections (); 899 GCC_check_connections ();
864 GCP_start_search (peer); 900 GCP_start_search (peer);
865 GCC_check_connections (); 901 GCC_check_connections ();
866} 902}
867 903
868 904
@@ -875,16 +911,16 @@ delayed_search (void *cls)
875static int 911static int
876peer_is_used (struct CadetPeer *peer) 912peer_is_used (struct CadetPeer *peer)
877{ 913{
878 struct CadetPeerPath *p; 914 struct CadetPeerPath *p;
879 915
880 if (NULL != peer->tunnel) 916 if (NULL != peer->tunnel)
881 return GNUNET_YES; 917 return GNUNET_YES;
882 918
883 for (p = peer->path_head; NULL != p; p = p->next) 919 for (p = peer->path_head; NULL != p; p = p->next)
884 { 920 {
885 if (p->length < 3) 921 if (p->length < 3)
886 return GNUNET_YES; 922 return GNUNET_YES;
887 } 923 }
888 return GNUNET_NO; 924 return GNUNET_NO;
889} 925}
890 926
@@ -901,17 +937,17 @@ peer_get_oldest (void *cls,
901 const struct GNUNET_PeerIdentity *key, 937 const struct GNUNET_PeerIdentity *key,
902 void *value) 938 void *value)
903{ 939{
904 struct CadetPeer *p = value; 940 struct CadetPeer *p = value;
905 struct GNUNET_TIME_Absolute *abs = cls; 941 struct GNUNET_TIME_Absolute *abs = cls;
906 942
907 /* Don't count active peers */ 943 /* Don't count active peers */
908 if (GNUNET_YES == peer_is_used (p)) 944 if (GNUNET_YES == peer_is_used (p))
909 return GNUNET_YES; 945 return GNUNET_YES;
910 946
911 if (abs->abs_value_us < p->last_contact.abs_value_us) 947 if (abs->abs_value_us < p->last_contact.abs_value_us)
912 abs->abs_value_us = p->last_contact.abs_value_us; 948 abs->abs_value_us = p->last_contact.abs_value_us;
913 949
914 return GNUNET_YES; 950 return GNUNET_YES;
915} 951}
916 952
917 953
@@ -927,18 +963,18 @@ peer_timeout (void *cls,
927 const struct GNUNET_PeerIdentity *key, 963 const struct GNUNET_PeerIdentity *key,
928 void *value) 964 void *value)
929{ 965{
930 struct CadetPeer *p = value; 966 struct CadetPeer *p = value;
931 struct GNUNET_TIME_Absolute *abs = cls; 967 struct GNUNET_TIME_Absolute *abs = cls;
932 968
933 LOG (GNUNET_ERROR_TYPE_WARNING, 969 LOG (GNUNET_ERROR_TYPE_WARNING,
934 "peer %s timeout\n", GNUNET_i2s (key)); 970 "peer %s timeout\n", GNUNET_i2s (key));
935 971
936 if (p->last_contact.abs_value_us == abs->abs_value_us && 972 if (p->last_contact.abs_value_us == abs->abs_value_us &&
937 GNUNET_NO == peer_is_used (p)) 973 GNUNET_NO == peer_is_used (p))
938 { 974 {
939 peer_destroy (p); 975 peer_destroy (p);
940 return GNUNET_NO; 976 return GNUNET_NO;
941 } 977 }
942 return GNUNET_YES; 978 return GNUNET_YES;
943} 979}
944 980
@@ -949,16 +985,16 @@ peer_timeout (void *cls,
949static void 985static void
950peer_delete_oldest (void) 986peer_delete_oldest (void)
951{ 987{
952 struct GNUNET_TIME_Absolute abs; 988 struct GNUNET_TIME_Absolute abs;
953 989
954 abs = GNUNET_TIME_UNIT_FOREVER_ABS; 990 abs = GNUNET_TIME_UNIT_FOREVER_ABS;
955 991
956 GNUNET_CONTAINER_multipeermap_iterate (peers, 992 GNUNET_CONTAINER_multipeermap_iterate (peers,
957 &peer_get_oldest, 993 &peer_get_oldest,
958 &abs); 994 &abs);
959 GNUNET_CONTAINER_multipeermap_iterate (peers, 995 GNUNET_CONTAINER_multipeermap_iterate (peers,
960 &peer_timeout, 996 &peer_timeout,
961 &abs); 997 &abs);
962} 998}
963 999
964 1000
@@ -972,27 +1008,27 @@ peer_delete_oldest (void)
972static struct CadetPeerPath * 1008static struct CadetPeerPath *
973peer_get_best_path (const struct CadetPeer *peer) 1009peer_get_best_path (const struct CadetPeer *peer)
974{ 1010{
975 struct CadetPeerPath *best_p; 1011 struct CadetPeerPath *best_p;
976 struct CadetPeerPath *p; 1012 struct CadetPeerPath *p;
977 unsigned int best_cost; 1013 unsigned int best_cost;
978 unsigned int cost; 1014 unsigned int cost;
979 1015
980 best_cost = UINT_MAX; 1016 best_cost = UINT_MAX;
981 best_p = NULL; 1017 best_p = NULL;
982 for (p = peer->path_head; NULL != p; p = p->next) 1018 for (p = peer->path_head; NULL != p; p = p->next)
983 {
984 if (GNUNET_NO == path_is_valid (p))
985 continue; /* Don't use invalid paths. */
986 if (GNUNET_YES == GCT_is_path_used (peer->tunnel, p))
987 continue; /* If path is already in use, skip it. */
988
989 if ((cost = GCT_get_path_cost (peer->tunnel, p)) < best_cost)
990 { 1019 {
991 best_cost = cost; 1020 if (GNUNET_NO == path_is_valid (p))
992 best_p = p; 1021 continue; /* Don't use invalid paths. */
1022 if (GNUNET_YES == GCT_is_path_used (peer->tunnel, p))
1023 continue; /* If path is already in use, skip it. */
1024
1025 if ((cost = GCT_get_path_cost (peer->tunnel, p)) < best_cost)
1026 {
1027 best_cost = cost;
1028 best_p = p;
1029 }
993 } 1030 }
994 } 1031 return best_p;
995 return best_p;
996} 1032}
997 1033
998 1034
@@ -1007,28 +1043,28 @@ peer_get_best_path (const struct CadetPeer *peer)
1007static void 1043static void
1008search_handler (void *cls, const struct CadetPeerPath *path) 1044search_handler (void *cls, const struct CadetPeerPath *path)
1009{ 1045{
1010 struct CadetPeer *peer = cls; 1046 struct CadetPeer *peer = cls;
1011 unsigned int connection_count; 1047 unsigned int connection_count;
1012 1048
1013 GCC_check_connections (); 1049 GCC_check_connections ();
1014 GCP_add_path_to_all (path, GNUNET_NO); 1050 GCP_add_path_to_all (path, GNUNET_NO);
1015 1051
1016 /* Count connections */ 1052 /* Count connections */
1017 connection_count = GCT_count_connections (peer->tunnel); 1053 connection_count = GCT_count_connections (peer->tunnel);
1018 1054
1019 /* If we already have our minimum (or more) connections, it's enough */ 1055 /* If we already have our minimum (or more) connections, it's enough */
1020 if (CONNECTIONS_PER_TUNNEL <= connection_count) 1056 if (CONNECTIONS_PER_TUNNEL <= connection_count)
1021 { 1057 {
1022 GCC_check_connections (); 1058 GCC_check_connections ();
1023 return; 1059 return;
1024 } 1060 }
1025 1061
1026 if (CADET_TUNNEL_SEARCHING == GCT_get_cstate (peer->tunnel)) 1062 if (CADET_TUNNEL_SEARCHING == GCT_get_cstate (peer->tunnel))
1027 { 1063 {
1028 LOG (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n"); 1064 LOG (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
1029 GCP_connect (peer); 1065 GCP_connect (peer);
1030 } 1066 }
1031 GCC_check_connections (); 1067 GCC_check_connections ();
1032} 1068}
1033 1069
1034 1070
@@ -1043,8 +1079,8 @@ search_handler (void *cls, const struct CadetPeerPath *path)
1043static int 1079static int
1044is_connection_management (uint16_t type) 1080is_connection_management (uint16_t type)
1045{ 1081{
1046 return type == GNUNET_MESSAGE_TYPE_CADET_ACK || 1082 return type == GNUNET_MESSAGE_TYPE_CADET_ACK ||
1047 type == GNUNET_MESSAGE_TYPE_CADET_POLL; 1083 type == GNUNET_MESSAGE_TYPE_CADET_POLL;
1048} 1084}
1049 1085
1050 1086
@@ -1057,13 +1093,13 @@ is_connection_management (uint16_t type)
1057static int 1093static int
1058should_I_drop (void) 1094should_I_drop (void)
1059{ 1095{
1060 if (0 == drop_percent) 1096 if (0 == drop_percent)
1061 return GNUNET_NO; 1097 return GNUNET_NO;
1062 1098
1063 if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 101) < drop_percent) 1099 if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 101) < drop_percent)
1064 return GNUNET_YES; 1100 return GNUNET_YES;
1065 1101
1066 return GNUNET_NO; 1102 return GNUNET_NO;
1067} 1103}
1068 1104
1069 1105
@@ -1074,25 +1110,28 @@ should_I_drop (void)
1074/** 1110/**
1075 * Call the continuation after a message has been sent or dropped. 1111 * Call the continuation after a message has been sent or dropped.
1076 * 1112 *
1113 * This funcion removes the message from the queue.
1114 *
1077 * @param q Queue handle. 1115 * @param q Queue handle.
1078 * @param sent #GNUNET_YES if was sent to CORE, #GNUNET_NO if dropped. 1116 * @param sent #GNUNET_YES if was sent to CORE, #GNUNET_NO if dropped.
1079 */ 1117 */
1080static void 1118static void
1081call_peer_cont (const struct CadetPeerQueue *q, int sent) 1119call_peer_cont (struct CadetPeerQueue *q, int sent)
1082{ 1120{
1083 LOG (GNUNET_ERROR_TYPE_DEBUG, " core mq just sent %s\n", GC_m2s (q->type)); 1121 LOG (GNUNET_ERROR_TYPE_DEBUG, " core mq just sent %s\n", GC_m2s (q->type));
1084 if (NULL != q->cont) 1122 if (NULL != q->cont)
1085 { 1123 {
1086 struct GNUNET_TIME_Relative wait_time; 1124 struct GNUNET_TIME_Relative wait_time;
1087 1125
1088 wait_time = GNUNET_TIME_absolute_get_duration (q->queue_timestamp); 1126 wait_time = GNUNET_TIME_absolute_get_duration (q->queue_timestamp);
1089 LOG (GNUNET_ERROR_TYPE_DEBUG, " calling callback, time elapsed %s\n", 1127 LOG (GNUNET_ERROR_TYPE_DEBUG, " calling callback, time elapsed %s\n",
1090 GNUNET_STRINGS_relative_time_to_string (wait_time, GNUNET_NO)); 1128 GNUNET_STRINGS_relative_time_to_string (wait_time, GNUNET_NO));
1091 q->cont (q->cont_cls, 1129 q->cont (q->cont_cls,
1092 q->c, q->c_fwd, sent, 1130 q->c, q->c_fwd, sent,
1093 q->type, q->payload_type, q->payload_id, 1131 q->type, q->payload_type, q->payload_id,
1094 q->size, wait_time); 1132 q->size, wait_time);
1095 } 1133 }
1134 GNUNET_CONTAINER_DLL_remove (q->peer->q_head, q->peer->q_tail, q);
1096} 1135}
1097 1136
1098 1137
@@ -1104,14 +1143,14 @@ call_peer_cont (const struct CadetPeerQueue *q, int sent)
1104static void 1143static void
1105mq_sent (void *cls) 1144mq_sent (void *cls)
1106{ 1145{
1107 struct CadetPeerQueue *q = cls; 1146 struct CadetPeerQueue *q = cls;
1108 1147
1109 if (GNUNET_NO == q->management_traffic) 1148 if (GNUNET_NO == q->management_traffic)
1110 { 1149 {
1111 q->peer->queue_n--; 1150 q->peer->queue_n--;
1112 } 1151 }
1113 call_peer_cont (q, GNUNET_YES); 1152 call_peer_cont (q, GNUNET_YES);
1114 GNUNET_free (q); 1153 GNUNET_free (q);
1115} 1154}
1116 1155
1117 1156
@@ -1141,65 +1180,66 @@ GCP_send (struct CadetPeer *peer,
1141 GCP_sent cont, 1180 GCP_sent cont,
1142 void *cont_cls) 1181 void *cont_cls)
1143{ 1182{
1144 struct CadetPeerQueue *q; 1183 struct CadetPeerQueue *q;
1145 uint16_t type; 1184 uint16_t type;
1146 uint16_t size; 1185 uint16_t size;
1147 1186
1148 GCC_check_connections (); 1187 GCC_check_connections ();
1149 type = ntohs (message->type); 1188 type = ntohs (message->type);
1150 size = ntohs (message->size); 1189 size = ntohs (message->size);
1151 LOG (GNUNET_ERROR_TYPE_DEBUG, 1190 LOG (GNUNET_ERROR_TYPE_DEBUG,
1152 "que %s (%s %4u) on conn %s (%p) %s towards %s (size %u)\n", 1191 "que %s (%s %4u) on conn %s (%p) %s towards %s (size %u)\n",
1153 GC_m2s (type), GC_m2s (payload_type), payload_id, 1192 GC_m2s (type), GC_m2s (payload_type), payload_id,
1154 GCC_2s (c), c, GC_f2s (fwd), GCP_2s (peer), size); 1193 GCC_2s (c), c, GC_f2s (fwd), GCP_2s (peer), size);
1155 1194
1156 if (NULL == peer->connections) 1195 if (NULL == peer->connections)
1157 {
1158 /* We are not connected to this peer, ignore request. */
1159 GNUNET_break (0);
1160 LOG (GNUNET_ERROR_TYPE_INFO, "%s not a neighbor\n", GCP_2s (peer));
1161 GNUNET_STATISTICS_update (stats, "# messages dropped due to wrong hop", 1,
1162 GNUNET_NO);
1163 return NULL;
1164 }
1165
1166 q = GNUNET_new (struct CadetPeerQueue);
1167 q->env = GNUNET_MQ_msg_copy (message);
1168 q->peer = peer;
1169 q->cont = cont;
1170 q->cont_cls = cont_cls;
1171 q->queue_timestamp = GNUNET_TIME_absolute_get ();
1172 q->management_traffic = is_connection_management (type);
1173 q->type = type;
1174 q->size = size;
1175 q->payload_type = payload_type;
1176 q->payload_id = payload_id;
1177 q->c = c;
1178 q->c_fwd = fwd;
1179 GNUNET_MQ_notify_sent (q->env, mq_sent, q);
1180
1181 if (GNUNET_YES == q->management_traffic)
1182 {
1183 GNUNET_MQ_send (peer->core_mq, q->env); // FIXME implement "_urgent", use
1184 }
1185 else
1186 {
1187 if (GNUNET_YES == should_I_drop())
1188 { 1196 {
1189 LOG (GNUNET_ERROR_TYPE_WARNING, "DD %s (%s %u) on conn %s %s\n", 1197 /* We are not connected to this peer, ignore request. */
1190 GC_m2s (q->type), GC_m2s (q->payload_type), 1198 GNUNET_break (0);
1191 q->payload_id, GCC_2s (c), GC_f2s (q->c_fwd)); 1199 LOG (GNUNET_ERROR_TYPE_INFO, "%s not a neighbor\n", GCP_2s (peer));
1192 GNUNET_MQ_discard (q->env); 1200 GNUNET_STATISTICS_update (stats, "# messages dropped due to wrong hop", 1,
1193 call_peer_cont (q, GNUNET_NO); 1201 GNUNET_NO);
1194 GNUNET_free (q); 1202 return NULL;
1195 return NULL;
1196 } 1203 }
1197 GNUNET_MQ_send (peer->core_mq, q->env);
1198 peer->queue_n++;
1199 }
1200 1204
1201 GCC_check_connections (); 1205 q = GNUNET_new (struct CadetPeerQueue);
1202 return q; 1206 q->env = GNUNET_MQ_msg_copy (message);
1207 q->peer = peer;
1208 q->cont = cont;
1209 q->cont_cls = cont_cls;
1210 q->queue_timestamp = GNUNET_TIME_absolute_get ();
1211 q->management_traffic = is_connection_management (type);
1212 q->type = type;
1213 q->size = size;
1214 q->payload_type = payload_type;
1215 q->payload_id = payload_id;
1216 q->c = c;
1217 q->c_fwd = fwd;
1218 GNUNET_MQ_notify_sent (q->env, mq_sent, q);
1219
1220 if (GNUNET_YES == q->management_traffic)
1221 {
1222 GNUNET_MQ_send (peer->core_mq, q->env); // FIXME implement "_urgent", use
1223 }
1224 else
1225 {
1226 if (GNUNET_YES == should_I_drop ())
1227 {
1228 LOG (GNUNET_ERROR_TYPE_WARNING, "DD %s (%s %u) on conn %s %s\n",
1229 GC_m2s (q->type), GC_m2s (q->payload_type),
1230 q->payload_id, GCC_2s (c), GC_f2s (q->c_fwd));
1231 GNUNET_MQ_discard (q->env);
1232 call_peer_cont (q, GNUNET_YES);
1233 GNUNET_free (q);
1234 return NULL;
1235 }
1236 GNUNET_MQ_send (peer->core_mq, q->env);
1237 peer->queue_n++;
1238 }
1239
1240 GNUNET_CONTAINER_DLL_insert (peer->q_head, peer->q_tail, q);
1241 GCC_check_connections ();
1242 return q;
1203} 1243}
1204 1244
1205 1245
@@ -1215,9 +1255,9 @@ GCP_send (struct CadetPeer *peer,
1215void 1255void
1216GCP_send_cancel (struct CadetPeerQueue *q) 1256GCP_send_cancel (struct CadetPeerQueue *q)
1217{ 1257{
1218 call_peer_cont (q, GNUNET_NO); 1258 call_peer_cont (q, GNUNET_NO);
1219 GNUNET_MQ_send_cancel (q->env); 1259 GNUNET_MQ_send_cancel (q->env);
1220 GNUNET_free (q); 1260 GNUNET_free (q);
1221} 1261}
1222 1262
1223 1263
@@ -1229,41 +1269,41 @@ GCP_send_cancel (struct CadetPeerQueue *q)
1229void 1269void
1230GCP_init (const struct GNUNET_CONFIGURATION_Handle *c) 1270GCP_init (const struct GNUNET_CONFIGURATION_Handle *c)
1231{ 1271{
1232 cfg = c; 1272 cfg = c;
1233 LOG (GNUNET_ERROR_TYPE_DEBUG, 1273 LOG (GNUNET_ERROR_TYPE_DEBUG,
1234 "GCP_init\n"); 1274 "GCP_init\n");
1235 in_shutdown = GNUNET_NO; 1275 in_shutdown = GNUNET_NO;
1236 peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO); 1276 peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
1237 if (GNUNET_OK != 1277 if (GNUNET_OK !=
1238 GNUNET_CONFIGURATION_get_value_number (c, "CADET", "MAX_PEERS", 1278 GNUNET_CONFIGURATION_get_value_number (c, "CADET", "MAX_PEERS",
1239 &max_peers)) 1279 &max_peers))
1240 { 1280 {
1241 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, 1281 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1242 "CADET", "MAX_PEERS", "USING DEFAULT"); 1282 "CADET", "MAX_PEERS", "USING DEFAULT");
1243 max_peers = 1000; 1283 max_peers = 1000;
1244 } 1284 }
1245 1285
1246 if (GNUNET_OK != 1286 if (GNUNET_OK !=
1247 GNUNET_CONFIGURATION_get_value_number (c, "CADET", "DROP_PERCENT", 1287 GNUNET_CONFIGURATION_get_value_number (c, "CADET", "DROP_PERCENT",
1248 &drop_percent)) 1288 &drop_percent))
1249 { 1289 {
1250 drop_percent = 0; 1290 drop_percent = 0;
1251 } 1291 }
1252 else 1292 else
1253 { 1293 {
1254 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n"); 1294 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1255 LOG (GNUNET_ERROR_TYPE_WARNING, "Cadet is running with DROP enabled.\n"); 1295 LOG (GNUNET_ERROR_TYPE_WARNING, "Cadet is running with DROP enabled.\n");
1256 LOG (GNUNET_ERROR_TYPE_WARNING, "This is NOT a good idea!\n"); 1296 LOG (GNUNET_ERROR_TYPE_WARNING, "This is NOT a good idea!\n");
1257 LOG (GNUNET_ERROR_TYPE_WARNING, "Remove DROP_PERCENT from config file.\n"); 1297 LOG (GNUNET_ERROR_TYPE_WARNING, "Remove DROP_PERCENT from config file.\n");
1258 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n"); 1298 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1259 } 1299 }
1260 ats_ch = GNUNET_ATS_connectivity_init (c); 1300 ats_ch = GNUNET_ATS_connectivity_init (c);
1261 connect_to_core (c); 1301 connect_to_core (c);
1262 if (NULL == core_handle) 1302 if (NULL == core_handle)
1263 { 1303 {
1264 GNUNET_break (0); 1304 GNUNET_break (0);
1265 GNUNET_SCHEDULER_shutdown (); 1305 GNUNET_SCHEDULER_shutdown ();
1266 } 1306 }
1267} 1307}
1268 1308
1269 1309
@@ -1273,28 +1313,28 @@ GCP_init (const struct GNUNET_CONFIGURATION_Handle *c)
1273void 1313void
1274GCP_shutdown (void) 1314GCP_shutdown (void)
1275{ 1315{
1276 LOG (GNUNET_ERROR_TYPE_DEBUG, 1316 LOG (GNUNET_ERROR_TYPE_DEBUG,
1277 "Shutting down peer subsystem\n"); 1317 "Shutting down peer subsystem\n");
1278 in_shutdown = GNUNET_YES; 1318 in_shutdown = GNUNET_YES;
1279 if (NULL != core_handle) 1319 if (NULL != core_handle)
1280 { 1320 {
1281 GNUNET_CORE_disconnecT (core_handle); 1321 GNUNET_CORE_disconnecT (core_handle);
1282 core_handle = NULL; 1322 core_handle = NULL;
1283 } 1323 }
1284 GNUNET_PEER_change_rc (myid, -1); 1324 GNUNET_PEER_change_rc (myid, -1);
1285 /* With MQ API, CORE calls the disconnect handler for every peer 1325 /* With MQ API, CORE calls the disconnect handler for every peer
1286 * after calling GNUNET_CORE_disconnecT, shutdown must occur *after* that. 1326 * after calling GNUNET_CORE_disconnecT, shutdown must occur *after* that.
1287 */ 1327 */
1288 GNUNET_CONTAINER_multipeermap_iterate (peers, 1328 GNUNET_CONTAINER_multipeermap_iterate (peers,
1289 &shutdown_peer, 1329 &shutdown_peer,
1290 NULL); 1330 NULL);
1291 if (NULL != ats_ch) 1331 if (NULL != ats_ch)
1292 { 1332 {
1293 GNUNET_ATS_connectivity_done (ats_ch); 1333 GNUNET_ATS_connectivity_done (ats_ch);
1294 ats_ch = NULL; 1334 ats_ch = NULL;
1295 } 1335 }
1296 GNUNET_CONTAINER_multipeermap_destroy (peers); 1336 GNUNET_CONTAINER_multipeermap_destroy (peers);
1297 peers = NULL; 1337 peers = NULL;
1298} 1338}
1299 1339
1300 1340
@@ -1312,26 +1352,26 @@ GCP_shutdown (void)
1312struct CadetPeer * 1352struct CadetPeer *
1313GCP_get (const struct GNUNET_PeerIdentity *peer_id, int create) 1353GCP_get (const struct GNUNET_PeerIdentity *peer_id, int create)
1314{ 1354{
1315 struct CadetPeer *peer; 1355 struct CadetPeer *peer;
1316 1356
1317 peer = GNUNET_CONTAINER_multipeermap_get (peers, peer_id); 1357 peer = GNUNET_CONTAINER_multipeermap_get (peers, peer_id);
1318 if (NULL == peer) 1358 if (NULL == peer)
1319 {
1320 peer = GNUNET_new (struct CadetPeer);
1321 if (GNUNET_CONTAINER_multipeermap_size (peers) > max_peers)
1322 { 1359 {
1323 peer_delete_oldest (); 1360 peer = GNUNET_new (struct CadetPeer);
1361 if (GNUNET_CONTAINER_multipeermap_size (peers) > max_peers)
1362 {
1363 peer_delete_oldest ();
1364 }
1365 GNUNET_assert (GNUNET_OK ==
1366 GNUNET_CONTAINER_multipeermap_put (peers,
1367 peer_id,
1368 peer,
1369 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1370 peer->id = GNUNET_PEER_intern (peer_id);
1324 } 1371 }
1325 GNUNET_assert (GNUNET_OK == 1372 peer->last_contact = GNUNET_TIME_absolute_get ();
1326 GNUNET_CONTAINER_multipeermap_put (peers,
1327 peer_id,
1328 peer,
1329 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1330 peer->id = GNUNET_PEER_intern (peer_id);
1331 }
1332 peer->last_contact = GNUNET_TIME_absolute_get ();
1333 1373
1334 return peer; 1374 return peer;
1335} 1375}
1336 1376
1337 1377
@@ -1350,7 +1390,7 @@ GCP_get (const struct GNUNET_PeerIdentity *peer_id, int create)
1350struct CadetPeer * 1390struct CadetPeer *
1351GCP_get_short (const GNUNET_PEER_Id peer, int create) 1391GCP_get_short (const GNUNET_PEER_Id peer, int create)
1352{ 1392{
1353 return GCP_get (GNUNET_PEER_resolve2 (peer), create); 1393 return GCP_get (GNUNET_PEER_resolve2 (peer), create);
1354} 1394}
1355 1395
1356 1396
@@ -1363,9 +1403,9 @@ GCP_get_short (const GNUNET_PEER_Id peer, int create)
1363static void 1403static void
1364hello_offer_done (void *cls) 1404hello_offer_done (void *cls)
1365{ 1405{
1366 struct CadetPeer *peer = cls; 1406 struct CadetPeer *peer = cls;
1367 1407
1368 peer->hello_offer = NULL; 1408 peer->hello_offer = NULL;
1369} 1409}
1370 1410
1371 1411
@@ -1379,82 +1419,82 @@ hello_offer_done (void *cls)
1379void 1419void
1380GCP_connect (struct CadetPeer *peer) 1420GCP_connect (struct CadetPeer *peer)
1381{ 1421{
1382 struct CadetTunnel *t; 1422 struct CadetTunnel *t;
1383 struct CadetPeerPath *path; 1423 struct CadetPeerPath *path;
1384 struct CadetConnection *c; 1424 struct CadetConnection *c;
1385 int rerun_search; 1425 int rerun_search;
1386 1426
1387 GCC_check_connections (); 1427 GCC_check_connections ();
1388 LOG (GNUNET_ERROR_TYPE_DEBUG, 1428 LOG (GNUNET_ERROR_TYPE_DEBUG,
1389 "peer_connect towards %s\n", 1429 "peer_connect towards %s\n",
1390 GCP_2s (peer)); 1430 GCP_2s (peer));
1391 /* If we have a current hello, try to connect using it. */ 1431 /* If we have a current hello, try to connect using it. */
1392 GCP_try_connect (peer); 1432 GCP_try_connect (peer);
1393 1433
1394 t = peer->tunnel; 1434 t = peer->tunnel;
1395 c = NULL; 1435 c = NULL;
1396 rerun_search = GNUNET_NO; 1436 rerun_search = GNUNET_NO;
1397 1437
1398 if (NULL != peer->path_head) 1438 if (NULL != peer->path_head)
1399 {
1400 LOG (GNUNET_ERROR_TYPE_DEBUG, " some path exists\n");
1401 path = peer_get_best_path (peer);
1402 if (NULL != path)
1403 { 1439 {
1404 char *s; 1440 LOG (GNUNET_ERROR_TYPE_DEBUG, " some path exists\n");
1405 1441 path = peer_get_best_path (peer);
1406 s = path_2s (path); 1442 if (NULL != path)
1407 LOG (GNUNET_ERROR_TYPE_DEBUG, " path to use: %s\n", s); 1443 {
1408 GNUNET_free (s); 1444 char *s;
1409 1445
1410 c = GCT_use_path (t, path); 1446 s = path_2s (path);
1411 if (NULL == c) 1447 LOG (GNUNET_ERROR_TYPE_DEBUG, " path to use: %s\n", s);
1412 { 1448 GNUNET_free (s);
1413 /* This case can happen when the path includes a first hop that is 1449
1414 * not yet known to be connected. 1450 c = GCT_use_path (t, path);
1415 * 1451 if (NULL == c)
1416 * This happens quite often during testing when running cadet 1452 {
1417 * under valgrind: core connect notifications come very late 1453 /* This case can happen when the path includes a first hop that is
1418 * and the DHT result has already come and created a valid 1454 * not yet known to be connected.
1419 * path. In this case, the peer->connections 1455 *
1420 * hashmaps will be NULL and tunnel_use_path will not be able 1456 * This happens quite often during testing when running cadet
1421 * to create a connection from that path. 1457 * under valgrind: core connect notifications come very late
1422 * 1458 * and the DHT result has already come and created a valid
1423 * Re-running the DHT GET should give core time to callback. 1459 * path. In this case, the peer->connections
1424 * 1460 * hashmaps will be NULL and tunnel_use_path will not be able
1425 * GCT_use_path -> GCC_new -> register_neighbors takes care of 1461 * to create a connection from that path.
1426 * updating statistics about this issue. 1462 *
1427 */ 1463 * Re-running the DHT GET should give core time to callback.
1428 rerun_search = GNUNET_YES; 1464 *
1429 } 1465 * GCT_use_path -> GCC_new -> register_neighbors takes care of
1430 else 1466 * updating statistics about this issue.
1431 { 1467 */
1432 GCC_send_create (c); 1468 rerun_search = GNUNET_YES;
1433 return; 1469 }
1434 } 1470 else
1471 {
1472 GCC_send_create (c);
1473 return;
1474 }
1475 }
1476 else
1477 {
1478 LOG (GNUNET_ERROR_TYPE_DEBUG, " but is NULL, all paths are in use\n");
1479 }
1435 } 1480 }
1436 else 1481
1482 if (GNUNET_YES == rerun_search)
1437 { 1483 {
1438 LOG (GNUNET_ERROR_TYPE_DEBUG, " but is NULL, all paths are in use\n"); 1484 struct GNUNET_TIME_Relative delay;
1485
1486 GCP_stop_search (peer);
1487 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100);
1488 peer->search_delayed = GNUNET_SCHEDULER_add_delayed (delay,
1489 &delayed_search,
1490 peer);
1491 GCC_check_connections ();
1492 return;
1439 } 1493 }
1440 }
1441 1494
1442 if (GNUNET_YES == rerun_search) 1495 if (GNUNET_NO == is_searching (peer))
1443 { 1496 GCP_start_search (peer);
1444 struct GNUNET_TIME_Relative delay;
1445
1446 GCP_stop_search (peer);
1447 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100);
1448 peer->search_delayed = GNUNET_SCHEDULER_add_delayed (delay,
1449 &delayed_search,
1450 peer);
1451 GCC_check_connections (); 1497 GCC_check_connections ();
1452 return;
1453 }
1454
1455 if (GNUNET_NO == is_searching (peer))
1456 GCP_start_search (peer);
1457 GCC_check_connections ();
1458} 1498}
1459 1499
1460 1500
@@ -1468,19 +1508,19 @@ GCP_connect (struct CadetPeer *peer)
1468int 1508int
1469GCP_is_neighbor (const struct CadetPeer *peer) 1509GCP_is_neighbor (const struct CadetPeer *peer)
1470{ 1510{
1471 struct CadetPeerPath *path; 1511 struct CadetPeerPath *path;
1472 1512
1473 if (NULL == peer->connections) 1513 if (NULL == peer->connections)
1474 return GNUNET_NO; 1514 return GNUNET_NO;
1475 1515
1476 for (path = peer->path_head; NULL != path; path = path->next) 1516 for (path = peer->path_head; NULL != path; path = path->next)
1477 { 1517 {
1478 if (3 > path->length) 1518 if (3 > path->length)
1479 return GNUNET_YES; 1519 return GNUNET_YES;
1480 } 1520 }
1481 1521
1482 /* Is not a neighbor but connections is not NULL, probably disconnecting */ 1522 /* Is not a neighbor but connections is not NULL, probably disconnecting */
1483 return GNUNET_NO; 1523 return GNUNET_NO;
1484} 1524}
1485 1525
1486 1526
@@ -1495,11 +1535,11 @@ GCP_is_neighbor (const struct CadetPeer *peer)
1495void 1535void
1496GCP_add_tunnel (struct CadetPeer *peer) 1536GCP_add_tunnel (struct CadetPeer *peer)
1497{ 1537{
1498 GCC_check_connections (); 1538 GCC_check_connections ();
1499 if (NULL != peer->tunnel) 1539 if (NULL != peer->tunnel)
1500 return; 1540 return;
1501 peer->tunnel = GCT_new (peer); 1541 peer->tunnel = GCT_new (peer);
1502 GCC_check_connections (); 1542 GCC_check_connections ();
1503} 1543}
1504 1544
1505 1545
@@ -1519,22 +1559,22 @@ GCP_add_connection (struct CadetPeer *peer,
1519 struct CadetConnection *c, 1559 struct CadetConnection *c,
1520 int pred) 1560 int pred)
1521{ 1561{
1522 LOG (GNUNET_ERROR_TYPE_DEBUG, 1562 LOG (GNUNET_ERROR_TYPE_DEBUG,
1523 "adding connection %s\n", 1563 "adding connection %s\n",
1524 GCC_2s (c)); 1564 GCC_2s (c));
1525 LOG (GNUNET_ERROR_TYPE_DEBUG, 1565 LOG (GNUNET_ERROR_TYPE_DEBUG,
1526 "to peer %s\n", 1566 "to peer %s\n",
1527 GCP_2s (peer)); 1567 GCP_2s (peer));
1528 GNUNET_assert (NULL != peer->connections); 1568 GNUNET_assert (NULL != peer->connections);
1529 GNUNET_assert (GNUNET_OK == 1569 GNUNET_assert (GNUNET_OK ==
1530 GNUNET_CONTAINER_multihashmap_put (peer->connections, 1570 GNUNET_CONTAINER_multihashmap_put (peer->connections,
1531 GCC_get_h (c), 1571 GCC_get_h (c),
1532 c, 1572 c,
1533 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 1573 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1534 LOG (GNUNET_ERROR_TYPE_DEBUG, 1574 LOG (GNUNET_ERROR_TYPE_DEBUG,
1535 "Peer %s has now %u connections.\n", 1575 "Peer %s has now %u connections.\n",
1536 GCP_2s (peer), 1576 GCP_2s (peer),
1537 GNUNET_CONTAINER_multihashmap_size (peer->connections)); 1577 GNUNET_CONTAINER_multihashmap_size (peer->connections));
1538} 1578}
1539 1579
1540 1580
@@ -1555,90 +1595,90 @@ GCP_add_path (struct CadetPeer *peer,
1555 struct CadetPeerPath *path, 1595 struct CadetPeerPath *path,
1556 int trusted) 1596 int trusted)
1557{ 1597{
1558 struct CadetPeerPath *aux; 1598 struct CadetPeerPath *aux;
1559 unsigned int l; 1599 unsigned int l;
1560 unsigned int l2; 1600 unsigned int l2;
1561 1601
1562 GCC_check_connections (); 1602 GCC_check_connections ();
1563 LOG (GNUNET_ERROR_TYPE_DEBUG, 1603 LOG (GNUNET_ERROR_TYPE_DEBUG,
1564 "adding path [%u] to peer %s\n", 1604 "adding path [%u] to peer %s\n",
1565 path->length, GCP_2s (peer)); 1605 path->length, GCP_2s (peer));
1566
1567 if (NULL == peer || NULL == path
1568 || path->peers[path->length - 1] != peer->id)
1569 {
1570 GNUNET_break (0);
1571 path_destroy (path);
1572 return NULL;
1573 }
1574 1606
1575 for (l = 1; l < path->length; l++) 1607 if (NULL == peer || NULL == path
1576 { 1608 || path->peers[path->length - 1] != peer->id)
1577 if (path->peers[l] == myid)
1578 { 1609 {
1579 LOG (GNUNET_ERROR_TYPE_DEBUG, " shortening path by %u\n", l); 1610 GNUNET_break (0);
1580 for (l2 = 0; l2 < path->length - l; l2++) 1611 path_destroy (path);
1581 { 1612 return NULL;
1582 path->peers[l2] = path->peers[l + l2];
1583 }
1584 path->length -= l;
1585 l = 1;
1586 path->peers = GNUNET_realloc (path->peers,
1587 path->length * sizeof (GNUNET_PEER_Id));
1588 } 1613 }
1589 }
1590
1591 LOG (GNUNET_ERROR_TYPE_DEBUG, " final length: %u\n", path->length);
1592 1614
1593 if (2 >= path->length && GNUNET_NO == trusted) 1615 for (l = 1; l < path->length; l++)
1594 { 1616 {
1595 /* Only allow CORE to tell us about direct paths */ 1617 if (path->peers[l] == myid)
1596 path_destroy (path); 1618 {
1597 return NULL; 1619 LOG (GNUNET_ERROR_TYPE_DEBUG, " shortening path by %u\n", l);
1598 } 1620 for (l2 = 0; l2 < path->length - l; l2++)
1621 {
1622 path->peers[l2] = path->peers[l + l2];
1623 }
1624 path->length -= l;
1625 l = 1;
1626 path->peers = GNUNET_realloc (path->peers,
1627 path->length * sizeof (GNUNET_PEER_Id));
1628 }
1629 }
1599 1630
1600 l = path_get_length (path); 1631 LOG (GNUNET_ERROR_TYPE_DEBUG, " final length: %u\n", path->length);
1601 if (0 == l)
1602 {
1603 path_destroy (path);
1604 return NULL;
1605 }
1606 1632
1607 GNUNET_assert (peer->id == path->peers[path->length - 1]); 1633 if (2 >= path->length && GNUNET_NO == trusted)
1608 for (aux = peer->path_head; aux != NULL; aux = aux->next)
1609 {
1610 l2 = path_get_length (aux);
1611 if (l2 > l)
1612 { 1634 {
1613 LOG (GNUNET_ERROR_TYPE_DEBUG, " added\n"); 1635 /* Only allow CORE to tell us about direct paths */
1614 GNUNET_CONTAINER_DLL_insert_before (peer->path_head, 1636 path_destroy (path);
1615 peer->path_tail, aux, path); 1637 return NULL;
1616 goto finish;
1617 } 1638 }
1618 else 1639
1640 l = path_get_length (path);
1641 if (0 == l)
1619 { 1642 {
1620 if (l2 == l && memcmp (path->peers, aux->peers, l) == 0)
1621 {
1622 LOG (GNUNET_ERROR_TYPE_DEBUG, " already known\n");
1623 path_destroy (path); 1643 path_destroy (path);
1624 return aux; 1644 return NULL;
1625 }
1626 } 1645 }
1627 } 1646
1628 GNUNET_CONTAINER_DLL_insert_tail (peer->path_head, 1647 GNUNET_assert (peer->id == path->peers[path->length - 1]);
1629 peer->path_tail, 1648 for (aux = peer->path_head; aux != NULL; aux = aux->next)
1630 path); 1649 {
1631 LOG (GNUNET_ERROR_TYPE_DEBUG, " added last\n"); 1650 l2 = path_get_length (aux);
1651 if (l2 > l)
1652 {
1653 LOG (GNUNET_ERROR_TYPE_DEBUG, " added\n");
1654 GNUNET_CONTAINER_DLL_insert_before (peer->path_head,
1655 peer->path_tail, aux, path);
1656 goto finish;
1657 }
1658 else
1659 {
1660 if (l2 == l && memcmp (path->peers, aux->peers, l) == 0)
1661 {
1662 LOG (GNUNET_ERROR_TYPE_DEBUG, " already known\n");
1663 path_destroy (path);
1664 return aux;
1665 }
1666 }
1667 }
1668 GNUNET_CONTAINER_DLL_insert_tail (peer->path_head,
1669 peer->path_tail,
1670 path);
1671 LOG (GNUNET_ERROR_TYPE_DEBUG, " added last\n");
1632 1672
1633finish: 1673finish:
1634 if (NULL != peer->tunnel 1674 if (NULL != peer->tunnel
1635 && CONNECTIONS_PER_TUNNEL > GCT_count_connections (peer->tunnel) 1675 && CONNECTIONS_PER_TUNNEL > GCT_count_connections (peer->tunnel)
1636 && 2 < path->length) /* Direct paths are handled by core_connect */ 1676 && 2 < path->length) /* Direct paths are handled by core_connect */
1637 { 1677 {
1638 GCP_connect (peer); 1678 GCP_connect (peer);
1639 } 1679 }
1640 GCC_check_connections (); 1680 GCC_check_connections ();
1641 return path; 1681 return path;
1642} 1682}
1643 1683
1644 1684
@@ -1661,10 +1701,10 @@ GCP_add_path_to_origin (struct CadetPeer *peer,
1661 struct CadetPeerPath *path, 1701 struct CadetPeerPath *path,
1662 int trusted) 1702 int trusted)
1663{ 1703{
1664 if (NULL == path) 1704 if (NULL == path)
1665 return NULL; 1705 return NULL;
1666 path_invert (path); 1706 path_invert (path);
1667 return GCP_add_path (peer, path, trusted); 1707 return GCP_add_path (peer, path, trusted);
1668} 1708}
1669 1709
1670 1710
@@ -1677,23 +1717,23 @@ GCP_add_path_to_origin (struct CadetPeer *peer,
1677void 1717void
1678GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed) 1718GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed)
1679{ 1719{
1680 unsigned int i; 1720 unsigned int i;
1681 1721
1682 /* TODO: invert and add to origin */ 1722 /* TODO: invert and add to origin */
1683 /* TODO: replace all "GCP_add_path" with this, make the other one static */ 1723 /* TODO: replace all "GCP_add_path" with this, make the other one static */
1684 GCC_check_connections (); 1724 GCC_check_connections ();
1685 for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ; 1725 for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
1686 for (i++; i < p->length; i++) 1726 for (i++; i < p->length; i++)
1687 { 1727 {
1688 struct CadetPeer *peer; 1728 struct CadetPeer *peer;
1689 struct CadetPeerPath *copy; 1729 struct CadetPeerPath *copy;
1690 1730
1691 peer = GCP_get_short (p->peers[i], GNUNET_YES); 1731 peer = GCP_get_short (p->peers[i], GNUNET_YES);
1692 copy = path_duplicate (p); 1732 copy = path_duplicate (p);
1693 copy->length = i + 1; 1733 copy->length = i + 1;
1694 GCP_add_path (peer, copy, 3 > p->length ? GNUNET_NO : confirmed); 1734 GCP_add_path (peer, copy, 3 > p->length ? GNUNET_NO : confirmed);
1695 } 1735 }
1696 GCC_check_connections (); 1736 GCC_check_connections ();
1697} 1737}
1698 1738
1699 1739
@@ -1705,33 +1745,33 @@ GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed)
1705 */ 1745 */
1706void 1746void
1707GCP_remove_path (struct CadetPeer *peer, 1747GCP_remove_path (struct CadetPeer *peer,
1708 struct CadetPeerPath *path) 1748 struct CadetPeerPath *path)
1709{ 1749{
1710 struct CadetPeerPath *iter; 1750 struct CadetPeerPath *iter;
1711 struct CadetPeerPath *next; 1751 struct CadetPeerPath *next;
1712 1752
1713 GCC_check_connections (); 1753 GCC_check_connections ();
1714 GNUNET_assert (myid == path->peers[0]); 1754 GNUNET_assert (myid == path->peers[0]);
1715 GNUNET_assert (peer->id == path->peers[path->length - 1]); 1755 GNUNET_assert (peer->id == path->peers[path->length - 1]);
1716 1756
1717 LOG (GNUNET_ERROR_TYPE_INFO, 1757 LOG (GNUNET_ERROR_TYPE_INFO,
1718 "Removing path %p (%u) from %s\n", 1758 "Removing path %p (%u) from %s\n",
1719 path, path->length, GCP_2s (peer)); 1759 path, path->length, GCP_2s (peer));
1720 1760
1721 for (iter = peer->path_head; NULL != iter; iter = next) 1761 for (iter = peer->path_head; NULL != iter; iter = next)
1722 {
1723 next = iter->next;
1724 if (0 == path_cmp (path, iter))
1725 { 1762 {
1726 GNUNET_CONTAINER_DLL_remove (peer->path_head, 1763 next = iter->next;
1727 peer->path_tail, 1764 if (0 == path_cmp (path, iter))
1728 iter); 1765 {
1729 if (iter != path) 1766 GNUNET_CONTAINER_DLL_remove (peer->path_head,
1730 path_destroy (iter); 1767 peer->path_tail,
1768 iter);
1769 if (iter != path)
1770 path_destroy (iter);
1771 }
1731 } 1772 }
1732 } 1773 path_destroy (path);
1733 path_destroy (path); 1774 GCC_check_connections ();
1734 GCC_check_connections ();
1735} 1775}
1736 1776
1737 1777
@@ -1745,13 +1785,13 @@ void
1745GCP_check_connection (const struct CadetPeer *peer, 1785GCP_check_connection (const struct CadetPeer *peer,
1746 const struct CadetConnection *c) 1786 const struct CadetConnection *c)
1747{ 1787{
1748 GNUNET_assert (NULL != peer); 1788 GNUNET_assert (NULL != peer);
1749 GNUNET_assert (NULL != peer->connections); 1789 GNUNET_assert (NULL != peer->connections);
1750 return; 1790 return;
1751 GNUNET_assert (GNUNET_YES == 1791 GNUNET_assert (GNUNET_YES ==
1752 GNUNET_CONTAINER_multihashmap_contains_value (peer->connections, 1792 GNUNET_CONTAINER_multihashmap_contains_value (peer->connections,
1753 GCC_get_h (c), 1793 GCC_get_h (c),
1754 c)); 1794 c));
1755} 1795}
1756 1796
1757 1797
@@ -1765,23 +1805,23 @@ void
1765GCP_remove_connection (struct CadetPeer *peer, 1805GCP_remove_connection (struct CadetPeer *peer,
1766 const struct CadetConnection *c) 1806 const struct CadetConnection *c)
1767{ 1807{
1768 LOG (GNUNET_ERROR_TYPE_DEBUG, 1808 LOG (GNUNET_ERROR_TYPE_DEBUG,
1769 "Removing connection %s\n", 1809 "Removing connection %s\n",
1770 GCC_2s (c)); 1810 GCC_2s (c));
1771 LOG (GNUNET_ERROR_TYPE_DEBUG, 1811 LOG (GNUNET_ERROR_TYPE_DEBUG,
1772 "from peer %s\n", 1812 "from peer %s\n",
1773 GCP_2s (peer)); 1813 GCP_2s (peer));
1774 if ( (NULL == peer) || 1814 if ( (NULL == peer) ||
1775 (NULL == peer->connections) ) 1815 (NULL == peer->connections) )
1776 return; 1816 return;
1777 GNUNET_assert (GNUNET_YES == 1817 GNUNET_assert (GNUNET_YES ==
1778 GNUNET_CONTAINER_multihashmap_remove (peer->connections, 1818 GNUNET_CONTAINER_multihashmap_remove (peer->connections,
1779 GCC_get_h (c), 1819 GCC_get_h (c),
1780 c)); 1820 c));
1781 LOG (GNUNET_ERROR_TYPE_DEBUG, 1821 LOG (GNUNET_ERROR_TYPE_DEBUG,
1782 "Peer %s remains with %u connections.\n", 1822 "Peer %s remains with %u connections.\n",
1783 GCP_2s (peer), 1823 GCP_2s (peer),
1784 GNUNET_CONTAINER_multihashmap_size (peer->connections)); 1824 GNUNET_CONTAINER_multihashmap_size (peer->connections));
1785} 1825}
1786 1826
1787 1827
@@ -1794,35 +1834,35 @@ GCP_remove_connection (struct CadetPeer *peer,
1794void 1834void
1795GCP_start_search (struct CadetPeer *peer) 1835GCP_start_search (struct CadetPeer *peer)
1796{ 1836{
1797 const struct GNUNET_PeerIdentity *id; 1837 const struct GNUNET_PeerIdentity *id;
1798 struct CadetTunnel *t = peer->tunnel; 1838 struct CadetTunnel *t = peer->tunnel;
1799 1839
1800 GCC_check_connections (); 1840 GCC_check_connections ();
1801 if (NULL != peer->search_h) 1841 if (NULL != peer->search_h)
1802 { 1842 {
1803 GNUNET_break (0); 1843 GNUNET_break (0);
1804 return; 1844 return;
1805 } 1845 }
1806 1846
1807 if (NULL != peer->search_delayed) 1847 if (NULL != peer->search_delayed)
1808 GCP_stop_search (peer); 1848 GCP_stop_search (peer);
1809 1849
1810 id = GNUNET_PEER_resolve2 (peer->id); 1850 id = GNUNET_PEER_resolve2 (peer->id);
1811 peer->search_h = GCD_search (id, &search_handler, peer); 1851 peer->search_h = GCD_search (id, &search_handler, peer);
1812 1852
1813 if (NULL == t) 1853 if (NULL == t)
1814 { 1854 {
1815 /* Why would we search for a peer with no tunnel towards it? */ 1855 /* Why would we search for a peer with no tunnel towards it? */
1816 GNUNET_break (0); 1856 GNUNET_break (0);
1817 return; 1857 return;
1818 } 1858 }
1819 1859
1820 if (CADET_TUNNEL_NEW == GCT_get_cstate (t) 1860 if (CADET_TUNNEL_NEW == GCT_get_cstate (t)
1821 || 0 == GCT_count_any_connections (t)) 1861 || 0 == GCT_count_any_connections (t))
1822 { 1862 {
1823 GCT_change_cstate (t, CADET_TUNNEL_SEARCHING); 1863 GCT_change_cstate (t, CADET_TUNNEL_SEARCHING);
1824 } 1864 }
1825 GCC_check_connections (); 1865 GCC_check_connections ();
1826} 1866}
1827 1867
1828 1868
@@ -1835,18 +1875,18 @@ GCP_start_search (struct CadetPeer *peer)
1835void 1875void
1836GCP_stop_search (struct CadetPeer *peer) 1876GCP_stop_search (struct CadetPeer *peer)
1837{ 1877{
1838 GCC_check_connections (); 1878 GCC_check_connections ();
1839 if (NULL != peer->search_h) 1879 if (NULL != peer->search_h)
1840 { 1880 {
1841 GCD_search_stop (peer->search_h); 1881 GCD_search_stop (peer->search_h);
1842 peer->search_h = NULL; 1882 peer->search_h = NULL;
1843 } 1883 }
1844 if (NULL != peer->search_delayed) 1884 if (NULL != peer->search_delayed)
1845 { 1885 {
1846 GNUNET_SCHEDULER_cancel (peer->search_delayed); 1886 GNUNET_SCHEDULER_cancel (peer->search_delayed);
1847 peer->search_delayed = NULL; 1887 peer->search_delayed = NULL;
1848 } 1888 }
1849 GCC_check_connections (); 1889 GCC_check_connections ();
1850} 1890}
1851 1891
1852 1892
@@ -1860,7 +1900,7 @@ GCP_stop_search (struct CadetPeer *peer)
1860const struct GNUNET_PeerIdentity * 1900const struct GNUNET_PeerIdentity *
1861GCP_get_id (const struct CadetPeer *peer) 1901GCP_get_id (const struct CadetPeer *peer)
1862{ 1902{
1863 return GNUNET_PEER_resolve2 (peer->id); 1903 return GNUNET_PEER_resolve2 (peer->id);
1864} 1904}
1865 1905
1866 1906
@@ -1874,7 +1914,7 @@ GCP_get_id (const struct CadetPeer *peer)
1874GNUNET_PEER_Id 1914GNUNET_PEER_Id
1875GCP_get_short_id (const struct CadetPeer *peer) 1915GCP_get_short_id (const struct CadetPeer *peer)
1876{ 1916{
1877 return peer->id; 1917 return peer->id;
1878} 1918}
1879 1919
1880 1920
@@ -1889,11 +1929,11 @@ GCP_get_short_id (const struct CadetPeer *peer)
1889void 1929void
1890GCP_set_tunnel (struct CadetPeer *peer, struct CadetTunnel *t) 1930GCP_set_tunnel (struct CadetPeer *peer, struct CadetTunnel *t)
1891{ 1931{
1892 peer->tunnel = t; 1932 peer->tunnel = t;
1893 if (NULL == t && GNUNET_YES == is_searching (peer)) 1933 if (NULL == t && GNUNET_YES == is_searching (peer))
1894 { 1934 {
1895 GCP_stop_search (peer); 1935 GCP_stop_search (peer);
1896 } 1936 }
1897} 1937}
1898 1938
1899 1939
@@ -1907,9 +1947,9 @@ GCP_set_tunnel (struct CadetPeer *peer, struct CadetTunnel *t)
1907struct CadetTunnel * 1947struct CadetTunnel *
1908GCP_get_tunnel (const struct CadetPeer *peer) 1948GCP_get_tunnel (const struct CadetPeer *peer)
1909{ 1949{
1910 if (NULL == peer) 1950 if (NULL == peer)
1911 return NULL; 1951 return NULL;
1912 return peer->tunnel; 1952 return peer->tunnel;
1913} 1953}
1914 1954
1915 1955
@@ -1921,29 +1961,29 @@ GCP_get_tunnel (const struct CadetPeer *peer)
1921 */ 1961 */
1922void 1962void
1923GCP_set_hello (struct CadetPeer *peer, 1963GCP_set_hello (struct CadetPeer *peer,
1924 const struct GNUNET_HELLO_Message *hello) 1964 const struct GNUNET_HELLO_Message *hello)
1925{ 1965{
1926 struct GNUNET_HELLO_Message *old; 1966 struct GNUNET_HELLO_Message *old;
1927 size_t size; 1967 size_t size;
1928 1968
1929 GCC_check_connections (); 1969 GCC_check_connections ();
1930 LOG (GNUNET_ERROR_TYPE_DEBUG, "set hello for %s\n", GCP_2s (peer)); 1970 LOG (GNUNET_ERROR_TYPE_DEBUG, "set hello for %s\n", GCP_2s (peer));
1931 if (NULL == hello) 1971 if (NULL == hello)
1932 return; 1972 return;
1933 1973
1934 old = GCP_get_hello (peer); 1974 old = GCP_get_hello (peer);
1935 if (NULL == old) 1975 if (NULL == old)
1936 { 1976 {
1937 size = GNUNET_HELLO_size (hello); 1977 size = GNUNET_HELLO_size (hello);
1938 peer->hello = GNUNET_malloc (size); 1978 peer->hello = GNUNET_malloc (size);
1939 GNUNET_memcpy (peer->hello, hello, size); 1979 GNUNET_memcpy (peer->hello, hello, size);
1940 } 1980 }
1941 else 1981 else
1942 { 1982 {
1943 peer->hello = GNUNET_HELLO_merge (old, hello); 1983 peer->hello = GNUNET_HELLO_merge (old, hello);
1944 GNUNET_free (old); 1984 GNUNET_free (old);
1945 } 1985 }
1946 GCC_check_connections (); 1986 GCC_check_connections ();
1947} 1987}
1948 1988
1949 1989
@@ -1957,22 +1997,22 @@ GCP_set_hello (struct CadetPeer *peer,
1957struct GNUNET_HELLO_Message * 1997struct GNUNET_HELLO_Message *
1958GCP_get_hello (struct CadetPeer *peer) 1998GCP_get_hello (struct CadetPeer *peer)
1959{ 1999{
1960 struct GNUNET_TIME_Absolute expiration; 2000 struct GNUNET_TIME_Absolute expiration;
1961 struct GNUNET_TIME_Relative remaining; 2001 struct GNUNET_TIME_Relative remaining;
1962 2002
1963 if (NULL == peer->hello) 2003 if (NULL == peer->hello)
1964 return NULL; 2004 return NULL;
1965 2005
1966 expiration = GNUNET_HELLO_get_last_expiration (peer->hello); 2006 expiration = GNUNET_HELLO_get_last_expiration (peer->hello);
1967 remaining = GNUNET_TIME_absolute_get_remaining (expiration); 2007 remaining = GNUNET_TIME_absolute_get_remaining (expiration);
1968 if (0 == remaining.rel_value_us) 2008 if (0 == remaining.rel_value_us)
1969 { 2009 {
1970 LOG (GNUNET_ERROR_TYPE_DEBUG, " get - hello expired on %s\n", 2010 LOG (GNUNET_ERROR_TYPE_DEBUG, " get - hello expired on %s\n",
1971 GNUNET_STRINGS_absolute_time_to_string (expiration)); 2011 GNUNET_STRINGS_absolute_time_to_string (expiration));
1972 GNUNET_free (peer->hello); 2012 GNUNET_free (peer->hello);
1973 peer->hello = NULL; 2013 peer->hello = NULL;
1974 } 2014 }
1975 return peer->hello; 2015 return peer->hello;
1976} 2016}
1977 2017
1978 2018
@@ -1984,37 +2024,37 @@ GCP_get_hello (struct CadetPeer *peer)
1984void 2024void
1985GCP_try_connect (struct CadetPeer *peer) 2025GCP_try_connect (struct CadetPeer *peer)
1986{ 2026{
1987 struct GNUNET_HELLO_Message *hello; 2027 struct GNUNET_HELLO_Message *hello;
1988 struct GNUNET_MessageHeader *mh; 2028 struct GNUNET_MessageHeader *mh;
1989 2029
1990 if (GNUNET_YES != 2030 if (GNUNET_YES !=
1991 GNUNET_CONFIGURATION_get_value_yesno (cfg, 2031 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1992 "CADET", 2032 "CADET",
1993 "DISABLE_TRY_CONNECT")) 2033 "DISABLE_TRY_CONNECT"))
1994 return; 2034 return;
1995 GCC_check_connections (); 2035 GCC_check_connections ();
1996 if (GNUNET_YES == GCP_is_neighbor (peer)) 2036 if (GNUNET_YES == GCP_is_neighbor (peer))
1997 return; 2037 return;
1998 hello = GCP_get_hello (peer); 2038 hello = GCP_get_hello (peer);
1999 if (NULL == hello) 2039 if (NULL == hello)
2000 return; 2040 return;
2001 2041
2002 mh = GNUNET_HELLO_get_header (hello); 2042 mh = GNUNET_HELLO_get_header (hello);
2003 if (NULL != peer->hello_offer) 2043 if (NULL != peer->hello_offer)
2004 { 2044 {
2005 GNUNET_TRANSPORT_offer_hello_cancel (peer->hello_offer); 2045 GNUNET_TRANSPORT_offer_hello_cancel (peer->hello_offer);
2006 peer->hello_offer = NULL; 2046 peer->hello_offer = NULL;
2007 } 2047 }
2008 peer->hello_offer = GNUNET_TRANSPORT_offer_hello (cfg, 2048 peer->hello_offer = GNUNET_TRANSPORT_offer_hello (cfg,
2009 mh, 2049 mh,
2010 &hello_offer_done, 2050 &hello_offer_done,
2011 peer); 2051 peer);
2012 if (NULL == peer->connectivity_suggestion) 2052 if (NULL == peer->connectivity_suggestion)
2013 peer->connectivity_suggestion 2053 peer->connectivity_suggestion
2014 = GNUNET_ATS_connectivity_suggest (ats_ch, 2054 = GNUNET_ATS_connectivity_suggest (ats_ch,
2015 GNUNET_PEER_resolve2 (peer->id), 2055 GCP_get_id (peer),
2016 1 /* strength */); 2056 1); /* strength */
2017 GCC_check_connections (); 2057 GCC_check_connections ();
2018} 2058}
2019 2059
2020 2060
@@ -2031,42 +2071,42 @@ GCP_notify_broken_link (struct CadetPeer *peer,
2031 const struct GNUNET_PeerIdentity *peer1, 2071 const struct GNUNET_PeerIdentity *peer1,
2032 const struct GNUNET_PeerIdentity *peer2) 2072 const struct GNUNET_PeerIdentity *peer2)
2033{ 2073{
2034 struct CadetPeerPath *iter; 2074 struct CadetPeerPath *iter;
2035 struct CadetPeerPath *next; 2075 struct CadetPeerPath *next;
2036 unsigned int i; 2076 unsigned int i;
2037 GNUNET_PEER_Id p1; 2077 GNUNET_PEER_Id p1;
2038 GNUNET_PEER_Id p2; 2078 GNUNET_PEER_Id p2;
2039 2079
2040 GCC_check_connections (); 2080 GCC_check_connections ();
2041 p1 = GNUNET_PEER_search (peer1); 2081 p1 = GNUNET_PEER_search (peer1);
2042 p2 = GNUNET_PEER_search (peer2); 2082 p2 = GNUNET_PEER_search (peer2);
2043
2044 LOG (GNUNET_ERROR_TYPE_DEBUG, "Link %u-%u broken\n", p1, p2);
2045 if (0 == p1 || 0 == p2)
2046 {
2047 /* We don't even know them */
2048 return;
2049 }
2050 2083
2051 for (iter = peer->path_head; NULL != iter; iter = next) 2084 LOG (GNUNET_ERROR_TYPE_DEBUG, "Link %u-%u broken\n", p1, p2);
2052 { 2085 if (0 == p1 || 0 == p2)
2053 next = iter->next;
2054 for (i = 0; i < iter->length - 1; i++)
2055 { 2086 {
2056 if ((iter->peers[i] == p1 && iter->peers[i + 1] == p2) 2087 /* We don't even know them */
2057 || (iter->peers[i] == p2 && iter->peers[i + 1] == p1)) 2088 return;
2058 { 2089 }
2059 char *s;
2060
2061 s = path_2s (iter);
2062 LOG (GNUNET_ERROR_TYPE_DEBUG, " - invalidating %s\n", s);
2063 GNUNET_free (s);
2064 2090
2065 path_invalidate (iter); 2091 for (iter = peer->path_head; NULL != iter; iter = next)
2066 } 2092 {
2093 next = iter->next;
2094 for (i = 0; i < iter->length - 1; i++)
2095 {
2096 if ((iter->peers[i] == p1 && iter->peers[i + 1] == p2)
2097 || (iter->peers[i] == p2 && iter->peers[i + 1] == p1))
2098 {
2099 char *s;
2100
2101 s = path_2s (iter);
2102 LOG (GNUNET_ERROR_TYPE_DEBUG, " - invalidating %s\n", s);
2103 GNUNET_free (s);
2104
2105 path_invalidate (iter);
2106 }
2107 }
2067 } 2108 }
2068 } 2109 GCC_check_connections ();
2069 GCC_check_connections ();
2070} 2110}
2071 2111
2072 2112
@@ -2080,13 +2120,13 @@ GCP_notify_broken_link (struct CadetPeer *peer,
2080unsigned int 2120unsigned int
2081GCP_count_paths (const struct CadetPeer *peer) 2121GCP_count_paths (const struct CadetPeer *peer)
2082{ 2122{
2083 struct CadetPeerPath *iter; 2123 struct CadetPeerPath *iter;
2084 unsigned int i; 2124 unsigned int i;
2085 2125
2086 for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next) 2126 for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next)
2087 i++; 2127 i++;
2088 2128
2089 return i; 2129 return i;
2090} 2130}
2091 2131
2092 2132
@@ -2104,17 +2144,17 @@ GCP_iterate_paths (struct CadetPeer *peer,
2104 GCP_path_iterator callback, 2144 GCP_path_iterator callback,
2105 void *cls) 2145 void *cls)
2106{ 2146{
2107 struct CadetPeerPath *iter; 2147 struct CadetPeerPath *iter;
2108 unsigned int i; 2148 unsigned int i;
2109 2149
2110 for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next) 2150 for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next)
2111 { 2151 {
2112 i++; 2152 i++;
2113 if (GNUNET_YES != callback (cls, peer, iter)) 2153 if (GNUNET_YES != callback (cls, peer, iter))
2114 break; 2154 break;
2115 } 2155 }
2116 2156
2117 return i; 2157 return i;
2118} 2158}
2119 2159
2120 2160
@@ -2128,11 +2168,11 @@ void
2128GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, 2168GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
2129 void *cls) 2169 void *cls)
2130{ 2170{
2131 GCC_check_connections (); 2171 GCC_check_connections ();
2132 GNUNET_CONTAINER_multipeermap_iterate (peers, 2172 GNUNET_CONTAINER_multipeermap_iterate (peers,
2133 iter, 2173 iter,
2134 cls); 2174 cls);
2135 GCC_check_connections (); 2175 GCC_check_connections ();
2136} 2176}
2137 2177
2138 2178
@@ -2146,9 +2186,9 @@ GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
2146const char * 2186const char *
2147GCP_2s (const struct CadetPeer *peer) 2187GCP_2s (const struct CadetPeer *peer)
2148{ 2188{
2149 if (NULL == peer) 2189 if (NULL == peer)
2150 return "(NULL)"; 2190 return "(NULL)";
2151 return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id)); 2191 return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id));
2152} 2192}
2153 2193
2154 2194