aboutsummaryrefslogtreecommitdiff
path: root/src/rps
diff options
context:
space:
mode:
authorJulius Bünger <buenger@mytum.de>2018-03-05 18:25:39 +0100
committerJulius Bünger <buenger@mytum.de>2018-03-05 18:34:35 +0100
commit132597e5050e591617cd4e303015608ff503d879 (patch)
treef8cebacaf2915bdcf812a89608ec90d540cca170 /src/rps
parentd036b626b8eea15f99d91faf309843936289fde7 (diff)
downloadgnunet-132597e5050e591617cd4e303015608ff503d879.tar.gz
gnunet-132597e5050e591617cd4e303015608ff503d879.zip
rps: add debug function to api to get view of service
Diffstat (limited to 'src/rps')
-rw-r--r--src/rps/gnunet-service-rps.c113
-rw-r--r--src/rps/rps.h43
-rw-r--r--src/rps/rps_api.c95
3 files changed, 250 insertions, 1 deletions
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 56c3c52b6..0499eb0ab 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -1856,6 +1856,11 @@ struct ClientContext
1856 struct ReplyCls *rep_cls_tail; 1856 struct ReplyCls *rep_cls_tail;
1857 1857
1858 /** 1858 /**
1859 * @brief How many updates this client expects to receive.
1860 */
1861 int64_t view_updates_left;
1862
1863 /**
1859 * The client handle to send the reply to 1864 * The client handle to send the reply to
1860 */ 1865 */
1861 struct GNUNET_SERVICE_Client *client; 1866 struct GNUNET_SERVICE_Client *client;
@@ -2940,6 +2945,107 @@ handle_client_seed (void *cls,
2940} 2945}
2941 2946
2942/** 2947/**
2948 * @brief Send view to client
2949 *
2950 * @param cli_ctx the context of the client
2951 * @param view_array the peerids of the view as array (can be empty)
2952 * @param view_size the size of the view array (can be 0)
2953 */
2954void
2955send_view (const struct ClientContext *cli_ctx,
2956 const struct GNUNET_PeerIdentity *view_array,
2957 uint64_t view_size)
2958{
2959 struct GNUNET_MQ_Envelope *ev;
2960 struct GNUNET_RPS_CS_DEBUG_ViewReply *out_msg;
2961
2962 if (NULL == view_array)
2963 {
2964 view_size = View_size ();
2965 view_array = View_get_as_array();
2966 }
2967
2968 ev = GNUNET_MQ_msg_extra (out_msg,
2969 view_size * sizeof (struct GNUNET_PeerIdentity),
2970 GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_REPLY);
2971 out_msg->num_peers = htonl (view_size);
2972
2973 GNUNET_memcpy (&out_msg[1],
2974 view_array,
2975 view_size * sizeof (struct GNUNET_PeerIdentity));
2976 GNUNET_MQ_send (cli_ctx->mq, ev);
2977}
2978
2979/**
2980 * @brief sends updates to clients that are interested
2981 */
2982static void
2983clients_notify_view_update (void)
2984{
2985 struct ClientContext *cli_ctx_iter;
2986 uint64_t num_peers;
2987 const struct GNUNET_PeerIdentity *view_array;
2988
2989 num_peers = View_size ();
2990 view_array = View_get_as_array();
2991 /* check size of view is small enough */
2992 if (GNUNET_MAX_MESSAGE_SIZE < num_peers)
2993 {
2994 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2995 "View is too big to send\n");
2996 return;
2997 }
2998
2999 for (cli_ctx_iter = cli_ctx_head;
3000 NULL != cli_ctx_iter;
3001 cli_ctx_iter = cli_ctx_head->next)
3002 {
3003 if (1 < cli_ctx_iter->view_updates_left)
3004 {
3005 /* Client wants to receive limited amount of updates */
3006 cli_ctx_iter->view_updates_left -= 1;
3007 } else if (1 == cli_ctx_iter->view_updates_left)
3008 {
3009 /* Last update of view for client */
3010 cli_ctx_iter->view_updates_left = -1;
3011 } else if (0 > cli_ctx_iter->view_updates_left) {
3012 /* Client is not interested in updates */
3013 continue;
3014 }
3015 /* else _updates_left == 0 - infinite amount of updates */
3016
3017 /* send view */
3018 send_view (cli_ctx_iter, view_array, num_peers);
3019 }
3020}
3021
3022
3023/**
3024 * Handle RPS request from the client.
3025 *
3026 * @param cls closure
3027 * @param message the actual message
3028 */
3029static void
3030handle_client_view_request (void *cls,
3031 const struct GNUNET_RPS_CS_DEBUG_ViewRequest *msg)
3032{
3033 struct ClientContext *cli_ctx = cls;
3034 uint64_t num_updates;
3035
3036 num_updates = ntohl (msg->num_updates);
3037
3038 LOG (GNUNET_ERROR_TYPE_DEBUG,
3039 "Client requested %" PRIu64 " updates of view.\n",
3040 num_updates);
3041
3042 GNUNET_assert (NULL != cli_ctx);
3043 cli_ctx->view_updates_left = num_updates;
3044 send_view (cli_ctx, NULL, 0);
3045 GNUNET_SERVICE_client_continue (cli_ctx->client);
3046}
3047
3048/**
2943 * Handle a CHECK_LIVE message from another peer. 3049 * Handle a CHECK_LIVE message from another peer.
2944 * 3050 *
2945 * This does nothing. But without calling #GNUNET_CADET_receive_done() 3051 * This does nothing. But without calling #GNUNET_CADET_receive_done()
@@ -3554,7 +3660,6 @@ do_mal_round (void *cls)
3554} 3660}
3555#endif /* ENABLE_MALICIOUS */ 3661#endif /* ENABLE_MALICIOUS */
3556 3662
3557
3558/** 3663/**
3559 * Send out PUSHes and PULLs, possibly update #view, samplers. 3664 * Send out PUSHes and PULLs, possibly update #view, samplers.
3560 * 3665 *
@@ -3724,6 +3829,7 @@ do_round (void *cls)
3724 } 3829 }
3725 3830
3726 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, 0); 3831 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, 0);
3832 clients_notify_view_update();
3727 } else { 3833 } else {
3728 LOG (GNUNET_ERROR_TYPE_DEBUG, "No update of the view.\n"); 3834 LOG (GNUNET_ERROR_TYPE_DEBUG, "No update of the view.\n");
3729 GNUNET_STATISTICS_update(stats, "# rounds blocked", 1, GNUNET_NO); 3835 GNUNET_STATISTICS_update(stats, "# rounds blocked", 1, GNUNET_NO);
@@ -3973,6 +4079,7 @@ client_connect_cb (void *cls,
3973 return client; /* Server was destroyed before a client connected. Shutting down */ 4079 return client; /* Server was destroyed before a client connected. Shutting down */
3974 cli_ctx = GNUNET_new (struct ClientContext); 4080 cli_ctx = GNUNET_new (struct ClientContext);
3975 cli_ctx->mq = GNUNET_SERVICE_client_get_mq (client); 4081 cli_ctx->mq = GNUNET_SERVICE_client_get_mq (client);
4082 cli_ctx->view_updates_left = -1;
3976 cli_ctx->client = client; 4083 cli_ctx->client = client;
3977 GNUNET_CONTAINER_DLL_insert (cli_ctx_head, 4084 GNUNET_CONTAINER_DLL_insert (cli_ctx_head,
3978 cli_ctx_tail, 4085 cli_ctx_tail,
@@ -4216,6 +4323,10 @@ GNUNET_SERVICE_MAIN
4216 struct GNUNET_RPS_CS_ActMaliciousMessage, 4323 struct GNUNET_RPS_CS_ActMaliciousMessage,
4217 NULL), 4324 NULL),
4218#endif /* ENABLE_MALICIOUS */ 4325#endif /* ENABLE_MALICIOUS */
4326 GNUNET_MQ_hd_fixed_size (client_view_request,
4327 GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_REQUEST,
4328 struct GNUNET_RPS_CS_DEBUG_ViewRequest,
4329 NULL),
4219 GNUNET_MQ_handler_end()); 4330 GNUNET_MQ_handler_end());
4220 4331
4221/* end of gnunet-service-rps.c */ 4332/* end of gnunet-service-rps.c */
diff --git a/src/rps/rps.h b/src/rps/rps.h
index f5cc2e8d1..6a7fa3e14 100644
--- a/src/rps/rps.h
+++ b/src/rps/rps.h
@@ -176,6 +176,49 @@ struct GNUNET_RPS_CS_ActMaliciousMessage
176#endif /* ENABLE_MALICIOUS */ 176#endif /* ENABLE_MALICIOUS */
177 177
178 178
179/* Debug messages */
180
181/**
182 * Message from client to service indicating that
183 * clients wants to get updates of the view
184 */
185struct GNUNET_RPS_CS_DEBUG_ViewRequest
186{
187 /**
188 * Header including size and type in NBO
189 */
190 struct GNUNET_MessageHeader header;
191
192 /**
193 * Number of updates
194 * 0 for sending updates until cancellation
195 */
196 uint32_t num_updates GNUNET_PACKED;
197};
198
199/**
200 * Message from service to client containing current update of view
201 */
202struct GNUNET_RPS_CS_DEBUG_ViewReply
203{
204 /**
205 * Header including size and type in NBO
206 */
207 struct GNUNET_MessageHeader header;
208
209 /**
210 * Identifyer of the message.
211 */
212 uint32_t id GNUNET_PACKED;
213
214 /**
215 * Number of peers in the view
216 */
217 uint64_t num_peers GNUNET_PACKED;
218};
219 /* Followed by num_peers * GNUNET_PeerIdentity */
220
221
179/*********************************************************************** 222/***********************************************************************
180 * Defines from old gnunet-service-rps_peers.h 223 * Defines from old gnunet-service-rps_peers.h
181***********************************************************************/ 224***********************************************************************/
diff --git a/src/rps/rps_api.c b/src/rps/rps_api.c
index ccd480086..62ba9e226 100644
--- a/src/rps/rps_api.c
+++ b/src/rps/rps_api.c
@@ -56,6 +56,16 @@ struct GNUNET_RPS_Handle
56 * The id of the last request. 56 * The id of the last request.
57 */ 57 */
58 uint32_t current_request_id; 58 uint32_t current_request_id;
59
60 /**
61 * @brief Callback called on each update of the view
62 */
63 GNUNET_RPS_ViewUpdateCB view_update_cb;
64
65 /**
66 * @brief Callback called on each update of the view
67 */
68 void *view_update_cls;
59}; 69};
60 70
61 71
@@ -236,6 +246,86 @@ handle_reply (void *cls,
236} 246}
237 247
238 248
249/* Get internals for debugging/profiling purposes */
250
251/**
252 * Request updates of view
253 *
254 * @param rps_handle handle to the rps service
255 * @param num_req_peers number of peers we want to receive
256 * (0 for infinite updates)
257 * @param cls a closure that will be given to the callback
258 * @param ready_cb the callback called when the peers are available
259 */
260void
261GNUNET_RPS_view_request (struct GNUNET_RPS_Handle *rps_handle,
262 uint32_t num_updates,
263 GNUNET_RPS_ViewUpdateCB view_update_cb,
264 void *cls)
265{
266 struct GNUNET_MQ_Envelope *ev;
267 struct GNUNET_RPS_CS_DEBUG_ViewRequest *msg;
268
269 rps_handle->view_update_cb = view_update_cb;
270 rps_handle->view_update_cls = cls;
271
272 ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_REQUEST);
273 msg->num_updates = htonl (num_updates);
274 GNUNET_MQ_send (rps_handle->mq, ev);
275}
276
277/**
278 * This function is called, when the service updates the view.
279 * It verifies that @a msg is well-formed.
280 *
281 * @param cls the closure
282 * @param msg the message
283 * @return #GNUNET_OK if @a msg is well-formed
284 */
285static int
286check_view_update (void *cls,
287 const struct GNUNET_RPS_CS_DEBUG_ViewReply *msg)
288{
289 uint16_t msize = ntohs (msg->header.size);
290 uint32_t num_peers = ntohl (msg->num_peers);
291
292 msize -= sizeof (struct GNUNET_RPS_CS_DEBUG_ViewReply);
293 if ( (msize / sizeof (struct GNUNET_PeerIdentity) != num_peers) ||
294 (msize % sizeof (struct GNUNET_PeerIdentity) != 0) )
295 {
296 GNUNET_break (0);
297 return GNUNET_SYSERR;
298 }
299 return GNUNET_OK;
300}
301
302/**
303 * This function is called, when the service updated its view.
304 * It calls the callback the caller provided
305 * and disconnects afterwards.
306 *
307 * @param msg the message
308 */
309static void
310handle_view_update (void *cls,
311 const struct GNUNET_RPS_CS_DEBUG_ViewReply *msg)
312{
313 struct GNUNET_RPS_Handle *h = cls;
314 struct GNUNET_PeerIdentity *peers;
315
316 /* Give the peers back */
317 LOG (GNUNET_ERROR_TYPE_DEBUG,
318 "New view of %" PRIu32 " peers:\n",
319 ntohl (msg->num_peers));
320
321 peers = (struct GNUNET_PeerIdentity *) &msg[1];
322 GNUNET_assert (NULL != h);
323 GNUNET_assert (NULL != h->view_update_cb);
324 h->view_update_cb (h->view_update_cls, ntohl (msg->num_peers), peers);
325}
326
327
328
239/** 329/**
240 * Reconnect to the service 330 * Reconnect to the service
241 */ 331 */
@@ -281,6 +371,10 @@ reconnect (struct GNUNET_RPS_Handle *h)
281 GNUNET_MESSAGE_TYPE_RPS_CS_REPLY, 371 GNUNET_MESSAGE_TYPE_RPS_CS_REPLY,
282 struct GNUNET_RPS_CS_ReplyMessage, 372 struct GNUNET_RPS_CS_ReplyMessage,
283 h), 373 h),
374 GNUNET_MQ_hd_var_size (view_update,
375 GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_REPLY,
376 struct GNUNET_RPS_CS_DEBUG_ViewReply,
377 h),
284 GNUNET_MQ_handler_end () 378 GNUNET_MQ_handler_end ()
285 }; 379 };
286 380
@@ -306,6 +400,7 @@ GNUNET_RPS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
306 struct GNUNET_RPS_Handle *h; 400 struct GNUNET_RPS_Handle *h;
307 401
308 h = GNUNET_new (struct GNUNET_RPS_Handle); 402 h = GNUNET_new (struct GNUNET_RPS_Handle);
403 h->current_request_id = 0;
309 h->cfg = cfg; 404 h->cfg = cfg;
310 reconnect (h); 405 reconnect (h);
311 if (NULL == h->mq) 406 if (NULL == h->mq)