Loading src/or/control.c +183 −23 Original line number Diff line number Diff line Loading @@ -2053,6 +2053,29 @@ getinfo_helper_dir(control_connection_t *control_conn, return 0; } /** Turn a smartlist of digests into a human-readable list of hex strings */ static char * digest_list_to_string(smartlist_t *sl) { int len; char *result, *s; /* Allow for newlines, and a \0 at the end */ len = smartlist_len(sl) * (HEX_DIGEST_LEN + 1) + 1; result = tor_malloc_zero(len); s = result; SMARTLIST_FOREACH_BEGIN(sl, char *, digest) { base16_encode(s, HEX_DIGEST_LEN + 1, digest, DIGEST_LEN); s[HEX_DIGEST_LEN] = '\n'; s += HEX_DIGEST_LEN + 1; } SMARTLIST_FOREACH_END(digest); *s = '\0'; return result; } /** Turn a download_status_t into a human-readable description in a newly * allocated string. */ Loading Loading @@ -2155,6 +2178,135 @@ download_status_to_string(const download_status_t *dl) return rv; } /** Handle the consensus download cases for getinfo_helper_downloads() */ static void getinfo_helper_downloads_networkstatus(const char *flavor, download_status_t **dl_to_emit, const char **errmsg) { /* * We get the one for the current bootstrapped status by default, or * take an extra /bootstrap or /running suffix */ if (strcmp(flavor, "ns") == 0) { *dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_NS); } else if (strcmp(flavor, "ns/bootstrap") == 0) { *dl_to_emit = networkstatus_get_dl_status_by_flavor_bootstrap(FLAV_NS); } else if (strcmp(flavor, "ns/running") == 0 ) { *dl_to_emit = networkstatus_get_dl_status_by_flavor_running(FLAV_NS); } else if (strcmp(flavor, "microdesc") == 0) { *dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_MICRODESC); } else if (strcmp(flavor, "microdesc/bootstrap") == 0) { *dl_to_emit = networkstatus_get_dl_status_by_flavor_bootstrap(FLAV_MICRODESC); } else if (strcmp(flavor, "microdesc/running") == 0) { *dl_to_emit = networkstatus_get_dl_status_by_flavor_running(FLAV_MICRODESC); } else { *errmsg = "Unknown flavor"; } } /** Handle the cert download cases for getinfo_helper_downloads() */ static void getinfo_helper_downloads_cert(const char *fp_sk_req, download_status_t **dl_to_emit, smartlist_t **digest_list, const char **errmsg) { const char *sk_req; char id_digest[DIGEST_LEN]; char sk_digest[DIGEST_LEN]; /* * We have to handle four cases; fp_sk_req is the request with * a prefix of "downloads/cert/" snipped off. * * Case 1: fp_sk_req = "fps" * - We should emit a digest_list with a list of all the identity * fingerprints that can be queried for certificate download status; * get it by calling list_authority_ids_with_downloads(). * * Case 2: fp_sk_req = "fp/<fp>" for some fingerprint fp * - We want the default certificate for this identity fingerprint's * download status; this is the download we get from URLs starting * in /fp/ on the directory server. We can get it with * id_only_download_status_for_authority_id(). * * Case 3: fp_sk_req = "fp/<fp>/sks" for some fingerprint fp * - We want a list of all signing key digests for this identity * fingerprint which can be queried for certificate download status. * Get it with list_sk_digests_for_authority_id(). * * Case 4: fp_sk_req = "fp/<fp>/<sk>" for some fingerprint fp and * signing key digest sk * - We want the download status for the certificate for this specific * signing key and fingerprint. These correspond to the ones we get * from URLs starting in /fp-sk/ on the directory server. Get it with * list_sk_digests_for_authority_id(). */ if (strcmp(fp_sk_req, "fps") == 0) { *digest_list = list_authority_ids_with_downloads(); if (!(*digest_list)) { *errmsg = "Failed to get list of authority identity digests (!)"; } } else if (!strcmpstart(fp_sk_req, "fp/")) { fp_sk_req += strlen("fp/"); /* Okay, look for another / to tell the fp from fp-sk cases */ sk_req = strchr(fp_sk_req, '/'); if (sk_req) { /* okay, split it here and try to parse <fp> */ if (base16_decode(id_digest, DIGEST_LEN, fp_sk_req, sk_req - fp_sk_req) == DIGEST_LEN) { /* Skip past the '/' */ ++sk_req; if (strcmp(sk_req, "sks") == 0) { /* We're asking for the list of signing key fingerprints */ *digest_list = list_sk_digests_for_authority_id(id_digest); if (!(*digest_list)) { *errmsg = "Failed to get list of signing key digests for this " "authority identity digest"; } } else { /* We've got a signing key digest */ if (base16_decode(sk_digest, DIGEST_LEN, sk_req, strlen(sk_req)) == DIGEST_LEN) { *dl_to_emit = download_status_for_authority_id_and_sk(id_digest, sk_digest); if (!(*dl_to_emit)) { *errmsg = "Failed to get download status for this identity/" "signing key digest pair"; } } else { *errmsg = "That didn't look like a signing key digest"; } } } else { *errmsg = "That didn't look like an identity digest"; } } else { /* We're either in downloads/certs/fp/<fp>, or we can't parse <fp> */ if (strlen(fp_sk_req) == HEX_DIGEST_LEN) { if (base16_decode(id_digest, DIGEST_LEN, fp_sk_req, strlen(fp_sk_req)) == DIGEST_LEN) { *dl_to_emit = id_only_download_status_for_authority_id(id_digest); if (!(*dl_to_emit)) { *errmsg = "Failed to get download status for this authority " "identity digest"; } } else { *errmsg = "That didn't look like a digest"; } } else { *errmsg = "That didn't look like a digest"; } } } else { *errmsg = "Unknown certificate download status query"; } } /** Implementation helper for GETINFO: knows the answers for questions about * download status information. */ static int Loading @@ -2162,8 +2314,8 @@ getinfo_helper_downloads(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg) { const char *flavor; download_status_t *dl_to_emit = NULL; smartlist_t *digest_list = NULL; /* Assert args are sane */ tor_assert(control_conn != NULL); Loading @@ -2176,33 +2328,26 @@ getinfo_helper_downloads(control_connection_t *control_conn, /* Are we after networkstatus downloads? */ if (!strcmpstart(question, "downloads/networkstatus/")) { flavor = question + strlen("downloads/networkstatus/"); /* * We get the one for the current bootstrapped status by default, or * take an extra /bootstrap or /running suffix */ if (strcmp(flavor, "ns") == 0) { dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_NS); } else if (strcmp(flavor, "ns/bootstrap") == 0) { dl_to_emit = networkstatus_get_dl_status_by_flavor_bootstrap(FLAV_NS); } else if (strcmp(flavor, "ns/running") == 0 ) { dl_to_emit = networkstatus_get_dl_status_by_flavor_running(FLAV_NS); } else if (strcmp(flavor, "microdesc") == 0) { dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_MICRODESC); } else if (strcmp(flavor, "microdesc/bootstrap") == 0) { dl_to_emit = networkstatus_get_dl_status_by_flavor_bootstrap(FLAV_MICRODESC); } else if (strcmp(flavor, "microdesc/running") == 0) { dl_to_emit = networkstatus_get_dl_status_by_flavor_running(FLAV_MICRODESC); getinfo_helper_downloads_networkstatus( question + strlen("downloads/networkstatus/"), &dl_to_emit, errmsg); } else if (!strcmpstart(question, "downloads/cert/")) { getinfo_helper_downloads_cert( question + strlen("downloads/cert/"), &dl_to_emit, &digest_list, errmsg); } else { *errmsg = "Unknown flavor"; } *errmsg = "Unknown download status query"; } if (dl_to_emit) { *answer = download_status_to_string(dl_to_emit); return 0; } else if (digest_list) { *answer = digest_list_to_string(digest_list); SMARTLIST_FOREACH(digest_list, void *, s, tor_free(s)); smartlist_free(digest_list); return 0; } else { if (!(*errmsg)) { Loading Loading @@ -2666,6 +2811,21 @@ static const getinfo_item_t getinfo_items[] = { "Download status for bootstrap-time microdesc download"), DOC("downloads/networkstatus/microdesc/running", "Download status for run-time microdesc download"), PREFIX("downloads/cert/", downloads, "Download statuses for certificates, by id fingerprint and " "signing key"), DOC("downloads/cert/fps", "List of authority fingerprints for which any download statuses " "exist"), DOC("downloads/cert/fp/<fp>", "Download status for <fp> with the default signing key; corresponds " "to /fp/ URLs on directory server."), DOC("downloads/cert/fp/<fp>/sks", "List of signing keys for which specific download statuses are " "available for this id fingerprint"), DOC("downloads/cert/fp/<fp>/<sk>", "Download status for <fp> with signing key <sk>; corresponds " "to /fp-sk/ URLs on directory server."), ITEM("info/names", misc, "List of GETINFO options, types, and documentation."), ITEM("events/names", misc, Loading src/or/routerlist.c +106 −0 Original line number Diff line number Diff line Loading @@ -253,6 +253,112 @@ get_cert_list(const char *id_digest) return cl; } /** Return a list of authority ID digests with potentially enumerable lists * of download_status_t objects; used by controller GETINFO queries. */ smartlist_t * list_authority_ids_with_downloads(void) { smartlist_t *ids = smartlist_new(); digestmap_iter_t *i; const char *digest; char *tmp; void *cl; if (trusted_dir_certs) { for (i = digestmap_iter_init(trusted_dir_certs); !(digestmap_iter_done(i)); i = digestmap_iter_next(trusted_dir_certs, i)) { /* * We always have at least dl_status_by_id to query, so no need to * probe deeper than the existence of a cert_list_t. */ digestmap_iter_get(i, &digest, &cl); tmp = tor_malloc(DIGEST_LEN); memcpy(tmp, digest, DIGEST_LEN); smartlist_add(ids, tmp); } } /* else definitely no downlaods going since nothing even has a cert list */ return ids; } /** Given an authority ID digest, return a pointer to the default download * status, or NULL if there is no such entry in trusted_dir_certs */ download_status_t * id_only_download_status_for_authority_id(const char *digest) { download_status_t *dl = NULL; cert_list_t *cl; if (trusted_dir_certs) { cl = digestmap_get(trusted_dir_certs, digest); if (cl) { dl = &(cl->dl_status_by_id); } } return dl; } /** Given an authority ID digest, return a smartlist of signing key digests * for which download_status_t is potentially queryable, or NULL if no such * authority ID digest is known. */ smartlist_t * list_sk_digests_for_authority_id(const char *digest) { smartlist_t *sks = NULL; cert_list_t *cl; dsmap_iter_t *i; const char *sk_digest; char *tmp; download_status_t *dl; if (trusted_dir_certs) { cl = digestmap_get(trusted_dir_certs, digest); if (cl) { sks = smartlist_new(); if (cl->dl_status_map) { for (i = dsmap_iter_init(cl->dl_status_map); !(dsmap_iter_done(i)); i = dsmap_iter_next(cl->dl_status_map, i)) { /* Pull the digest out and add it to the list */ dsmap_iter_get(i, &sk_digest, &dl); tmp = tor_malloc(DIGEST_LEN); memcpy(tmp, sk_digest, DIGEST_LEN); smartlist_add(sks, tmp); } } } } return sks; } /** Given an authority ID digest and a signing key digest, return the * download_status_t or NULL if none exists. */ download_status_t * download_status_for_authority_id_and_sk(const char *id_digest, const char *sk_digest) { download_status_t *dl = NULL; cert_list_t *cl = NULL; if (trusted_dir_certs) { cl = digestmap_get(trusted_dir_certs, id_digest); if (cl && cl->dl_status_map) { dl = dsmap_get(cl->dl_status_map, sk_digest); } } return dl; } /** Release all space held by a cert_list_t */ static void cert_list_free(cert_list_t *cl) Loading src/or/routerlist.h +8 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,14 @@ void routerlist_remove(routerlist_t *rl, routerinfo_t *ri, int make_old, void routerlist_free_all(void); void routerlist_reset_warnings(void); smartlist_t * list_authority_ids_with_downloads(void); download_status_t * id_only_download_status_for_authority_id( const char *digest); smartlist_t * list_sk_digests_for_authority_id(const char *digest); download_status_t * download_status_for_authority_id_and_sk( const char *id_digest, const char *sk_digest); static int WRA_WAS_ADDED(was_router_added_t s); static int WRA_WAS_OUTDATED(was_router_added_t s); static int WRA_WAS_REJECTED(was_router_added_t s); Loading Loading
src/or/control.c +183 −23 Original line number Diff line number Diff line Loading @@ -2053,6 +2053,29 @@ getinfo_helper_dir(control_connection_t *control_conn, return 0; } /** Turn a smartlist of digests into a human-readable list of hex strings */ static char * digest_list_to_string(smartlist_t *sl) { int len; char *result, *s; /* Allow for newlines, and a \0 at the end */ len = smartlist_len(sl) * (HEX_DIGEST_LEN + 1) + 1; result = tor_malloc_zero(len); s = result; SMARTLIST_FOREACH_BEGIN(sl, char *, digest) { base16_encode(s, HEX_DIGEST_LEN + 1, digest, DIGEST_LEN); s[HEX_DIGEST_LEN] = '\n'; s += HEX_DIGEST_LEN + 1; } SMARTLIST_FOREACH_END(digest); *s = '\0'; return result; } /** Turn a download_status_t into a human-readable description in a newly * allocated string. */ Loading Loading @@ -2155,6 +2178,135 @@ download_status_to_string(const download_status_t *dl) return rv; } /** Handle the consensus download cases for getinfo_helper_downloads() */ static void getinfo_helper_downloads_networkstatus(const char *flavor, download_status_t **dl_to_emit, const char **errmsg) { /* * We get the one for the current bootstrapped status by default, or * take an extra /bootstrap or /running suffix */ if (strcmp(flavor, "ns") == 0) { *dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_NS); } else if (strcmp(flavor, "ns/bootstrap") == 0) { *dl_to_emit = networkstatus_get_dl_status_by_flavor_bootstrap(FLAV_NS); } else if (strcmp(flavor, "ns/running") == 0 ) { *dl_to_emit = networkstatus_get_dl_status_by_flavor_running(FLAV_NS); } else if (strcmp(flavor, "microdesc") == 0) { *dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_MICRODESC); } else if (strcmp(flavor, "microdesc/bootstrap") == 0) { *dl_to_emit = networkstatus_get_dl_status_by_flavor_bootstrap(FLAV_MICRODESC); } else if (strcmp(flavor, "microdesc/running") == 0) { *dl_to_emit = networkstatus_get_dl_status_by_flavor_running(FLAV_MICRODESC); } else { *errmsg = "Unknown flavor"; } } /** Handle the cert download cases for getinfo_helper_downloads() */ static void getinfo_helper_downloads_cert(const char *fp_sk_req, download_status_t **dl_to_emit, smartlist_t **digest_list, const char **errmsg) { const char *sk_req; char id_digest[DIGEST_LEN]; char sk_digest[DIGEST_LEN]; /* * We have to handle four cases; fp_sk_req is the request with * a prefix of "downloads/cert/" snipped off. * * Case 1: fp_sk_req = "fps" * - We should emit a digest_list with a list of all the identity * fingerprints that can be queried for certificate download status; * get it by calling list_authority_ids_with_downloads(). * * Case 2: fp_sk_req = "fp/<fp>" for some fingerprint fp * - We want the default certificate for this identity fingerprint's * download status; this is the download we get from URLs starting * in /fp/ on the directory server. We can get it with * id_only_download_status_for_authority_id(). * * Case 3: fp_sk_req = "fp/<fp>/sks" for some fingerprint fp * - We want a list of all signing key digests for this identity * fingerprint which can be queried for certificate download status. * Get it with list_sk_digests_for_authority_id(). * * Case 4: fp_sk_req = "fp/<fp>/<sk>" for some fingerprint fp and * signing key digest sk * - We want the download status for the certificate for this specific * signing key and fingerprint. These correspond to the ones we get * from URLs starting in /fp-sk/ on the directory server. Get it with * list_sk_digests_for_authority_id(). */ if (strcmp(fp_sk_req, "fps") == 0) { *digest_list = list_authority_ids_with_downloads(); if (!(*digest_list)) { *errmsg = "Failed to get list of authority identity digests (!)"; } } else if (!strcmpstart(fp_sk_req, "fp/")) { fp_sk_req += strlen("fp/"); /* Okay, look for another / to tell the fp from fp-sk cases */ sk_req = strchr(fp_sk_req, '/'); if (sk_req) { /* okay, split it here and try to parse <fp> */ if (base16_decode(id_digest, DIGEST_LEN, fp_sk_req, sk_req - fp_sk_req) == DIGEST_LEN) { /* Skip past the '/' */ ++sk_req; if (strcmp(sk_req, "sks") == 0) { /* We're asking for the list of signing key fingerprints */ *digest_list = list_sk_digests_for_authority_id(id_digest); if (!(*digest_list)) { *errmsg = "Failed to get list of signing key digests for this " "authority identity digest"; } } else { /* We've got a signing key digest */ if (base16_decode(sk_digest, DIGEST_LEN, sk_req, strlen(sk_req)) == DIGEST_LEN) { *dl_to_emit = download_status_for_authority_id_and_sk(id_digest, sk_digest); if (!(*dl_to_emit)) { *errmsg = "Failed to get download status for this identity/" "signing key digest pair"; } } else { *errmsg = "That didn't look like a signing key digest"; } } } else { *errmsg = "That didn't look like an identity digest"; } } else { /* We're either in downloads/certs/fp/<fp>, or we can't parse <fp> */ if (strlen(fp_sk_req) == HEX_DIGEST_LEN) { if (base16_decode(id_digest, DIGEST_LEN, fp_sk_req, strlen(fp_sk_req)) == DIGEST_LEN) { *dl_to_emit = id_only_download_status_for_authority_id(id_digest); if (!(*dl_to_emit)) { *errmsg = "Failed to get download status for this authority " "identity digest"; } } else { *errmsg = "That didn't look like a digest"; } } else { *errmsg = "That didn't look like a digest"; } } } else { *errmsg = "Unknown certificate download status query"; } } /** Implementation helper for GETINFO: knows the answers for questions about * download status information. */ static int Loading @@ -2162,8 +2314,8 @@ getinfo_helper_downloads(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg) { const char *flavor; download_status_t *dl_to_emit = NULL; smartlist_t *digest_list = NULL; /* Assert args are sane */ tor_assert(control_conn != NULL); Loading @@ -2176,33 +2328,26 @@ getinfo_helper_downloads(control_connection_t *control_conn, /* Are we after networkstatus downloads? */ if (!strcmpstart(question, "downloads/networkstatus/")) { flavor = question + strlen("downloads/networkstatus/"); /* * We get the one for the current bootstrapped status by default, or * take an extra /bootstrap or /running suffix */ if (strcmp(flavor, "ns") == 0) { dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_NS); } else if (strcmp(flavor, "ns/bootstrap") == 0) { dl_to_emit = networkstatus_get_dl_status_by_flavor_bootstrap(FLAV_NS); } else if (strcmp(flavor, "ns/running") == 0 ) { dl_to_emit = networkstatus_get_dl_status_by_flavor_running(FLAV_NS); } else if (strcmp(flavor, "microdesc") == 0) { dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_MICRODESC); } else if (strcmp(flavor, "microdesc/bootstrap") == 0) { dl_to_emit = networkstatus_get_dl_status_by_flavor_bootstrap(FLAV_MICRODESC); } else if (strcmp(flavor, "microdesc/running") == 0) { dl_to_emit = networkstatus_get_dl_status_by_flavor_running(FLAV_MICRODESC); getinfo_helper_downloads_networkstatus( question + strlen("downloads/networkstatus/"), &dl_to_emit, errmsg); } else if (!strcmpstart(question, "downloads/cert/")) { getinfo_helper_downloads_cert( question + strlen("downloads/cert/"), &dl_to_emit, &digest_list, errmsg); } else { *errmsg = "Unknown flavor"; } *errmsg = "Unknown download status query"; } if (dl_to_emit) { *answer = download_status_to_string(dl_to_emit); return 0; } else if (digest_list) { *answer = digest_list_to_string(digest_list); SMARTLIST_FOREACH(digest_list, void *, s, tor_free(s)); smartlist_free(digest_list); return 0; } else { if (!(*errmsg)) { Loading Loading @@ -2666,6 +2811,21 @@ static const getinfo_item_t getinfo_items[] = { "Download status for bootstrap-time microdesc download"), DOC("downloads/networkstatus/microdesc/running", "Download status for run-time microdesc download"), PREFIX("downloads/cert/", downloads, "Download statuses for certificates, by id fingerprint and " "signing key"), DOC("downloads/cert/fps", "List of authority fingerprints for which any download statuses " "exist"), DOC("downloads/cert/fp/<fp>", "Download status for <fp> with the default signing key; corresponds " "to /fp/ URLs on directory server."), DOC("downloads/cert/fp/<fp>/sks", "List of signing keys for which specific download statuses are " "available for this id fingerprint"), DOC("downloads/cert/fp/<fp>/<sk>", "Download status for <fp> with signing key <sk>; corresponds " "to /fp-sk/ URLs on directory server."), ITEM("info/names", misc, "List of GETINFO options, types, and documentation."), ITEM("events/names", misc, Loading
src/or/routerlist.c +106 −0 Original line number Diff line number Diff line Loading @@ -253,6 +253,112 @@ get_cert_list(const char *id_digest) return cl; } /** Return a list of authority ID digests with potentially enumerable lists * of download_status_t objects; used by controller GETINFO queries. */ smartlist_t * list_authority_ids_with_downloads(void) { smartlist_t *ids = smartlist_new(); digestmap_iter_t *i; const char *digest; char *tmp; void *cl; if (trusted_dir_certs) { for (i = digestmap_iter_init(trusted_dir_certs); !(digestmap_iter_done(i)); i = digestmap_iter_next(trusted_dir_certs, i)) { /* * We always have at least dl_status_by_id to query, so no need to * probe deeper than the existence of a cert_list_t. */ digestmap_iter_get(i, &digest, &cl); tmp = tor_malloc(DIGEST_LEN); memcpy(tmp, digest, DIGEST_LEN); smartlist_add(ids, tmp); } } /* else definitely no downlaods going since nothing even has a cert list */ return ids; } /** Given an authority ID digest, return a pointer to the default download * status, or NULL if there is no such entry in trusted_dir_certs */ download_status_t * id_only_download_status_for_authority_id(const char *digest) { download_status_t *dl = NULL; cert_list_t *cl; if (trusted_dir_certs) { cl = digestmap_get(trusted_dir_certs, digest); if (cl) { dl = &(cl->dl_status_by_id); } } return dl; } /** Given an authority ID digest, return a smartlist of signing key digests * for which download_status_t is potentially queryable, or NULL if no such * authority ID digest is known. */ smartlist_t * list_sk_digests_for_authority_id(const char *digest) { smartlist_t *sks = NULL; cert_list_t *cl; dsmap_iter_t *i; const char *sk_digest; char *tmp; download_status_t *dl; if (trusted_dir_certs) { cl = digestmap_get(trusted_dir_certs, digest); if (cl) { sks = smartlist_new(); if (cl->dl_status_map) { for (i = dsmap_iter_init(cl->dl_status_map); !(dsmap_iter_done(i)); i = dsmap_iter_next(cl->dl_status_map, i)) { /* Pull the digest out and add it to the list */ dsmap_iter_get(i, &sk_digest, &dl); tmp = tor_malloc(DIGEST_LEN); memcpy(tmp, sk_digest, DIGEST_LEN); smartlist_add(sks, tmp); } } } } return sks; } /** Given an authority ID digest and a signing key digest, return the * download_status_t or NULL if none exists. */ download_status_t * download_status_for_authority_id_and_sk(const char *id_digest, const char *sk_digest) { download_status_t *dl = NULL; cert_list_t *cl = NULL; if (trusted_dir_certs) { cl = digestmap_get(trusted_dir_certs, id_digest); if (cl && cl->dl_status_map) { dl = dsmap_get(cl->dl_status_map, sk_digest); } } return dl; } /** Release all space held by a cert_list_t */ static void cert_list_free(cert_list_t *cl) Loading
src/or/routerlist.h +8 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,14 @@ void routerlist_remove(routerlist_t *rl, routerinfo_t *ri, int make_old, void routerlist_free_all(void); void routerlist_reset_warnings(void); smartlist_t * list_authority_ids_with_downloads(void); download_status_t * id_only_download_status_for_authority_id( const char *digest); smartlist_t * list_sk_digests_for_authority_id(const char *digest); download_status_t * download_status_for_authority_id_and_sk( const char *id_digest, const char *sk_digest); static int WRA_WAS_ADDED(was_router_added_t s); static int WRA_WAS_OUTDATED(was_router_added_t s); static int WRA_WAS_REJECTED(was_router_added_t s); Loading