diff --git a/src/common/tortls.c b/src/common/tortls.c
index 8dc160702c..cfca993caf 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -375,7 +375,10 @@ tor_tls_context_new(crypto_pk_env_t *identity,
SSL_CTX_free(result->ctx);
if (result)
free(result);
- /* leak certs XXXX ? */
+ if (cert)
+ X509_free(cert);
+ if (idcert)
+ X509_free(cert);
return -1;
}
@@ -641,7 +644,8 @@ tor_tls_verify(tor_tls *tls, crypto_pk_env_t *identity_key)
if (id_pkey)
EVP_PKEY_free(id_pkey);
- /* XXXX This should never get invoked, but let's make sure for now. */
+ /* This should never get invoked, but let's make sure in case OpenSSL
+ * acts unexpectedly. */
tls_log_errors(LOG_WARN, "finishing tor_tls_verify");
return r;
diff --git a/src/common/util.c b/src/common/util.c
index d41b0e2728..727af645b0 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1323,7 +1323,28 @@ write_str_to_file(const char *fname, const char *str)
return -1;
}
fclose(file);
- /* XXXX This won't work on windows: you can't use rename to replace a file.*/
+
+#ifdef MS_WINDOWS
+ /* On Windows, rename doesn't replace. We could call ReplaceFile, but
+ * that's hard, and we can probably sneak by without atomicity. */
+ switch (file_status(fname)) {
+ case FN_ERROR:
+ log(LOG_WARN, "Error replacing %s: %s", fname, strerror(errno));
+ return -1;
+ case FN_DIR:
+ log(LOG_WARN, "Error replacing %s: is directory", fname);
+ return -1;
+ case FN_FILE:
+ if (unlink(fname)) {
+ log(LOG_WARN, "Error replacing %s while removing old copy: %s",
+ fname, strerror(errno));
+ return -1;
+ }
+ break;
+ case FN_NOENT:
+ ;
+ }
+#endif
if (rename(tempname, fname)) {
log(LOG_WARN, "Error replacing %s: %s", fname, strerror(errno));
return -1;
diff --git a/src/common/util.h b/src/common/util.h
index 04811abfa1..6f707ca729 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -77,10 +77,12 @@
#define tor_close_socket(s) close(s)
#endif
-
-/* XXXX This isn't so on windows. */
/** Legal characters in a filename */
-#define CONFIG_LEGAL_FILENAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/"
+#ifdef MS_WINDOWS
+#define CONFIG_LEGAL_FILENAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/\\ "
+#else
+#define CONFIG_LEGAL_FILENAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/ "
+#endif
size_t strlcat(char *dst, const char *src, size_t siz);
size_t strlcpy(char *dst, const char *src, size_t siz);
diff --git a/src/or/buffers.c b/src/or/buffers.c
index b15e43028e..8acab16a6e 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -91,29 +91,13 @@ static INLINE void buf_remove_from_front(buf_t *buf, size_t n) {
buf_shrink_if_underfull(buf);
}
-/** Find the first instance of the str_len byte string str on the
- * buf_len byte string bufstr. Strings are not necessary
- * NUL-terminated. If none exists, return -1. Otherwise, return index
- * of the first character in bufstr _after_ the first instance of str.
- */
-/* XXXX The way this function is used, we could always get away with
- * XXXX assuming that str is NUL terminated, and use strstr instead. */
-static int find_mem_in_mem(const char *str, int str_len,
- const char *bufstr, int buf_len)
+/** Make sure that the memory in buf ends with a zero byte. */
+static INLINE int buf_nul_terminate(buf_t *buf)
{
- const char *location;
- const char *last_possible = bufstr + buf_len - str_len;
-
- tor_assert(str && str_len > 0 && bufstr);
-
- if(buf_len < str_len)
+ if (buf_ensure_capacity(buf,buf->len+1)<0)
return -1;
-
- for(location = bufstr; location <= last_possible; location++)
- if((*location == *str) && !memcmp(location+1, str+1, str_len-1))
- return location-bufstr+str_len;
-
- return -1;
+ buf->mem[buf->len] = '\0';
+ return 0;
}
/** Create and return a new buf with capacity size.
@@ -366,19 +350,22 @@ int fetch_from_buf(char *string, size_t string_len, buf_t *buf) {
int fetch_from_buf_http(buf_t *buf,
char **headers_out, int max_headerlen,
char **body_out, int *body_used, int max_bodylen) {
- char *headers, *body;
- int i;
+ char *headers, *body, *p;
int headerlen, bodylen, contentlen;
assert_buf_ok(buf);
headers = buf->mem;
- i = find_mem_in_mem("\r\n\r\n", 4, buf->mem, buf->datalen);
- if(i < 0) {
+ if (buf_nul_terminate(buf)<0) {
+ log_fn(LOG_WARN,"Couldn't nul-terminate buffer");
+ return -1;
+ }
+ body = strstr(headers,"\r\n\r\n");
+ if (!body) {
log_fn(LOG_DEBUG,"headers not all here yet.");
return 0;
}
- body = buf->mem+i;
+ body += 4; /* Skip the the CRLFCRLF */
headerlen = body-headers; /* includes the CRLFCRLF */
bodylen = buf->datalen - headerlen;
log_fn(LOG_DEBUG,"headerlen %d, bodylen %d.", headerlen, bodylen);
@@ -393,10 +380,9 @@ int fetch_from_buf_http(buf_t *buf,
}
#define CONTENT_LENGTH "\r\nContent-Length: "
- i = find_mem_in_mem(CONTENT_LENGTH, strlen(CONTENT_LENGTH),
- headers, headerlen);
- if(i > 0) {
- contentlen = atoi(headers+i);
+ p = strstr(headers, CONTENT_LENGTH);
+ if (p) {
+ contentlen = atoi(p+strlen(CONTENT_LENGTH));
/* if content-length is malformed, then our body length is 0. fine. */
log_fn(LOG_DEBUG,"Got a contentlen of %d.",contentlen);
if(bodylen < contentlen) {
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 81926e8e36..4f611b2196 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -419,25 +419,23 @@ void assert_cpath_layer_ok(const crypt_path_t *cp)
* correct. Trigger an assert if anything is invalid.
*/
static void
- assert_cpath_ok(const crypt_path_t *cp)
+assert_cpath_ok(const crypt_path_t *cp)
{
- while(cp->prev)
- cp = cp->prev;
- //XXX this is broken. cp is a doubly linked list.
+ const crypt_path_t *start = cp;
- while(cp->next) {
+ do {
assert_cpath_layer_ok(cp);
/* layers must be in sequence of: "open* awaiting? closed*" */
- if (cp->prev) {
- if (cp->prev->state == CPATH_STATE_OPEN) {
- tor_assert(cp->state == CPATH_STATE_CLOSED ||
- cp->state == CPATH_STATE_AWAITING_KEYS);
- } else {
- tor_assert(cp->state == CPATH_STATE_CLOSED);
+ if (cp != start) {
+ if (cp->state == CPATH_STATE_AWAITING_KEYS) {
+ tor_assert(cp->prev->state == CPATH_STATE_OPEN);
+ } else if (cp->state == CPATH_STATE_OPEN) {
+ tor_assert(cp->prev->state == CPATH_STATE_OPEN);
}
}
cp = cp->next;
- }
+ tor_assert(cp);
+ } while (cp != start);
}
/** Verify that circuit c has all of its invariants
@@ -479,8 +477,7 @@ void assert_circuit_ok(const circuit_t *c)
}
}
if (c->cpath) {
-// assert_cpath_ok(c->cpath);
-// XXX the above call causes an infinite loop.
+ assert_cpath_ok(c->cpath);
}
if (c->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED) {
if (!c->marked_for_close) {
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index c4b76406aa..fc21a3ebf7 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -331,9 +331,12 @@ dirserv_add_descriptor(const char **desc)
free_descriptor_entry(*desc_ent_ptr);
} else {
/* Add this at the end. */
- log_fn(LOG_INFO,"Dirserv adding desc for nickname %s",ri->nickname);
- desc_ent_ptr = &descriptor_list[n_descriptors++];
- /* XXX check if n_descriptors is too big */
+ if (n_descriptors >= MAX_ROUTERS_IN_DIR) {
+ log_fn(LOG_WARN,"Too many descriptors in directory; can't add another.");
+ } else {
+ log_fn(LOG_INFO,"Dirserv adding desc for nickname %s",ri->nickname);
+ desc_ent_ptr = &descriptor_list[n_descriptors++];
+ }
}
(*desc_ent_ptr) = tor_malloc(sizeof(descriptor_entry_t));
diff --git a/src/or/main.c b/src/or/main.c
index 20da0c1a3f..c494908aa8 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -215,8 +215,6 @@ static void conn_read(int i) {
connection_handle_read(conn) < 0) {
if (!conn->marked_for_close) {
/* this connection is broken. remove it */
- /* XXX This shouldn't ever happen anymore. */
- /* XXX but it'll clearly happen on MS_WINDOWS from POLLERR, right? */
log_fn(LOG_ERR,"Unhandled error on read for %s connection (fd %d); removing",
CONN_TYPE_TO_STRING(conn->type), conn->s);
connection_mark_for_close(conn);
@@ -289,7 +287,6 @@ static void conn_close_if_marked(int i) {
if(connection_speaks_cells(conn)) {
if(conn->state == OR_CONN_STATE_OPEN) {
retval = flush_buf_tls(conn->tls, conn->outbuf, &conn->outbuf_flushlen);
- /* XXX actually, some non-zero results are maybe ok. which ones? */
} else
retval = -1; /* never flush non-open broken tls connections */
} else {
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index 3260b9ff9a..38e8d7b013 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -44,7 +44,7 @@ rend_encode_service_descriptor(rend_service_descriptor_t *desc,
char *buf, *cp, *ipoint;
int i, keylen, asn1len;
keylen = crypto_pk_keysize(desc->pk);
- buf = tor_malloc(keylen*2); /* XXXX */
+ buf = tor_malloc(keylen*2); /* Too long, but that's okay. */
asn1len = crypto_pk_asn1_encode(desc->pk, buf, keylen*2);
if (asn1len<0) {
tor_free(buf);
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 849a79e349..b5e86a4d89 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -482,7 +482,7 @@ rend_service_relaunch_rendezvous(circuit_t *oldcirc)
circuit_t *newcirc;
cpath_build_state_t *newstate, *oldstate;
- /* XXXX assert type and build_state */
+ tor_assert(oldcirc->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND);
if (!oldcirc->build_state ||
oldcirc->build_state->failure_count > MAX_REND_FAILURES) {
diff --git a/src/or/rephist.c b/src/or/rephist.c
index df737a65a6..cd71eabc4c 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -154,10 +154,9 @@ void rep_hist_note_connection_died(const char* nickname, time_t when)
{
or_history_t *hist;
if(!nickname) {
- /* XXX
- * If conn has no nickname, it's either an OP, or it is an OR
+ /* If conn has no nickname, it's either an OP, or it is an OR
* which didn't complete its handshake (or did and was unapproved).
- * Ignore it. Is there anything better we could do?
+ * Ignore it.
*/
return;
}
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 48bb723885..ef6c601ec4 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -8,10 +8,9 @@
* \brief Code to parse and validate router descriptors and directories.
**/
-#define _GNU_SOURCE
-/* XXX this is required on rh7 to make strptime not complain. how bad
- * is this for portability?
+/* This is required on rh7 to make strptime not complain.
*/
+#define _GNU_SOURCE
#include "or.h"
@@ -32,7 +31,7 @@ typedef enum {
K_SIGNED_DIRECTORY,
K_SIGNING_KEY,
K_ONION_KEY,
- K_LINK_KEY, /* XXXX obsolete */
+ K_LINK_KEY, /* XXXX obsolete; remove in June. */
K_ROUTER_SIGNATURE,
K_PUBLISHED,
K_RUNNING_ROUTERS,