mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-03-01 00:59:49 +01:00
For various reasons, this was a nontrivial movement. There are several places in the code where we do something like "update the flags on this routerstatus or node if we're an authority", and at least one where we pretended to be an authority when we weren't.
98 lines
3.2 KiB
C
98 lines
3.2 KiB
C
/* Copyright (c) 2001-2004, Roger Dingledine.
|
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
|
* Copyright (c) 2007-2019, The Tor Project, Inc. */
|
|
/* See LICENSE for licensing information */
|
|
|
|
#include "core/or/or.h"
|
|
#include "feature/control/fmt_serverstatus.h"
|
|
|
|
#include "app/config/config.h"
|
|
#include "feature/dirauth/authmode.h"
|
|
#include "feature/dirauth/voteflags.h"// XXXX remove
|
|
#include "feature/nodelist/nodelist.h"
|
|
#include "feature/nodelist/routerinfo.h"
|
|
|
|
#include "feature/nodelist/node_st.h"
|
|
#include "feature/nodelist/routerinfo_st.h"
|
|
|
|
/**
|
|
* Allocate and return a description of the status of the server <b>desc</b>,
|
|
* for use in a v1-style router-status line. The server is listed
|
|
* as running iff <b>is_live</b> is true.
|
|
*
|
|
* This is deprecated: it's only used for controllers that want outputs in
|
|
* the old format.
|
|
*/
|
|
static char *
|
|
list_single_server_status(const routerinfo_t *desc, int is_live)
|
|
{
|
|
char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
|
|
char *cp;
|
|
const node_t *node;
|
|
|
|
tor_assert(desc);
|
|
|
|
cp = buf;
|
|
if (!is_live) {
|
|
*cp++ = '!';
|
|
}
|
|
node = node_get_by_id(desc->cache_info.identity_digest);
|
|
if (node && node->is_valid) {
|
|
strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
|
|
cp += strlen(cp);
|
|
*cp++ = '=';
|
|
}
|
|
*cp++ = '$';
|
|
base16_encode(cp, HEX_DIGEST_LEN+1, desc->cache_info.identity_digest,
|
|
DIGEST_LEN);
|
|
return tor_strdup(buf);
|
|
}
|
|
|
|
/** Based on the routerinfo_ts in <b>routers</b>, allocate the
|
|
* contents of a v1-style router-status line, and store it in
|
|
* *<b>router_status_out</b>. Return 0 on success, -1 on failure.
|
|
*
|
|
* If for_controller is true, include the routers with very old descriptors.
|
|
*
|
|
* This is deprecated: it's only used for controllers that want outputs in
|
|
* the old format.
|
|
*/
|
|
int
|
|
list_server_status_v1(smartlist_t *routers, char **router_status_out,
|
|
int for_controller)
|
|
{
|
|
/* List of entries in a router-status style: An optional !, then an optional
|
|
* equals-suffixed nickname, then a dollar-prefixed hexdigest. */
|
|
smartlist_t *rs_entries;
|
|
time_t now = time(NULL);
|
|
time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
|
|
/* We include v2 dir auths here too, because they need to answer
|
|
* controllers. Eventually we'll deprecate this whole function;
|
|
* see also networkstatus_getinfo_by_purpose(). */
|
|
tor_assert(router_status_out);
|
|
|
|
rs_entries = smartlist_new();
|
|
|
|
SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
|
|
const node_t *node = node_get_by_id(ri->cache_info.identity_digest);
|
|
tor_assert(node);
|
|
if (for_controller) {
|
|
char name_buf[MAX_VERBOSE_NICKNAME_LEN+2];
|
|
char *cp = name_buf;
|
|
if (!node->is_running)
|
|
*cp++ = '!';
|
|
router_get_verbose_nickname(cp, ri);
|
|
smartlist_add_strdup(rs_entries, name_buf);
|
|
} else if (ri->cache_info.published_on >= cutoff) {
|
|
smartlist_add(rs_entries, list_single_server_status(ri,
|
|
node->is_running));
|
|
}
|
|
} SMARTLIST_FOREACH_END(ri);
|
|
|
|
*router_status_out = smartlist_join_strings(rs_entries, " ", 0, NULL);
|
|
|
|
SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp));
|
|
smartlist_free(rs_entries);
|
|
|
|
return 0;
|
|
}
|