Hide smartlist internals

svn:r1451
This commit is contained in:
Nick Mathewson 2004-04-03 00:58:54 +00:00
parent bbc9484957
commit fc4d15baf6
7 changed files with 202 additions and 113 deletions

View File

@ -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
*/

View File

@ -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;

View File

@ -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);

View File

@ -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--);
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}