prkey is only fetched when it's needed
tor nodes who aren't dirservers now fetch directories and autoconnect
  to new nodes listed in the directory
default role is a non-dirserver node


svn:r120
This commit is contained in:
Roger Dingledine 2002-09-28 00:52:59 +00:00
parent 6934eb9f10
commit 22285e6ff1
13 changed files with 70 additions and 53 deletions

View File

@ -3,6 +3,8 @@
# List of routers
RouterFile ../config/routers.or
Role 63
# Private key
PrivateKeyFile moria1-private

View File

@ -3,6 +3,8 @@
# List of routers
RouterFile ../config/routers.or
Role 63
# Private key
PrivateKeyFile moria2-private

View File

@ -3,6 +3,8 @@
# List of routers
RouterFile ../config/routers.or
Role 63
# Private key
PrivateKeyFile moria3-private

View File

@ -123,8 +123,7 @@ RETURN VALUE: 0 on success, non-zero on error
options->DirRebuildPeriod = 600;
options->DirFetchPeriod = 6000;
// options->ReconnectPeriod = 6001;
options->Role = ROLE_OR_LISTEN | ROLE_OR_CONNECT_ALL | ROLE_OP_LISTEN | ROLE_AP_LISTEN |
ROLE_DIR_LISTEN | ROLE_DIR_SERVER;
options->Role = ROLE_OR_LISTEN | ROLE_OR_CONNECT_ALL | ROLE_OP_LISTEN | ROLE_AP_LISTEN;
code = poptGetNextOpt(optCon); /* first we handle command-line args */
if ( code == -1 )

View File

