aboutsummaryrefslogtreecommitdiff
path: root/src/rps/gnunet-service-rps.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rps/gnunet-service-rps.c')
-rw-r--r--src/rps/gnunet-service-rps.c676
1 files changed, 343 insertions, 333 deletions
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 84fb33be2..d601ac7d4 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -68,6 +68,7 @@ static struct GNUNET_STATISTICS_Handle *stats;
68 */ 68 */
69static struct GNUNET_PeerIdentity own_identity; 69static struct GNUNET_PeerIdentity own_identity;
70 70
71static int in_shutdown = GNUNET_NO;
71 72
72/** 73/**
73 * @brief Port used for cadet. 74 * @brief Port used for cadet.
@@ -97,11 +98,6 @@ static struct GNUNET_HashCode port;
97#define unset_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) &= ~(mask)) 98#define unset_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) &= ~(mask))
98 99
99/** 100/**
100 * Set a channel flag of given channel context.
101 */
102#define set_channel_flag(channel_flags, mask) ((*channel_flags) |= (mask))
103
104/**
105 * Get channel flag of given channel context. 101 * Get channel flag of given channel context.
106 */ 102 */
107#define check_channel_flag_set(channel_flags, mask)\ 103#define check_channel_flag_set(channel_flags, mask)\
@@ -164,6 +160,11 @@ struct PendingMessage
164}; 160};
165 161
166/** 162/**
163 * @brief Context for a channel
164 */
165struct ChannelCtx;
166
167/**
167 * Struct used to keep track of other peer's status 168 * Struct used to keep track of other peer's status
168 * 169 *
169 * This is stored in a multipeermap. 170 * This is stored in a multipeermap.
@@ -181,22 +182,12 @@ struct PeerContext
181 /** 182 /**
182 * Channel open to client. 183 * Channel open to client.
183 */ 184 */
184 struct GNUNET_CADET_Channel *send_channel; 185 struct ChannelCtx *send_channel_ctx;
185
186 /**
187 * Flags to the sending channel
188 */
189 uint32_t *send_channel_flags;
190 186
191 /** 187 /**
192 * Channel open from client. 188 * Channel open from client.
193 */ 189 */
194 struct GNUNET_CADET_Channel *recv_channel; // unneeded? 190 struct ChannelCtx *recv_channel_ctx;
195
196 /**
197 * Flags to the receiving channel
198 */
199 uint32_t *recv_channel_flags;
200 191
201 /** 192 /**
202 * Array of pending operations on this peer. 193 * Array of pending operations on this peer.
@@ -242,6 +233,11 @@ struct PeerContext
242 struct PendingMessage *pending_messages_tail; 233 struct PendingMessage *pending_messages_tail;
243 234
244 /** 235 /**
236 * @brief Task to destroy this context.
237 */
238 struct GNUNET_SCHEDULER_Task *destruction_task;
239
240 /**
245 * This is pobably followed by 'statistical' data (when we first saw 241 * This is pobably followed by 'statistical' data (when we first saw
246 * it, how did we get its ID, how many pushes (in a timeinterval), 242 * it, how did we get its ID, how many pushes (in a timeinterval),
247 * ...) 243 * ...)
@@ -265,6 +261,33 @@ struct PeersIteratorCls
265}; 261};
266 262
267/** 263/**
264 * @brief Context for a channel
265 */
266struct ChannelCtx
267{
268 /**
269 * @brief Meant to be used in a DLL
270 */
271 struct ChannelCtx *next;
272 struct ChannelCtx *prev;
273
274 /**
275 * @brief The channel itself
276 */
277 struct GNUNET_CADET_Channel *channel;
278
279 /**
280 * @brief The peer context associated with the channel
281 */
282 struct PeerContext *peer_ctx;
283
284 /**
285 * @brief Scheduled task that will destroy this context
286 */
287 struct GNUNET_SCHEDULER_Task *destruction_task;
288};
289
290/**
268 * @brief Hashmap of valid peers. 291 * @brief Hashmap of valid peers.
269 */ 292 */
270static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers; 293static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers;
@@ -332,8 +355,6 @@ create_peer_ctx (const struct GNUNET_PeerIdentity *peer)
332 355
333 ctx = GNUNET_new (struct PeerContext); 356 ctx = GNUNET_new (struct PeerContext);
334 ctx->peer_id = *peer; 357 ctx->peer_id = *peer;
335 ctx->send_channel_flags = GNUNET_new (uint32_t);
336 ctx->recv_channel_flags = GNUNET_new (uint32_t);
337 ret = GNUNET_CONTAINER_multipeermap_put (peer_map, peer, ctx, 358 ret = GNUNET_CONTAINER_multipeermap_put (peer_map, peer, ctx,
338 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 359 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
339 GNUNET_assert (GNUNET_OK == ret); 360 GNUNET_assert (GNUNET_OK == ret);
@@ -387,8 +408,8 @@ Peers_check_connected (const struct GNUNET_PeerIdentity *peer)
387 /* Get the context */ 408 /* Get the context */
388 peer_ctx = get_peer_ctx (peer); 409 peer_ctx = get_peer_ctx (peer);
389 /* If we have no channel to this peer we don't know whether it's online */ 410 /* If we have no channel to this peer we don't know whether it's online */
390 if ( (NULL == peer_ctx->send_channel) && 411 if ( (NULL == peer_ctx->send_channel_ctx) &&
391 (NULL == peer_ctx->recv_channel) ) 412 (NULL == peer_ctx->recv_channel_ctx) )
392 { 413 {
393 Peers_unset_peer_flag (peer, Peers_ONLINE); 414 Peers_unset_peer_flag (peer, Peers_ONLINE);
394 return GNUNET_NO; 415 return GNUNET_NO;
@@ -575,6 +596,24 @@ handle_peer_pull_reply (void *cls,
575 596
576/* End declaration of handlers */ 597/* End declaration of handlers */
577 598
599/**
600 * @brief Allocate memory for a new channel context and insert it into DLL
601 *
602 * @param peer_ctx context of the according peer
603 *
604 * @return The channel context
605 */
606static struct ChannelCtx *
607add_channel_ctx (struct PeerContext *peer_ctx);
608
609/**
610 * @brief Remove the channel context from the DLL and free the memory.
611 *
612 * @param channel_ctx The channel context.
613 */
614static void
615remove_channel_ctx (struct ChannelCtx *channel_ctx);
616
578 617
579/** 618/**
580 * @brief Get the channel of a peer. If not existing, create. 619 * @brief Get the channel of a peer. If not existing, create.
@@ -610,16 +649,17 @@ get_channel (const struct GNUNET_PeerIdentity *peer)
610 649
611 650
612 peer_ctx = get_peer_ctx (peer); 651 peer_ctx = get_peer_ctx (peer);
613 if (NULL == peer_ctx->send_channel) 652 if (NULL == peer_ctx->send_channel_ctx)
614 { 653 {
615 LOG (GNUNET_ERROR_TYPE_DEBUG, 654 LOG (GNUNET_ERROR_TYPE_DEBUG,
616 "Trying to establish channel to peer %s\n", 655 "Trying to establish channel to peer %s\n",
617 GNUNET_i2s (peer)); 656 GNUNET_i2s (peer));
618 ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity); 657 ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity);
619 *ctx_peer = *peer; 658 *ctx_peer = *peer;
620 peer_ctx->send_channel = 659 peer_ctx->send_channel_ctx = add_channel_ctx (peer_ctx);
660 peer_ctx->send_channel_ctx->channel =
621 GNUNET_CADET_channel_create (cadet_handle, 661 GNUNET_CADET_channel_create (cadet_handle,
622 (struct GNUNET_PeerIdentity *) ctx_peer, /* context */ 662 peer_ctx->send_channel_ctx, /* context */
623 peer, 663 peer,
624 &port, 664 &port,
625 GNUNET_CADET_OPTION_RELIABLE, 665 GNUNET_CADET_OPTION_RELIABLE,
@@ -627,8 +667,9 @@ get_channel (const struct GNUNET_PeerIdentity *peer)
627 cleanup_destroyed_channel, /* Disconnect handler */ 667 cleanup_destroyed_channel, /* Disconnect handler */
628 cadet_handlers); 668 cadet_handlers);
629 } 669 }
630 GNUNET_assert (NULL != peer_ctx->send_channel); 670 GNUNET_assert (NULL != peer_ctx->send_channel_ctx);
631 return peer_ctx->send_channel; 671 GNUNET_assert (NULL != peer_ctx->send_channel_ctx->channel);
672 return peer_ctx->send_channel_ctx->channel;
632} 673}
633 674
634 675
@@ -1045,12 +1086,10 @@ restore_valid_peers ()
1045 */ 1086 */
1046void 1087void
1047Peers_initialise (char* fn_valid_peers, 1088Peers_initialise (char* fn_valid_peers,
1048 struct GNUNET_CADET_Handle *cadet_h, 1089 struct GNUNET_CADET_Handle *cadet_h)
1049 const struct GNUNET_PeerIdentity *own_id)
1050{ 1090{
1051 filename_valid_peers = GNUNET_strdup (fn_valid_peers); 1091 filename_valid_peers = GNUNET_strdup (fn_valid_peers);
1052 cadet_handle = cadet_h; 1092 cadet_handle = cadet_h;
1053 own_identity = *own_id;
1054 peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); 1093 peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO);
1055 valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); 1094 valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO);
1056 restore_valid_peers (); 1095 restore_valid_peers ();
@@ -1136,14 +1175,12 @@ Peers_get_valid_peers (PeersIterator iterator,
1136 * @param peer the new #GNUNET_PeerIdentity 1175 * @param peer the new #GNUNET_PeerIdentity
1137 * 1176 *
1138 * @return #GNUNET_YES if peer was inserted 1177 * @return #GNUNET_YES if peer was inserted
1139 * #GNUNET_NO otherwise (if peer was already known or 1178 * #GNUNET_NO otherwise
1140 * peer was #own_identity)
1141 */ 1179 */
1142int 1180int
1143Peers_insert_peer (const struct GNUNET_PeerIdentity *peer) 1181Peers_insert_peer (const struct GNUNET_PeerIdentity *peer)
1144{ 1182{
1145 if ( (GNUNET_YES == Peers_check_peer_known (peer)) || 1183 if (GNUNET_YES == Peers_check_peer_known (peer))
1146 (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity)) )
1147 { 1184 {
1148 return GNUNET_NO; /* We already know this peer - nothing to do */ 1185 return GNUNET_NO; /* We already know this peer - nothing to do */
1149 } 1186 }
@@ -1161,8 +1198,7 @@ Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFl
1161 * 1198 *
1162 * @param peer the peer whose liveliness is to be checked 1199 * @param peer the peer whose liveliness is to be checked
1163 * @return #GNUNET_YES if peer had to be inserted 1200 * @return #GNUNET_YES if peer had to be inserted
1164 * #GNUNET_NO otherwise (if peer was already known or 1201 * #GNUNET_NO otherwise
1165 * peer was #own_identity)
1166 */ 1202 */
1167int 1203int
1168Peers_issue_peer_liveliness_check (const struct GNUNET_PeerIdentity *peer) 1204Peers_issue_peer_liveliness_check (const struct GNUNET_PeerIdentity *peer)
@@ -1170,13 +1206,10 @@ Peers_issue_peer_liveliness_check (const struct GNUNET_PeerIdentity *peer)
1170 struct PeerContext *peer_ctx; 1206 struct PeerContext *peer_ctx;
1171 int ret; 1207 int ret;
1172 1208
1173 if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity))
1174 {
1175 return GNUNET_NO;
1176 }
1177 ret = Peers_insert_peer (peer); 1209 ret = Peers_insert_peer (peer);
1178 peer_ctx = get_peer_ctx (peer); 1210 peer_ctx = get_peer_ctx (peer);
1179 if (GNUNET_NO == Peers_check_peer_flag (peer, Peers_ONLINE)) 1211 if ( (GNUNET_NO == Peers_check_peer_flag (peer, Peers_ONLINE)) &&
1212 (NULL == peer_ctx->liveliness_check_pending) )
1180 { 1213 {
1181 check_peer_live (peer_ctx); 1214 check_peer_live (peer_ctx);
1182 } 1215 }
@@ -1208,7 +1241,7 @@ Peers_check_removable (const struct GNUNET_PeerIdentity *peer)
1208 } 1241 }
1209 1242
1210 peer_ctx = get_peer_ctx (peer); 1243 peer_ctx = get_peer_ctx (peer);
1211 if ( (NULL != peer_ctx->recv_channel) || 1244 if ( (NULL != peer_ctx->recv_channel_ctx) ||
1212 (NULL != peer_ctx->pending_messages_head) || 1245 (NULL != peer_ctx->pending_messages_head) ||
1213 (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) ) 1246 (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) )
1214 { 1247 {
@@ -1225,6 +1258,65 @@ int
1225Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags); 1258Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags);
1226 1259
1227/** 1260/**
1261 * @brief Callback for the scheduler to destroy the knowledge of a peer.
1262 *
1263 * @param cls Context of the peer
1264 */
1265static void
1266destroy_peer (void *cls)
1267{
1268 struct PeerContext *peer_ctx = cls;
1269
1270 GNUNET_assert (NULL != peer_ctx);
1271 peer_ctx->destruction_task = NULL;
1272 Peers_remove_peer (&peer_ctx->peer_id);
1273}
1274
1275static void
1276destroy_channel (void *cls);
1277
1278
1279/**
1280 * @brief Schedule the destruction of the given channel.
1281 *
1282 * Do so only if it was not already scheduled and not during shutdown.
1283 *
1284 * @param channel_ctx The context of the channel to destroy.
1285 */
1286static void
1287schedule_channel_destruction (struct ChannelCtx *channel_ctx)
1288{
1289 GNUNET_assert (NULL != channel_ctx);
1290 if (NULL != channel_ctx->destruction_task &&
1291 GNUNET_NO == in_shutdown)
1292 {
1293 channel_ctx->destruction_task =
1294 GNUNET_SCHEDULER_add_now (destroy_channel, channel_ctx);
1295 }
1296}
1297
1298
1299/**
1300 * @brief Schedule the destruction of the given peer.
1301 *
1302 * Do so only if it was not already scheduled and not during shutdown.
1303 *
1304 * @param peer_ctx The context of the peer to destroy.
1305 */
1306static void
1307schedule_peer_destruction (struct PeerContext *peer_ctx)
1308{
1309 GNUNET_assert (NULL != peer_ctx);
1310 if (NULL != peer_ctx->destruction_task &&
1311 GNUNET_NO == in_shutdown)
1312 {
1313 peer_ctx->destruction_task =
1314 GNUNET_SCHEDULER_add_now (destroy_peer, peer_ctx);
1315 }
1316}
1317
1318
1319/**
1228 * @brief Remove peer 1320 * @brief Remove peer
1229 * 1321 *
1230 * @param peer the peer to clean 1322 * @param peer the peer to clean
@@ -1235,7 +1327,8 @@ int
1235Peers_remove_peer (const struct GNUNET_PeerIdentity *peer) 1327Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1236{ 1328{
1237 struct PeerContext *peer_ctx; 1329 struct PeerContext *peer_ctx;
1238 uint32_t *channel_flag; 1330
1331 GNUNET_assert (NULL != peer_map);
1239 1332
1240 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer)) 1333 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer))
1241 { 1334 {
@@ -1249,7 +1342,12 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1249 GNUNET_i2s (&peer_ctx->peer_id)); 1342 GNUNET_i2s (&peer_ctx->peer_id));
1250 Peers_unset_peer_flag (peer, Peers_ONLINE); 1343 Peers_unset_peer_flag (peer, Peers_ONLINE);
1251 1344
1345 /* Clear list of pending operations */
1346 // TODO this probably leaks memory
1347 // ('only' the cls to the function. Not sure what to do with it)
1252 GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0); 1348 GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0);
1349
1350 /* Remove all pending messages */
1253 while (NULL != peer_ctx->pending_messages_head) 1351 while (NULL != peer_ctx->pending_messages_head)
1254 { 1352 {
1255 LOG (GNUNET_ERROR_TYPE_DEBUG, 1353 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1261,10 +1359,12 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1261 peer_ctx->liveliness_check_pending, 1359 peer_ctx->liveliness_check_pending,
1262 sizeof (struct PendingMessage))) ) 1360 sizeof (struct PendingMessage))) )
1263 { 1361 {
1362 // TODO this may leak memory
1264 peer_ctx->liveliness_check_pending = NULL; 1363 peer_ctx->liveliness_check_pending = NULL;
1265 } 1364 }
1266 remove_pending_message (peer_ctx->pending_messages_head, GNUNET_YES); 1365 remove_pending_message (peer_ctx->pending_messages_head, GNUNET_YES);
1267 } 1366 }
1367
1268 /* If we are still waiting for notification whether this peer is live 1368 /* If we are still waiting for notification whether this peer is live
1269 * cancel the according task */ 1369 * cancel the according task */
1270 if (NULL != peer_ctx->liveliness_check_pending) 1370 if (NULL != peer_ctx->liveliness_check_pending)
@@ -1277,28 +1377,40 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1277 remove_pending_message (peer_ctx->liveliness_check_pending, GNUNET_YES); 1377 remove_pending_message (peer_ctx->liveliness_check_pending, GNUNET_YES);
1278 peer_ctx->liveliness_check_pending = NULL; 1378 peer_ctx->liveliness_check_pending = NULL;
1279 } 1379 }
1280 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING); 1380
1281 if (NULL != peer_ctx->send_channel && 1381
1282 GNUNET_YES != Peers_check_channel_flag (channel_flag, Peers_CHANNEL_DESTROING)) 1382 /* Do we still have to wait for destruction of channels
1383 * or issue the destruction? */
1384 if (NULL != peer_ctx->send_channel_ctx &&
1385 NULL != peer_ctx->send_channel_ctx->destruction_task
1386 )
1283 { 1387 {
1284 LOG (GNUNET_ERROR_TYPE_DEBUG, 1388 schedule_peer_destruction (peer_ctx);
1285 "Destroying send channel\n"); 1389 return GNUNET_NO;
1286 GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
1287 peer_ctx->send_channel = NULL;
1288 peer_ctx->mq = NULL;
1289 } 1390 }
1290 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_RECEIVING); 1391 if (NULL != peer_ctx->recv_channel_ctx &&
1291 if (NULL != peer_ctx->recv_channel && 1392 NULL != peer_ctx->recv_channel_ctx->destruction_task)
1292 GNUNET_YES != Peers_check_channel_flag (channel_flag, Peers_CHANNEL_DESTROING))
1293 { 1393 {
1294 LOG (GNUNET_ERROR_TYPE_DEBUG, 1394 schedule_peer_destruction (peer_ctx);
1295 "Destroying recv channel\n"); 1395 return GNUNET_NO;
1296 GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); 1396 }
1297 peer_ctx->recv_channel = NULL; 1397 if (NULL != peer_ctx->recv_channel_ctx)
1398 {
1399 schedule_channel_destruction (peer_ctx->recv_channel_ctx);
1400 schedule_peer_destruction (peer_ctx);
1401 return GNUNET_NO;
1402 }
1403 if (NULL != peer_ctx->send_channel_ctx)
1404 {
1405 schedule_channel_destruction (peer_ctx->send_channel_ctx);
1406 schedule_peer_destruction (peer_ctx);
1407 return GNUNET_NO;
1298 } 1408 }
1299 1409
1300 GNUNET_free (peer_ctx->send_channel_flags); 1410 if (NULL != peer_ctx->destruction_task)
1301 GNUNET_free (peer_ctx->recv_channel_flags); 1411 {
1412 GNUNET_SCHEDULER_cancel (peer_ctx->destruction_task);
1413 }
1302 1414
1303 if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, &peer_ctx->peer_id)) 1415 if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, &peer_ctx->peer_id))
1304 { 1416 {
@@ -1308,7 +1420,6 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1308 return GNUNET_YES; 1420 return GNUNET_YES;
1309} 1421}
1310 1422
1311
1312/** 1423/**
1313 * @brief set flags on a given peer. 1424 * @brief set flags on a given peer.
1314 * 1425 *
@@ -1364,77 +1475,6 @@ Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFl
1364 return check_peer_flag_set (peer_ctx, flags); 1475 return check_peer_flag_set (peer_ctx, flags);
1365} 1476}
1366 1477
1367
1368/**
1369 * @brief set flags on a given channel.
1370 *
1371 * @param channel the channel to set flags on
1372 * @param flags the flags
1373 */
1374void
1375Peers_set_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags)
1376{
1377 set_channel_flag (channel_flags, flags);
1378}
1379
1380
1381/**
1382 * @brief unset flags on a given channel.
1383 *
1384 * @param channel the channel to unset flags on
1385 * @param flags the flags
1386 */
1387void
1388Peers_unset_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags)
1389{
1390 unset_channel_flag (channel_flags, flags);
1391}
1392
1393
1394/**
1395 * @brief Check whether flags on a channel are set.
1396 *
1397 * @param channel the channel to check the flag of
1398 * @param flags the flags to check
1399 *
1400 * @return #GNUNET_YES if all given flags are set
1401 * #GNUNET_NO otherwise
1402 */
1403int
1404Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags)
1405{
1406 return check_channel_flag_set (channel_flags, flags);
1407}
1408
1409/**
1410 * @brief Get the flags for the channel in @a role for @a peer.
1411 *
1412 * @param peer Peer to get the channel flags for.
1413 * @param role Role of channel to get flags for
1414 *
1415 * @return The flags.
1416 */
1417uint32_t *
1418Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
1419 enum Peers_ChannelRole role)
1420{
1421 const struct PeerContext *peer_ctx;
1422
1423 peer_ctx = get_peer_ctx (peer);
1424 if (Peers_CHANNEL_ROLE_SENDING == role)
1425 {
1426 return peer_ctx->send_channel_flags;
1427 }
1428 else if (Peers_CHANNEL_ROLE_RECEIVING == role)
1429 {
1430 return peer_ctx->recv_channel_flags;
1431 }
1432 else
1433 {
1434 GNUNET_assert (0);
1435 }
1436}
1437
1438/** 1478/**
1439 * @brief Check whether we have information about the given peer. 1479 * @brief Check whether we have information about the given peer.
1440 * 1480 *
@@ -1505,7 +1545,7 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer)
1505 const struct PeerContext *peer_ctx; 1545 const struct PeerContext *peer_ctx;
1506 1546
1507 peer_ctx = get_peer_ctx (peer); 1547 peer_ctx = get_peer_ctx (peer);
1508 if (NULL != peer_ctx->recv_channel) 1548 if (NULL != peer_ctx->recv_channel_ctx)
1509 { 1549 {
1510 return GNUNET_YES; 1550 return GNUNET_YES;
1511 } 1551 }
@@ -1530,6 +1570,7 @@ Peers_handle_inbound_channel (void *cls,
1530{ 1570{
1531 struct PeerContext *peer_ctx; 1571 struct PeerContext *peer_ctx;
1532 struct GNUNET_PeerIdentity *ctx_peer; 1572 struct GNUNET_PeerIdentity *ctx_peer;
1573 struct ChannelCtx *channel_ctx;
1533 1574
1534 LOG (GNUNET_ERROR_TYPE_DEBUG, 1575 LOG (GNUNET_ERROR_TYPE_DEBUG,
1535 "New channel was established to us (Peer %s).\n", 1576 "New channel was established to us (Peer %s).\n",
@@ -1540,19 +1581,22 @@ Peers_handle_inbound_channel (void *cls,
1540 set_peer_live (peer_ctx); 1581 set_peer_live (peer_ctx);
1541 ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity); 1582 ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity);
1542 *ctx_peer = *initiator; 1583 *ctx_peer = *initiator;
1584 channel_ctx = add_channel_ctx (peer_ctx);
1585 channel_ctx->channel = channel;
1543 /* We only accept one incoming channel per peer */ 1586 /* We only accept one incoming channel per peer */
1544 if (GNUNET_YES == Peers_check_peer_send_intention (initiator)) 1587 if (GNUNET_YES == Peers_check_peer_send_intention (initiator))
1545 { 1588 {
1546 set_channel_flag (peer_ctx->recv_channel_flags, 1589 LOG (GNUNET_ERROR_TYPE_WARNING,
1547 Peers_CHANNEL_ESTABLISHED_TWICE); 1590 "Already got one receive channel. Destroying old one.\n");
1548 //GNUNET_CADET_channel_destroy (channel); 1591 GNUNET_break_op (0);
1549 GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); 1592 GNUNET_CADET_channel_destroy (peer_ctx->recv_channel_ctx->channel);
1550 peer_ctx->recv_channel = channel; 1593 remove_channel_ctx (peer_ctx->recv_channel_ctx);
1594 peer_ctx->recv_channel_ctx = channel_ctx;
1551 /* return the channel context */ 1595 /* return the channel context */
1552 return ctx_peer; 1596 return channel_ctx;
1553 } 1597 }
1554 peer_ctx->recv_channel = channel; 1598 peer_ctx->recv_channel_ctx = channel_ctx;
1555 return ctx_peer; 1599 return channel_ctx;
1556} 1600}
1557 1601
1558 1602
@@ -1574,7 +1618,7 @@ Peers_check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer)
1574 return GNUNET_NO; 1618 return GNUNET_NO;
1575 } 1619 }
1576 peer_ctx = get_peer_ctx (peer); 1620 peer_ctx = get_peer_ctx (peer);
1577 if (NULL == peer_ctx->send_channel) 1621 if (NULL == peer_ctx->send_channel_ctx)
1578 { 1622 {
1579 return GNUNET_NO; 1623 return GNUNET_NO;
1580 } 1624 }
@@ -1607,12 +1651,14 @@ Peers_check_channel_role (const struct GNUNET_PeerIdentity *peer,
1607 } 1651 }
1608 peer_ctx = get_peer_ctx (peer); 1652 peer_ctx = get_peer_ctx (peer);
1609 if ( (Peers_CHANNEL_ROLE_SENDING == role) && 1653 if ( (Peers_CHANNEL_ROLE_SENDING == role) &&
1610 (channel == peer_ctx->send_channel) ) 1654 (NULL != peer_ctx->send_channel_ctx) &&
1655 (channel == peer_ctx->send_channel_ctx->channel) )
1611 { 1656 {
1612 return GNUNET_YES; 1657 return GNUNET_YES;
1613 } 1658 }
1614 if ( (Peers_CHANNEL_ROLE_RECEIVING == role) && 1659 if ( (Peers_CHANNEL_ROLE_RECEIVING == role) &&
1615 (channel == peer_ctx->recv_channel) ) 1660 (NULL != peer_ctx->recv_channel_ctx) &&
1661 (channel == peer_ctx->recv_channel_ctx->channel) )
1616 { 1662 {
1617 return GNUNET_YES; 1663 return GNUNET_YES;
1618 } 1664 }
@@ -1642,12 +1688,9 @@ Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer)
1642 return GNUNET_NO; 1688 return GNUNET_NO;
1643 } 1689 }
1644 peer_ctx = get_peer_ctx (peer); 1690 peer_ctx = get_peer_ctx (peer);
1645 if (NULL != peer_ctx->send_channel) 1691 if (NULL != peer_ctx->send_channel_ctx)
1646 { 1692 {
1647 set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_CLEAN); 1693 schedule_channel_destruction (peer_ctx->send_channel_ctx);
1648 GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
1649 peer_ctx->send_channel = NULL;
1650 peer_ctx->mq = NULL;
1651 (void) Peers_check_connected (peer); 1694 (void) Peers_check_connected (peer);
1652 return GNUNET_YES; 1695 return GNUNET_YES;
1653 } 1696 }
@@ -1655,6 +1698,25 @@ Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer)
1655} 1698}
1656 1699
1657/** 1700/**
1701 * @brief Callback for scheduler to destroy a channel
1702 *
1703 * @param cls Context of the channel
1704 */
1705static void
1706destroy_channel (void *cls)
1707{
1708 struct ChannelCtx *channel_ctx = cls;
1709 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
1710
1711 GNUNET_assert (channel_ctx == peer_ctx->send_channel_ctx ||
1712 channel_ctx == peer_ctx->recv_channel_ctx);
1713
1714 channel_ctx->destruction_task = NULL;
1715 GNUNET_CADET_channel_destroy (channel_ctx->channel);
1716 remove_channel_ctx (peer_ctx->send_channel_ctx);
1717}
1718
1719/**
1658 * This is called when a channel is destroyed. 1720 * This is called when a channel is destroyed.
1659 * 1721 *
1660 * @param cls The closure 1722 * @param cls The closure
@@ -1664,77 +1726,45 @@ void
1664Peers_cleanup_destroyed_channel (void *cls, 1726Peers_cleanup_destroyed_channel (void *cls,
1665 const struct GNUNET_CADET_Channel *channel) 1727 const struct GNUNET_CADET_Channel *channel)
1666{ 1728{
1667 struct GNUNET_PeerIdentity *peer = cls; 1729 struct ChannelCtx *channel_ctx = cls;
1668 struct PeerContext *peer_ctx; 1730 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
1731 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
1669 1732
1670 if (GNUNET_NO == Peers_check_peer_known (peer)) 1733 if (GNUNET_NO == Peers_check_peer_known (peer))
1671 {/* We don't want to implicitly create a context that we're about to kill */ 1734 {/* We don't want to implicitly create a context that we're about to kill */
1672 LOG (GNUNET_ERROR_TYPE_DEBUG, 1735 LOG (GNUNET_ERROR_TYPE_WARNING,
1673 "channel (%s) without associated context was destroyed\n", 1736 "channel (%s) without associated context was destroyed\n",
1674 GNUNET_i2s (peer)); 1737 GNUNET_i2s (peer));
1675 return; 1738 return;
1676 } 1739 }
1677 peer_ctx = get_peer_ctx (peer);
1678 1740
1679 /* If our peer issued the destruction of the channel, the #Peers_TO_DESTROY 1741 /* If our peer issued the destruction of the channel, the #Peers_TO_DESTROY
1680 * flag will be set. In this case simply make sure that the channels are 1742 * flag will be set. In this case simply make sure that the channels are
1681 * cleaned. */ 1743 * cleaned. */
1682 /* FIXME This distinction seems to be redundant */ 1744 /* The distinction seems to be redundant */
1683 if (Peers_check_peer_flag (peer, Peers_TO_DESTROY)) 1745 LOG (GNUNET_ERROR_TYPE_DEBUG,
1684 {/* We initiatad the destruction of this particular peer */ 1746 "Peer is NOT in the process of being destroyed\n");
1747 if ( (NULL != peer_ctx->send_channel_ctx) &&
1748 (channel == peer_ctx->send_channel_ctx->channel) )
1749 { /* Something (but us) killd the channel - clean up peer */
1685 LOG (GNUNET_ERROR_TYPE_DEBUG, 1750 LOG (GNUNET_ERROR_TYPE_DEBUG,
1686 "Peer is in the process of being destroyed\n"); 1751 "send channel (%s) was destroyed - cleaning up\n",
1687 if (channel == peer_ctx->send_channel) 1752 GNUNET_i2s (peer));
1688 { 1753 remove_channel_ctx (peer_ctx->send_channel_ctx);
1689 peer_ctx->send_channel = NULL;
1690 peer_ctx->mq = NULL;
1691 }
1692 else if (channel == peer_ctx->recv_channel)
1693 {
1694 peer_ctx->recv_channel = NULL;
1695 }
1696
1697 if (NULL != peer_ctx->send_channel)
1698 {
1699 GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
1700 peer_ctx->send_channel = NULL;
1701 peer_ctx->mq = NULL;
1702 }
1703 if (NULL != peer_ctx->recv_channel)
1704 {
1705 GNUNET_CADET_channel_destroy (peer_ctx->recv_channel);
1706 peer_ctx->recv_channel = NULL;
1707 }
1708 /* Set the #Peers_ONLINE flag accordingly */
1709 (void) Peers_check_connected (peer);
1710 return;
1711 } 1754 }
1712 1755 else if ( (NULL != peer_ctx->recv_channel_ctx) &&
1713 else 1756 (channel == peer_ctx->recv_channel_ctx->channel) )
1714 { /* We did not initiate the destruction of this peer */ 1757 { /* Other peer doesn't want to send us messages anymore */
1715 LOG (GNUNET_ERROR_TYPE_DEBUG, 1758 LOG (GNUNET_ERROR_TYPE_DEBUG,
1716 "Peer is NOT in the process of being destroyed\n"); 1759 "Peer %s destroyed recv channel - cleaning up channel\n",
1717 if (channel == peer_ctx->send_channel) 1760 GNUNET_i2s (peer));
1718 { /* Something (but us) killd the channel - clean up peer */ 1761 remove_channel_ctx (peer_ctx->send_channel_ctx);
1719 LOG (GNUNET_ERROR_TYPE_DEBUG, 1762 }
1720 "send channel (%s) was destroyed - cleaning up\n", 1763 else
1721 GNUNET_i2s (peer)); 1764 {
1722 peer_ctx->send_channel = NULL; 1765 LOG (GNUNET_ERROR_TYPE_WARNING,
1723 peer_ctx->mq = NULL; 1766 "unknown channel (%s) was destroyed\n",
1724 } 1767 GNUNET_i2s (peer));
1725 else if (channel == peer_ctx->recv_channel)
1726 { /* Other peer doesn't want to send us messages anymore */
1727 LOG (GNUNET_ERROR_TYPE_DEBUG,
1728 "Peer %s destroyed recv channel - cleaning up channel\n",
1729 GNUNET_i2s (peer));
1730 peer_ctx->recv_channel = NULL;
1731 }
1732 else
1733 {
1734 LOG (GNUNET_ERROR_TYPE_WARNING,
1735 "unknown channel (%s) was destroyed\n",
1736 GNUNET_i2s (peer));
1737 }
1738 } 1768 }
1739 (void) Peers_check_connected (peer); 1769 (void) Peers_check_connected (peer);
1740} 1770}
@@ -1786,10 +1816,6 @@ Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer,
1786 struct PeerPendingOp pending_op; 1816 struct PeerPendingOp pending_op;
1787 struct PeerContext *peer_ctx; 1817 struct PeerContext *peer_ctx;
1788 1818
1789 if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity))
1790 {
1791 return GNUNET_NO;
1792 }
1793 GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); 1819 GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
1794 1820
1795 //TODO if LIVE/ONLINE execute immediately 1821 //TODO if LIVE/ONLINE execute immediately
@@ -1823,7 +1849,7 @@ Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer)
1823 1849
1824 GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); 1850 GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
1825 peer_ctx = get_peer_ctx (peer); 1851 peer_ctx = get_peer_ctx (peer);
1826 return peer_ctx->recv_channel; 1852 return peer_ctx->recv_channel_ctx->channel;
1827} 1853}
1828/*********************************************************************** 1854/***********************************************************************
1829 * /Old gnunet-service-rps_peers.c 1855 * /Old gnunet-service-rps_peers.c
@@ -2484,6 +2510,9 @@ send_pull_reply (const struct GNUNET_PeerIdentity *peer_id,
2484 2510
2485 Peers_send_message (peer_id, ev, "PULL REPLY"); 2511 Peers_send_message (peer_id, ev, "PULL REPLY");
2486 GNUNET_STATISTICS_update(stats, "# pull reply send issued", 1, GNUNET_NO); 2512 GNUNET_STATISTICS_update(stats, "# pull reply send issued", 1, GNUNET_NO);
2513 // TODO check with send intention: as send_channel is used/opened we indicate
2514 // a sending intention without intending it.
2515 // -> clean peer afterwards?
2487} 2516}
2488 2517
2489 2518
@@ -2616,7 +2645,7 @@ remove_peer (const struct GNUNET_PeerIdentity *peer)
2616 CustomPeerMap_remove_peer (push_map, peer); 2645 CustomPeerMap_remove_peer (push_map, peer);
2617 RPS_sampler_reinitialise_by_value (prot_sampler, peer); 2646 RPS_sampler_reinitialise_by_value (prot_sampler, peer);
2618 RPS_sampler_reinitialise_by_value (client_sampler, peer); 2647 RPS_sampler_reinitialise_by_value (client_sampler, peer);
2619 Peers_remove_peer (peer); 2648 schedule_peer_destruction (get_peer_ctx (peer));
2620} 2649}
2621 2650
2622 2651
@@ -2660,6 +2689,58 @@ clean_peer (const struct GNUNET_PeerIdentity *peer)
2660} 2689}
2661 2690
2662/** 2691/**
2692 * @brief Allocate memory for a new channel context and insert it into DLL
2693 *
2694 * @param peer_ctx context of the according peer
2695 *
2696 * @return The channel context
2697 */
2698static struct ChannelCtx *
2699add_channel_ctx (struct PeerContext *peer_ctx)
2700{
2701 struct ChannelCtx *channel_ctx;
2702 channel_ctx = GNUNET_new (struct ChannelCtx);
2703 channel_ctx->peer_ctx = peer_ctx;
2704 return channel_ctx;
2705}
2706
2707/**
2708 * @brief Remove the channel context from the DLL and free the memory.
2709 *
2710 * @param channel_ctx The channel context.
2711 */
2712static void
2713remove_channel_ctx (struct ChannelCtx *channel_ctx)
2714{
2715 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
2716 if (NULL != channel_ctx->destruction_task)
2717 {
2718 GNUNET_SCHEDULER_cancel (channel_ctx->destruction_task);
2719 }
2720 GNUNET_free (channel_ctx);
2721
2722 if (channel_ctx == peer_ctx->send_channel_ctx)
2723 {
2724 peer_ctx->send_channel_ctx = NULL;
2725 peer_ctx->mq = NULL;
2726 }
2727 else if (channel_ctx == peer_ctx->recv_channel_ctx)
2728 {
2729 peer_ctx->recv_channel_ctx = NULL;
2730 }
2731 else
2732 {
2733 LOG (GNUNET_ERROR_TYPE_ERROR,
2734 "Trying to remove channel_ctx that is not associated with a peer\n");
2735 LOG (GNUNET_ERROR_TYPE_ERROR,
2736 "\trecv: %p\n", peer_ctx->recv_channel_ctx);
2737 LOG (GNUNET_ERROR_TYPE_ERROR,
2738 "\tsend: %p\n", peer_ctx->send_channel_ctx);
2739 GNUNET_assert (0);
2740 }
2741}
2742
2743/**
2663 * @brief This is called when a channel is destroyed. 2744 * @brief This is called when a channel is destroyed.
2664 * 2745 *
2665 * Removes peer completely from our knowledge if the send_channel was destroyed 2746 * Removes peer completely from our knowledge if the send_channel was destroyed
@@ -2675,8 +2756,8 @@ static void
2675cleanup_destroyed_channel (void *cls, 2756cleanup_destroyed_channel (void *cls,
2676 const struct GNUNET_CADET_Channel *channel) 2757 const struct GNUNET_CADET_Channel *channel)
2677{ 2758{
2678 struct GNUNET_PeerIdentity *peer = cls; 2759 struct ChannelCtx *channel_ctx = cls;
2679 uint32_t *channel_flag; 2760 struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
2680 struct PeerContext *peer_ctx; 2761 struct PeerContext *peer_ctx;
2681 2762
2682 GNUNET_assert (NULL != peer); 2763 GNUNET_assert (NULL != peer);
@@ -2686,94 +2767,26 @@ cleanup_destroyed_channel (void *cls,
2686 LOG (GNUNET_ERROR_TYPE_WARNING, 2767 LOG (GNUNET_ERROR_TYPE_WARNING,
2687 "channel (%s) without associated context was destroyed\n", 2768 "channel (%s) without associated context was destroyed\n",
2688 GNUNET_i2s (peer)); 2769 GNUNET_i2s (peer));
2689 GNUNET_free (peer); 2770 remove_channel_ctx (channel_ctx);
2690 return; 2771 return;
2691 } 2772 }
2692 2773
2693 peer_ctx = get_peer_ctx (peer); 2774 peer_ctx = get_peer_ctx (peer);
2694 if (GNUNET_YES == Peers_check_channel_role (peer, channel, Peers_CHANNEL_ROLE_RECEIVING))
2695 {
2696 LOG (GNUNET_ERROR_TYPE_DEBUG,
2697 "Callback on destruction of recv-channel was called (%s)\n",
2698 GNUNET_i2s (peer));
2699 set_channel_flag (peer_ctx->recv_channel_flags, Peers_CHANNEL_DESTROING);
2700 } else if (GNUNET_YES == Peers_check_channel_role (peer, channel, Peers_CHANNEL_ROLE_SENDING))
2701 {
2702 LOG (GNUNET_ERROR_TYPE_DEBUG,
2703 "Callback on destruction of send-channel was called (%s)\n",
2704 GNUNET_i2s (peer));
2705 set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_DESTROING);
2706 } else {
2707 LOG (GNUNET_ERROR_TYPE_ERROR,
2708 "Channel to be destroyed has is neither sending nor receiving role\n");
2709 }
2710 2775
2711 if (GNUNET_YES == Peers_check_peer_flag (peer, Peers_TO_DESTROY)) 2776 // What should be done here:
2712 { /* We are in the middle of removing that peer from our knowledge. In this 2777 // * cleanup everything related to the channel
2713 case simply make sure that the channels are cleaned. */ 2778 // * memory
2714 Peers_cleanup_destroyed_channel (cls, channel); 2779 // * remove peer if necessary
2715 to_file (file_name_view_log,
2716 "-%s\t(cleanup channel, ourself)",
2717 GNUNET_i2s_full (peer));
2718 GNUNET_free (peer);
2719 return;
2720 }
2721 2780
2722 if (GNUNET_YES == 2781 if (peer_ctx->recv_channel_ctx == channel_ctx)
2723 Peers_check_channel_role (peer, channel, Peers_CHANNEL_ROLE_SENDING)) 2782 {
2724 { /* Channel used for sending was destroyed */ 2783 remove_channel_ctx (channel_ctx);
2725 /* Possible causes of channel destruction:
2726 * - ourselves -> cleaning send channel -> clean context
2727 * - other peer -> peer probably went down -> remove
2728 */
2729 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING);
2730 if (GNUNET_YES == Peers_check_channel_flag (channel_flag, Peers_CHANNEL_CLEAN))
2731 { /* We are about to clean the sending channel. Clean the respective
2732 * context */
2733 Peers_cleanup_destroyed_channel (cls, channel);
2734 GNUNET_free (peer);
2735 return;
2736 }
2737 else
2738 { /* Other peer destroyed our sending channel that it is supposed to keep
2739 * open. It probably went down. Remove it from our knowledge. */
2740 Peers_cleanup_destroyed_channel (cls, channel);
2741 remove_peer (peer);
2742 GNUNET_free (peer);
2743 return;
2744 }
2745 }
2746 else if (GNUNET_YES ==
2747 Peers_check_channel_role (peer, channel, Peers_CHANNEL_ROLE_RECEIVING))
2748 { /* Channel used for receiving was destroyed */
2749 /* Possible causes of channel destruction:
2750 * - ourselves -> peer tried to establish channel twice -> clean context
2751 * - other peer -> peer doesn't want to send us data -> clean
2752 */
2753 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_RECEIVING);
2754 if (GNUNET_YES ==
2755 Peers_check_channel_flag (channel_flag, Peers_CHANNEL_ESTABLISHED_TWICE))
2756 { /* Other peer tried to establish a channel to us twice. We do not accept
2757 * that. Clean the context. */
2758 Peers_cleanup_destroyed_channel (cls, channel);
2759 GNUNET_free (peer);
2760 return;
2761 }
2762 else
2763 { /* Other peer doesn't want to send us data anymore. We are free to clean
2764 * it. */
2765 Peers_cleanup_destroyed_channel (cls, channel);
2766 clean_peer (peer);
2767 GNUNET_free (peer);
2768 return;
2769 }
2770 } 2784 }
2771 else 2785 else if (peer_ctx->send_channel_ctx == channel_ctx)
2772 { 2786 {
2773 LOG (GNUNET_ERROR_TYPE_WARNING, 2787 remove_channel_ctx (channel_ctx);
2774 "Destroyed channel is neither sending nor receiving channel\n"); 2788 remove_peer (&peer_ctx->peer_id);
2775 } 2789 }
2776 GNUNET_free (peer);
2777} 2790}
2778 2791
2779/*********************************************************************** 2792/***********************************************************************
@@ -3032,8 +3045,6 @@ handle_client_seed (void *cls,
3032 3045
3033 num_peers = ntohl (msg->num_peers); 3046 num_peers = ntohl (msg->num_peers);
3034 peers = (struct GNUNET_PeerIdentity *) &msg[1]; 3047 peers = (struct GNUNET_PeerIdentity *) &msg[1];
3035 //peers = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
3036 //GNUNET_memcpy (peers, &msg[1], num_peers * sizeof (struct GNUNET_PeerIdentity));
3037 3048
3038 LOG (GNUNET_ERROR_TYPE_DEBUG, 3049 LOG (GNUNET_ERROR_TYPE_DEBUG,
3039 "Client seeded peers:\n"); 3050 "Client seeded peers:\n");
@@ -3048,9 +3059,6 @@ handle_client_seed (void *cls,
3048 3059
3049 got_peer (&peers[i]); 3060 got_peer (&peers[i]);
3050 } 3061 }
3051
3052 ////GNUNET_free (peers);
3053
3054 GNUNET_SERVICE_client_continue (cli_ctx->client); 3062 GNUNET_SERVICE_client_continue (cli_ctx->client);
3055} 3063}
3056 3064
@@ -3168,11 +3176,12 @@ static void
3168handle_peer_check (void *cls, 3176handle_peer_check (void *cls,
3169 const struct GNUNET_MessageHeader *msg) 3177 const struct GNUNET_MessageHeader *msg)
3170{ 3178{
3171 const struct GNUNET_PeerIdentity *peer = cls; 3179 const struct ChannelCtx *channel_ctx = cls;
3180 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3172 LOG (GNUNET_ERROR_TYPE_DEBUG, 3181 LOG (GNUNET_ERROR_TYPE_DEBUG,
3173 "Received CHECK_LIVE (%s)\n", GNUNET_i2s (peer)); 3182 "Received CHECK_LIVE (%s)\n", GNUNET_i2s (peer));
3174 3183
3175 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); 3184 GNUNET_CADET_receive_done (channel_ctx->channel);
3176} 3185}
3177 3186
3178/** 3187/**
@@ -3188,7 +3197,8 @@ static void
3188handle_peer_push (void *cls, 3197handle_peer_push (void *cls,
3189 const struct GNUNET_MessageHeader *msg) 3198 const struct GNUNET_MessageHeader *msg)
3190{ 3199{
3191 const struct GNUNET_PeerIdentity *peer = cls; 3200 const struct ChannelCtx *channel_ctx = cls;
3201 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3192 3202
3193 // (check the proof of work (?)) 3203 // (check the proof of work (?))
3194 3204
@@ -3233,7 +3243,7 @@ handle_peer_push (void *cls,
3233 CustomPeerMap_put (push_map, peer); 3243 CustomPeerMap_put (push_map, peer);
3234 3244
3235 GNUNET_break_op (Peers_check_peer_known (peer)); 3245 GNUNET_break_op (Peers_check_peer_known (peer));
3236 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); 3246 GNUNET_CADET_receive_done (channel_ctx->channel);
3237} 3247}
3238 3248
3239 3249
@@ -3249,7 +3259,8 @@ static void
3249handle_peer_pull_request (void *cls, 3259handle_peer_pull_request (void *cls,
3250 const struct GNUNET_MessageHeader *msg) 3260 const struct GNUNET_MessageHeader *msg)
3251{ 3261{
3252 struct GNUNET_PeerIdentity *peer = cls; 3262 const struct ChannelCtx *channel_ctx = cls;
3263 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3253 const struct GNUNET_PeerIdentity *view_array; 3264 const struct GNUNET_PeerIdentity *view_array;
3254 3265
3255 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (peer)); 3266 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (peer));
@@ -3272,7 +3283,7 @@ handle_peer_pull_request (void *cls,
3272 #endif /* ENABLE_MALICIOUS */ 3283 #endif /* ENABLE_MALICIOUS */
3273 3284
3274 GNUNET_break_op (Peers_check_peer_known (peer)); 3285 GNUNET_break_op (Peers_check_peer_known (peer));
3275 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); 3286 GNUNET_CADET_receive_done (channel_ctx->channel);
3276 view_array = View_get_as_array (); 3287 view_array = View_get_as_array ();
3277 send_pull_reply (peer, view_array, View_size ()); 3288 send_pull_reply (peer, view_array, View_size ());
3278} 3289}
@@ -3312,7 +3323,8 @@ check_peer_pull_reply (void *cls,
3312 if (GNUNET_YES != Peers_check_peer_flag (sender, Peers_PULL_REPLY_PENDING)) 3323 if (GNUNET_YES != Peers_check_peer_flag (sender, Peers_PULL_REPLY_PENDING))
3313 { 3324 {
3314 LOG (GNUNET_ERROR_TYPE_WARNING, 3325 LOG (GNUNET_ERROR_TYPE_WARNING,
3315 "Received a pull reply from a peer we didn't request one from!\n"); 3326 "Received a pull reply from a peer (%s) we didn't request one from!\n",
3327 GNUNET_i2s (sender));
3316 GNUNET_break_op (0); 3328 GNUNET_break_op (0);
3317 return GNUNET_SYSERR; 3329 return GNUNET_SYSERR;
3318 } 3330 }
@@ -3329,8 +3341,9 @@ static void
3329handle_peer_pull_reply (void *cls, 3341handle_peer_pull_reply (void *cls,
3330 const struct GNUNET_RPS_P2P_PullReplyMessage *msg) 3342 const struct GNUNET_RPS_P2P_PullReplyMessage *msg)
3331{ 3343{
3344 const struct ChannelCtx *channel_ctx = cls;
3345 const struct GNUNET_PeerIdentity *sender = &channel_ctx->peer_ctx->peer_id;
3332 const struct GNUNET_PeerIdentity *peers; 3346 const struct GNUNET_PeerIdentity *peers;
3333 struct GNUNET_PeerIdentity *sender = cls;
3334 uint32_t i; 3347 uint32_t i;
3335#ifdef ENABLE_MALICIOUS 3348#ifdef ENABLE_MALICIOUS
3336 struct AttackedPeer *tmp_att_peer; 3349 struct AttackedPeer *tmp_att_peer;
@@ -3368,9 +3381,7 @@ handle_peer_pull_reply (void *cls,
3368 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (att_peer_set, 3381 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (att_peer_set,
3369 &peers[i]) 3382 &peers[i])
3370 && GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (mal_peer_set, 3383 && GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (mal_peer_set,
3371 &peers[i]) 3384 &peers[i]))
3372 && 0 != GNUNET_CRYPTO_cmp_peer_identity (&peers[i],
3373 &own_identity))
3374 { 3385 {
3375 tmp_att_peer = GNUNET_new (struct AttackedPeer); 3386 tmp_att_peer = GNUNET_new (struct AttackedPeer);
3376 tmp_att_peer->peer_id = peers[i]; 3387 tmp_att_peer->peer_id = peers[i];
@@ -3382,21 +3393,17 @@ handle_peer_pull_reply (void *cls,
3382 continue; 3393 continue;
3383 } 3394 }
3384 #endif /* ENABLE_MALICIOUS */ 3395 #endif /* ENABLE_MALICIOUS */
3385 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, 3396 /* Make sure we 'know' about this peer */
3386 &peers[i])) 3397 (void) Peers_insert_peer (&peers[i]);
3387 {
3388 /* Make sure we 'know' about this peer */
3389 (void) Peers_insert_peer (&peers[i]);
3390 3398
3391 if (GNUNET_YES == Peers_check_peer_valid (&peers[i])) 3399 if (GNUNET_YES == Peers_check_peer_valid (&peers[i]))
3392 { 3400 {
3393 CustomPeerMap_put (pull_map, &peers[i]); 3401 CustomPeerMap_put (pull_map, &peers[i]);
3394 } 3402 }
3395 else 3403 else
3396 { 3404 {
3397 Peers_schedule_operation (&peers[i], insert_in_pull_map); 3405 Peers_schedule_operation (&peers[i], insert_in_pull_map);
3398 (void) Peers_issue_peer_liveliness_check (&peers[i]); 3406 (void) Peers_issue_peer_liveliness_check (&peers[i]);
3399 }
3400 } 3407 }
3401 } 3408 }
3402 3409
@@ -3404,7 +3411,7 @@ handle_peer_pull_reply (void *cls,
3404 clean_peer (sender); 3411 clean_peer (sender);
3405 3412
3406 GNUNET_break_op (Peers_check_peer_known (sender)); 3413 GNUNET_break_op (Peers_check_peer_known (sender));
3407 GNUNET_CADET_receive_done (Peers_get_recv_channel (sender)); 3414 GNUNET_CADET_receive_done (channel_ctx->channel);
3408} 3415}
3409 3416
3410 3417
@@ -3831,10 +3838,8 @@ do_round (void *cls)
3831 for (i = 0; i < a_peers; i++) 3838 for (i = 0; i < a_peers; i++)
3832 { 3839 {
3833 peer = view_array[permut[i]]; 3840 peer = view_array[permut[i]];
3834 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, &peer)) // TODO 3841 // FIXME if this fails schedule/loop this for later
3835 { // FIXME if this fails schedule/loop this for later 3842 send_push (&peer);
3836 send_push (&peer);
3837 }
3838 } 3843 }
3839 3844
3840 /* Send PULL requests */ 3845 /* Send PULL requests */
@@ -3852,8 +3857,7 @@ do_round (void *cls)
3852 for (i = first_border; i < second_border; i++) 3857 for (i = first_border; i < second_border; i++)
3853 { 3858 {
3854 peer = view_array[permut[i]]; 3859 peer = view_array[permut[i]];
3855 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, &peer) && 3860 if ( GNUNET_NO == Peers_check_peer_flag (&peer, Peers_PULL_REPLY_PENDING))
3856 GNUNET_NO == Peers_check_peer_flag (&peer, Peers_PULL_REPLY_PENDING)) // TODO
3857 { // FIXME if this fails schedule/loop this for later 3861 { // FIXME if this fails schedule/loop this for later
3858 send_pull_request (&peer); 3862 send_pull_request (&peer);
3859 } 3863 }
@@ -3950,7 +3954,6 @@ do_round (void *cls)
3950 "-%s", 3954 "-%s",
3951 GNUNET_i2s_full (&peers_to_clean[i])); 3955 GNUNET_i2s_full (&peers_to_clean[i]));
3952 clean_peer (&peers_to_clean[i]); 3956 clean_peer (&peers_to_clean[i]);
3953 //peer_destroy_channel_send (sender);
3954 } 3957 }
3955 3958
3956 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, 0); 3959 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, 0);
@@ -4006,7 +4009,6 @@ do_round (void *cls)
4006 GNUNET_i2s (update_peer)); 4009 GNUNET_i2s (update_peer));
4007 insert_in_sampler (NULL, update_peer); 4010 insert_in_sampler (NULL, update_peer);
4008 clean_peer (update_peer); /* This cleans only if it is not in the view */ 4011 clean_peer (update_peer); /* This cleans only if it is not in the view */
4009 //peer_destroy_channel_send (sender);
4010 } 4012 }
4011 4013
4012 for (i = 0; i < CustomPeerMap_size (pull_map); i++) 4014 for (i = 0; i < CustomPeerMap_size (pull_map); i++)
@@ -4017,7 +4019,6 @@ do_round (void *cls)
4017 insert_in_sampler (NULL, CustomPeerMap_get_peer_by_index (pull_map, i)); 4019 insert_in_sampler (NULL, CustomPeerMap_get_peer_by_index (pull_map, i));
4018 /* This cleans only if it is not in the view */ 4020 /* This cleans only if it is not in the view */
4019 clean_peer (CustomPeerMap_get_peer_by_index (pull_map, i)); 4021 clean_peer (CustomPeerMap_get_peer_by_index (pull_map, i));
4020 //peer_destroy_channel_send (sender);
4021 } 4022 }
4022 4023
4023 4024
@@ -4120,6 +4121,8 @@ shutdown_task (void *cls)
4120 struct ClientContext *client_ctx; 4121 struct ClientContext *client_ctx;
4121 struct ReplyCls *reply_cls; 4122 struct ReplyCls *reply_cls;
4122 4123
4124 in_shutdown = GNUNET_YES;
4125
4123 LOG (GNUNET_ERROR_TYPE_DEBUG, 4126 LOG (GNUNET_ERROR_TYPE_DEBUG,
4124 "RPS is going down\n"); 4127 "RPS is going down\n");
4125 4128
@@ -4364,10 +4367,17 @@ run (void *cls,
4364 NULL, /* WindowSize handler */ 4367 NULL, /* WindowSize handler */
4365 cleanup_destroyed_channel, /* Disconnect handler */ 4368 cleanup_destroyed_channel, /* Disconnect handler */
4366 cadet_handlers); 4369 cadet_handlers);
4370 if (NULL == cadet_port)
4371 {
4372 LOG (GNUNET_ERROR_TYPE_ERROR,
4373 "Cadet port `%s' is already in use.\n",
4374 GNUNET_APPLICATION_PORT_RPS);
4375 GNUNET_assert (0);
4376 }
4367 4377
4368 4378
4369 peerinfo_handle = GNUNET_PEERINFO_connect (cfg); 4379 peerinfo_handle = GNUNET_PEERINFO_connect (cfg);
4370 Peers_initialise (fn_valid_peers, cadet_handle, &own_identity); 4380 Peers_initialise (fn_valid_peers, cadet_handle);
4371 GNUNET_free (fn_valid_peers); 4381 GNUNET_free (fn_valid_peers);
4372 4382
4373 /* Initialise sampler */ 4383 /* Initialise sampler */