[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[or-cvs] directory servers in and functional
Update of /home/or/cvsroot/src/or
In directory moria.seul.org:/home/arma/work/onion/cvs/src/or
Modified Files:
Makefile.am config.c connection.c connection_exit.c
connection_or.c main.c or.h routers.c
Added Files:
directory.c
Log Message:
directory servers in and functional
proxies now periodically pull down an hourly-updated directory,
and replace their router list with it if it parses correctly.
--- NEW FILE: directory.c ---
(This appears to be a binary file; contents omitted.)
Index: Makefile.am
===================================================================
RCS file: /home/or/cvsroot/src/or/Makefile.am,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- Makefile.am 3 Sep 2002 22:53:34 -0000 1.7
+++ Makefile.am 26 Sep 2002 12:09:09 -0000 1.8
@@ -9,7 +9,7 @@
or_SOURCES = buffers.c cell.c circuit.c command.c connection.c \
connection_exit.c connection_ap.c connection_op.c connection_or.c config.c \
- main.c onion.c routers.c
+ main.c onion.c routers.c directory.c
test_config_SOURCES = test_config.c
Index: config.c
===================================================================
RCS file: /home/or/cvsroot/src/or/config.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- config.c 4 Sep 2002 06:29:27 -0000 1.16
+++ config.c 26 Sep 2002 12:09:09 -0000 1.17
@@ -85,6 +85,8 @@
0, "onion proxy port", "<port>" },
{ "ORPort", 'p', POPT_ARG_INT, &options->ORPort,
0, "onion router port", "<port>" },
+ { "DirPort", 'd', POPT_ARG_INT, &options->DirPort,
+ 0, "directory server port", "<port>" },
{ "PrivateKeyFile", 'k', POPT_ARG_STRING, &options->PrivateKeyFile,
0, "maximum number of incoming connections", "<file>" },
{ "RouterFile", 'r', POPT_ARG_STRING, &options->RouterFile,
@@ -92,8 +94,14 @@
{ "TrafficShaping", 't', POPT_ARG_INT, &options->TrafficShaping,
0, "which traffic shaping policy to use", "<policy>" },
{ "LinkPadding", 'P', POPT_ARG_INT, &options->LinkPadding,
- 0, "whether to use link padding", "<padding>" },
- { "Role", 'g', POPT_ARG_INT, &options->Role,
+ 0, "whether to use link padding", "<padding>" },
+ { "DirRebuildPeriod",'D', POPT_ARG_INT, &options->DirRebuildPeriod,
+ 0, "how many seconds between directory rebuilds", "<rebuildperiod>" },
+ { "DirFetchPeriod", 'F', POPT_ARG_INT, &options->DirFetchPeriod,
+ 0, "how many seconds between directory fetches", "<fetchperiod>" },
+// { "ReconnectPeriod", 'e', POPT_ARG_INT, &options->ReconnectPeriod,
+// 0, "how many seconds between retrying all OR connections", "<reconnectperiod>" },
+ { "Role", 'R', POPT_ARG_INT, &options->Role,
0, "4-bit global role id", "<role>" },
{ "Verbose", 'v', POPT_ARG_NONE, &Verbose,
0, "display options selected before execution", NULL },
@@ -112,7 +120,11 @@
options->loglevel = LOG_DEBUG;
options->CoinWeight = 0.8;
options->LinkPadding = 0;
- options->Role = ROLE_OR_LISTEN | ROLE_OR_CONNECT_ALL | ROLE_OP_LISTEN | ROLE_AP_LISTEN;
+ 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;
code = poptGetNextOpt(optCon); /* first we handle command-line args */
if ( code == -1 )
@@ -151,14 +163,17 @@
printf("RouterFile=%s, PrivateKeyFile=%s\n",
options->RouterFile,
options->PrivateKeyFile);
- printf("ORPort=%d, OPPort=%d, APPort=%d\n",
+ printf("ORPort=%d, OPPort=%d, APPort=%d DirPort=%d\n",
options->ORPort,options->OPPort,
- options->APPort);
+ options->APPort,options->DirPort);
printf("CoinWeight=%6.4f, MaxConn=%d, TrafficShaping=%d, LinkPadding=%d\n",
options->CoinWeight,
options->MaxConn,
options->TrafficShaping,
options->LinkPadding);
+ printf("DirRebuildPeriod=%d, DirFetchPeriod=%d\n",
+ options->DirRebuildPeriod,
+ options->DirFetchPeriod);
}
/* Validate options */
@@ -188,9 +203,9 @@
}
}
- if ( options->Role < 0 || options->Role > 15 )
+ if ( options->Role < 0 || options->Role > 63 )
{
- log(LOG_ERR,"Role option must be an integer between 0 and 15 (inclusive).");
+ log(LOG_ERR,"Role option must be an integer between 0 and 63 (inclusive).");
code = -1;
}
@@ -224,6 +239,12 @@
code = -1;
}
+ if ( (options->Role & ROLE_DIR_LISTEN) && options->DirPort < 1 )
+ {
+ log(LOG_ERR,"DirPort option required and must be a positive integer value.");
+ code = -1;
+ }
+
if ( (options->Role & ROLE_AP_LISTEN) &&
(options->CoinWeight < 0.0 || options->CoinWeight >= 1.0) )
{
@@ -252,6 +273,18 @@
if ( options->LinkPadding != 0 && options->LinkPadding != 1 )
{
log(LOG_ERR,"LinkPadding option must be either 0 or 1.");
+ code = -1;
+ }
+
+ if ( options->DirRebuildPeriod < 1)
+ {
+ log(LOG_ERR,"DirRebuildPeriod option must be positive.");
+ code = -1;
+ }
+
+ if ( options->DirFetchPeriod < 1)
+ {
+ log(LOG_ERR,"DirFetchPeriod option must be positive.");
code = -1;
}
Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- connection.c 24 Sep 2002 10:43:56 -0000 1.24
+++ connection.c 26 Sep 2002 12:09:10 -0000 1.25
@@ -16,10 +16,12 @@
"OR", /* 4 */
"Exit", /* 5 */
"App listener",/* 6 */
- "App" /* 7 */
+ "App", /* 7 */
+ "Dir listener",/* 8 */
+ "Dir", /* 9 */
};
-char *conn_state_to_string[][10] = {
+char *conn_state_to_string[][15] = {
{ }, /* no type associated with 0 */
{ "ready" }, /* op listener, 0 */
{ "awaiting keys", /* op, 0 */
@@ -43,7 +45,13 @@
{ "ready" }, /* app listener, 0 */
{ "awaiting dest info", /* app, 0 */
"waiting for OR connection", /* 1 */
- "open" } /* 2 */
+ "open" }, /* 2 */
+ { "ready" }, /* dir listener, 0 */
+ { "connecting", /* 0 */
+ "sending command", /* 1 */
+ "reading", /* 2 */
+ "awaiting command", /* 3 */
+ "writing" }, /* 4 */
};
/********* END VARIABLES ************/
@@ -261,27 +269,20 @@
return 0;
}
-int retry_all_connections(int role, routerinfo_t **router_array, int rarray_len,
- crypto_pk_env_t *prkey, uint16_t or_listenport, uint16_t op_listenport, uint16_t ap_listenport) {
+int retry_all_connections(int role, crypto_pk_env_t *prkey, 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 */
- routerinfo_t *router;
- int i;
struct sockaddr_in local; /* local address */
if(learn_local(&local) < 0)
return -1;
local.sin_port = htons(or_listenport);
+
if(role & ROLE_OR_CONNECT_ALL) {
- for (i=0;i<rarray_len;i++) {
- 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);
- }
- }
+ router_retry_connections(prkey, &local);
}
if(role & ROLE_OR_LISTEN) {
@@ -303,6 +304,13 @@
connection_ap_create_listener(NULL, &local); /* no need to tell it the private key. */
}
}
+
+ 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. */
+ }
+ }
return 0;
}
@@ -415,7 +423,8 @@
int connection_is_listener(connection_t *conn) {
if(conn->type == CONN_TYPE_OP_LISTENER ||
conn->type == CONN_TYPE_OR_LISTENER ||
- conn->type == CONN_TYPE_AP_LISTENER)
+ conn->type == CONN_TYPE_AP_LISTENER ||
+ conn->type == CONN_TYPE_DIR_LISTENER)
return 1;
return 0;
}
@@ -586,6 +595,8 @@
return connection_exit_process_inbuf(conn);
case CONN_TYPE_AP:
return connection_ap_process_inbuf(conn);
+ case CONN_TYPE_DIR:
+ return connection_dir_process_inbuf(conn);
default:
log(LOG_DEBUG,"connection_process_inbuf() got unexpected conn->type.");
return -1;
@@ -709,6 +720,8 @@
return connection_or_finished_flushing(conn);
case CONN_TYPE_EXIT:
return connection_exit_finished_flushing(conn);
+ case CONN_TYPE_DIR:
+ return connection_dir_finished_flushing(conn);
default:
log(LOG_DEBUG,"connection_finished_flushing() got unexpected conn->type.");
return -1;
Index: connection_exit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_exit.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- connection_exit.c 22 Sep 2002 11:09:07 -0000 1.11
+++ connection_exit.c 26 Sep 2002 12:09:10 -0000 1.12
@@ -179,8 +179,8 @@
/* also, deliver a 'connected' cell back through the circuit. */
return connection_exit_send_connected(conn);
} else {
- log(LOG_DEBUG,"connection_exit_process_data_cell(): in connecting_wait, but I've already received everything. Closing.");
- return -1;
+ log(LOG_DEBUG,"connection_exit_process_data_cell(): in connecting_wait, but I've already received everything. Closing.");
+ return -1;
}
return 0;
case EXIT_CONN_STATE_CONNECTING:
Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_or.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- connection_or.c 24 Sep 2002 10:43:56 -0000 1.14
+++ connection_or.c 26 Sep 2002 12:09:10 -0000 1.15
@@ -66,7 +66,7 @@
if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, &e, &len) < 0) { /* not yet */
if(errno != EINPROGRESS){
/* yuck. kill it. */
- log(LOG_DEBUG,"connection_or_finished_flushing(): in-progress connect failed. Removing.");
+ log(LOG_DEBUG,"connection_or_finished_flushing(): in-progress connect failed. Removing.");
return -1;
} else {
return 0; /* no change, see if next time is better */
Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- main.c 24 Sep 2002 10:43:56 -0000 1.24
+++ main.c 26 Sep 2002 12:09:10 -0000 1.25
@@ -21,10 +21,6 @@
/* private key */
static crypto_pk_env_t *prkey;
-/* router array */
-static routerinfo_t **router_array = NULL;
-static int rarray_len = 0;
-
/********* END VARIABLES ************/
/****************************************************************************
@@ -154,44 +150,6 @@
-/* the next 4 functions should move to routers.c once we get it
- * cleaned up more. The router_array and rarray_len variables should
- * move there too.
- */
-
-routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port) {
- int i;
- routerinfo_t *router;
-
- assert(router_array);
-
- for(i=0;i<rarray_len;i++) {
- router = router_array[i];
- if ((router->addr == addr) && (router->or_port == port))
- return router;
- }
-
- return NULL;
-}
-
-routerinfo_t *router_get_first_in_route(unsigned int *route, int routelen) {
- return router_array[route[routelen-1]];
-}
-
-/* a wrapper around new_route. put all these in routers.c perhaps? */
-unsigned int *router_new_route(int *routelen) {
- return new_route(options.CoinWeight, router_array, rarray_len, routelen);
-}
-
-/* a wrapper around create_onion */
-unsigned char *router_create_onion(unsigned int *route, int routelen, int *len, crypt_path_t **cpath) {
- return create_onion(router_array,rarray_len,route,routelen,len,cpath);
-}
-
-
-
-
-
/* FIXME can we cut this function out? */
connection_t *connect_to_router_as_op(routerinfo_t *router) {
return connection_connect_to_router_as_op(router, options.ORPort);
@@ -252,12 +210,13 @@
retval = connection_or_handle_listener_read(conn);
} else if (conn->type == CONN_TYPE_AP_LISTENER) {
retval = connection_ap_handle_listener_read(conn);
+ } else if (conn->type == CONN_TYPE_DIR_LISTENER) {
+ retval = connection_dir_handle_listener_read(conn);
} else {
- /* else it's an OP, OR, or exit */
retval = connection_read_to_buf(conn);
if (retval >= 0) { /* all still well */
retval = connection_process_inbuf(conn);
-// log(LOG_DEBUG,"check_conn_read(): connection_process_inbuf returned %d.",retval);
+// log(LOG_DEBUG,"check_conn_read(): connection_process_inbuf returned %d.",retval);
if(retval >= 0 && !connection_state_is_open(conn) && conn->receiver_bucket == 0) {
log(LOG_DEBUG,"check_conn_read(): receiver bucket reached 0 before handshake finished. Closing.");
retval = -1;
@@ -286,8 +245,7 @@
conn = connection_array[i];
// log(LOG_DEBUG,"check_conn_write(): socket %d wants to write.",conn->s);
- if(conn->type == CONN_TYPE_OP_LISTENER ||
- conn->type == CONN_TYPE_OR_LISTENER) {
+ if(connection_is_listener(conn)) {
log(LOG_DEBUG,"check_conn_write(): Got a listener socket. Can't happen!");
retval = -1;
} else {
@@ -337,6 +295,8 @@
connection_t *tmpconn;
struct timeval now, soonest;
static int current_second = 0; /* from previous calls to gettimeofday */
+ static int time_to_rebuild_directory = 0;
+ static int time_to_fetch_directory = 0;
int ms_until_conn;
*timeout = -1; /* set it to never timeout, possibly overridden below */
@@ -352,6 +312,34 @@
if(gettimeofday(&now,NULL) < 0)
return -1;
+ if(options.Role & ROLE_DIR_SERVER) {
+ if(time_to_rebuild_directory < now.tv_sec) {
+ /* it's time to rebuild our directory */
+ if(time_to_rebuild_directory == 0) {
+ /* we just started up. if we build a directory now it will be meaningless. */
+ log(LOG_DEBUG,"prepare_for_poll(): Delaying initial dir build for 15 seconds.");
+ time_to_rebuild_directory = now.tv_sec + 15; /* try in 15 seconds */
+ } else {
+ directory_rebuild();
+ time_to_rebuild_directory = now.tv_sec + options.DirRebuildPeriod;
+ }
+ }
+ *timeout = 1000*(time_to_rebuild_directory - now.tv_sec) + (1000 - (now.tv_usec / 1000));
+// log(LOG_DEBUG,"prepare_for_poll(): DirBuild timeout is %d",*timeout);
+ }
+
+ if(!(options.Role & ROLE_DIR_SERVER)) {
+ if(time_to_fetch_directory < now.tv_sec) {
+ /* it's time to fetch a new directory */
+ /* NOTE directory servers do not currently fetch directories.
+ * Hope this doesn't bite us later.
+ */
+ directory_initiate_fetch(router_pick_directory_server());
+ time_to_fetch_directory = now.tv_sec + options.DirFetchPeriod;
+ }
+ *timeout = 1000*(time_to_fetch_directory - now.tv_sec) + (1000 - (now.tv_usec / 1000));
+ }
+
if(need_to_refill_buckets) {
if(now.tv_sec > current_second) { /* the second has already rolled over! */
// log(LOG_DEBUG,"prepare_for_poll(): The second has rolled over, immediately refilling.");
@@ -359,8 +347,8 @@
connection_increment_receiver_bucket(connection_array[i]);
current_second = now.tv_sec; /* remember which second it is, for next time */
}
+ /* this timeout is definitely sooner than either of the above two */
*timeout = 1000 - (now.tv_usec / 1000); /* how many milliseconds til the next second? */
-// log(LOG_DEBUG,"prepare_for_poll(): %d milliseconds til next second.",*timeout);
}
if(options.LinkPadding) {
@@ -406,9 +394,7 @@
int poll_result;
/* load the routers file */
- router_array = router_get_list_from_file(options.RouterFile,&rarray_len, options.ORPort);
- if (!router_array)
- {
+ if(router_get_list_from_file(options.RouterFile, options.ORPort) < 0) {
log(LOG_ERR,"Error loading router list.");
return -1;
}
@@ -429,8 +415,8 @@
/* 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, router_array, rarray_len, prkey,
- options.ORPort, options.OPPort, options.APPort);
+ retry_all_connections(options.Role, prkey, options.ORPort,
+ options.OPPort, options.APPort, options.DirPort);
for(;;) {
if(please_dumpstats) {
@@ -496,7 +482,7 @@
int i;
connection_t *conn;
extern char *conn_type_to_string[];
- extern char *conn_state_to_string[][10];
+ extern char *conn_state_to_string[][15];
printf("Dumping stats:\n");
@@ -513,6 +499,53 @@
}
please_dumpstats = 0;
+}
+
+void dump_directory_to_string(char *s, int maxlen) {
+ int i;
+ connection_t *conn;
+ char *pkey;
+ int pkeylen;
+ int written;
+ routerinfo_t *router;
+
+ for(i=0;i<nfds;i++) {
+ conn = connection_array[i];
+
+ if(conn->type != CONN_TYPE_OR)
+ continue; /* we only want to list ORs */
+ router = router_get_by_addr_port(conn->addr,conn->port);
+ if(!router) {
+ log(LOG_ERR,"dump_directory_to_string(): couldn't find router %d:%d!",conn->addr,conn->port);
+ return;
+ }
+ if(crypto_pk_write_public_key_to_string(router->pkey,&pkey,&pkeylen)<0) {
+ log(LOG_ERR,"dump_directory_to_string(): write pkey to string failed!");
+ return;
+ }
+ written = snprintf(s, maxlen, "%s %d %d %d %d %d\n%s\n",
+ router->address,
+ router->or_port,
+ router->op_port,
+ router->ap_port,
+ router->dir_port,
+ router->bandwidth,
+ pkey);
+
+ free(pkey);
+
+ if(written < 0 || written > maxlen) {
+ /* apparently different glibcs do different things on error.. so check both */
+ log(LOG_ERR,"dump_directory_to_string(): tried to exceed string length.");
+ s[maxlen-1] = 0; /* make sure it's null terminated */
+ return;
+ }
+
+ maxlen -= written;
+ s += written;
+
+ }
+
}
int main(int argc, char *argv[]) {
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- or.h 24 Sep 2002 10:43:57 -0000 1.26
+++ or.h 26 Sep 2002 12:09:10 -0000 1.27
@@ -58,6 +58,8 @@
#define ROLE_OR_CONNECT_ALL 2
#define ROLE_OP_LISTEN 4
#define ROLE_AP_LISTEN 8
+#define ROLE_DIR_LISTEN 16
+#define ROLE_DIR_SERVER 32
#define ROLE_IS_OR(role) ((role & ROLE_OR_LISTEN) || (role & ROLE_OR_CONNECT_ALL) || (role & ROLE_OP_LISTEN))
@@ -68,6 +70,8 @@
#define CONN_TYPE_EXIT 5
#define CONN_TYPE_AP_LISTENER 6
#define CONN_TYPE_AP 7
+#define CONN_TYPE_DIR_LISTENER 8
+#define CONN_TYPE_DIR 9
#define LISTENER_STATE_READY 0
@@ -105,6 +109,12 @@
#define AP_CONN_STATE_OR_WAIT 1
#define AP_CONN_STATE_OPEN 2
+#define DIR_CONN_STATE_CONNECTING 0
+#define DIR_CONN_STATE_SENDING_COMMAND 1
+#define DIR_CONN_STATE_READING 2
+#define DIR_CONN_STATE_COMMAND_WAIT 3
+#define DIR_CONN_STATE_WRITING 4
+
#define CIRCUIT_STATE_OPEN_WAIT 0 /* receiving/processing the onion */
#define CIRCUIT_STATE_OR_WAIT 1 /* I'm at the beginning of the path, my firsthop is still connecting */
#define CIRCUIT_STATE_OPEN 2 /* onion processed, ready to send data along the connection */
@@ -342,9 +352,12 @@
int ORPort;
int OPPort;
int APPort;
+ int DirPort;
int MaxConn;
int TrafficShaping;
int LinkPadding;
+ int DirRebuildPeriod;
+ int DirFetchPeriod;
int Role;
int loglevel;
} or_options_t;
@@ -441,8 +454,8 @@
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, routerinfo_t **router_array, int rarray_len,
- crypto_pk_env_t *prkey, uint16_t or_port, uint16_t op_port, uint16_t ap_port);
+int retry_all_connections(int role, crypto_pk_env_t *prkey, 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);
int connection_read_to_buf(connection_t *conn);
@@ -548,6 +561,18 @@
int connection_or_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local);
int connection_or_handle_listener_read(connection_t *conn);
+/********************************* directory.c ***************************/
+
+void directory_initiate_fetch(routerinfo_t *router);
+int directory_send_command(connection_t *conn);
+void directory_rebuild(void);
+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_handle_listener_read(connection_t *conn);
+
/********************************* main.c ***************************/
int connection_add(connection_t *conn);
@@ -559,10 +584,6 @@
connection_t *connection_get_by_type(int type);
-routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port);
-unsigned int *router_new_route(int *routelen);
-unsigned char *router_create_onion(unsigned int *route, int routelen, int *len, crypt_path_t **cpath);
-routerinfo_t *router_get_first_in_route(unsigned int *route, int routelen);
connection_t *connect_to_router_as_op(routerinfo_t *router);
void connection_watch_events(connection_t *conn, short events);
@@ -582,6 +603,7 @@
void catchint();
void catchusr1();
void dumpstats(void);
+void dump_directory_to_string(char *s, int maxlen);
int main(int argc, char *argv[]);
@@ -625,6 +647,13 @@
/********************************* routers.c ***************************/
-routerinfo_t **router_get_list_from_file(char *routerfile, int *len, uint16_t or_listenport);
+void router_retry_connections(crypto_pk_env_t *prkey, 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);
+unsigned char *router_create_onion(unsigned int *route, int routelen, int *len, crypt_path_t **cpath);
+routerinfo_t *router_get_first_in_route(unsigned int *route, int routelen);
+int router_get_list_from_file(char *routerfile, uint16_t or_listenport);
+int router_get_list_from_string(char *s, uint16_t or_listenport);
#endif
Index: routers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routers.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- routers.c 24 Sep 2002 10:43:57 -0000 1.11
+++ routers.c 26 Sep 2002 12:09:10 -0000 1.12
@@ -13,7 +13,16 @@
#include "or.h"
+/****************************************************************************/
+
+/* router array */
+static routerinfo_t **router_array = NULL;
+static int rarray_len = 0;
+
extern int global_role; /* from main.c */
+extern or_options_t options; /* command-line and config-file options */
+
+/****************************************************************************/
/* static function prototypes */
static int router_is_me(uint32_t or_address, uint16_t or_listenport, uint16_t my_or_listenport);
@@ -23,6 +32,67 @@
static char *find_whitespace(char *s);
static routerinfo_t *router_get_entry_from_string(char **s);
+/****************************************************************************/
+
+void router_retry_connections(crypto_pk_env_t *prkey, struct sockaddr_in *local) {
+ int i;
+ routerinfo_t *router;
+
+ for (i=0;i<rarray_len;i++) {
+ 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);
+ }
+ }
+}
+
+routerinfo_t *router_pick_directory_server(void) {
+ /* currently, pick the first router with a positive dir_port */
+ int i;
+ routerinfo_t *router;
+
+ if(!router_array)
+ return NULL;
+
+ for(i=0;i<rarray_len;i++) {
+ router = router_array[i];
+ if(router->dir_port > 0)
+ return router;
+ }
+
+ return NULL;
+}
+
+routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port) {
+ int i;
+ routerinfo_t *router;
+
+ assert(router_array);
+
+ for(i=0;i<rarray_len;i++) {
+ router = router_array[i];
+ if ((router->addr == addr) && (router->or_port == port))
+ return router;
+ }
+
+ return NULL;
+}
+
+routerinfo_t *router_get_first_in_route(unsigned int *route, int routelen) {
+ return router_array[route[routelen-1]];
+}
+
+/* a wrapper around new_route. put all these in routers.c perhaps? */
+unsigned int *router_new_route(int *routelen) {
+ return new_route(options.CoinWeight, router_array, rarray_len, routelen);
+}
+
+/* a wrapper around create_onion */
+unsigned char *router_create_onion(unsigned int *route, int routelen, int *len, crypt_path_t **cpath) {
+ return create_onion(router_array,rarray_len,route,routelen,len,cpath);
+}
+
/* 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)
{
@@ -58,8 +128,8 @@
a = (struct in_addr *)addr;
tmp1 = strdup(inet_ntoa(*a)); /* can't call inet_ntoa twice in the same
- printf, since it overwrites its static
- memory each time */
+ printf, since it overwrites its static
+ memory each time */
log(LOG_DEBUG,"router_is_me(): Comparing '%s' to '%s'.",tmp1,
inet_ntoa( *((struct in_addr *)&or_address) ) );
free(tmp1);
@@ -151,64 +221,87 @@
/* load the router list */
-routerinfo_t **router_get_list_from_file(char *routerfile, int *len, uint16_t or_listenport)
+int router_get_list_from_file(char *routerfile, uint16_t or_listenport)
{
- routerinfo_t *routerlist=NULL;
- routerinfo_t *router;
int fd; /* router file */
struct stat statbuf;
char *string;
- char *tmps;
- assert(routerfile && len);
+ assert(routerfile);
if (strcspn(routerfile,CONFIG_LEGAL_FILENAME_CHARACTERS) != 0) {
log(LOG_ERR,"router_get_list_from_file(): Filename %s contains illegal characters.",routerfile);
- return NULL;
+ return -1;
}
if(stat(routerfile, &statbuf) < 0) {
log(LOG_ERR,"router_get_list_from_file(): Could not stat %s.",routerfile);
- return NULL;
+ return -1;
}
/* open the router list */
fd = open(routerfile,O_RDONLY,0);
if (fd<0) {
log(LOG_ERR,"router_get_list_from_file(): Could not open %s.",routerfile);
- return NULL;
+ return -1;
}
string = malloc(statbuf.st_size+1);
if(!string) {
log(LOG_ERR,"router_get_list_from_file(): Out of memory.");
- return NULL;
+ return -1;
}
if(read(fd,string,statbuf.st_size) != statbuf.st_size) {
log(LOG_ERR,"router_get_list_from_file(): Couldn't read all %d bytes of file '%s'.",statbuf.st_size,routerfile);
- return NULL;
+ free(string);
+ close(fd);
+ return -1;
}
close(fd);
string[statbuf.st_size] = 0; /* null terminate it */
- tmps = string;
- while(*tmps) { /* while not at the end of the string */
- router = router_get_entry_from_string(&tmps);
+
+ if(router_get_list_from_string(string, or_listenport) < 0) {
+ log(LOG_ERR,"router_get_list_from_file(): The routerfile itself was corrupt.");
+ free(string);
+ return -1;
+ }
+
+ free(string);
+ return 0;
+}
+
+int router_get_list_from_string(char *s, uint16_t or_listenport) {
+ routerinfo_t *routerlist=NULL;
+ routerinfo_t *router;
+ routerinfo_t **new_router_array;
+ int new_rarray_len;
+
+ assert(s);
+
+ while(*s) { /* while not at the end of the string */
+ router = router_get_entry_from_string(&s);
if(router == NULL) {
routerlist_free(routerlist);
- free(string);
- return NULL;
+ return -1;
}
if(!router_is_me(router->addr, router->or_port, or_listenport)) {
router->next = routerlist;
routerlist = router;
}
- tmps = eat_whitespace(tmps);
+ s = eat_whitespace(s);
}
- free(string);
- return make_rarray(routerlist, len);
-}
+
+ new_router_array = make_rarray(routerlist, &new_rarray_len);
+ if(new_router_array) { /* success! replace the old one */
+ rarray_free(router_array); /* free the old one first */
+ router_array = new_router_array;
+ rarray_len = new_rarray_len;
+ return 0;
+ }
+ return -1;
+}
/* return the first char of s that is not whitespace and not a comment */
static char *eat_whitespace(char *s) {
@@ -322,7 +415,7 @@
next = strchr(next, '\n');
assert(next); /* can't fail, we just checked it was here */
*next = 0;
- log(LOG_DEBUG,"Key about to be read is: '%s'",*s);
+// log(LOG_DEBUG,"Key about to be read is: '%s'",*s);
if((crypto_pk_read_public_key_from_string(router->pkey, *s, strlen(*s))<0)) {
log(LOG_ERR,"router_get_entry_from_string(): Couldn't read pk from string");
goto router_read_failed;