@ -135,8 +135,6 @@ void connection_free(connection_t *conn) {
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);
@ -145,7 +143,7 @@ void connection_free(connection_t *conn) {
free(conn);
}
int connection_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local, int type) {
int connection_create_listener(struct sockaddr_in *local, int type) {
connection_t *conn;
int s;
int one=1;
@ -188,8 +186,6 @@ 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));
if(prkey)
conn->prkey = crypto_pk_dup_key(prkey);
log(LOG_DEBUG,"connection_create_listener(): Listening on local port %u.",ntohs(local->sin_port));
@ -228,8 +224,6 @@ 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));
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 */
@ -244,8 +238,8 @@ int connection_handle_listener_read(connection_t *conn, int new_type, int new_st
return 0;
}
/* private function, to create the 'local' variable used below */
static int learn_local(struct sockaddr_in *local) {
/* create the 'local' variable used below */
int learn_local(struct sockaddr_in *local) {
/* local host information */
char localhostname[512];
struct hostent *localhost;
@ -269,7 +263,7 @@ static int learn_local(struct sockaddr_in *local) {
return 0;
}
int retry_all_connections(int role, crypto_pk_env_t *prkey, uint16_t or_listenport,
int retry_all_connections(int role, uint16_t or_listenport,
uint16_t op_listenport, uint16_t ap_listenport, uint16_t dir_listenport) {
/* start all connections that should be up but aren't */
@ -282,33 +276,33 @@ int retry_all_connections(int role, crypto_pk_env_t *prkey, uint16_t or_listenpo
local.sin_port = htons(or_listenport);
if(role & ROLE_OR_CONNECT_ALL) {
router_retry_connections(prkey, &local);
router_retry_connections(&local);
}
if(role & ROLE_OR_LISTEN) {
if(!connection_get_by_type(CONN_TYPE_OR_LISTENER)) {
connection_or_create_listener(prkey, &local);
connection_or_create_listener(&local);
}
}
if(role & ROLE_OP_LISTEN) {
local.sin_port = htons(op_listenport);
if(!connection_get_by_type(CONN_TYPE_OP_LISTENER)) {
connection_op_create_listener(prkey, &local);
connection_op_create_listener(&local);
}
}
if(role & ROLE_AP_LISTEN) {
local.sin_port = htons(ap_listenport);
if(!connection_get_by_type(CONN_TYPE_AP_LISTENER)) {
connection_ap_create_listener(NULL, &local); /* no need to tell it the private key. */
connection_ap_create_listener(&local);
}
}
if(role & ROLE_DIR_LISTEN) {
local.sin_port = htons(dir_listenport);
if(!connection_get_by_type(CONN_TYPE_DIR_LISTENER)) {
connection_dir_create_listener(NULL, &local); /* no need to tell it the private key. */
connection_dir_create_listener(&local);
}
}

View File

@ -393,9 +393,9 @@ int connection_ap_finished_flushing(connection_t *conn) {
}
int connection_ap_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local) {
int connection_ap_create_listener(struct sockaddr_in *local) {
log(LOG_DEBUG,"connection_create_ap_listener starting");
return connection_create_listener(prkey, local, CONN_TYPE_AP_LISTENER);
return connection_create_listener(local, CONN_TYPE_AP_LISTENER);
}
int connection_ap_handle_listener_read(connection_t *conn) {

View File

@ -51,7 +51,7 @@ int op_handshake_process_keys(connection_t *conn) {
log(LOG_DEBUG,"op_handshake_process_keys() : Received auth.");
/* decrypt response */
retval = crypto_pk_private_decrypt(conn->prkey, auth_cipher, 128, auth_plain,RSA_PKCS1_PADDING);
retval = crypto_pk_private_decrypt(getprivatekey(), auth_cipher, 128, auth_plain,RSA_PKCS1_PADDING);
if (retval == -1)
{
log(LOG_ERR,"Decrypting keys from new OP failed.");
@ -110,9 +110,9 @@ int connection_op_finished_flushing(connection_t *conn) {
}
int connection_op_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local) {
int connection_op_create_listener(struct sockaddr_in *local) {
log(LOG_DEBUG,"connection_create_op_listener starting");
return connection_create_listener(prkey, local, CONN_TYPE_OP_LISTENER);
return connection_create_listener(local, CONN_TYPE_OP_LISTENER);
}
int connection_op_handle_listener_read(connection_t *conn) {

View File

@ -142,7 +142,7 @@ void conn_or_init_crypto(connection_t *conn) {
* *result to 1 if connect() returned before completing, or to 2
* if it completed, and returns the new conn.
*/
connection_t *connection_or_connect(routerinfo_t *router, crypto_pk_env_t *prkey, struct sockaddr_in *local,
connection_t *connection_or_connect(routerinfo_t *router, struct sockaddr_in *local,
uint16_t port, int *result) {
connection_t *conn;
struct sockaddr_in router_addr;
@ -154,8 +154,6 @@ 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 */
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);
@ -237,7 +235,7 @@ connection_t *connection_or_connect_as_op(routerinfo_t *router, struct sockaddr_
if(conn)
return conn;
conn = connection_or_connect(router, NULL, local, router->op_port, &result);
conn = connection_or_connect(router, local, router->op_port, &result);
if(!conn)
return NULL;
@ -342,11 +340,11 @@ int or_handshake_op_finished_sending_keys(connection_t *conn) {
*
*/
connection_t *connection_or_connect_as_or(routerinfo_t *router, crypto_pk_env_t *prkey, struct sockaddr_in *local) {
connection_t *connection_or_connect_as_or(routerinfo_t *router, struct sockaddr_in *local) {
connection_t *conn;
int result=0; /* so connection_or_connect() can tell us what happened */
assert(router && prkey && local);
assert(router && local);
if(router->addr == local->sin_addr.s_addr && router->or_port == ntohs(local->sin_port)) {
/* this is me! don't connect to me. */
@ -354,7 +352,7 @@ connection_t *connection_or_connect_as_or(routerinfo_t *router, crypto_pk_env_t
return NULL;
}
conn = connection_or_connect(router, prkey, local, router->or_port, &result);
conn = connection_or_connect(router, local, router->or_port, &result);
if(!conn)
return NULL;
@ -454,7 +452,7 @@ int or_handshake_client_process_auth(connection_t *conn) {
log(LOG_DEBUG,"or_handshake_client_process_auth() : Received auth.");
/* decrypt response */
retval = crypto_pk_private_decrypt(conn->prkey, cipher, 128, buf, RSA_PKCS1_PADDING);
retval = crypto_pk_private_decrypt(getprivatekey(), cipher, 128, buf, RSA_PKCS1_PADDING);
if (retval == -1)
{
log(LOG_ERR,"Public-key decryption failed during authentication to %s:%u.",
@ -562,7 +560,7 @@ int or_handshake_server_process_auth(connection_t *conn) {
log(LOG_DEBUG,"or_handshake_server_process_auth() : Received auth.");
/* decrypt response */
retval = crypto_pk_private_decrypt(conn->prkey, cipher, 128, buf, RSA_PKCS1_PADDING);
retval = crypto_pk_private_decrypt(getprivatekey(), cipher, 128, buf, RSA_PKCS1_PADDING);
if (retval == -1)
{
log(LOG_ERR,"Public-key decryption failed processing auth message from new client.");
@ -678,7 +676,7 @@ int or_handshake_server_process_nonce(connection_t *conn) {
log(LOG_DEBUG,"or_handshake_server_process_nonce() : Received auth.");
/* decrypt response */
retval = crypto_pk_private_decrypt(conn->prkey, cipher, 128, buf,RSA_PKCS1_PADDING);
retval = crypto_pk_private_decrypt(getprivatekey(), cipher, 128, buf,RSA_PKCS1_PADDING);
if (retval == -1)
{
log(LOG_ERR,"Public-key decryption failed during authentication to %s:%u.",
@ -719,9 +717,9 @@ int or_handshake_server_process_nonce(connection_t *conn) {
/* ********************************** */
int connection_or_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local) {
int connection_or_create_listener(struct sockaddr_in *local) {
log(LOG_DEBUG,"connection_create_or_listener starting");
return connection_create_listener(prkey, local, CONN_TYPE_OR_LISTENER);
return connection_create_listener(local, CONN_TYPE_OR_LISTENER);
}
int connection_or_handle_listener_read(connection_t *conn) {

View File

@ -122,8 +122,8 @@ int connection_dir_process_inbuf(connection_t *conn) {
return -1;
}
/* eof reached, kill it, but first process the_directory and learn about new routers. */
log(LOG_DEBUG,"connection_dir_process_inbuf(): conn reached eof. Processing directory.");
log(LOG_DEBUG,"connection_dir_process_inbuf(): Received directory (size %d) '%s'", directorylen, the_directory);
// log(LOG_DEBUG,"connection_dir_process_inbuf(): conn reached eof. Processing directory.");
log(LOG_DEBUG,"connection_dir_process_inbuf(): Received directory (size %d)\n%s", directorylen, the_directory);
if(directorylen == 0) {
log(LOG_DEBUG,"connection_dir_process_inbuf(): Empty directory. Ignoring.");
return -1;
@ -131,6 +131,13 @@ int connection_dir_process_inbuf(connection_t *conn) {
if(router_get_list_from_string(the_directory, options.ORPort) < 0) {
log(LOG_DEBUG,"connection_dir_process_inbuf(): ...but parsing failed. Ignoring.");
}
if(options.Role & ROLE_OR_CONNECT_ALL) { /* connect to them all */
struct sockaddr_in local; /* local address */
if(learn_local(&local) < 0)
return -1;
local.sin_port = htons(options.ORPort);
router_retry_connections(&local);
}
return -1;
}
@ -240,9 +247,9 @@ int connection_dir_finished_flushing(connection_t *conn) {
return 0;
}
int connection_dir_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local) {
int connection_dir_create_listener(struct sockaddr_in *local) {
log(LOG_DEBUG,"connection_create_dir_listener starting");
return connection_create_listener(prkey, local, CONN_TYPE_DIR_LISTENER);
return connection_create_listener(local, CONN_TYPE_DIR_LISTENER);
}
int connection_dir_handle_listener_read(connection_t *conn) {

View File

@ -19,12 +19,21 @@ static int nfds=0; /* number of connections currently active */
static int please_dumpstats=0; /* whether we should dump stats during the loop */
/* private key */
static crypto_pk_env_t *prkey;
static crypto_pk_env_t *privatekey;
routerinfo_t *my_routerinfo=NULL;
/********* END VARIABLES ************/
void setprivatekey(crypto_pk_env_t *k) {
privatekey = k;
}
crypto_pk_env_t *getprivatekey(void) {
assert(privatekey);
return privatekey;
}
/****************************************************************************
*
* This section contains accessors and other methods on the connection_array
@ -398,6 +407,7 @@ int do_main_loop(void) {
int i;
int timeout;
int poll_result;
crypto_pk_env_t *prkey;
/* load the routers file */
if(router_get_list_from_file(options.RouterFile, options.ORPort) < 0) {
@ -417,11 +427,12 @@ int do_main_loop(void) {
log(LOG_ERR,"Error loading private key.");
return -1;
}
setprivatekey(prkey);
}
/* start-up the necessary connections based on global_role. This is where we
* try to connect to all the other ORs, and start the listeners */
retry_all_connections(options.Role, prkey, options.ORPort,
retry_all_connections(options.Role, options.ORPort,
options.OPPort, options.APPort, options.DirPort);
for(;;) {

View File

@ -30,7 +30,7 @@ int decide_aci_type(uint32_t local_addr, uint16_t local_port,
int process_onion(circuit_t *circ, connection_t *conn) {
aci_t aci_type;
if(!decrypt_onion((onion_layer_t *)circ->onion,circ->onionlen,conn->prkey)) {
if(!decrypt_onion((onion_layer_t *)circ->onion,circ->onionlen,getprivatekey())) {
log(LOG_DEBUG,"command_process_create_cell(): decrypt_onion() failed, closing circuit.");
return -1;
}

View File

@ -230,7 +230,6 @@ typedef struct
/* used by OR, to keep state while connect()ing: Kludge. */
crypto_pk_env_t *prkey;
struct sockaddr_in local;
#if 0 /* obsolete, we now use conn->bandwidth */
@ -449,12 +448,13 @@ connection_t *connection_new(int type);
void connection_free(connection_t *conn);
int connection_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local, int type);
int connection_create_listener(struct sockaddr_in *local, int type);
int connection_handle_listener_read(connection_t *conn, int new_type, int new_state);
/* start all connections that should be up but aren't */
int retry_all_connections(int role, crypto_pk_env_t *prkey, uint16_t or_listenport,
int learn_local(struct sockaddr_in *local);
int retry_all_connections(int role, uint16_t or_listenport,
uint16_t op_listenport, uint16_t ap_listenport, uint16_t dir_listenport);
connection_t *connection_connect_to_router_as_op(routerinfo_t *router, uint16_t local_or_port);
@ -512,7 +512,7 @@ int connection_ap_process_data_cell(cell_t *cell, connection_t *conn);
int connection_ap_finished_flushing(connection_t *conn);
int connection_ap_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local);
int connection_ap_create_listener(struct sockaddr_in *local);
int connection_ap_handle_listener_read(connection_t *conn);
@ -534,7 +534,7 @@ int connection_op_process_inbuf(connection_t *conn);
int connection_op_finished_flushing(connection_t *conn);
int connection_op_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local);
int connection_op_create_listener(struct sockaddr_in *local);
int connection_op_handle_listener_read(connection_t *conn);
@ -554,11 +554,11 @@ int or_handshake_client_send_auth(connection_t *conn);
int or_handshake_server_process_auth(connection_t *conn);
int or_handshake_server_process_nonce(connection_t *conn);
connection_t *connect_to_router_as_or(routerinfo_t *router, crypto_pk_env_t *prkey, struct sockaddr_in *local);
connection_t *connection_or_connect_as_or(routerinfo_t *router, crypto_pk_env_t *prkey, struct sockaddr_in *local);
connection_t *connect_to_router_as_or(routerinfo_t *router, struct sockaddr_in *local);
connection_t *connection_or_connect_as_or(routerinfo_t *router, struct sockaddr_in *local);
connection_t *connection_or_connect_as_op(routerinfo_t *router, struct sockaddr_in *local);
int connection_or_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local);
int connection_or_create_listener(struct sockaddr_in *local);
int connection_or_handle_listener_read(connection_t *conn);
/********************************* directory.c ***************************/
@ -570,11 +570,13 @@ int connection_dir_process_inbuf(connection_t *conn);
int directory_handle_command(connection_t *conn);
int directory_handle_reading(connection_t *conn);
int connection_dir_finished_flushing(connection_t *conn);
int connection_dir_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local);
int connection_dir_create_listener(struct sockaddr_in *local);
int connection_dir_handle_listener_read(connection_t *conn);
/********************************* main.c ***************************/
void setprivatekey(crypto_pk_env_t *k);
crypto_pk_env_t *getprivatekey(void);
int connection_add(connection_t *conn);
int connection_remove(connection_t *conn);
void connection_set_poll_socket(connection_t *conn);
@ -647,7 +649,7 @@ tracked_onion_t *id_tracked_onion(unsigned char *onion, uint32_t onionlen, track
/********************************* routers.c ***************************/
void router_retry_connections(crypto_pk_env_t *prkey, struct sockaddr_in *local);
void router_retry_connections(struct sockaddr_in *local);
routerinfo_t *router_pick_directory_server(void);
routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port);
unsigned int *router_new_route(int *routelen);

View File

@ -35,7 +35,7 @@ static routerinfo_t *router_get_entry_from_string(char **s);
/****************************************************************************/
void router_retry_connections(crypto_pk_env_t *prkey, struct sockaddr_in *local) {
void router_retry_connections(struct sockaddr_in *local) {
int i;
routerinfo_t *router;
@ -43,7 +43,7 @@ void router_retry_connections(crypto_pk_env_t *prkey, struct sockaddr_in *local)
router = router_array[i];
if(!connection_exact_get_by_addr_port(router->addr,router->or_port)) { /* not in the list */
log(LOG_DEBUG,"retry_all_connections(): connecting to OR %s:%u.",router->address,router->or_port);
connection_or_connect_as_or(router, prkey, local);
connection_or_connect_as_or(router, local);
}
}
}