aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
Diffstat (limited to 'src/or')
-rw-r--r--src/or/dirserv.c42
-rw-r--r--src/or/main.c211
-rw-r--r--src/or/or.h7
-rw-r--r--src/or/routers.c189
4 files changed, 235 insertions, 214 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 73ff278e0..afe91a161 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -10,6 +10,8 @@ static int the_directory_is_dirty = 1;
static char *the_directory = NULL;
static int the_directory_len = -1;
+static int list_running_servers(char **nicknames_out);
+
/************** Fingerprint handling code ************/
typedef struct fingerprint_entry_t {
@@ -291,6 +293,46 @@ dirserv_init_from_directory_string(const char *dir)
return 0;
}
+static int
+list_running_servers(char **nicknames_out)
+{
+ char *nickname_lst[MAX_ROUTERS_IN_DIR];
+ connection_t **connection_array;
+ int n_conns;
+ connection_t *conn;
+ char *cp;
+ int n = 0, i;
+ int length;
+ *nicknames_out = NULL;
+ nickname_lst[n++] = options.Nickname;
+
+ get_connection_array(&connection_array, &n_conns);
+ for (i = 0; i<n_conns; ++i) {
+ conn = connection_array[i];
+ if (conn->type != CONN_TYPE_OR || conn->state != OR_CONN_STATE_OPEN)
+ continue; /* only list successfully handshaked OR's. */
+ if(!conn->nickname) /* it's an OP, don't list it */
+ continue;
+ nickname_lst[n++] = conn->nickname;
+ }
+ length = n + 1; /* spaces + EOS + 1. */
+ for (i = 0; i<n; ++i) {
+ length += strlen(nickname_lst[i]);
+ }
+ *nicknames_out = tor_malloc(length);
+ cp = *nicknames_out;
+ memset(cp,0,length);
+ for (i = 0; i<n; ++i) {
+ if (i)
+ strcat(cp, " ");
+ strcat(cp, nickname_lst[i]);
+ while (*cp)
+ ++cp;
+ }
+ return 0;
+}
+
+
int
dirserv_dump_directory_to_string(char *s, int maxlen,
crypto_pk_env_t *private_key)
diff --git a/src/or/main.c b/src/or/main.c
index be88ae270..befcc893d 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -3,9 +3,6 @@
/* $Id$ */
#include "or.h"
-#ifdef HAVE_UNAME
-#include <sys/utsname.h>
-#endif
/********* START PROTOTYPES **********/
@@ -38,8 +35,6 @@ static crypto_pk_env_t *onionkey=NULL;
static crypto_pk_env_t *linkkey=NULL;
static crypto_pk_env_t *identitykey=NULL;
-routerinfo_t *my_routerinfo=NULL;
-
/********* END VARIABLES ************/
void set_onion_key(crypto_pk_env_t *k) {
@@ -279,11 +274,7 @@ static int prepare_for_poll(void) {
if(time_to_fetch_directory < now.tv_sec) {
/* it's time to fetch a new directory and/or post our descriptor */
if(options.OnionRouter) {
- if (init_descriptor()<0) {
- log_fn(LOG_WARNING, "Error initializing descriptor. Not uploading desc.");
- } else {
- router_upload_desc_to_dirservers();
- }
+ router_upload_desc_to_dirservers();
}
if(!options.DirPort) {
/* NOTE directory servers do not currently fetch directories.
@@ -482,7 +473,7 @@ static int init_keys(void)
}
/* 4. Dump router descriptor to 'router.desc' */
/* Must be called after keys are initialized. */
- if (init_descriptor()<0) {
+ if (!(router_get_my_descriptor())) {
log_fn(LOG_ERR, "Error initializing descriptor.");
return -1;
}
@@ -681,204 +672,6 @@ static void dumpstats(void) { /* dump stats to stdout */
}
}
-static void get_platform_str(char *platform, int len)
-{
-#ifdef HAVE_UNAME
- struct utsname u;
- if (!uname(&u)) {
- snprintf(platform, len-1, "Tor %s on %s %s %s %s %s",
- VERSION, u.sysname, u.nodename, u.release, u.version, u.machine);
- platform[len-1] = '\0';
- return;
- } else
-#endif
- {
- snprintf(platform, len-1, "Tor %s", VERSION);
- }
-}
-
-int dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
- crypto_pk_env_t *ident_key) {
- char *onion_pkey;
- char *link_pkey;
- char *identity_pkey;
- char platform[256];
- char digest[20];
- char signature[128];
- char published[32];
- int onion_pkeylen, link_pkeylen, identity_pkeylen;
- int written;
- int result=0;
- struct exit_policy_t *tmpe;
-
- get_platform_str(platform, sizeof(platform));
-
- if(crypto_pk_write_public_key_to_string(router->onion_pkey,
- &onion_pkey,&onion_pkeylen)<0) {
- log_fn(LOG_WARNING,"write onion_pkey to string failed!");
- return -1;
- }
-
- if(crypto_pk_write_public_key_to_string(router->identity_pkey,
- &identity_pkey,&identity_pkeylen)<0) {
- log_fn(LOG_WARNING,"write identity_pkey to string failed!");
- return -1;
- }
-
- if(crypto_pk_write_public_key_to_string(router->link_pkey,
- &link_pkey,&link_pkeylen)<0) {
- log_fn(LOG_WARNING,"write link_pkey to string failed!");
- return -1;
- }
- strftime(published, 32, "%Y-%m-%d %H:%M:%S", gmtime(&router->published_on));
-
- result = snprintf(s, maxlen,
- "router %s %s %d %d %d %d\n"
- "platform %s\n"
- "published %s\n"
- "onion-key\n%s"
- "link-key\n%s"
- "signing-key\n%s",
- router->nickname,
- router->address,
- router->or_port,
- router->ap_port,
- router->dir_port,
- router->bandwidth,
- platform,
- published,
- onion_pkey, link_pkey, identity_pkey);
-
- free(onion_pkey);
- free(link_pkey);
- free(identity_pkey);
-
- if(result < 0 || result >= maxlen) {
- /* apparently different glibcs do different things on snprintf error.. so check both */
- return -1;
- }
- written = result;
-
- for(tmpe=router->exit_policy; tmpe; tmpe=tmpe->next) {
- result = snprintf(s+written, maxlen-written, "%s %s:%s\n",
- tmpe->policy_type == EXIT_POLICY_ACCEPT ? "accept" : "reject",
- tmpe->address, tmpe->port);
- if(result < 0 || result+written > maxlen) {
- /* apparently different glibcs do different things on snprintf error.. so check both */
- return -1;
- }
- written += result;
- }
- if (written > maxlen-256) /* Not enough room for signature. */
- return -1;
-
- strcat(s+written, "router-signature\n");
- written += strlen(s+written);
- s[written] = '\0';
- if (router_get_router_hash(s, digest) < 0)
- return -1;
-
- if (crypto_pk_private_sign(ident_key, digest, 20, signature) < 0) {
- log_fn(LOG_WARNING, "Error signing digest");
- return -1;
- }
- strcat(s+written, "-----BEGIN SIGNATURE-----\n");
- written += strlen(s+written);
- if (base64_encode(s+written, maxlen-written, signature, 128) < 0) {
- log_fn(LOG_WARNING, "Couldn't base64-encode signature");
- return -1;
- }
- written += strlen(s+written);
- strcat(s+written, "-----END SIGNATURE-----\n");
- written += strlen(s+written);
-
- if (written > maxlen-2)
- return -1;
- /* include a last '\n' */
- s[written] = '\n';
- s[written+1] = 0;
- return written+1;
-}
-
-int
-list_running_servers(char **nicknames_out)
-{
- char *nickname_lst[MAX_ROUTERS_IN_DIR];
- connection_t *conn;
- char *cp;
- int n = 0, i;
- int length;
- *nicknames_out = NULL;
- if (my_routerinfo)
- nickname_lst[n++] = my_routerinfo->nickname;
- for (i = 0; i<nfds; ++i) {
- conn = connection_array[i];
- if (conn->type != CONN_TYPE_OR || conn->state != OR_CONN_STATE_OPEN)
- continue; /* only list successfully handshaked OR's. */
- if(!conn->nickname) /* it's an OP, don't list it */
- continue;
- nickname_lst[n++] = conn->nickname;
- }
- length = n + 1; /* spaces + EOS + 1. */
- for (i = 0; i<n; ++i) {
- length += strlen(nickname_lst[i]);
- }
- *nicknames_out = tor_malloc(length);
- cp = *nicknames_out;
- memset(cp,0,length);
- for (i = 0; i<n; ++i) {
- if (i)
- strcat(cp, " ");
- strcat(cp, nickname_lst[i]);
- while (*cp)
- ++cp;
- }
- return 0;
-}
-
-static char descriptor[8192];
-/* XXX should this replace my_routerinfo? */
-static routerinfo_t *desc_routerinfo;
-const char *router_get_my_descriptor(void) {
- log_fn(LOG_DEBUG,"my desc is '%s'",descriptor);
- return descriptor;
-}
-
-static int init_descriptor(void) {
- routerinfo_t *ri;
- char localhostname[256];
- char *address = options.Address;
-
- if(!address) { /* if not specified in config, we find a default */
- if(gethostname(localhostname,sizeof(localhostname)) < 0) {
- log_fn(LOG_WARNING,"Error obtaining local hostname");
- return -1;
- }
- address = localhostname;
- }
- ri = tor_malloc(sizeof(routerinfo_t));
- ri->address = strdup(address);
- ri->nickname = strdup(options.Nickname);
- /* No need to set addr. */
- ri->or_port = options.ORPort;
- ri->ap_port = options.APPort;
- ri->dir_port = options.DirPort;
- ri->published_on = time(NULL);
- ri->onion_pkey = crypto_pk_dup_key(get_onion_key());
- ri->link_pkey = crypto_pk_dup_key(get_link_key());
- ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
- ri->bandwidth = options.TotalBandwidth;
- ri->exit_policy = NULL; /* XXX implement this. */
- if (desc_routerinfo)
- routerinfo_free(desc_routerinfo);
- desc_routerinfo = ri;
- if (dump_router_to_string(descriptor, 8192, ri, get_identity_key())<0) {
- log_fn(LOG_WARNING, "Couldn't dump router to string.");
- return -1;
- }
- return 0;
-}
-
void daemonize(void) {
#ifndef MS_WINDOWS
/* Fork; parent exits. */
diff --git a/src/or/or.h b/src/or/or.h
index c44b780e4..b739eadcd 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -616,6 +616,7 @@ void set_onion_key(crypto_pk_env_t *k);
crypto_pk_env_t *get_onion_key(void);
void set_identity_key(crypto_pk_env_t *k);
crypto_pk_env_t *get_identity_key(void);
+crypto_pk_env_t *get_link_key(void);
int connection_add(connection_t *conn);
int connection_remove(connection_t *conn);
void connection_set_poll_socket(connection_t *conn);
@@ -629,8 +630,6 @@ void connection_start_reading(connection_t *conn);
void connection_stop_writing(connection_t *conn);
void connection_start_writing(connection_t *conn);
-int list_running_servers(char **nicknames_out);
-
const char *router_get_my_descriptor(void);
int main(int argc, char *argv[]);
@@ -691,6 +690,10 @@ int router_get_dir_from_string_impl(char *s, directory_t **dest,
routerinfo_t *router_get_entry_from_string(char **s);
int router_compare_to_exit_policy(connection_t *conn);
void routerinfo_free(routerinfo_t *router);
+int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
+ crypto_pk_env_t *ident_key);
+const routerinfo_t *router_get_desc_routerinfo(void);
+const char *router_get_my_descriptor(void);
/********************************* dirserv.c ***************************/
int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk);
diff --git a/src/or/routers.c b/src/or/routers.c
index 5e0d609aa..9d82e3f47 100644
--- a/src/or/routers.c
+++ b/src/or/routers.c
@@ -13,6 +13,9 @@
*/
#include "or.h"
+#ifdef HAVE_UNAME
+#include <sys/utsname.h>
+#endif
/****************************************************************************/
@@ -20,7 +23,7 @@
static directory_t *directory = NULL;
extern or_options_t options; /* command-line and config-file options */
-extern routerinfo_t *my_routerinfo; /* from main.c */
+static routerinfo_t *my_routerinfo;
/****************************************************************************/
@@ -35,8 +38,8 @@ static char *find_whitespace(char *s);
static void router_free_exit_policy(routerinfo_t *router);
static int router_add_exit_policy(routerinfo_t *router,
directory_token_t *tok);
-static int
-router_resolve_directory(directory_t *dir);
+static int router_resolve_directory(directory_t *dir);
+static int init_descriptor(void);
/****************************************************************************/
@@ -113,6 +116,11 @@ void router_upload_desc_to_dirservers(void) {
if(!directory)
return;
+ if (!router_get_my_descriptor()) {
+ log_fn(LOG_WARNING, "No descriptor; skipping upload");
+ return;
+ }
+
for(i=0;i<directory->n_routers;i++) {
router = directory->routers[i];
if(router->dir_port > 0)
@@ -1087,6 +1095,181 @@ int router_compare_to_exit_policy(connection_t *conn) {
}
+static char descriptor[8192];
+/* XXX should this replace my_routerinfo? */
+static routerinfo_t *desc_routerinfo = NULL;
+const char *router_get_my_descriptor(void) {
+ if (!desc_routerinfo) {
+ if (init_descriptor())
+ return NULL;
+ }
+ log_fn(LOG_DEBUG,"my desc is '%s'",descriptor);
+ return descriptor;
+}
+const routerinfo_t *router_get_desc_routerinfo(void) {
+ if (!desc_routerinfo) {
+ if (init_descriptor())
+ return NULL;
+ }
+ return desc_routerinfo;
+}
+
+static int init_descriptor(void) {
+ routerinfo_t *ri;
+ char localhostname[256];
+ char *address = options.Address;
+
+ if(!address) { /* if not specified in config, we find a default */
+ if(gethostname(localhostname,sizeof(localhostname)) < 0) {
+ log_fn(LOG_WARNING,"Error obtaining local hostname");
+ return -1;
+ }
+ address = localhostname;
+ }
+ ri = tor_malloc(sizeof(routerinfo_t));
+ ri->address = strdup(address);
+ ri->nickname = strdup(options.Nickname);
+ /* No need to set addr. */
+ ri->or_port = options.ORPort;
+ ri->ap_port = options.APPort;
+ ri->dir_port = options.DirPort;
+ ri->published_on = time(NULL);
+ ri->onion_pkey = crypto_pk_dup_key(get_onion_key());
+ ri->link_pkey = crypto_pk_dup_key(get_link_key());
+ ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
+ ri->bandwidth = options.TotalBandwidth;
+ ri->exit_policy = NULL; /* XXX implement this. */
+ if (desc_routerinfo)
+ routerinfo_free(desc_routerinfo);
+ desc_routerinfo = ri;
+ if (router_dump_router_to_string(descriptor, 8192, ri, get_identity_key())<0) {
+ log_fn(LOG_WARNING, "Couldn't dump router to string.");
+ return -1;
+ }
+ return 0;
+}
+
+static void get_platform_str(char *platform, int len)
+{
+#ifdef HAVE_UNAME
+ struct utsname u;
+ if (!uname(&u)) {
+ snprintf(platform, len-1, "Tor %s on %s %s %s %s %s",
+ VERSION, u.sysname, u.nodename, u.release, u.version, u.machine);
+ platform[len-1] = '\0';
+ return;
+ } else
+#endif
+ {
+ snprintf(platform, len-1, "Tor %s", VERSION);
+ }
+}
+
+int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
+ crypto_pk_env_t *ident_key) {
+ char *onion_pkey;
+ char *link_pkey;
+ char *identity_pkey;
+ char platform[256];
+ char digest[20];
+ char signature[128];
+ char published[32];
+ int onion_pkeylen, link_pkeylen, identity_pkeylen;
+ int written;
+ int result=0;
+ struct exit_policy_t *tmpe;
+
+ get_platform_str(platform, sizeof(platform));
+
+ if(crypto_pk_write_public_key_to_string(router->onion_pkey,
+ &onion_pkey,&onion_pkeylen)<0) {
+ log_fn(LOG_WARNING,"write onion_pkey to string failed!");
+ return -1;
+ }
+
+ if(crypto_pk_write_public_key_to_string(router->identity_pkey,
+ &identity_pkey,&identity_pkeylen)<0) {
+ log_fn(LOG_WARNING,"write identity_pkey to string failed!");
+ return -1;
+ }
+
+ if(crypto_pk_write_public_key_to_string(router->link_pkey,
+ &link_pkey,&link_pkeylen)<0) {
+ log_fn(LOG_WARNING,"write link_pkey to string failed!");
+ return -1;
+ }
+ strftime(published, 32, "%Y-%m-%d %H:%M:%S", gmtime(&router->published_on));
+
+ result = snprintf(s, maxlen,
+ "router %s %s %d %d %d %d\n"
+ "platform %s\n"
+ "published %s\n"
+ "onion-key\n%s"
+ "link-key\n%s"
+ "signing-key\n%s",
+ router->nickname,
+ router->address,
+ router->or_port,
+ router->ap_port,
+ router->dir_port,
+ router->bandwidth,
+ platform,
+ published,
+ onion_pkey, link_pkey, identity_pkey);
+
+ free(onion_pkey);
+ free(link_pkey);
+ free(identity_pkey);
+
+ if(result < 0 || result >= maxlen) {
+ /* apparently different glibcs do different things on snprintf error.. so check both */
+ return -1;
+ }
+ written = result;
+
+ for(tmpe=router->exit_policy; tmpe; tmpe=tmpe->next) {
+ result = snprintf(s+written, maxlen-written, "%s %s:%s\n",
+ tmpe->policy_type == EXIT_POLICY_ACCEPT ? "accept" : "reject",
+ tmpe->address, tmpe->port);
+ if(result < 0 || result+written > maxlen) {
+ /* apparently different glibcs do different things on snprintf error.. so check both */
+ return -1;
+ }
+ written += result;
+ }
+ if (written > maxlen-256) /* Not enough room for signature. */
+ return -1;
+
+ strcat(s+written, "router-signature\n");
+ written += strlen(s+written);
+ s[written] = '\0';
+ if (router_get_router_hash(s, digest) < 0)
+ return -1;
+
+ if (crypto_pk_private_sign(ident_key, digest, 20, signature) < 0) {
+ log_fn(LOG_WARNING, "Error signing digest");
+ return -1;
+ }
+ strcat(s+written, "-----BEGIN SIGNATURE-----\n");
+ written += strlen(s+written);
+ if (base64_encode(s+written, maxlen-written, signature, 128) < 0) {
+ log_fn(LOG_WARNING, "Couldn't base64-encode signature");
+ return -1;
+ }
+ written += strlen(s+written);
+ strcat(s+written, "-----END SIGNATURE-----\n");
+ written += strlen(s+written);
+
+ if (written > maxlen-2)
+ return -1;
+ /* include a last '\n' */
+ s[written] = '\n';
+ s[written+1] = 0;
+ return written+1;
+}
+
+
+
/*
Local Variables:
mode:c