diff options
author | Julius Bünger <buenger@mytum.de> | 2015-08-02 14:48:28 +0000 |
---|---|---|
committer | Julius Bünger <buenger@mytum.de> | 2015-08-02 14:48:28 +0000 |
commit | bae0066688e7571b4abdebfb914dba6df0578a6b (patch) | |
tree | 4ee2b2171170d169ff8cd55cfe5ad9adf640d5d2 /src/rps/gnunet-service-rps.c | |
parent | 847e9575ed85eadb979bc416afec7cf898cf00d1 (diff) | |
download | gnunet-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.c | 206 |
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 | */ | ||
81 | struct 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 | */ |
80 | struct ClientContext | 109 | struct 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 | */ | ||
132 | struct ClientContext *cli_ctx_head; | ||
133 | struct 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 | */ |
91 | enum PeerFlags | 138 | enum 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; | |||
365 | uint32_t num_hist_update_tasks; | 416 | uint32_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 | */ | ||
372 | struct 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 | ||
1270 | static void | ||
1271 | destroy_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 | ||
1284 | static void | ||
1285 | destroy_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 | */ | ||
1453 | static void | ||
1454 | handle_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 | */ | ||
2687 | static void | ||
2688 | handle_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 | */ |
2592 | static void | 2711 | static void |
2593 | handle_client_disconnect (void *cls, | 2712 | handle_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, | |||
2716 | rps_start (struct GNUNET_SERVER_Handle *server) | 2847 | rps_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); |