aboutsummaryrefslogtreecommitdiff
path: root/src/rps/gnunet-service-rps.c
diff options
context:
space:
mode:
authorJulius Bünger <buenger@mytum.de>2015-08-02 14:48:28 +0000
committerJulius Bünger <buenger@mytum.de>2015-08-02 14:48:28 +0000
commitbae0066688e7571b4abdebfb914dba6df0578a6b (patch)
tree4ee2b2171170d169ff8cd55cfe5ad9adf640d5d2 /src/rps/gnunet-service-rps.c
parent847e9575ed85eadb979bc416afec7cf898cf00d1 (diff)
downloadgnunet-bae0066688e7571b4abdebfb914dba6df0578a6b.tar.gz
gnunet-bae0066688e7571b4abdebfb914dba6df0578a6b.zip
cancellation of request and according test improvements
Diffstat (limited to 'src/rps/gnunet-service-rps.c')
-rw-r--r--src/rps/gnunet-service-rps.c206
1 files changed, 171 insertions, 35 deletions
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 3c98d79da..8c1a1dc12 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -75,22 +75,73 @@ get_rand_peer_ignore_list (const struct GNUNET_PeerIdentity *peer_list, unsigned
75***********************************************************************/ 75***********************************************************************/
76 76
77/** 77/**
78 * Closure used to pass the client and the id to the callback
79 * that replies to a client's request
80 */
81struct ReplyCls
82{
83 /**
84 * DLL
85 */
86 struct ReplyCls *next;
87 struct ReplyCls *prev;
88
89 /**
90 * The identifier of the request
91 */
92 uint32_t id;
93
94 /**
95 * The handle to the request
96 */
97 struct RPS_SamplerRequestHandle *req_handle;
98
99 /**
100 * The client handle to send the reply to
101 */
102 struct GNUNET_SERVER_Client *client;
103};
104
105
106/**
78 * Struct used to store the context of a connected client. 107 * Struct used to store the context of a connected client.
79 */ 108 */
80struct ClientContext 109struct ClientContext
81{ 110{
82 /** 111 /**
112 * DLL
113 */
114 struct ClientContext *next;
115 struct ClientContext *prev;
116
117 /**
83 * The message queue to communicate with the client. 118 * The message queue to communicate with the client.
84 */ 119 */
85 struct GNUNET_MQ_Handle *mq; 120 struct GNUNET_MQ_Handle *mq;
121
122 /**
123 * DLL with handles to single requests from the client
124 */
125 struct ReplyCls *rep_cls_head;
126 struct ReplyCls *rep_cls_tail;
86}; 127};
87 128
88/** 129/**
130 * DLL with all clients currently connected to us
131 */
132struct ClientContext *cli_ctx_head;
133struct ClientContext *cli_ctx_tail;
134
135/**
89 * Used to keep track in what lists single peerIDs are. 136 * Used to keep track in what lists single peerIDs are.
90 */ 137 */
91enum PeerFlags 138enum PeerFlags
92{ 139{
140 /**
141 * If we are waiting for a reply from that peer (sent a pull request).
142 */
93 PULL_REPLY_PENDING = 0x01, 143 PULL_REPLY_PENDING = 0x01,
144
94 IN_OTHER_GOSSIP_LIST = 0x02, // unneeded? 145 IN_OTHER_GOSSIP_LIST = 0x02, // unneeded?
95 IN_OWN_SAMPLER_LIST = 0x04, // unneeded? 146 IN_OWN_SAMPLER_LIST = 0x04, // unneeded?
96 IN_OWN_GOSSIP_LIST = 0x08, // unneeded? 147 IN_OWN_GOSSIP_LIST = 0x08, // unneeded?
@@ -365,24 +416,6 @@ static struct GNUNET_TIME_Relative request_rate;
365uint32_t num_hist_update_tasks; 416uint32_t num_hist_update_tasks;
366 417
367 418
368/**
369 * Closure used to pass the client and the id to the callback
370 * that replies to a client's request
371 */
372struct ReplyCls
373{
374 /**
375 * The identifier of the request
376 */
377 uint32_t id;
378
379 /**
380 * The client handle to send the reply to
381 */
382 struct GNUNET_SERVER_Client *client;
383};
384
385
386#ifdef ENABLE_MALICIOUS 419#ifdef ENABLE_MALICIOUS
387/** 420/**
388 * Type of malicious peer 421 * Type of malicious peer
@@ -1234,8 +1267,36 @@ new_peer_id (const struct GNUNET_PeerIdentity *peer_id)
1234 * /Util functions 1267 * /Util functions
1235***********************************************************************/ 1268***********************************************************************/
1236 1269
1270static void
1271destroy_reply_cls (struct ReplyCls *rep_cls)
1272{
1273 struct ClientContext *cli_ctx;
1237 1274
1275 cli_ctx = GNUNET_SERVER_client_get_user_context (rep_cls->client,
1276 struct ClientContext);
1277 GNUNET_assert (NULL != cli_ctx);
1278 GNUNET_CONTAINER_DLL_remove (cli_ctx->rep_cls_head,
1279 cli_ctx->rep_cls_tail,
1280 rep_cls);
1281 GNUNET_free (rep_cls);
1282}
1238 1283
1284static void
1285destroy_cli_ctx (struct ClientContext *cli_ctx)
1286{
1287 GNUNET_assert (NULL != cli_ctx);
1288 if (NULL != cli_ctx->rep_cls_head)
1289 {
1290 LOG (GNUNET_ERROR_TYPE_WARNING,
1291 "Trying to destroy the context of a client that still has pending requests. Going to clean those\n");
1292 while (NULL != cli_ctx->rep_cls_head)
1293 destroy_reply_cls (cli_ctx->rep_cls_head);
1294 }
1295 GNUNET_CONTAINER_DLL_remove (cli_ctx_head,
1296 cli_ctx_tail,
1297 cli_ctx);
1298 GNUNET_free (cli_ctx);
1299}
1239 1300
1240 1301
1241/** 1302/**
@@ -1316,15 +1377,10 @@ void client_respond (void *cls,
1316 num_peers * sizeof (struct GNUNET_PeerIdentity)); 1377 num_peers * sizeof (struct GNUNET_PeerIdentity));
1317 GNUNET_free (peer_ids); 1378 GNUNET_free (peer_ids);
1318 1379
1319 cli_ctx = GNUNET_SERVER_client_get_user_context (reply_cls->client, struct ClientContext); 1380 cli_ctx = GNUNET_SERVER_client_get_user_context (reply_cls->client,
1320 if (NULL == cli_ctx) { 1381 struct ClientContext);
1321 cli_ctx = GNUNET_new (struct ClientContext); 1382 GNUNET_assert (NULL != cli_ctx);
1322 cli_ctx->mq = GNUNET_MQ_queue_for_server_client (reply_cls->client); 1383 destroy_reply_cls (reply_cls);
1323 GNUNET_SERVER_client_set_user_context (reply_cls->client, cli_ctx);
1324 }
1325
1326 GNUNET_free (reply_cls);
1327
1328 GNUNET_MQ_send (cli_ctx->mq, ev); 1384 GNUNET_MQ_send (cli_ctx->mq, ev);
1329} 1385}
1330 1386
@@ -1346,6 +1402,7 @@ handle_client_request (void *cls,
1346 uint32_t size_needed; 1402 uint32_t size_needed;
1347 struct ReplyCls *reply_cls; 1403 struct ReplyCls *reply_cls;
1348 uint32_t i; 1404 uint32_t i;
1405 struct ClientContext *cli_ctx;
1349 1406
1350 msg = (struct GNUNET_RPS_CS_RequestMessage *) message; 1407 msg = (struct GNUNET_RPS_CS_RequestMessage *) message;
1351 1408
@@ -1371,12 +1428,50 @@ handle_client_request (void *cls,
1371 reply_cls = GNUNET_new (struct ReplyCls); 1428 reply_cls = GNUNET_new (struct ReplyCls);
1372 reply_cls->id = ntohl (msg->id); 1429 reply_cls->id = ntohl (msg->id);
1373 reply_cls->client = client; 1430 reply_cls->client = client;
1431 reply_cls->req_handle = RPS_sampler_get_n_rand_peers (client_sampler,
1432 client_respond,
1433 reply_cls,
1434 num_peers);
1435
1436 cli_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientContext);
1437 GNUNET_assert (NULL != cli_ctx);
1438 GNUNET_CONTAINER_DLL_insert (cli_ctx->rep_cls_head,
1439 cli_ctx->rep_cls_tail,
1440 reply_cls);
1441 GNUNET_SERVER_receive_done (client,
1442 GNUNET_OK);
1443}
1374 1444
1375 RPS_sampler_get_n_rand_peers (client_sampler,
1376 client_respond,
1377 reply_cls,
1378 num_peers);
1379 1445
1446/**
1447 * @brief Handle a message that requests the cancellation of a request
1448 *
1449 * @param cls unused
1450 * @param client the client that requests the cancellation
1451 * @param message the message containing the id of the request
1452 */
1453static void
1454handle_client_request_cancel (void *cls,
1455 struct GNUNET_SERVER_Client *client,
1456 const struct GNUNET_MessageHeader *message)
1457{
1458 struct GNUNET_RPS_CS_RequestCancelMessage *msg =
1459 (struct GNUNET_RPS_CS_RequestCancelMessage *) message;
1460 struct ClientContext *cli_ctx;
1461 struct ReplyCls *rep_cls;
1462
1463 cli_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientContext);
1464 GNUNET_assert (NULL != cli_ctx->rep_cls_head);
1465 rep_cls = cli_ctx->rep_cls_head;
1466 LOG (GNUNET_ERROR_TYPE_DEBUG,
1467 "Client cancels request with id %lu\n",
1468 ntohl (msg->id));
1469 while ( (NULL != rep_cls->next) &&
1470 (rep_cls->id != ntohl (msg->id)) )
1471 rep_cls = rep_cls->next;
1472 GNUNET_assert (rep_cls->id == ntohl (msg->id));
1473 RPS_sampler_request_cancel (rep_cls->req_handle);
1474 destroy_reply_cls (rep_cls);
1380 GNUNET_SERVER_receive_done (client, 1475 GNUNET_SERVER_receive_done (client,
1381 GNUNET_OK); 1476 GNUNET_OK);
1382} 1477}
@@ -2584,6 +2679,30 @@ shutdown_task (void *cls,
2584 2679
2585 2680
2586/** 2681/**
2682 * @brief Get informed about a connecting client.
2683 *
2684 * @param cls unused
2685 * @param client the client that connects
2686 */
2687static void
2688handle_client_connect (void *cls,
2689 struct GNUNET_SERVER_Client *client)
2690{
2691 struct ClientContext *cli_ctx;
2692
2693 LOG (GNUNET_ERROR_TYPE_DEBUG,
2694 "Client connected\n");
2695 if (NULL == client)
2696 return; /* Server was destroyed before a client connected. Shutting down */
2697 cli_ctx = GNUNET_new (struct ClientContext);
2698 cli_ctx->mq = GNUNET_MQ_queue_for_server_client (client);
2699 GNUNET_SERVER_client_set_user_context (client, cli_ctx);
2700 GNUNET_CONTAINER_DLL_insert (cli_ctx_head,
2701 cli_ctx_tail,
2702 cli_ctx);
2703}
2704
2705/**
2587 * A client disconnected. Remove all of its data structure entries. 2706 * A client disconnected. Remove all of its data structure entries.
2588 * 2707 *
2589 * @param cls closure, NULL 2708 * @param cls closure, NULL
@@ -2591,8 +2710,20 @@ shutdown_task (void *cls,
2591 */ 2710 */
2592static void 2711static void
2593handle_client_disconnect (void *cls, 2712handle_client_disconnect (void *cls,
2594 struct GNUNET_SERVER_Client * client) 2713 struct GNUNET_SERVER_Client *client)
2595{ 2714{
2715 struct ClientContext *cli_ctx;
2716
2717 if (NULL == client)
2718 {/* shutdown task */
2719 while (NULL != cli_ctx_head)
2720 destroy_cli_ctx (cli_ctx_head);
2721 }
2722 else
2723 {
2724 cli_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientContext);
2725 destroy_cli_ctx (cli_ctx);
2726 }
2596} 2727}
2597 2728
2598 2729
@@ -2716,16 +2847,21 @@ cleanup_channel (void *cls,
2716rps_start (struct GNUNET_SERVER_Handle *server) 2847rps_start (struct GNUNET_SERVER_Handle *server)
2717{ 2848{
2718 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 2849 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
2719 {&handle_client_request, NULL, GNUNET_MESSAGE_TYPE_RPS_CS_REQUEST, 2850 {&handle_client_request, NULL, GNUNET_MESSAGE_TYPE_RPS_CS_REQUEST,
2720 sizeof (struct GNUNET_RPS_CS_RequestMessage)}, 2851 sizeof (struct GNUNET_RPS_CS_RequestMessage)},
2721 {&handle_client_seed, NULL, GNUNET_MESSAGE_TYPE_RPS_CS_SEED, 0}, 2852 {&handle_client_request_cancel, NULL, GNUNET_MESSAGE_TYPE_RPS_CS_REQUEST_CANCEL,
2853 sizeof (struct GNUNET_RPS_CS_RequestCancelMessage)},
2854 {&handle_client_seed, NULL, GNUNET_MESSAGE_TYPE_RPS_CS_SEED, 0},
2722 #ifdef ENABLE_MALICIOUS 2855 #ifdef ENABLE_MALICIOUS
2723 {&handle_client_act_malicious, NULL, GNUNET_MESSAGE_TYPE_RPS_ACT_MALICIOUS , 0}, 2856 {&handle_client_act_malicious, NULL, GNUNET_MESSAGE_TYPE_RPS_ACT_MALICIOUS , 0},
2724 #endif /* ENABLE_MALICIOUS */ 2857 #endif /* ENABLE_MALICIOUS */
2725 {NULL, NULL, 0, 0} 2858 {NULL, NULL, 0, 0}
2726 }; 2859 };
2727 2860
2728 GNUNET_SERVER_add_handlers (server, handlers); 2861 GNUNET_SERVER_add_handlers (server, handlers);
2862 GNUNET_SERVER_connect_notify (server,
2863 &handle_client_connect,
2864 NULL);
2729 GNUNET_SERVER_disconnect_notify (server, 2865 GNUNET_SERVER_disconnect_notify (server,
2730 &handle_client_disconnect, 2866 &handle_client_disconnect,
2731 NULL); 2867 NULL);