mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Separate "start-establishing-introduction" from "upload descriptors"; only upload descriptors containing fully established intro points.
svn:r1607
This commit is contained in:
parent
e0ce205a76
commit
a2ece0fc08
@ -546,7 +546,7 @@ void circuit_build_needed_circs(time_t now) {
|
|||||||
connection_ap_attach_pending();
|
connection_ap_attach_pending();
|
||||||
|
|
||||||
/* make sure any hidden services have enough intro points */
|
/* make sure any hidden services have enough intro points */
|
||||||
rend_services_init();
|
rend_services_introduce();
|
||||||
|
|
||||||
circ = circuit_get_youngest_clean_open(CIRCUIT_PURPOSE_C_GENERAL);
|
circ = circuit_get_youngest_clean_open(CIRCUIT_PURPOSE_C_GENERAL);
|
||||||
|
|
||||||
|
@ -354,6 +354,8 @@ static void run_scheduled_events(time_t now) {
|
|||||||
/* We're a directory; dump any old descriptors. */
|
/* We're a directory; dump any old descriptors. */
|
||||||
dirserv_remove_old_servers();
|
dirserv_remove_old_servers();
|
||||||
}
|
}
|
||||||
|
/* Force an upload of our descriptors every DirFetchPostPeriod seconds. */
|
||||||
|
rend_services_upload(1);
|
||||||
rend_cache_clean(); /* should this go elsewhere? */
|
rend_cache_clean(); /* should this go elsewhere? */
|
||||||
time_to_fetch_directory = now + options.DirFetchPostPeriod;
|
time_to_fetch_directory = now + options.DirFetchPostPeriod;
|
||||||
}
|
}
|
||||||
@ -393,6 +395,10 @@ static void run_scheduled_events(time_t now) {
|
|||||||
/* 5. And remove any marked circuits... */
|
/* 5. And remove any marked circuits... */
|
||||||
circuit_close_all_marked();
|
circuit_close_all_marked();
|
||||||
|
|
||||||
|
/* 6. And upload service descriptors for any services whose intro points
|
||||||
|
* have changed in the last second. */
|
||||||
|
rend_services_upload(0);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* 6. and blow away any connections that need to die. can't do this later
|
/* 6. and blow away any connections that need to die. can't do this later
|
||||||
* because we might open up a circuit and not realize we're about to cull
|
* because we might open up a circuit and not realize we're about to cull
|
||||||
@ -501,7 +507,7 @@ static int do_hup(void) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/* reload keys as needed for rendezvous services. */
|
/* reload keys as needed for rendezvous services. */
|
||||||
if (rend_service_init_keys()<0) {
|
if (rend_service_load_keys()<0) {
|
||||||
log_fn(LOG_ERR,"Error reloading rendezvous service keys");
|
log_fn(LOG_ERR,"Error reloading rendezvous service keys");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -518,7 +524,7 @@ static int do_hup(void) {
|
|||||||
}
|
}
|
||||||
/* Since we aren't fetching a directory, we won't retry rendezvous points
|
/* Since we aren't fetching a directory, we won't retry rendezvous points
|
||||||
* when it gets in. Try again now. */
|
* when it gets in. Try again now. */
|
||||||
rend_services_init();
|
rend_services_introduce();
|
||||||
} else {
|
} else {
|
||||||
/* fetch a new directory */
|
/* fetch a new directory */
|
||||||
directory_initiate_command(router_pick_directory_server(),
|
directory_initiate_command(router_pick_directory_server(),
|
||||||
@ -547,7 +553,7 @@ static int do_main_loop(void) {
|
|||||||
|
|
||||||
/* load the private keys, if we're supposed to have them, and set up the
|
/* load the private keys, if we're supposed to have them, and set up the
|
||||||
* TLS context. */
|
* TLS context. */
|
||||||
if (init_keys() < 0 || rend_service_init_keys() < 0) {
|
if (init_keys() < 0 || rend_service_load_keys() < 0) {
|
||||||
log_fn(LOG_ERR,"Error initializing keys; exiting");
|
log_fn(LOG_ERR,"Error initializing keys; exiting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1082,8 +1082,10 @@ int rend_cache_store(char *desc, int desc_len);
|
|||||||
/********************************* rendservice.c ***************************/
|
/********************************* rendservice.c ***************************/
|
||||||
|
|
||||||
int rend_config_services(or_options_t *options);
|
int rend_config_services(or_options_t *options);
|
||||||
int rend_service_init_keys(void);
|
int rend_service_load_keys(void);
|
||||||
void rend_services_init(void);
|
void rend_services_init(void);
|
||||||
|
void rend_services_introduce(void);
|
||||||
|
void rend_services_upload(int force);
|
||||||
|
|
||||||
void rend_service_intro_is_ready(circuit_t *circuit);
|
void rend_service_intro_is_ready(circuit_t *circuit);
|
||||||
int rend_service_intro_established(circuit_t *circuit, const char *request, int request_len);
|
int rend_service_intro_established(circuit_t *circuit, const char *request, int request_len);
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "or.h"
|
#include "or.h"
|
||||||
|
|
||||||
|
static circuit_t *find_intro_circuit(routerinfo_t *router, const char *pk_digest);
|
||||||
|
|
||||||
/* Represents the mapping from a virtual port of a rendezvous service to
|
/* Represents the mapping from a virtual port of a rendezvous service to
|
||||||
* a real port on some IP.
|
* a real port on some IP.
|
||||||
*/
|
*/
|
||||||
@ -32,8 +34,9 @@ typedef struct rend_service_t {
|
|||||||
crypto_pk_env_t *private_key;
|
crypto_pk_env_t *private_key;
|
||||||
char service_id[REND_SERVICE_ID_LEN+1];
|
char service_id[REND_SERVICE_ID_LEN+1];
|
||||||
char pk_digest[DIGEST_LEN];
|
char pk_digest[DIGEST_LEN];
|
||||||
smartlist_t *intro_nodes; /* list of nicknames */
|
smartlist_t *intro_nodes; /* list of nicknames for intro points we _want_ */
|
||||||
rend_service_descriptor_t *desc;
|
rend_service_descriptor_t *desc;
|
||||||
|
int desc_is_dirty;
|
||||||
} rend_service_t;
|
} rend_service_t;
|
||||||
|
|
||||||
/* A list of rend_service_t's for services run on this OP.
|
/* A list of rend_service_t's for services run on this OP.
|
||||||
@ -231,7 +234,9 @@ int rend_config_services(or_options_t *options)
|
|||||||
static void rend_service_update_descriptor(rend_service_t *service)
|
static void rend_service_update_descriptor(rend_service_t *service)
|
||||||
{
|
{
|
||||||
rend_service_descriptor_t *d;
|
rend_service_descriptor_t *d;
|
||||||
|
circuit_t *circ;
|
||||||
int i,n;
|
int i,n;
|
||||||
|
routerinfo_t *router;
|
||||||
|
|
||||||
if (service->desc) {
|
if (service->desc) {
|
||||||
rend_service_descriptor_free(service->desc);
|
rend_service_descriptor_free(service->desc);
|
||||||
@ -240,17 +245,23 @@ static void rend_service_update_descriptor(rend_service_t *service)
|
|||||||
d = service->desc = tor_malloc(sizeof(rend_service_descriptor_t));
|
d = service->desc = tor_malloc(sizeof(rend_service_descriptor_t));
|
||||||
d->pk = crypto_pk_dup_key(service->private_key);
|
d->pk = crypto_pk_dup_key(service->private_key);
|
||||||
d->timestamp = time(NULL);
|
d->timestamp = time(NULL);
|
||||||
n = d->n_intro_points = smartlist_len(service->intro_nodes);
|
n = smartlist_len(service->intro_nodes);
|
||||||
|
d->n_intro_points = 0;
|
||||||
d->intro_points = tor_malloc(sizeof(char*)*n);
|
d->intro_points = tor_malloc(sizeof(char*)*n);
|
||||||
for (i=0; i < n; ++i) {
|
for (i=0; i < n; ++i) {
|
||||||
d->intro_points[i] = tor_strdup(smartlist_get(service->intro_nodes, i));
|
router = router_get_by_nickname(smartlist_get(service->intro_nodes, i));
|
||||||
|
circ = find_intro_circuit(router, service->pk_digest);
|
||||||
|
if (circ->purpose == CIRCUIT_PURPOSE_S_INTRO) {
|
||||||
|
/* We have an entirely established intro circuit. */
|
||||||
|
d->intro_points[d->n_intro_points++] = tor_strdup(router->nickname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load and/or generate private keys for all hidden services. Return 0 on
|
/* Load and/or generate private keys for all hidden services. Return 0 on
|
||||||
* success, -1 on failure.
|
* success, -1 on failure.
|
||||||
*/
|
*/
|
||||||
int rend_service_init_keys(void)
|
int rend_service_load_keys(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
rend_service_t *s;
|
rend_service_t *s;
|
||||||
@ -529,14 +540,23 @@ rend_service_intro_is_ready(circuit_t *circuit)
|
|||||||
circuit_mark_for_close(circuit);
|
circuit_mark_for_close(circuit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle an intro_established cell. */
|
/* Handle an INTRO_ESTABLISHED cell. */
|
||||||
int
|
int
|
||||||
rend_service_intro_established(circuit_t *circuit, const char *request, int request_len)
|
rend_service_intro_established(circuit_t *circuit, const char *request, int request_len)
|
||||||
{
|
{
|
||||||
|
rend_service_t *service;
|
||||||
|
|
||||||
if (circuit->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO) {
|
if (circuit->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO) {
|
||||||
log_fn(LOG_WARN, "received INTRO_ESTABLISHED cell on non-intro circuit");
|
log_fn(LOG_WARN, "received INTRO_ESTABLISHED cell on non-intro circuit");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
service = rend_service_get_by_pk_digest(circuit->rend_pk_digest);
|
||||||
|
if (!service) {
|
||||||
|
log_fn(LOG_WARN, "Unknown service on introduction circuit %d",
|
||||||
|
circuit->n_circ_id);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
service->desc_is_dirty = 1;
|
||||||
circuit->purpose = CIRCUIT_PURPOSE_S_INTRO;
|
circuit->purpose = CIRCUIT_PURPOSE_S_INTRO;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -653,6 +673,31 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
upload_service_descriptor(rend_service_t *service)
|
||||||
|
{
|
||||||
|
char *desc;
|
||||||
|
int desc_len;
|
||||||
|
if (!service->desc_is_dirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Update the descriptor. */
|
||||||
|
rend_service_update_descriptor(service);
|
||||||
|
if (rend_encode_service_descriptor(service->desc,
|
||||||
|
service->private_key,
|
||||||
|
&desc, &desc_len)<0) {
|
||||||
|
log_fn(LOG_WARN, "Couldn't encode service descriptor; not uploading");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Post it to the dirservers */
|
||||||
|
router_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC, desc, desc_len);
|
||||||
|
tor_free(desc);
|
||||||
|
|
||||||
|
service->desc_is_dirty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* XXXX Make this longer once directories remember service descriptors across
|
/* XXXX Make this longer once directories remember service descriptors across
|
||||||
* restarts.*/
|
* restarts.*/
|
||||||
#define MAX_SERVICE_PUBLICATION_INTERVAL (15*60)
|
#define MAX_SERVICE_PUBLICATION_INTERVAL (15*60)
|
||||||
@ -660,18 +705,16 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest)
|
|||||||
/* For every service, check how many intro points it currently has, and:
|
/* For every service, check how many intro points it currently has, and:
|
||||||
* - Pick new intro points as necessary.
|
* - Pick new intro points as necessary.
|
||||||
* - Launch circuits to any new intro points.
|
* - Launch circuits to any new intro points.
|
||||||
* - Upload a fresh service descriptor if anything has changed.
|
|
||||||
*/
|
*/
|
||||||
void rend_services_init(void) {
|
void rend_services_introduce(void) {
|
||||||
int i,j,r;
|
int i,j,r;
|
||||||
routerinfo_t *router;
|
routerinfo_t *router;
|
||||||
routerlist_t *rl;
|
routerlist_t *rl;
|
||||||
rend_service_t *service;
|
rend_service_t *service;
|
||||||
char *desc, *intro;
|
char *intro;
|
||||||
int changed, prev_intro_nodes, desc_len;
|
int changed, prev_intro_nodes;
|
||||||
smartlist_t *intro_routers, *exclude_routers;
|
smartlist_t *intro_routers, *exclude_routers;
|
||||||
int n_old_routers;
|
int n_old_routers;
|
||||||
time_t now;
|
|
||||||
|
|
||||||
router_get_routerlist(&rl);
|
router_get_routerlist(&rl);
|
||||||
intro_routers = smartlist_create();
|
intro_routers = smartlist_create();
|
||||||
@ -686,7 +729,7 @@ void rend_services_init(void) {
|
|||||||
assert(service);
|
assert(service);
|
||||||
changed = 0;
|
changed = 0;
|
||||||
|
|
||||||
/* Find out which introduction points we really have for this service. */
|
/* Find out which introduction points we have in progress for this service. */
|
||||||
for (j=0;j< smartlist_len(service->intro_nodes); ++j) {
|
for (j=0;j< smartlist_len(service->intro_nodes); ++j) {
|
||||||
router = router_get_by_nickname(smartlist_get(service->intro_nodes,j));
|
router = router_get_by_nickname(smartlist_get(service->intro_nodes,j));
|
||||||
if (!router || !find_intro_circuit(router,service->pk_digest)) {
|
if (!router || !find_intro_circuit(router,service->pk_digest)) {
|
||||||
@ -728,26 +771,10 @@ void rend_services_init(void) {
|
|||||||
* time around the loop. */
|
* time around the loop. */
|
||||||
smartlist_truncate(exclude_routers, n_old_routers);
|
smartlist_truncate(exclude_routers, n_old_routers);
|
||||||
|
|
||||||
/* If there's no need to republish, stop here. */
|
/* If there's no need to launch new circuits, stop here. */
|
||||||
now = time(NULL);
|
if (!changed)
|
||||||
if (!changed && service->desc &&
|
|
||||||
service->desc->timestamp+MAX_SERVICE_PUBLICATION_INTERVAL >= now)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Update the descriptor. */
|
|
||||||
rend_service_update_descriptor(service);
|
|
||||||
if (rend_encode_service_descriptor(service->desc,
|
|
||||||
service->private_key,
|
|
||||||
&desc, &desc_len)<0) {
|
|
||||||
|
|
||||||
log_fn(LOG_WARN, "Couldn't encode service descriptor; not uploading");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Post it to the dirservers */
|
|
||||||
router_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC, desc, desc_len);
|
|
||||||
tor_free(desc);
|
|
||||||
|
|
||||||
/* Establish new introduction points. */
|
/* Establish new introduction points. */
|
||||||
for (j=prev_intro_nodes; j < smartlist_len(service->intro_nodes); ++j) {
|
for (j=prev_intro_nodes; j < smartlist_len(service->intro_nodes); ++j) {
|
||||||
intro = smartlist_get(service->intro_nodes, j);
|
intro = smartlist_get(service->intro_nodes, j);
|
||||||
@ -761,6 +788,21 @@ void rend_services_init(void) {
|
|||||||
smartlist_free(exclude_routers);
|
smartlist_free(exclude_routers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rend_services_upload(int force)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
rend_service_t *service;
|
||||||
|
|
||||||
|
for (i=0; i< smartlist_len(rend_service_list); ++i) {
|
||||||
|
service = smartlist_get(rend_service_list, i);
|
||||||
|
if (force)
|
||||||
|
service->desc_is_dirty = 1;
|
||||||
|
if (service->desc_is_dirty)
|
||||||
|
upload_service_descriptor(service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rend_service_dump_stats(int severity)
|
rend_service_dump_stats(int severity)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user