summaryrefslogtreecommitdiff
path: root/src/arm/arm_api.c
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2019-09-24 17:59:18 +0200
committerFlorian Dold <florian.dold@gmail.com>2019-09-24 17:59:18 +0200
commit6aa35f62a80056f31ccd97133a0764a0950e1566 (patch)
tree1a42157c50d6cd3d3332e6b4554a94222bc6adb9 /src/arm/arm_api.c
parent2e2790e1b4a563ef471be1b604c6ebee55f89203 (diff)
downloadgnunet-6aa35f62a80056f31ccd97133a0764a0950e1566.tar.gz
gnunet-6aa35f62a80056f31ccd97133a0764a0950e1566.zip
implement extended status information for arm
Diffstat (limited to 'src/arm/arm_api.c')
-rw-r--r--src/arm/arm_api.c102
1 files changed, 79 insertions, 23 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index b42c95dc0..4c3bb0488 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -294,7 +294,32 @@ handle_arm_result(void *cls, const struct GNUNET_ARM_ResultMessage *res)
294 294
295 295
296/** 296/**
297 * Checked that list result message is well-formed. 297 * Read from a string pool.
298 *
299 * @param pool_start start of the string pool
300 * @param pool_size size of the string pool
301 * @param str_index index into the string pool
302 * @returns an index into the string pool, or
303 * NULL if the index is out of bounds
304 */
305static const char *
306pool_get (const char *pool_start, size_t pool_size, size_t str_index)
307{
308 const char *str_start;
309 const char *end;
310
311 if (str_index >= pool_size)
312 return NULL;
313 str_start = pool_start + str_index;
314 end = memchr(str_start, 0, pool_size - str_index);
315 if (NULL == end)
316 return NULL;
317 return str_start;
318}
319
320
321/**
322 * Check that list result message is well-formed.
298 * 323 *
299 * @param cls our `struct GNUNET_ARM_Handle` 324 * @param cls our `struct GNUNET_ARM_Handle`
300 * @param lres the message received from the arm service 325 * @param lres the message received from the arm service
@@ -304,23 +329,38 @@ static int
304check_arm_list_result(void *cls, 329check_arm_list_result(void *cls,
305 const struct GNUNET_ARM_ListResultMessage *lres) 330 const struct GNUNET_ARM_ListResultMessage *lres)
306{ 331{
307 const char *pos = (const char *)&lres[1];
308 uint16_t rcount = ntohs(lres->count); 332 uint16_t rcount = ntohs(lres->count);
309 uint16_t msize = ntohs(lres->arm_msg.header.size) - sizeof(*lres); 333 uint16_t msize = ntohs(lres->arm_msg.header.size) - sizeof(*lres);
310 uint16_t size_check; 334 struct GNUNET_ARM_ServiceInfoMessage *ssm;
335 size_t pool_size;
336 char *pool_start;
337
338 if ((rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage) > msize))
339 {
340 GNUNET_break_op (0);
341 return GNUNET_NO;
342 }
343
344 ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &lres[1];
345 pool_start = (char *) (ssm + rcount);
346 pool_size = msize - (rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage));
311 347
312 (void)cls; 348 (void)cls;
313 size_check = 0;
314 for (unsigned int i = 0; i < rcount; i++) 349 for (unsigned int i = 0; i < rcount; i++)
315 { 350 {
316 const char *end = memchr(pos, 0, msize - size_check); 351 uint16_t name_index = ntohs (ssm->name_index);
317 if (NULL == end) 352 uint16_t binary_index = ntohs (ssm->binary_index);
318 { 353 if (NULL == pool_get (pool_start, pool_size, name_index))
319 GNUNET_break(0); 354 {
320 return GNUNET_SYSERR; 355 GNUNET_break_op (0);
321 } 356 return GNUNET_NO;
322 size_check += (end - pos) + 1; 357 }
323 pos = end + 1; 358 if (NULL == pool_get (pool_start, pool_size, binary_index))
359 {
360 GNUNET_break_op (0);
361 return GNUNET_NO;
362 }
363 ssm++;
324 } 364 }
325 return GNUNET_OK; 365 return GNUNET_OK;
326} 366}
@@ -338,12 +378,13 @@ handle_arm_list_result(void *cls,
338{ 378{
339 struct GNUNET_ARM_Handle *h = cls; 379 struct GNUNET_ARM_Handle *h = cls;
340 uint16_t rcount = ntohs(lres->count); 380 uint16_t rcount = ntohs(lres->count);
341 const char *list[rcount];
342 const char *pos = (const char *)&lres[1];
343 uint16_t msize = ntohs(lres->arm_msg.header.size) - sizeof(*lres); 381 uint16_t msize = ntohs(lres->arm_msg.header.size) - sizeof(*lres);
382 struct GNUNET_ARM_ServiceInfo list[rcount];
383 struct GNUNET_ARM_ServiceInfoMessage *ssm;
344 struct GNUNET_ARM_Operation *op; 384 struct GNUNET_ARM_Operation *op;
345 uint16_t size_check;
346 uint64_t id; 385 uint64_t id;
386 size_t pool_size;
387 char *pool_start;
347 388
348 id = GNUNET_ntohll(lres->arm_msg.request_id); 389 id = GNUNET_ntohll(lres->arm_msg.request_id);
349 op = find_op_by_id(h, id); 390 op = find_op_by_id(h, id);
@@ -354,16 +395,31 @@ handle_arm_list_result(void *cls,
354 (unsigned long long)id); 395 (unsigned long long)id);
355 return; 396 return;
356 } 397 }
357 size_check = 0; 398
399 GNUNET_assert ((rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage) <= msize));
400
401 ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &lres[1];
402 pool_start = (char *) (ssm + rcount);
403 pool_size = msize - (rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage));
404
358 for (unsigned int i = 0; i < rcount; i++) 405 for (unsigned int i = 0; i < rcount; i++)
359 { 406 {
360 const char *end = memchr(pos, 0, msize - size_check); 407 uint16_t name_index = ntohs (ssm->name_index);
361 408 uint16_t binary_index = ntohs (ssm->binary_index);
362 /* Assert, as this was already checked in #check_arm_list_result() */ 409 const char *name;
363 GNUNET_assert(NULL != end); 410 const char *binary;
364 list[i] = pos; 411
365 size_check += (end - pos) + 1; 412 GNUNET_assert (NULL != (name = pool_get (pool_start, pool_size, name_index)));
366 pos = end + 1; 413 GNUNET_assert (NULL != (binary = pool_get (pool_start, pool_size, binary_index)));
414 list[i] = (struct GNUNET_ARM_ServiceInfo) {
415 .name = name,
416 .binary = binary,
417 .status = ntohl (ssm->status),
418 .last_started_at = GNUNET_TIME_absolute_ntoh (ssm->last_started_at),
419 .restart_at = GNUNET_TIME_absolute_ntoh (ssm->restart_at),
420 .last_exit_status = ntohs (ssm->last_exit_status),
421 };
422 ssm++;
367 } 423 }
368 if (NULL != op->list_cont) 424 if (NULL != op->list_cont)
369 op->list_cont(op->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, rcount, list); 425 op->list_cont(op->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, rcount, list);