diff options
Diffstat (limited to 'src/or/routers.c')
-rw-r--r-- | src/or/routers.c | 137 |
1 files changed, 115 insertions, 22 deletions
diff --git a/src/or/routers.c b/src/or/routers.c index 4f9b0846ea..b7984fe593 100644 --- a/src/or/routers.c +++ b/src/or/routers.c @@ -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 *eat_whitespace(char *s); 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 @@ static int router_is_me(uint32_t or_address, uint16_t or_listenport, uint16_t my 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 @@ static routerinfo_t **make_rarray(routerinfo_t* list, int *len) /* 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 @@ static routerinfo_t *router_get_entry_from_string(char **s) { 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; |