mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Hide smartlist internals
svn:r1451
This commit is contained in:
parent
bbc9484957
commit
fc4d15baf6
@ -129,6 +129,13 @@ void hex_encode(const char *from, int fromlen, char *to)
|
||||
* _choose() returns a random element.
|
||||
*/
|
||||
#define SMARTLIST_DEFAULT_CAPACITY 32
|
||||
|
||||
struct smartlist_t {
|
||||
void **list;
|
||||
int num_used;
|
||||
int capacity;
|
||||
};
|
||||
|
||||
smartlist_t *smartlist_create() {
|
||||
smartlist_t *sl = tor_malloc(sizeof(smartlist_t));
|
||||
sl->num_used = 0;
|
||||
@ -143,6 +150,8 @@ void smartlist_free(smartlist_t *sl) {
|
||||
}
|
||||
|
||||
void smartlist_set_capacity(smartlist_t *sl, int n) {
|
||||
if (n<0)
|
||||
n = sl->num_used;
|
||||
if (sl->capacity != n && sl->num_used < n) {
|
||||
sl->capacity = n;
|
||||
sl->list = tor_realloc(sl->list, sizeof(void*)*sl->capacity);
|
||||
@ -208,6 +217,29 @@ void *smartlist_choose(smartlist_t *sl) {
|
||||
return NULL; /* no elements to choose from */
|
||||
}
|
||||
|
||||
void *smartlist_get(smartlist_t *sl, int idx)
|
||||
{
|
||||
return sl->list[idx];
|
||||
}
|
||||
void *smartlist_set(smartlist_t *sl, int idx, void *val)
|
||||
{
|
||||
void *old;
|
||||
old = sl->list[idx];
|
||||
sl->list[idx] = val;
|
||||
return old;
|
||||
}
|
||||
void *smartlist_del(smartlist_t *sl, int idx)
|
||||
{
|
||||
void *old;
|
||||
old = sl->list[idx];
|
||||
sl->list[idx] = sl->list[--sl->num_used];
|
||||
return old;
|
||||
}
|
||||
int smartlist_len(smartlist_t *sl)
|
||||
{
|
||||
return sl->num_used;
|
||||
}
|
||||
|
||||
/*
|
||||
* Splay-tree implementation of string-to-void* map
|
||||
*/
|
||||
|
@ -83,11 +83,7 @@ void set_uint32(char *cp, uint32_t v);
|
||||
|
||||
void hex_encode(const char *from, int fromlen, char *to);
|
||||
|
||||
typedef struct smartlist_t {
|
||||
void **list;
|
||||
int num_used;
|
||||
int capacity;
|
||||
} smartlist_t;
|
||||
typedef struct smartlist_t smartlist_t;
|
||||
|
||||
smartlist_t *smartlist_create();
|
||||
void smartlist_free(smartlist_t *sl);
|
||||
@ -99,6 +95,18 @@ int smartlist_overlap(smartlist_t *sl1, smartlist_t *sl2);
|
||||
void smartlist_intersect(smartlist_t *sl1, smartlist_t *sl2);
|
||||
void smartlist_subtract(smartlist_t *sl1, smartlist_t *sl2);
|
||||
void *smartlist_choose(smartlist_t *sl);
|
||||
void *smartlist_get(smartlist_t *sl, int idx);
|
||||
void *smartlist_set(smartlist_t *sl, int idx, void *val);
|
||||
void *smartlist_del(smartlist_t *sl, int idx);
|
||||
int smartlist_len(smartlist_t *sl);
|
||||
#define SMARTLIST_FOREACH(sl, type, var, cmd) \
|
||||
do { \
|
||||
int sl_idx, sl_len=smartlist_len(sl); \
|
||||
type var; \
|
||||
for(sl_idx = 0; sl_idx < sl_len; ++sl_idx) { \
|
||||
var = smartlist_get((sl),sl_idx); \
|
||||
do {cmd;} while(0); \
|
||||
} } while (0)
|
||||
|
||||
/* Map from const char * to void*. Implemented with a splay tree. */
|
||||
typedef struct strmap_t strmap_t;
|
||||
|
@ -1033,8 +1033,8 @@ void circuit_expire_unused_circuits(void) {
|
||||
smartlist_add(unused_open_circs, circ);
|
||||
}
|
||||
}
|
||||
for (i = MAX_UNUSED_OPEN_CIRCUITS; i < unused_open_circs->num_used; ++i) {
|
||||
circuit_t *circ=(circuit_t*)(unused_open_circs->list[i]);
|
||||
for (i = MAX_UNUSED_OPEN_CIRCUITS; i < smartlist_len(unused_open_circs); ++i) {
|
||||
circuit_t *circ = smartlist_get(unused_open_circs, i);
|
||||
circuit_mark_for_close(circ);
|
||||
}
|
||||
smartlist_free(unused_open_circs);
|
||||
|
@ -405,12 +405,10 @@ static void remove_twins_from_smartlist(smartlist_t *sl, routerinfo_t *twin) {
|
||||
if(twin == NULL)
|
||||
return;
|
||||
|
||||
/* XXX abstraction violation: this function reaches inside smartlist :( */
|
||||
for(i=0; i < sl->num_used; i++) {
|
||||
r = sl->list[i];
|
||||
for(i=0; i < smartlist_len(sl); i++) {
|
||||
r = smartlist_get(sl,i);
|
||||
if (!crypto_pk_cmp_keys(r->onion_pkey, twin->onion_pkey)) {
|
||||
sl->list[i] = sl->list[--sl->num_used]; /* swap with the end */
|
||||
i--; /* so we process the new i'th element */
|
||||
smartlist_del(sl,i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ rend_mid_establish_intro(circuit_t *circ, char *request, int request_len)
|
||||
circuit_t *c;
|
||||
char hexid[9];
|
||||
|
||||
log_fn(LOG_INFO, "Received an ESTABLISH_INTRO request on circuit %d", circ->p_circ_id);
|
||||
log_fn(LOG_INFO,
|
||||
"Received an ESTABLISH_INTRO request on circuit %d", circ->p_circ_id);
|
||||
|
||||
if (circ->purpose != CIRCUIT_PURPOSE_OR || circ->n_conn) {
|
||||
log_fn(LOG_WARN, "Rejecting ESTABLISH_INTRO on non-OR or non-edge circuit");
|
||||
@ -69,7 +70,8 @@ rend_mid_establish_intro(circuit_t *circ, char *request, int request_len)
|
||||
c = NULL;
|
||||
while ((c = circuit_get_next_by_pk_and_purpose(
|
||||
c,pk_digest,CIRCUIT_PURPOSE_INTRO_POINT))) {
|
||||
log_fn(LOG_INFO, "Replacing old circuit %d for service %s", c->p_circ_id, hexid);
|
||||
log_fn(LOG_INFO, "Replacing old circuit %d for service %s",
|
||||
c->p_circ_id, hexid);
|
||||
circuit_mark_for_close(c);
|
||||
}
|
||||
|
||||
@ -77,7 +79,8 @@ rend_mid_establish_intro(circuit_t *circ, char *request, int request_len)
|
||||
circ->purpose = CIRCUIT_PURPOSE_INTRO_POINT;
|
||||
memcpy(circ->rend_pk_digest, pk_digest, 20);
|
||||
|
||||
log_fn(LOG_INFO, "Established introduction point on circuit %d for service %s",
|
||||
log_fn(LOG_INFO,
|
||||
"Established introduction point on circuit %d for service %s",
|
||||
circ->p_circ_id, hexid);
|
||||
|
||||
return 0;
|
||||
@ -97,21 +100,37 @@ int
|
||||
rend_mid_introduce(circuit_t *circ, char *request, int request_len)
|
||||
{
|
||||
circuit_t *intro_circ;
|
||||
char hexid[9];
|
||||
|
||||
if (request_len < 276) {
|
||||
log_fn(LOG_WARN, "Impossibly short INTRODUCE2 cell; dropping.");
|
||||
if (circ->purpose != CIRCUIT_PURPOSE_OR || circ->n_conn) {
|
||||
log_fn(LOG_WARN, "Rejecting INTRODUCE2 on non-OR or non-edge circuit %d",
|
||||
circ->p_circ_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (request_len < 276) {
|
||||
log_fn(LOG_WARN,
|
||||
"Impossibly short INTRODUCE2 cell on circuit %d; dropping.",
|
||||
circ->p_circ_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
hex_encode(request,4,hexid);
|
||||
|
||||
/* The first 20 bytes are all we look at: they have a hash of Bob's PK. */
|
||||
intro_circ = circuit_get_next_by_pk_and_purpose(
|
||||
NULL, request, CIRCUIT_PURPOSE_INTRO_POINT);
|
||||
if (!intro_circ) {
|
||||
log_fn(LOG_WARN,
|
||||
"No introduction circuit matching INTRODUCE2 cell; dropping");
|
||||
"No intro circ found for INTRODUCE2 cell (%s) from circuit %d; dropping",
|
||||
hexid, circ->p_circ_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
log_fn(LOG_INFO,
|
||||
"Sending introduction request for service %s from circ %d to circ %d",
|
||||
hexid, circ->p_circ_id, intro_circ->p_circ_id);
|
||||
|
||||
/* Great. Now we just relay the cell down the circuit. */
|
||||
if (connection_edge_send_command(NULL, intro_circ,
|
||||
RELAY_COMMAND_INTRODUCE2,
|
||||
@ -132,6 +151,8 @@ rend_mid_introduce(circuit_t *circ, char *request, int request_len)
|
||||
int
|
||||
rend_mid_establish_rendezvous(circuit_t *circ, char *request, int request_len)
|
||||
{
|
||||
char hexid[9];
|
||||
|
||||
if (circ->purpose != CIRCUIT_PURPOSE_OR || circ->n_conn) {
|
||||
log_fn(LOG_WARN, "Tried to establish rendezvous on non-OR or non-edge circuit");
|
||||
goto err;
|
||||
@ -150,6 +171,10 @@ rend_mid_establish_rendezvous(circuit_t *circ, char *request, int request_len)
|
||||
circ->purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING;
|
||||
memcpy(circ->rend_cookie, request, REND_COOKIE_LEN);
|
||||
|
||||
hex_encode(request,4,hexid);
|
||||
log_fn(LOG_INFO, "Established rendezvous point on circuit %d for cookie %s",
|
||||
circ->p_circ_id, hexid);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
circuit_mark_for_close(circ);
|
||||
@ -163,20 +188,33 @@ int
|
||||
rend_mid_rendezvous(circuit_t *circ, char *request, int request_len)
|
||||
{
|
||||
circuit_t *rend_circ;
|
||||
char hexid[9];
|
||||
|
||||
if (request_len>=4) {
|
||||
hex_encode(request,4,hexid);
|
||||
log_fn(LOG_INFO, "Got request for rendezvous from circuit %d to cookie %s",
|
||||
circ->p_circ_id, hexid);
|
||||
}
|
||||
|
||||
if (circ->purpose != CIRCUIT_PURPOSE_OR || circ->n_conn) {
|
||||
log_fn(LOG_WARN, "Tried to complete rendezvous on non-OR or non-edge circuit");
|
||||
log_fn(LOG_WARN,
|
||||
"Tried to complete rendezvous on non-OR or non-edge circuit %d",
|
||||
circ->p_circ_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (request_len < 20+128+20) {
|
||||
log_fn(LOG_WARN, "Rejecting impossibly short RENDEZVOUS1 cell");
|
||||
log_fn(LOG_WARN,
|
||||
"Rejecting impossibly short RENDEZVOUS1 cell on circuit %d",
|
||||
circ->p_circ_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
rend_circ = circuit_get_rendezvous(request);
|
||||
if (!rend_circ) {
|
||||
log_fn(LOG_WARN, "Rejecting RENDEZVOUS1 cell with unrecognized rendezvous cookie");
|
||||
log_fn(LOG_WARN,
|
||||
"Rejecting RENDEZVOUS1 cell with unrecognized rendezvous cookie %s",
|
||||
hexid);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -184,11 +222,16 @@ rend_mid_rendezvous(circuit_t *circ, char *request, int request_len)
|
||||
if (connection_edge_send_command(NULL, rend_circ,
|
||||
RELAY_COMMAND_RENDEZVOUS2,
|
||||
request+20, request_len-20, NULL)) {
|
||||
log_fn(LOG_WARN, "Unable to send RENDEZVOUS2 cell to OP.");
|
||||
log_fn(LOG_WARN, "Unable to send RENDEZVOUS2 cell to OP on circuit %d",
|
||||
rend_circ->p_circ_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Join the circuits. */
|
||||
log_fn(LOG_INFO,
|
||||
"Completing rendezvous: circuit %d joins circuit %d (cookie %s)",
|
||||
circ->p_circ_id, rend_circ->p_circ_id, hexid);
|
||||
|
||||
circ->purpose = CIRCUIT_PURPOSE_REND_ESTABLISHED;
|
||||
rend_circ->purpose = CIRCUIT_PURPOSE_REND_ESTABLISHED;
|
||||
memset(circ->rend_cookie, 0, 20);
|
||||
|
@ -40,20 +40,15 @@ static smartlist_t *rend_service_list = NULL;
|
||||
|
||||
static void rend_service_free(rend_service_t *config)
|
||||
{
|
||||
int i;
|
||||
if (!config) return;
|
||||
tor_free(config->directory);
|
||||
for (i=0; i<config->ports->num_used; ++i) {
|
||||
tor_free(config->ports->list[i]);
|
||||
}
|
||||
SMARTLIST_FOREACH(config->ports, void*, p, tor_free(p));
|
||||
smartlist_free(config->ports);
|
||||
if (config->private_key)
|
||||
crypto_free_pk_env(config->private_key);
|
||||
tor_free(config->intro_prefer_nodes);
|
||||
tor_free(config->intro_exclude_nodes);
|
||||
for (i=0; i<config->intro_nodes->num_used; ++i) {
|
||||
tor_free(config->intro_nodes->list[i]);
|
||||
}
|
||||
SMARTLIST_FOREACH(config->intro_nodes, void*, p, tor_free(p));
|
||||
smartlist_free(config->intro_nodes);
|
||||
if (config->desc)
|
||||
rend_service_descriptor_free(config->desc);
|
||||
@ -62,14 +57,12 @@ static void rend_service_free(rend_service_t *config)
|
||||
|
||||
static void rend_service_free_all(void)
|
||||
{
|
||||
int i;
|
||||
if (!rend_service_list) {
|
||||
rend_service_list = smartlist_create();
|
||||
return;
|
||||
}
|
||||
for (i=0; i < rend_service_list->num_used; ++i) {
|
||||
rend_service_free(rend_service_list->list[i]);
|
||||
}
|
||||
SMARTLIST_FOREACH(rend_service_list, rend_service_t*, ptr,
|
||||
rend_service_free(ptr));
|
||||
smartlist_free(rend_service_list);
|
||||
rend_service_list = smartlist_create();
|
||||
}
|
||||
@ -85,15 +78,15 @@ static void add_service(rend_service_t *service)
|
||||
if (!service->intro_exclude_nodes)
|
||||
service->intro_exclude_nodes = tor_strdup("");
|
||||
|
||||
if (!service->ports->num_used) {
|
||||
if (!smartlist_len(service->ports)) {
|
||||
log_fn(LOG_WARN, "Hidden service with no ports configured; ignoring.");
|
||||
rend_service_free(service);
|
||||
} else {
|
||||
smartlist_set_capacity(service->ports, service->ports->num_used);
|
||||
smartlist_set_capacity(service->ports, -1);
|
||||
smartlist_add(rend_service_list, service);
|
||||
log_fn(LOG_INFO,"Configuring service with directory %s",service->directory);
|
||||
for (i = 0; i < service->ports->num_used; ++i) {
|
||||
p = (rend_service_port_config_t *) service->ports->list[i];
|
||||
for (i = 0; i < smartlist_len(service->ports); ++i) {
|
||||
p = smartlist_get(service->ports, i);
|
||||
addr.s_addr = htonl(p->real_address);
|
||||
log_fn(LOG_INFO,"Service maps port %d to %s:%d",
|
||||
p->virtual_port, inet_ntoa(addr), p->real_port);
|
||||
@ -220,8 +213,8 @@ int rend_config_services(or_options_t *options)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* DOCDOC
|
||||
/* Replace the old value of service->desc with one that reflects
|
||||
* the other fields in service.
|
||||
*/
|
||||
static void rend_service_update_descriptor(rend_service_t *service)
|
||||
{
|
||||
@ -235,10 +228,10 @@ static void rend_service_update_descriptor(rend_service_t *service)
|
||||
d = service->desc = tor_malloc(sizeof(rend_service_descriptor_t));
|
||||
d->pk = crypto_pk_dup_key(service->private_key);
|
||||
d->timestamp = time(NULL);
|
||||
n = d->n_intro_points = service->intro_nodes->num_used;
|
||||
n = d->n_intro_points = smartlist_len(service->intro_nodes);
|
||||
d->intro_points = tor_malloc(sizeof(char*)*n);
|
||||
for (i=0; i < n; ++i) {
|
||||
d->intro_points[i] = tor_strdup(service->intro_nodes->list[i]);
|
||||
d->intro_points[i] = tor_strdup(smartlist_get(service->intro_nodes, i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,10 +245,12 @@ int rend_service_init_keys(void)
|
||||
char fname[512];
|
||||
char buf[128];
|
||||
|
||||
for (i=0; i < rend_service_list->num_used; ++i) {
|
||||
s = (rend_service_t*) rend_service_list->list[i];
|
||||
for (i=0; i < smartlist_len(rend_service_list); ++i) {
|
||||
s = smartlist_get(rend_service_list,i);
|
||||
if (s->private_key)
|
||||
continue;
|
||||
log_fn(LOG_INFO, "Loading hidden-service keys from '%s'", s->directory);
|
||||
|
||||
/* Check/create directory */
|
||||
if (check_private_dir(s->directory, 1) < 0)
|
||||
return -1;
|
||||
@ -294,13 +289,8 @@ int rend_service_init_keys(void)
|
||||
static rend_service_t *
|
||||
rend_service_get_by_pk_digest(const char* digest)
|
||||
{
|
||||
int i;
|
||||
rend_service_t *s;
|
||||
for (i = 0; i < rend_service_list->num_used; ++i) {
|
||||
s = (rend_service_t*)rend_service_list->list[i];
|
||||
if (!memcmp(s->pk_digest, digest, 20))
|
||||
return s;
|
||||
}
|
||||
SMARTLIST_FOREACH(rend_service_list, rend_service_t*, s,
|
||||
if (!memcmp(s->pk_digest,digest,20)) return s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -322,22 +312,32 @@ rend_service_introduce(circuit_t *circuit, char *request, int request_len)
|
||||
crypto_dh_env_t *dh = NULL;
|
||||
circuit_t *launched = NULL;
|
||||
crypt_path_t *cpath = NULL;
|
||||
char hexid[9];
|
||||
char hexcookie[9];
|
||||
|
||||
hex_encode(circuit->rend_pk_digest, 4, hexid);
|
||||
|
||||
log_fn(LOG_INFO, "Received INTRODUCE2 cell for service %s on circ %d",
|
||||
hexid, circuit->n_circ_id);
|
||||
|
||||
if (circuit->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO) {
|
||||
log_fn(LOG_WARN, "Got an INTRODUCE2 over a non-introduction circuit.");
|
||||
log_fn(LOG_WARN, "Got an INTRODUCE2 over a non-introduction circuit %d",
|
||||
circuit->n_circ_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* min key length plus digest length */
|
||||
if (request_len < 148) {
|
||||
log_fn(LOG_WARN, "Got a truncated INTRODUCE2 cell.");
|
||||
log_fn(LOG_WARN, "Got a truncated INTRODUCE2 cell on circ %d",
|
||||
circuit->n_circ_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* first 20 bytes of request is service pk digest */
|
||||
service = rend_service_get_by_pk_digest(request);
|
||||
if (!service) {
|
||||
log_fn(LOG_WARN, "Got an INTRODUCE2 cell for an unrecognized service");
|
||||
log_fn(LOG_WARN, "Got an INTRODUCE2 cell for an unrecognized service %s",
|
||||
hexid);
|
||||
return -1;
|
||||
}
|
||||
if (!memcmp(circuit->rend_pk_digest, request, 20)) {
|
||||
@ -375,6 +375,7 @@ rend_service_introduce(circuit_t *circuit, char *request, int request_len)
|
||||
return -1;
|
||||
}
|
||||
r_cookie = ptr;
|
||||
hex_encode(r_cookie,4,hexcookie);
|
||||
|
||||
/* Try DH handshake... */
|
||||
dh = crypto_dh_new();
|
||||
@ -391,9 +392,13 @@ rend_service_introduce(circuit_t *circuit, char *request, int request_len)
|
||||
/* Launch a circuit to alice's chosen rendezvous point.
|
||||
*/
|
||||
launched = circuit_launch_new(CIRCUIT_PURPOSE_S_CONNECT_REND, rp_nickname);
|
||||
log_fn(LOG_INFO,
|
||||
"Accepted intro; launching circuit to '%s' (cookie %s) for service %s",
|
||||
rp_nickname, hexcookie, hexid);
|
||||
if (!launched) {
|
||||
log_fn(LOG_WARN, "Can't launch circuit to rendezvous point '%s'",
|
||||
rp_nickname);
|
||||
log_fn(LOG_WARN,
|
||||
"Can't launch circuit to rendezvous point '%s' for service %s",
|
||||
rp_nickname, hexid);
|
||||
return -1;
|
||||
}
|
||||
assert(launched->build_state);
|
||||
@ -423,9 +428,14 @@ static int
|
||||
rend_service_launch_establish_intro(rend_service_t *service, char *nickname)
|
||||
{
|
||||
circuit_t *launched;
|
||||
char hexid[9];
|
||||
|
||||
assert(service && nickname);
|
||||
|
||||
hex_encode(service->pk_digest, 4, hexid);
|
||||
log_fn(LOG_INFO, "Launching circuit to introduction point %s for service %s",
|
||||
nickname, hexid);
|
||||
|
||||
launched = circuit_launch_new(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, nickname);
|
||||
if (!launched) {
|
||||
log_fn(LOG_WARN, "Can't launch circuit to establish introduction at '%s'",
|
||||
@ -447,15 +457,23 @@ rend_service_intro_is_ready(circuit_t *circuit)
|
||||
int len, r;
|
||||
char buf[RELAY_PAYLOAD_SIZE];
|
||||
char auth[CRYPTO_SHA1_DIGEST_LEN + 10];
|
||||
char hexid[9];
|
||||
|
||||
assert(circuit->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO);
|
||||
assert(circuit->cpath);
|
||||
|
||||
hex_encode(circuit->rend_pk_digest, 4, hexid);
|
||||
service = rend_service_get_by_pk_digest(circuit->rend_pk_digest);
|
||||
if (!service) {
|
||||
log_fn(LOG_WARN, "Internal error: unrecognized service ID on introduction circuit");
|
||||
log_fn(LOG_WARN, "Unrecognized service ID %s on introduction circuit %d",
|
||||
hexid, circuit->n_circ_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
log_fn(LOG_INFO,
|
||||
"Established circuit %d as introduction point for service %s",
|
||||
circuit->n_circ_id, hexid);
|
||||
|
||||
/* Build the payload for a RELAY_ESTABLISH_INTRO cell. */
|
||||
len = crypto_pk_asn1_encode(service->private_key, buf+2,
|
||||
RELAY_PAYLOAD_SIZE-2);
|
||||
@ -475,7 +493,9 @@ rend_service_intro_is_ready(circuit_t *circuit)
|
||||
|
||||
if (connection_edge_send_command(NULL, circuit,RELAY_COMMAND_ESTABLISH_INTRO,
|
||||
buf, len, circuit->cpath->prev)<0) {
|
||||
log_fn(LOG_WARN, "Couldn't send introduction request");
|
||||
log_fn(LOG_WARN,
|
||||
"Couldn't send introduction request for service %s on circuit %d",
|
||||
hexid, circuit->n_circ_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -493,6 +513,8 @@ rend_service_rendezvous_is_ready(circuit_t *circuit)
|
||||
rend_service_t *service;
|
||||
char buf[RELAY_PAYLOAD_SIZE];
|
||||
crypt_path_t *hop;
|
||||
char hexid[9];
|
||||
char hexcookie[9];
|
||||
|
||||
assert(circuit->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND);
|
||||
assert(circuit->cpath);
|
||||
@ -500,6 +522,13 @@ rend_service_rendezvous_is_ready(circuit_t *circuit)
|
||||
hop = circuit->build_state->pending_final_cpath;
|
||||
assert(hop);
|
||||
|
||||
hex_encode(circuit->rend_pk_digest, 4, hexid);
|
||||
hex_encode(circuit->rend_cookie, 4, hexcookie);
|
||||
|
||||
log_fn(LOG_INFO,
|
||||
"Done building circuit %d to rendezvous with cookie %s for service %s",
|
||||
circuit->n_circ_id, hexcookie, hexid);
|
||||
|
||||
service = rend_service_get_by_pk_digest(circuit->rend_pk_digest);
|
||||
if (!service) {
|
||||
log_fn(LOG_WARN, "Internal error: unrecognized service ID on introduction circuit");
|
||||
@ -556,14 +585,16 @@ int rend_services_init(void) {
|
||||
|
||||
router_get_routerlist(&rl);
|
||||
|
||||
for (i=0;i<rend_service_list->num_used;++i) {
|
||||
service = rend_service_list->list[i];
|
||||
for (i=0; i< smartlist_len(rend_service_list); ++i) {
|
||||
service = smartlist_get(rend_service_list, i);
|
||||
|
||||
assert(service);
|
||||
changed = 0;
|
||||
|
||||
/* Find out which introduction points we really have for this service. */
|
||||
for (j=0;j<service->intro_nodes->num_used;++j) {
|
||||
router = router_get_by_nickname(service->intro_nodes->list[j]);
|
||||
for (j=0;j< smartlist_len(service->intro_nodes); ++j) {
|
||||
|
||||
router = router_get_by_nickname(smartlist_get(service->intro_nodes,j));
|
||||
if (!router)
|
||||
goto remove_point;
|
||||
circ = NULL;
|
||||
@ -580,22 +611,18 @@ int rend_services_init(void) {
|
||||
if (found) continue;
|
||||
|
||||
remove_point:
|
||||
tor_free(service->intro_nodes->list[j]);
|
||||
service->intro_nodes->list[j] =
|
||||
service->intro_nodes->list[service->intro_nodes->num_used-1];
|
||||
--service->intro_nodes->num_used;
|
||||
--j;
|
||||
smartlist_del(service->intro_nodes,j--);
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
/* We have enough intro points, and the intro points we thought we had were
|
||||
* all connected.
|
||||
*/
|
||||
if (!changed && service->intro_nodes->num_used >= NUM_INTRO_POINTS)
|
||||
if (!changed && smartlist_len(service->intro_nodes) >= NUM_INTRO_POINTS)
|
||||
continue;
|
||||
|
||||
/* Remember how many introduction circuits we started with. */
|
||||
prev_intro_nodes = service->intro_nodes->num_used;
|
||||
prev_intro_nodes = smartlist_len(service->intro_nodes);
|
||||
|
||||
/* The directory is now here. Pick three ORs as intro points. */
|
||||
for (j=prev_intro_nodes; j < NUM_INTRO_POINTS; ++j) {
|
||||
@ -605,7 +632,7 @@ int rend_services_init(void) {
|
||||
service->intro_nodes);
|
||||
if (!router) {
|
||||
log_fn(LOG_WARN, "Can't establish more than %d introduction points",
|
||||
service->intro_nodes->num_used);
|
||||
smartlist_len(service->intro_nodes));
|
||||
break;
|
||||
}
|
||||
changed = 1;
|
||||
@ -630,8 +657,8 @@ int rend_services_init(void) {
|
||||
tor_free(desc);
|
||||
|
||||
/* Establish new introduction points. */
|
||||
for (i=prev_intro_nodes; i < service->intro_nodes->num_used; ++i) {
|
||||
intro = (char*) service->intro_nodes->list[i];
|
||||
for (j=prev_intro_nodes; j < smartlist_len(service->intro_nodes); ++j) {
|
||||
intro = smartlist_get(service->intro_nodes, j);
|
||||
r = rend_service_launch_establish_intro(service, intro);
|
||||
if (r<0) {
|
||||
log_fn(LOG_WARN, "Error launching circuit to node %s", intro);
|
||||
|
@ -675,7 +675,7 @@ router_get_routerlist_from_directory_impl(const char *str,
|
||||
if (tokenize_string(str,end,tokens,1)) {
|
||||
log_fn(LOG_WARN, "Error tokenizing directory"); goto err;
|
||||
}
|
||||
if (tokens->num_used < 1) {
|
||||
if (smartlist_len(tokens) < 1) {
|
||||
log_fn(LOG_WARN, "Impossibly short directory header"); goto err;
|
||||
}
|
||||
if ((tok = find_first_by_keyword(tokens, _UNRECOGNIZED))) {
|
||||
@ -684,7 +684,7 @@ router_get_routerlist_from_directory_impl(const char *str,
|
||||
goto err;
|
||||
}
|
||||
|
||||
tok = (directory_token_t*)tokens->list[0];
|
||||
tok = smartlist_get(tokens,0);
|
||||
if (tok->tp != K_SIGNED_DIRECTORY) {
|
||||
log_fn(LOG_WARN, "Directory doesn't start with signed-directory.");
|
||||
goto err;
|
||||
@ -732,21 +732,20 @@ router_get_routerlist_from_directory_impl(const char *str,
|
||||
}
|
||||
new_dir->software_versions = versions; versions = NULL;
|
||||
new_dir->published_on = published_on;
|
||||
|
||||
for (i = 0; i < tokens->num_used; ++i) {
|
||||
token_free((directory_token_t*)tokens->list[i]);
|
||||
}
|
||||
|
||||
SMARTLIST_FOREACH(tokens, directory_token_t *, tok, token_free(tok));
|
||||
smartlist_free(tokens);
|
||||
|
||||
tokens = smartlist_create();
|
||||
if (tokenize_string(str,str+strlen(str),tokens,1)<0) {
|
||||
log_fn(LOG_WARN, "Error tokenizing signature"); goto err;
|
||||
}
|
||||
|
||||
if (tokens->num_used != 1 ||
|
||||
((directory_token_t*)tokens->list[0])->tp != K_DIRECTORY_SIGNATURE){
|
||||
if (smartlist_len(tokens) != 1 ||
|
||||
((directory_token_t*)smartlist_get(tokens,0))->tp != K_DIRECTORY_SIGNATURE){
|
||||
log_fn(LOG_WARN,"Expected a single directory signature"); goto err;
|
||||
}
|
||||
tok = (directory_token_t*)tokens->list[0];
|
||||
tok = smartlist_get(tokens,0);
|
||||
if (strcmp(tok->object_type, "SIGNATURE") || tok->object_size != 128) {
|
||||
log_fn(LOG_WARN, "Bad object type or length on directory signature");
|
||||
goto err;
|
||||
@ -782,9 +781,7 @@ router_get_routerlist_from_directory_impl(const char *str,
|
||||
}
|
||||
done:
|
||||
if (tokens) {
|
||||
for (i = 0; i < tokens->num_used; ++i) {
|
||||
token_free((directory_token_t*)tokens->list[i]);
|
||||
}
|
||||
SMARTLIST_FOREACH(tokens, directory_token_t *, tok, token_free(tok));
|
||||
smartlist_free(tokens);
|
||||
}
|
||||
return r;
|
||||
@ -872,7 +869,7 @@ routerinfo_t *router_get_entry_from_string(const char *s,
|
||||
char digest[128];
|
||||
smartlist_t *tokens = NULL, *exit_policy_tokens = NULL;
|
||||
directory_token_t *tok;
|
||||
int t, i;
|
||||
int t;
|
||||
int ports_set, bw_set;
|
||||
|
||||
if (!end) {
|
||||
@ -888,7 +885,7 @@ routerinfo_t *router_get_entry_from_string(const char *s,
|
||||
log_fn(LOG_WARN, "Error tokeninzing router descriptor."); goto err;
|
||||
}
|
||||
|
||||
if (tokens->num_used < 2) {
|
||||
if (smartlist_len(tokens) < 2) {
|
||||
log_fn(LOG_WARN, "Impossibly short router descriptor.");
|
||||
goto err;
|
||||
}
|
||||
@ -898,7 +895,7 @@ routerinfo_t *router_get_entry_from_string(const char *s,
|
||||
goto err;
|
||||
}
|
||||
|
||||
tok = (directory_token_t*)tokens->list[0];
|
||||
tok = smartlist_get(tokens,0);
|
||||
if (tok->tp != K_ROUTER) {
|
||||
log_fn(LOG_WARN,"Entry does not start with \"router\"");
|
||||
goto err;
|
||||
@ -991,18 +988,16 @@ routerinfo_t *router_get_entry_from_string(const char *s,
|
||||
tok->key = NULL; /* Prevent free */
|
||||
|
||||
exit_policy_tokens = find_all_exitpolicy(tokens);
|
||||
for (i = 0; i < exit_policy_tokens->num_used; ++i) {
|
||||
if (router_add_exit_policy(router,
|
||||
(directory_token_t*)exit_policy_tokens->list[i])<0) {
|
||||
log_fn(LOG_WARN, "Error in exit policy"); goto err;
|
||||
}
|
||||
}
|
||||
|
||||
SMARTLIST_FOREACH(exit_policy_tokens, directory_token_t *, t,
|
||||
if (router_add_exit_policy(router,t)<0) {
|
||||
log_fn(LOG_WARN,"Error in exit policy"); goto err;}
|
||||
);
|
||||
|
||||
if (!(tok = find_first_by_keyword(tokens, K_ROUTER_SIGNATURE))) {
|
||||
log_fn(LOG_WARN, "Missing router signature"); goto err;
|
||||
}
|
||||
if (strcmp(tok->object_type, "SIGNATURE") || tok->object_size != 128) {
|
||||
log_fn(LOG_WARN, "Bad object type or length on router signature");
|
||||
log_fn(LOG_WARN, "Bad object type or length on router signature");
|
||||
goto err;
|
||||
}
|
||||
if ((t=crypto_pk_public_checksig(router->identity_pkey, tok->object_body,
|
||||
@ -1051,9 +1046,7 @@ routerinfo_t *router_get_entry_from_string(const char *s,
|
||||
router = NULL;
|
||||
done:
|
||||
if (tokens) {
|
||||
for (i = 0; i < tokens->num_used; ++i) {
|
||||
token_free((directory_token_t*)tokens->list[i]);
|
||||
}
|
||||
SMARTLIST_FOREACH(tokens, directory_token_t *, tok, token_free(tok));
|
||||
smartlist_free(tokens);
|
||||
}
|
||||
if (exit_policy_tokens) {
|
||||
@ -1453,29 +1446,17 @@ tokenize_string(const char *start, const char *end, smartlist_t *out,
|
||||
static directory_token_t *
|
||||
find_first_by_keyword(smartlist_t *s, directory_keyword keyword)
|
||||
{
|
||||
int i;
|
||||
directory_token_t *tok;
|
||||
for (i = 0; i < s->num_used; ++i) {
|
||||
tok = (directory_token_t*) s->list[i];
|
||||
if (tok->tp == keyword) {
|
||||
return tok;
|
||||
}
|
||||
}
|
||||
SMARTLIST_FOREACH(s, directory_token_t *, t, if (t->tp == keyword) return t);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static smartlist_t *
|
||||
find_all_exitpolicy(smartlist_t *s)
|
||||
{
|
||||
int i;
|
||||
directory_token_t *tok;
|
||||
smartlist_t *out = smartlist_create();
|
||||
for (i = 0; i < s->num_used; ++i) {
|
||||
tok = (directory_token_t*) s->list[i];
|
||||
if (tok->tp == K_ACCEPT || tok->tp == K_REJECT) {
|
||||
smartlist_add(out,tok);
|
||||
}
|
||||
}
|
||||
SMARTLIST_FOREACH(s, directory_token_t *, t,
|
||||
if (t->tp == K_ACCEPT || t->tp == K_REJECT)
|
||||
smartlist_add(out,t));
|
||||
return out;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user