diff options
author | Florian Dold <florian.dold@gmail.com> | 2019-09-24 17:59:18 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2019-09-24 17:59:18 +0200 |
commit | 6aa35f62a80056f31ccd97133a0764a0950e1566 (patch) | |
tree | 1a42157c50d6cd3d3332e6b4554a94222bc6adb9 /src/arm/arm_api.c | |
parent | 2e2790e1b4a563ef471be1b604c6ebee55f89203 (diff) | |
download | gnunet-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.c | 102 |
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 | */ | ||
305 | static const char * | ||
306 | pool_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 | |||
304 | check_arm_list_result(void *cls, | 329 | check_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); |