fmt_serverstatus.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "core/or/or.h"
  6. #include "feature/control/fmt_serverstatus.h"
  7. #include "app/config/config.h"
  8. #include "feature/dirauth/authmode.h"
  9. #include "feature/dirauth/voteflags.h"// XXXX remove
  10. #include "feature/nodelist/nodelist.h"
  11. #include "feature/nodelist/routerinfo.h"
  12. #include "feature/nodelist/node_st.h"
  13. #include "feature/nodelist/routerinfo_st.h"
  14. /**
  15. * Allocate and return a description of the status of the server <b>desc</b>,
  16. * for use in a v1-style router-status line. The server is listed
  17. * as running iff <b>is_live</b> is true.
  18. *
  19. * This is deprecated: it's only used for controllers that want outputs in
  20. * the old format.
  21. */
  22. static char *
  23. list_single_server_status(const routerinfo_t *desc, int is_live)
  24. {
  25. char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
  26. char *cp;
  27. const node_t *node;
  28. tor_assert(desc);
  29. cp = buf;
  30. if (!is_live) {
  31. *cp++ = '!';
  32. }
  33. node = node_get_by_id(desc->cache_info.identity_digest);
  34. if (node && node->is_valid) {
  35. strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
  36. cp += strlen(cp);
  37. *cp++ = '=';
  38. }
  39. *cp++ = '$';
  40. base16_encode(cp, HEX_DIGEST_LEN+1, desc->cache_info.identity_digest,
  41. DIGEST_LEN);
  42. return tor_strdup(buf);
  43. }
  44. /** Based on the routerinfo_ts in <b>routers</b>, allocate the
  45. * contents of a v1-style router-status line, and store it in
  46. * *<b>router_status_out</b>. Return 0 on success, -1 on failure.
  47. *
  48. * If for_controller is true, include the routers with very old descriptors.
  49. *
  50. * This is deprecated: it's only used for controllers that want outputs in
  51. * the old format.
  52. */
  53. int
  54. list_server_status_v1(smartlist_t *routers, char **router_status_out,
  55. int for_controller)
  56. {
  57. /* List of entries in a router-status style: An optional !, then an optional
  58. * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
  59. smartlist_t *rs_entries;
  60. time_t now = time(NULL);
  61. time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
  62. const or_options_t *options = get_options();
  63. /* We include v2 dir auths here too, because they need to answer
  64. * controllers. Eventually we'll deprecate this whole function;
  65. * see also networkstatus_getinfo_by_purpose(). */
  66. int authdir = authdir_mode_publishes_statuses(options);
  67. tor_assert(router_status_out);
  68. rs_entries = smartlist_new();
  69. SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
  70. const node_t *node = node_get_by_id(ri->cache_info.identity_digest);
  71. tor_assert(node);
  72. if (authdir) {
  73. /* Update router status in routerinfo_t. */
  74. dirserv_set_router_is_running(ri, now);
  75. }
  76. if (for_controller) {
  77. char name_buf[MAX_VERBOSE_NICKNAME_LEN+2];
  78. char *cp = name_buf;
  79. if (!node->is_running)
  80. *cp++ = '!';
  81. router_get_verbose_nickname(cp, ri);
  82. smartlist_add_strdup(rs_entries, name_buf);
  83. } else if (ri->cache_info.published_on >= cutoff) {
  84. smartlist_add(rs_entries, list_single_server_status(ri,
  85. node->is_running));
  86. }
  87. } SMARTLIST_FOREACH_END(ri);
  88. *router_status_out = smartlist_join_strings(rs_entries, " ", 0, NULL);
  89. SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp));
  90. smartlist_free(rs_entries);
  91. return 0;
  92. }