Commit 253f0f16 authored by Roger Dingledine's avatar Roger Dingledine
Browse files

laying the groundwork for dynamic router lists

revamped the router reading section

reference counting for crypto pk env's (so we can dup them)

we now read and write pem pk keys from string rather than from FILE*,
  in anticipation of fetching directories over a socket
  (so now on startup we slurp in the whole file, then parse it as a string)

fixed a bug in the proxy side, where you could get some circuits
  wedged if they showed up while the connection was being made


svn:r110
parent c262b34a
......@@ -57,6 +57,7 @@ crypto_pk_env_t *crypto_new_pk_env(int type)
return 0;
env->type = type;
env->refs = 1;
env->key = NULL;
env->aux = NULL;
......@@ -80,6 +81,9 @@ crypto_pk_env_t *crypto_new_pk_env(int type)
void crypto_free_pk_env(crypto_pk_env_t *env)
{
assert(env);
if(--env->refs > 0)
return;
switch(env->type) {
case CRYPTO_PK_RSA:
......@@ -224,7 +228,7 @@ int crypto_pk_generate_key(crypto_pk_env_t *env)
return 0;
}
int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src)
int crypto_pk_read_private_key_from_file(crypto_pk_env_t *env, FILE *src)
{
assert(env && src);
......@@ -244,7 +248,7 @@ int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src)
return 0;
}
int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *keyfile)
int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, unsigned char *keyfile)
{
FILE *f_pr;
int retval = 0;
......@@ -259,7 +263,7 @@ int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *key
return -1;
/* read the private key */
retval = crypto_pk_read_private_key(env, f_pr);
retval = crypto_pk_read_private_key_from_file(env, f_pr);
fclose(f_pr);
if (retval == -1)
{
......@@ -288,15 +292,12 @@ int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *key
return -1; /* report error */
}
int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src)
int crypto_pk_read_public_key_from_file(crypto_pk_env_t *env, FILE *src)
{
assert(env && src);
switch(env->type) {
case CRYPTO_PK_RSA:
/*
if (env->key)
RSA_free((RSA *)env->key);*/
env->key = (unsigned char *)PEM_read_RSAPublicKey(src, (RSA **)&env->key, NULL, NULL);
if (!env->key)
return -1;
......@@ -308,7 +309,69 @@ int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src)
return 0;
}
int crypto_pk_write_private_key(crypto_pk_env_t *env, FILE *dest)
int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int *len) {
BUF_MEM *buf;
BIO *b;
assert(env && env->key && dest);
switch(env->type) {
case CRYPTO_PK_RSA:
b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
/* Now you can treat b as if it were a file. Just use the
* * PEM_*_bio_* functions instead of the non-bio variants.
* */
if(!PEM_write_bio_RSAPublicKey(b, (RSA *)env->key))
return -1;
BIO_get_mem_ptr(b, &buf);
BIO_set_close(b, BIO_NOCLOSE); /* so BIO_free doesn't free buf */
BIO_free(b);
*dest = malloc(buf->length+1);
if(!*dest)
return -1;
memcpy(*dest, buf->data, buf->length);
(*dest)[buf->length] = 0; /* null terminate it */
*len = buf->length;
BUF_MEM_free(buf);
break;
default:
return -1;
}
return 0;
}
int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, char *src, int len) {
BIO *b;
assert(env && src);
switch(env->type) {
case CRYPTO_PK_RSA:
b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
BIO_write(b, src, len);
RSA_free((RSA *)env->key);
env->key = (unsigned char *)PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL);
if(!env->key)
return -1;
BIO_free(b);
break;
default:
return -1;
}
return 0;
}
int crypto_pk_write_private_key_to_file(crypto_pk_env_t *env, FILE *dest)
{
assert(env && dest);
......@@ -325,7 +388,7 @@ int crypto_pk_write_private_key(crypto_pk_env_t *env, FILE *dest)
return 0;
}
int crypto_pk_write_public_key(crypto_pk_env_t *env, FILE *dest)
int crypto_pk_write_public_key_to_file(crypto_pk_env_t *env, FILE *dest)
{
assert(env && dest);
......@@ -349,9 +412,9 @@ int crypto_pk_check_key(crypto_pk_env_t *env)
switch(env->type) {
case CRYPTO_PK_RSA:
return RSA_check_key((RSA *)env->key);
return RSA_check_key((RSA *)env->key);
default:
return -1;
return -1;
}
}
......@@ -364,6 +427,7 @@ int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key)
if (!env->key)
return -1;
memcpy((void *)env->key, (void *)key, sizeof(RSA));
/* XXX BUG XXX you can't memcpy an RSA, it's got a bunch of subpointers */
break;
default :
return -1;
......@@ -402,6 +466,21 @@ int crypto_pk_keysize(crypto_pk_env_t *env)
return RSA_size((RSA *)env->key);
}
crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *env) {
assert(env && env->key);
switch(env->type) {
case CRYPTO_PK_RSA:
env->refs++;
break;
default:
return NULL;
}
return env;
}
int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding)
{
assert(env && from && to);
......
......@@ -18,6 +18,7 @@
typedef struct
{
int type;
int refs; /* reference counting; so we don't have to copy keys */
unsigned char *key;
/* auxiliary data structure(s) used by the underlying crypto library */
unsigned char *aux;
......@@ -46,15 +47,18 @@ void crypto_free_cipher_env(crypto_cipher_env_t *env);
/* public key crypto */
int crypto_pk_generate_key(crypto_pk_env_t *env);
int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src);
int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src);
int crypto_pk_write_private_key(crypto_pk_env_t *env, FILE *dest);
int crypto_pk_write_public_key(crypto_pk_env_t *env, FILE *dest);
int crypto_pk_read_private_key_from_file(crypto_pk_env_t *env, FILE *src);
int crypto_pk_read_public_key_from_file(crypto_pk_env_t *env, FILE *src);
int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int *len);
int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, char *src, int len);
int crypto_pk_write_private_key_to_file(crypto_pk_env_t *env, FILE *dest);
int crypto_pk_write_public_key_to_file(crypto_pk_env_t *env, FILE *dest);
int crypto_pk_check_key(crypto_pk_env_t *env);
int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *keyfile);
int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, unsigned char *keyfile);
int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key);
int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b);
crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig);
int crypto_pk_keysize(crypto_pk_env_t *env);
int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding);
......
......@@ -4,7 +4,7 @@
# router-port is where the router is accepting connections from other routers.
# Router 1
moria.mit.edu 9001 102400 10240
moria.mit.edu 9001 9011 9021 9031 100000
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMBBuk1sYxEg5jLAJy86U3GGJ7EGMSV7yoA6mmcsEVU3pwTUrpbpCmwS
7BvovoY3z4zk63NZVBErgKQUDkn3pp8n83xZgEf4GI27gdWIIwaBjEimuJlEY+7K
......@@ -12,7 +12,7 @@ nZ7kVMRoiXCbjL6VAtNa4Zy1Af/GOm0iCIDpholeujQ95xew7rQnAgMA//8=
-----END RSA PUBLIC KEY-----
# Router 2
moria.mit.edu 9002 102400 10240
moria.mit.edu 9002 9012 9022 9032 100000
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBANX/HHRuudz274MFSQ4manX8DhtsIuogNUyco9/0dr+XsfioTGd3RgMj
aSWlD87arkZO4hHBPHe0q89Z3s1UtUsyQ/VmsxSv9g2OCnF/dU2Nz4h6+Al3iNJF
......@@ -20,30 +20,31 @@ aSWlD87arkZO4hHBPHe0q89Z3s1UtUsyQ/VmsxSv9g2OCnF/dU2Nz4h6+Al3iNJF
-----END RSA PUBLIC KEY-----
# Router 3
moria.mit.edu 9003 102400 10240
moria.mit.edu 9003 9013 9023 9033 100000
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAJfkNWCaNkYIRwfHT06KBU6dz8W1xDpW5ezGJwAOoxCX3/ZNoUicb/1V
oB3OzW6VxWIiht3da/3K0ywiBOOCcf6BabKoMdiPpH7NIeu6XRmBYK2uqW13gBgh
xJbQBb58Nx8Fr05XkvLG6i+vTDY3MZOW3E2/DwSe/jFzuHSD5b3nAgMA//8=
-----END RSA PUBLIC KEY-----
town-square.reputation.com 9004 102400 10240
town-square.reputation.com 9004 9014 9024 9034 100000
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKD2BDZQpGq/aAbZ7t+/7qktZVEbhUGe097gIjWH9gXcIOIm0CJMe3rN
MsBJsQMi5Uwqrz+Invb5n6bswrNlJp/bCKBhGTvUCfxg7c8xZy71PPSIPnTg1qXl
p5fyAkgCYkZNgEEZzQDHv1GRvLCs92kURjSJE5y8QU0dXfbzms8PAgMA//8=
-----END RSA PUBLIC KEY-----
moria.mit.edu 9004 102400 10240
moria.mit.edu 9004 9014 9024 9034 100000
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKD2BDZQpGq/aAbZ7t+/7qktZVEbhUGe097gIjWH9gXcIOIm0CJMe3rN
MsBJsQMi5Uwqrz+Invb5n6bswrNlJp/bCKBhGTvUCfxg7c8xZy71PPSIPnTg1qXl
p5fyAkgCYkZNgEEZzQDHv1GRvLCs92kURjSJE5y8QU0dXfbzms8PAgMA//8=
-----END RSA PUBLIC KEY-----
mosg.cl.cam.ac.uk 9005 102400 10240
mosg.cl.cam.ac.uk 9005 9015 9025 9035 100000
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMMHEjhhawM6S14ETFVcvByU7D/baN2JMcCweKKJ7zcSurDnpgRH/Uo7
05+bZE3BCy4OkAqQbGlKd/ejBOuXjEtS0mJo5xwDX9StKguhgFRk60hhrF2OFJm4
VLItXA6U2NLOrc+FBCv/9laLpBrxOb8Wuct0l/lyZ2/OfE9yYhC3AgMA//8=
-----END RSA PUBLIC KEY-----
......@@ -241,10 +241,14 @@ int circuit_init(circuit_t *circ, int aci_type) {
return 0;
}
circuit_t *circuit_get_by_naddr_nport(uint32_t naddr, uint16_t nport) {
circuit_t *circ;
circuit_t *circuit_enumerate_by_naddr_nport(circuit_t *circ, uint32_t naddr, uint16_t nport) {
for(circ=global_circuitlist;circ;circ = circ->next) {
if(!circ) /* use circ if it's defined, else start from the beginning */
circ = global_circuitlist;
else
circ = circ->next;
for( ;circ;circ = circ->next) {
if(circ->n_addr == naddr && circ->n_port == nport)
return circ;
}
......
......@@ -125,6 +125,11 @@ void connection_free(connection_t *conn) {
crypto_free_cipher_env(conn->b_crypto);
}
if (conn->pkey)
crypto_free_pk_env(conn->pkey);
if (conn->prkey)
crypto_free_pk_env(conn->prkey);
if(conn->s > 0) {
log(LOG_INFO,"connection_free(): closing fd %d.",conn->s);
close(conn->s);
......@@ -175,7 +180,8 @@ int connection_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local
/* remember things so you can tell the baby sockets */
memcpy(&conn->local,local,sizeof(struct sockaddr_in));
conn->prkey = prkey;
if(prkey)
conn->prkey = crypto_pk_dup_key(prkey);
log(LOG_DEBUG,"connection_create_listener(): Listening on local port %u.",ntohs(local->sin_port));
......@@ -214,7 +220,8 @@ int connection_handle_listener_read(connection_t *conn, int new_type, int new_st
/* learn things from parent, so we can perform auth */
memcpy(&newconn->local,&conn->local,sizeof(struct sockaddr_in));
newconn->prkey = conn->prkey;
if(conn->prkey)
newconn->prkey = crypto_pk_dup_key(conn->prkey);
newconn->address = strdup(inet_ntoa(remote.sin_addr)); /* remember the remote address */
if(connection_add(newconn) < 0) { /* no space, forget it */
......
......@@ -191,7 +191,7 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int
log(LOG_DEBUG,"ap_handshake_establish_circuit(): Looking for firsthop '%s:%u'",
firsthop->address,firsthop->or_port);
n_conn = connection_twin_get_by_addr_port(firsthop->addr,firsthop->or_port);
if(!n_conn) { /* not currently connected */
if(!n_conn || n_conn->state != OR_CONN_STATE_OPEN) { /* not currently connected */
circ->n_addr = firsthop->addr;
circ->n_port = firsthop->or_port;
if(global_role & ROLE_OR_CONNECT_ALL) { /* we would be connected if he were up. but he's not. */
......@@ -199,14 +199,15 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int
circuit_close(circ);
return -1;
}
/* ok, launch the connection */
n_conn = connect_to_router_as_op(firsthop);
if(!n_conn) { /* connect failed, forget the whole thing */
log(LOG_DEBUG,"ap_handshake_establish_circuit(): connect to firsthop failed. Closing.");
circuit_close(circ);
return -1;
}
if(!n_conn) { /* launch the connection */
n_conn = connect_to_router_as_op(firsthop);
if(!n_conn) { /* connect failed, forget the whole thing */
log(LOG_DEBUG,"ap_handshake_establish_circuit(): connect to firsthop failed. Closing.");
circuit_close(circ);
return -1;
}
}
conn->state = AP_CONN_STATE_OR_WAIT;
connection_stop_reading(conn); /* Stop listening for input from the AP! */
return 0; /* return success. The onion/circuit/etc will be taken care of automatically
......@@ -219,21 +220,31 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int
}
}
/* find the circ that's waiting on me, if any, and get it to send its onion */
int ap_handshake_n_conn_open(connection_t *or_conn) {
/* find circuits that are waiting on me, if any, and get them to send the onion */
void ap_handshake_n_conn_open(connection_t *or_conn) {
circuit_t *circ;
connection_t *p_conn;
log(LOG_DEBUG,"ap_handshake_n_conn_open(): Starting.");
circ = circuit_get_by_naddr_nport(or_conn->addr, or_conn->port);
if(!circ)
return 0; /* i'm ok with that. no need to close the connection or anything. */
if(circ->p_conn->state != AP_CONN_STATE_OR_WAIT) {
log(LOG_DEBUG,"Bug: ap_handshake_n_conn_open() got an ap_conn not in OR_WAIT state.");
circ = circuit_enumerate_by_naddr_nport(NULL, or_conn->addr, or_conn->port);
for(;;) {
if(!circ)
return;
p_conn = circ->p_conn;
if(p_conn->state != AP_CONN_STATE_OR_WAIT) {
log(LOG_WARNING,"Bug: ap_handshake_n_conn_open() got an ap_conn not in OR_WAIT state.");
}
connection_start_reading(p_conn); /* resume listening for reads */
log(LOG_DEBUG,"ap_handshake_n_conn_open(): Found circ, sending onion.");
if(ap_handshake_send_onion(p_conn, or_conn, circ)<0) {
log(LOG_DEBUG,"ap_handshake_n_conn_open(): circuit marked for closing.");
p_conn->marked_for_close = 1;
return; /* XXX will want to try the rest too */
} else {
circ = circuit_enumerate_by_naddr_nport(circ, or_conn->addr, or_conn->port);
}
}
connection_start_reading(circ->p_conn); /* resume listening for reads */
log(LOG_DEBUG,"ap_handshake_n_conn_open(): Found circ, sending onion.");
return ap_handshake_send_onion(circ->p_conn, or_conn, circ);
}
int ap_handshake_send_onion(connection_t *ap_conn, connection_t *n_conn, circuit_t *circ) {
......
......@@ -154,9 +154,10 @@ connection_t *connection_or_connect(routerinfo_t *router, crypto_pk_env_t *prkey
/* set up conn so it's got all the data we need to remember */
conn->addr = router->addr, conn->port = router->or_port; /* NOTE we store or_port here always */
conn->prkey = prkey;
conn->bandwidth = router->min; /* kludge, should make a router->bandwidth and use that */
conn->pkey = router->pkey;
if(prkey)
conn->prkey = crypto_pk_dup_key(prkey);
conn->bandwidth = router->bandwidth;
conn->pkey = crypto_pk_dup_key(router->pkey);
conn->address = strdup(router->address);
memcpy(&conn->local,local,sizeof(struct sockaddr_in));
......@@ -331,8 +332,8 @@ int or_handshake_op_finished_sending_keys(connection_t *conn) {
conn->state = OR_CONN_STATE_OPEN;
connection_init_timeval(conn);
connection_watch_events(conn, POLLIN); /* give it a default, tho the ap_handshake call may change it */
return ap_handshake_n_conn_open(conn); /* send the pending onion */
ap_handshake_n_conn_open(conn); /* send the pending onions */
return 0;
}
/*
......@@ -601,14 +602,14 @@ int or_handshake_server_process_auth(connection_t *conn) {
/* update link info */
bandwidth = ntohl(*(uint32_t *)(buf+28));
conn->bandwidth = router->min; /* FIXME, should make a router->bandwidth and use that */
conn->bandwidth = router->bandwidth;
if (conn->bandwidth > bandwidth)
conn->bandwidth = bandwidth;
/* copy all relevant info to conn */
conn->addr = router->addr, conn->port = router->or_port;
conn->pkey = router->pkey;
conn->pkey = crypto_pk_dup_key(router->pkey);
conn->address = strdup(router->address);
/* generate a nonce */
......
......@@ -87,12 +87,6 @@ int connection_remove(connection_t *conn) {
return 0;
}
int pkey_cmp(crypto_pk_env_t *a, crypto_pk_env_t *b) {
/* return 0 if a and b are "the same key". Return non-0 otherwise. */
return crypto_pk_cmp_keys(a, b);
}
connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port) {
/* Find a connection to the router described by addr and port,
* or alternately any router which knows its key.
......@@ -119,7 +113,7 @@ connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port) {
for(i=0;i<nfds;i++) {
conn = connection_array[i];
assert(conn);
if(connection_state_is_open(conn) && !pkey_cmp(conn->pkey, router->pkey)) {
if(connection_state_is_open(conn) && !crypto_pk_cmp_keys(conn->pkey, router->pkey)) {
log(LOG_INFO,"connection_twin_get_by_addr_port(): Found twin (%s).",conn->address);
return conn;
}
......@@ -412,7 +406,7 @@ int do_main_loop(void) {
int poll_result;
/* load the routers file */
router_array = getrouters(options.RouterFile,&rarray_len, options.ORPort);
router_array = router_get_list_from_file(options.RouterFile,&rarray_len, options.ORPort);
if (!router_array)
{
log(LOG_ERR,"Error loading router list.");
......@@ -426,7 +420,7 @@ int do_main_loop(void) {
log(LOG_ERR,"Error creating a crypto environment.");
return -1;
}
if (crypto_pk_read_private_key_filename(prkey, options.PrivateKeyFile))
if (crypto_pk_read_private_key_from_filename(prkey, options.PrivateKeyFile))
{
log(LOG_ERR,"Error loading private key.");
return -1;
......
......@@ -118,7 +118,7 @@ unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *r
goto next_i_loop;
}
for(j=0;j<i;j++) {
if(!pkey_cmp(rarray[i]->pkey, rarray[j]->pkey)) {
if(!crypto_pk_cmp_keys(rarray[i]->pkey, rarray[j]->pkey)) {
/* these guys are twins. so we've already counted him. */
log(LOG_DEBUG,"Nope, %d is a twin of %d.",i,j);
goto next_i_loop;
......@@ -158,7 +158,7 @@ unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *r
choice = choice % (rarray_len);
log(LOG_DEBUG,"new_route(): Contemplating router %u.",choice);
if(choice == oldchoice ||
(oldchoice < rarray_len && !pkey_cmp(rarray[choice]->pkey, rarray[oldchoice]->pkey)) ||
(oldchoice < rarray_len && !crypto_pk_cmp_keys(rarray[choice]->pkey, rarray[oldchoice]->pkey)) ||
((global_role & ROLE_OR_CONNECT_ALL) && !connection_twin_get_by_addr_port(rarray[choice]->addr, rarray[choice]->or_port))) {
/* Same router as last choice, or router twin,
* or no routers with that key are connected to us.
......
......@@ -30,6 +30,7 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
......@@ -244,12 +245,13 @@ typedef struct
uint16_t or_port;
uint16_t op_port;
uint16_t ap_port;
uint16_t dir_port;
crypto_pk_env_t *pkey; /* public RSA key */
/* link info */
uint32_t min;
uint32_t max;
uint32_t bandwidth;
// struct timeval min_interval;
/* time when last data was sent to that router */
......@@ -392,7 +394,7 @@ aci_t get_unique_aci_by_addr_port(uint32_t addr, uint16_t port, int aci_type);
circuit_t *circuit_get_by_aci_conn(aci_t aci, connection_t *conn);
circuit_t *circuit_get_by_conn(connection_t *conn);
circuit_t *circuit_get_by_naddr_nport(uint32_t naddr, uint16_t nport);
circuit_t *circuit_enumerate_by_naddr_nport(circuit_t *start, uint32_t naddr, uint16_t nport);
int circuit_deliver_data_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int crypt_type);
int circuit_crypt(circuit_t *circ, char *in, int inlen, char crypt_type);
......@@ -487,8 +489,7 @@ int ap_handshake_create_onion(connection_t *conn);
int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int routelen, char *onion,
int onionlen, crypt_path_t **cpath);
/* find the circ that's waiting on me, if any, and get it to send its onion */
int ap_handshake_n_conn_open(connection_t *or_conn);
void ap_handshake_n_conn_open(connection_t *or_conn);
int ap_handshake_send_onion(connection_t *ap_conn, connection_t *or_conn, circuit_t *circ);
......@@ -553,7 +554,6 @@ int connection_add(connection_t *conn);
int connection_remove(connection_t *conn);
void connection_set_poll_socket(connection_t *conn);
int pkey_cmp(crypto_pk_env_t *a, crypto_pk_env_t *b);
connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port);
connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port);
......@@ -625,10 +625,6 @@ tracked_onion_t *id_tracked_onion(unsigned char *onion, uint32_t onionlen, track
/********************************* routers.c ***************************/
routerinfo_t **getrouters(char *routerfile, int *listlenp, uint16_t or_listenport);
void delete_routerlist(routerinfo_t *list);
/* create an NULL-terminated array of pointers pointing to elements of a router list */
routerinfo_t **make_rarray(routerinfo_t* list, int *len);
routerinfo_t **router_get_list_from_file(char *routerfile, int *len, uint16_t or_listenport);
#endif
......@@ -9,13 +9,20 @@
* Matej Pfajfar <mp292@cam.ac.uk>
*/
#define OR_ROUTERLIST_SEPCHARS " \t\n"
#define OR_PUBLICKEY_BEGIN_TAG "-----BEGIN RSA PUBLIC KEY-----\n"
#define OR_PUBLICKEY_END_TAG "-----END RSA PUBLIC KEY-----\n"
#include "or.h"
extern int global_role; /* from main.c */
/* static function prototypes */
static int router_is_me(uint32_t or_address, uint16_t or_listenport, uint16_t my_or_listenport);
static void routerlist_free(routerinfo_t *list);
static routerinfo_t **make_rarray(routerinfo_t* list, int *len);
static char *eat_whitespace(char *s);
static char *find_whitespace(char *s);
static routerinfo_t *router_get_entry_from_string(char **s);
/* private function, to determine whether the current entry in the router list is actually us */
static int router_is_me(uint32_t or_address, uint16_t or_listenport, uint16_t my_or_listenport)
{
......@@ -35,12 +42,12 @@ static int router_is_me(uint32_t or_address, uint16_t or_listenport, uint16_t my
/* obtain local host information */
if (gethostname(localhostname,512) < 0) {
log(LOG_ERR,"Error obtaining local hostname.");
log(LOG_ERR,"router_is_me(): Error obtaining local hostname.");
return -1;
}
localhost = gethostbyname(localhostname);
if (!localhost) {
log(LOG_ERR,"Error obtaining local host info.");
log(LOG_ERR,"router_is_me(): Error obtaining local host info.");
return -1;
}
......@@ -71,7 +78,7 @@ static int router_is_me(uint32_t or_address, uint16_t or_listenport, uint16_t my
}
/* delete a list of routers from memory */
void delete_routerlist(routerinfo_t *list)
static void routerlist_free(routerinfo_t *list)
{
routerinfo_t *tmp = NULL;
......@@ -91,10 +98,17 @@ void delete_routerlist(routerinfo_t *list)
return;
}
void rarray_free(routerinfo_t **list) {
if(!list)
return;
routerlist_free(*list);
free(list);
}
/* create a NULL-terminated array of pointers pointing to elements of a router list */
/* this is done in two passes through the list - inefficient but irrelevant as this is
* only done once when op/or start up */
routerinfo_t **make_rarray(routerinfo_t* list, int *len)
static routerinfo_t **make_rarray(routerinfo_t* list, int *len)
{
routerinfo_t *tmp=NULL;
int listlen = 0;
......@@ -135,303 +149,220 @@ routerinfo_t **make_rarray(routerinfo_t* list, int *len)
return array;
}
/* load the router list */
routerinfo_t **getrouters(char *routerfile, int *len, uint16_t or_listenport)
routerinfo_t **router_get_list_from_file(char *routerfile, int *len, uint16_t or_listenport)
{
int retval = 0;
char *retp = NULL;
routerinfo_t *router=NULL, *routerlist=NULL, *lastrouter=NULL;