mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Merge branch 'maint-0.2.4' into release-0.2.4
This commit is contained in:
@@ -870,6 +870,9 @@ tor_lockfile_unlock(tor_lockfile_t *lockfile)
|
||||
/** @{ */
|
||||
/** Some old versions of Unix didn't define constants for these values,
|
||||
* and instead expect you to say 0, 1, or 2. */
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0
|
||||
#endif
|
||||
#ifndef SEEK_CUR
|
||||
#define SEEK_CUR 1
|
||||
#endif
|
||||
@@ -900,6 +903,18 @@ tor_fd_seekend(int fd)
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Move <b>fd</b> to position <b>pos</b> in the file. Return -1 on error, 0
|
||||
* on success. */
|
||||
int
|
||||
tor_fd_setpos(int fd, off_t pos)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _lseek(fd, pos, SEEK_SET) < 0 ? -1 : 0;
|
||||
#else
|
||||
return lseek(fd, pos, SEEK_SET) < 0 ? -1 : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef DEBUG_SOCKET_COUNTING
|
||||
#ifdef DEBUG_SOCKET_COUNTING
|
||||
/** A bitarray of all fds that should be passed to tor_socket_close(). Only
|
||||
|
||||
@@ -411,6 +411,7 @@ tor_lockfile_t *tor_lockfile_lock(const char *filename, int blocking,
|
||||
void tor_lockfile_unlock(tor_lockfile_t *lockfile);
|
||||
|
||||
off_t tor_fd_getpos(int fd);
|
||||
int tor_fd_setpos(int fd, off_t pos);
|
||||
int tor_fd_seekend(int fd);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
+17
-6
@@ -1711,8 +1711,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
|
||||
const node_t *node = node_get_by_hex_id(question+strlen("md/id/"));
|
||||
const microdesc_t *md = NULL;
|
||||
if (node) md = node->md;
|
||||
if (md) {
|
||||
tor_assert(md->body);
|
||||
if (md && md->body) {
|
||||
*answer = tor_strndup(md->body, md->bodylen);
|
||||
}
|
||||
} else if (!strcmpstart(question, "md/name/")) {
|
||||
@@ -1722,8 +1721,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
|
||||
/* XXXX duplicated code */
|
||||
const microdesc_t *md = NULL;
|
||||
if (node) md = node->md;
|
||||
if (md) {
|
||||
tor_assert(md->body);
|
||||
if (md && md->body) {
|
||||
*answer = tor_strndup(md->body, md->bodylen);
|
||||
}
|
||||
} else if (!strcmpstart(question, "desc-annotations/id/")) {
|
||||
@@ -3743,8 +3741,21 @@ control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp,
|
||||
}
|
||||
|
||||
if (tp == STREAM_EVENT_NEW || tp == STREAM_EVENT_NEW_RESOLVE) {
|
||||
tor_snprintf(addrport_buf,sizeof(addrport_buf), " SOURCE_ADDR=%s:%d",
|
||||
ENTRY_TO_CONN(conn)->address, ENTRY_TO_CONN(conn)->port);
|
||||
/*
|
||||
* When the control conn is an AF_UNIX socket and we have no address,
|
||||
* it gets set to "(Tor_internal)"; see dnsserv_launch_request() in
|
||||
* dnsserv.c.
|
||||
*/
|
||||
if (strcmp(ENTRY_TO_CONN(conn)->address, "(Tor_internal)") != 0) {
|
||||
tor_snprintf(addrport_buf,sizeof(addrport_buf), " SOURCE_ADDR=%s:%d",
|
||||
ENTRY_TO_CONN(conn)->address, ENTRY_TO_CONN(conn)->port);
|
||||
} else {
|
||||
/*
|
||||
* else leave it blank so control on AF_UNIX doesn't need to make
|
||||
* something up.
|
||||
*/
|
||||
addrport_buf[0] = '\0';
|
||||
}
|
||||
} else {
|
||||
addrport_buf[0] = '\0';
|
||||
}
|
||||
|
||||
+1
-1
@@ -3981,7 +3981,7 @@ connection_dirserv_add_microdescs_to_outbuf(dir_connection_t *conn)
|
||||
char *fp256 = smartlist_pop_last(conn->fingerprint_stack);
|
||||
microdesc_t *md = microdesc_cache_lookup_by_digest256(cache, fp256);
|
||||
tor_free(fp256);
|
||||
if (!md)
|
||||
if (!md || !md->body)
|
||||
continue;
|
||||
if (conn->zlib_state) {
|
||||
/* XXXX024 This 'last' business should actually happen on the last
|
||||
|
||||
@@ -183,8 +183,23 @@ dnsserv_launch_request(const char *name, int reverse,
|
||||
conn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
|
||||
|
||||
tor_addr_copy(&TO_CONN(conn)->addr, &control_conn->base_.addr);
|
||||
#ifdef AF_UNIX
|
||||
/*
|
||||
* The control connection can be AF_UNIX and if so tor_dup_addr will
|
||||
* unhelpfully say "<unknown address type>"; say "(Tor_internal)"
|
||||
* instead.
|
||||
*/
|
||||
if (control_conn->base_.socket_family == AF_UNIX) {
|
||||
TO_CONN(conn)->port = 0;
|
||||
TO_CONN(conn)->address = tor_strdup("(Tor_internal)");
|
||||
} else {
|
||||
TO_CONN(conn)->port = control_conn->base_.port;
|
||||
TO_CONN(conn)->address = tor_dup_addr(&control_conn->base_.addr);
|
||||
}
|
||||
#else
|
||||
TO_CONN(conn)->port = control_conn->base_.port;
|
||||
TO_CONN(conn)->address = tor_dup_addr(&control_conn->base_.addr);
|
||||
#endif
|
||||
|
||||
if (reverse)
|
||||
entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
|
||||
|
||||
+35
-10
@@ -74,7 +74,11 @@ static ssize_t
|
||||
dump_microdescriptor(int fd, microdesc_t *md, size_t *annotation_len_out)
|
||||
{
|
||||
ssize_t r = 0;
|
||||
size_t written;
|
||||
ssize_t written;
|
||||
if (md->body == NULL) {
|
||||
*annotation_len_out = 0;
|
||||
return 0;
|
||||
}
|
||||
/* XXXX drops unknown annotations. */
|
||||
if (md->last_listed) {
|
||||
char buf[ISO_TIME_LEN+1];
|
||||
@@ -95,10 +99,10 @@ dump_microdescriptor(int fd, microdesc_t *md, size_t *annotation_len_out)
|
||||
|
||||
md->off = tor_fd_getpos(fd);
|
||||
written = write_all(fd, md->body, md->bodylen, 0);
|
||||
if (written != md->bodylen) {
|
||||
if (written != (ssize_t)md->bodylen) {
|
||||
log_warn(LD_DIR,
|
||||
"Couldn't dump microdescriptor (wrote %lu out of %lu): %s",
|
||||
(unsigned long)written, (unsigned long)md->bodylen,
|
||||
"Couldn't dump microdescriptor (wrote %ld out of %lu): %s",
|
||||
(long)written, (unsigned long)md->bodylen,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
@@ -447,13 +451,20 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
|
||||
HT_FOREACH(mdp, microdesc_map, &cache->map) {
|
||||
microdesc_t *md = *mdp;
|
||||
size_t annotation_len;
|
||||
if (md->no_save)
|
||||
if (md->no_save || !md->body)
|
||||
continue;
|
||||
|
||||
size = dump_microdescriptor(fd, md, &annotation_len);
|
||||
if (size < 0) {
|
||||
/* XXX handle errors from dump_microdescriptor() */
|
||||
/* log? return -1? die? coredump the universe? */
|
||||
if (md->saved_location != SAVED_IN_CACHE)
|
||||
tor_free(md->body);
|
||||
md->saved_location = SAVED_NOWHERE;
|
||||
md->off = 0;
|
||||
md->bodylen = 0;
|
||||
md->no_save = 1;
|
||||
|
||||
/* rewind, in case it was a partial write. */
|
||||
tor_fd_setpos(fd, off);
|
||||
continue;
|
||||
}
|
||||
tor_assert(((size_t)size) == annotation_len + md->bodylen);
|
||||
@@ -474,15 +485,29 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
|
||||
smartlist_add(wrote, md);
|
||||
}
|
||||
|
||||
/* We must do this unmap _before_ we call finish_writing_to_file(), or
|
||||
* windows will not actually replace the file. */
|
||||
if (cache->cache_content)
|
||||
tor_munmap_file(cache->cache_content);
|
||||
|
||||
if (finish_writing_to_file(open_file) < 0) {
|
||||
log_warn(LD_DIR, "Error rebuilding microdescriptor cache: %s",
|
||||
strerror(errno));
|
||||
/* Okay. Let's prevent from making things worse elsewhere. */
|
||||
cache->cache_content = NULL;
|
||||
HT_FOREACH(mdp, microdesc_map, &cache->map) {
|
||||
microdesc_t *md = *mdp;
|
||||
if (md->saved_location == SAVED_IN_CACHE) {
|
||||
md->off = 0;
|
||||
md->saved_location = SAVED_NOWHERE;
|
||||
md->body = NULL;
|
||||
md->bodylen = 0;
|
||||
md->no_save = 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cache->cache_content)
|
||||
tor_munmap_file(cache->cache_content);
|
||||
|
||||
cache->cache_content = tor_mmap_file(cache->cache_fname);
|
||||
|
||||
if (!cache->cache_content && smartlist_len(wrote)) {
|
||||
|
||||
@@ -541,6 +541,8 @@ typedef enum {
|
||||
#define CIRCUIT_PURPOSE_IS_ESTABLISHED_REND(p) \
|
||||
((p) == CIRCUIT_PURPOSE_C_REND_JOINED || \
|
||||
(p) == CIRCUIT_PURPOSE_S_REND_JOINED)
|
||||
/** True iff the circuit_t c is actually an or_circuit_t */
|
||||
#define CIRCUIT_IS_ORCIRC(c) (((circuit_t *)(c))->magic == OR_CIRCUIT_MAGIC)
|
||||
|
||||
/** How many circuits do we want simultaneously in-progress to handle
|
||||
* a given stream? */
|
||||
@@ -818,6 +820,13 @@ typedef enum {
|
||||
/** Amount to increment a stream window when we get a stream SENDME. */
|
||||
#define STREAMWINDOW_INCREMENT 50
|
||||
|
||||
/** Maximum number of queued cells on a circuit for which we are the
|
||||
* midpoint before we give up and kill it. This must be >= circwindow
|
||||
* to avoid killing innocent circuits, and >= circwindow*2 to give
|
||||
* leaky-pipe a chance for being useful someday.
|
||||
*/
|
||||
#define ORCIRC_MAX_MIDDLE_CELLS (21*(CIRCWINDOW_START_MAX)/10)
|
||||
|
||||
/* Cell commands. These values are defined in tor-spec.txt. */
|
||||
#define CELL_PADDING 0
|
||||
#define CELL_CREATE 1
|
||||
|
||||
+27
-1
@@ -2466,8 +2466,10 @@ append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan,
|
||||
cell_t *cell, cell_direction_t direction,
|
||||
streamid_t fromstream)
|
||||
{
|
||||
or_circuit_t *orcirc = NULL;
|
||||
cell_queue_t *queue;
|
||||
int streams_blocked;
|
||||
|
||||
if (circ->marked_for_close)
|
||||
return;
|
||||
|
||||
@@ -2475,11 +2477,35 @@ append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan,
|
||||
queue = &circ->n_chan_cells;
|
||||
streams_blocked = circ->streams_blocked_on_n_chan;
|
||||
} else {
|
||||
or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
|
||||
orcirc = TO_OR_CIRCUIT(circ);
|
||||
queue = &orcirc->p_chan_cells;
|
||||
streams_blocked = circ->streams_blocked_on_p_chan;
|
||||
}
|
||||
|
||||
/* Are we a middle circuit about to exceed ORCIRC_MAX_MIDDLE_CELLS? */
|
||||
if ((circ->n_chan != NULL) && CIRCUIT_IS_ORCIRC(circ)) {
|
||||
orcirc = TO_OR_CIRCUIT(circ);
|
||||
if (orcirc->p_chan) {
|
||||
if (queue->n + 1 >= ORCIRC_MAX_MIDDLE_CELLS) {
|
||||
/* Queueing this cell would put queue over the cap */
|
||||
log_warn(LD_CIRC,
|
||||
"Got a cell exceeding the cap of %u in the %s direction "
|
||||
"on middle circ ID %u on chan ID " U64_FORMAT
|
||||
"; killing the circuit.",
|
||||
ORCIRC_MAX_MIDDLE_CELLS,
|
||||
(direction == CELL_DIRECTION_OUT) ? "n" : "p",
|
||||
(direction == CELL_DIRECTION_OUT) ?
|
||||
circ->n_circ_id : orcirc->p_circ_id,
|
||||
U64_PRINTF_ARG(
|
||||
(direction == CELL_DIRECTION_OUT) ?
|
||||
circ->n_chan->global_identifier :
|
||||
orcirc->p_chan->global_identifier));
|
||||
circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cell_queue_append_packed_copy(queue, cell, chan->wide_circ_ids);
|
||||
|
||||
/* If we have too many cells on the circuit, we should stop reading from
|
||||
|
||||
@@ -208,11 +208,25 @@ test_md_cache(void *data)
|
||||
md3 = NULL; /* it's history now! */
|
||||
|
||||
/* rebuild again, make sure it stays gone. */
|
||||
microdesc_cache_rebuild(mc, 1);
|
||||
tt_int_op(microdesc_cache_rebuild(mc, 1), ==, 0);
|
||||
tt_ptr_op(md1, ==, microdesc_cache_lookup_by_digest256(mc, d1));
|
||||
tt_ptr_op(md2, ==, microdesc_cache_lookup_by_digest256(mc, d2));
|
||||
tt_ptr_op(NULL, ==, microdesc_cache_lookup_by_digest256(mc, d3));
|
||||
|
||||
/* Re-add md3, and make sure we can rebuild the cache. */
|
||||
added = microdescs_add_to_cache(mc, test_md3_noannotation, NULL,
|
||||
SAVED_NOWHERE, 0, time3, NULL);
|
||||
tt_int_op(1, ==, smartlist_len(added));
|
||||
md3 = smartlist_get(added, 0);
|
||||
smartlist_free(added);
|
||||
added = NULL;
|
||||
tt_int_op(md1->saved_location, ==, SAVED_IN_CACHE);
|
||||
tt_int_op(md2->saved_location, ==, SAVED_IN_CACHE);
|
||||
tt_int_op(md3->saved_location, ==, SAVED_IN_JOURNAL);
|
||||
|
||||
tt_int_op(microdesc_cache_rebuild(mc, 1), ==, 0);
|
||||
tt_int_op(md3->saved_location, ==, SAVED_IN_CACHE);
|
||||
|
||||
done:
|
||||
if (options)
|
||||
tor_free(options->DataDirectory);
|
||||
|
||||
Reference in New Issue
Block a user