mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-25 23:21:38 +01:00
Add consensus_cache_entry spooling support to spooled_resource_t
This commit is contained in:
parent
24ba1864d8
commit
a32083bd03
2 changed files with 70 additions and 8 deletions
|
@ -13,6 +13,7 @@
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "connection_or.h"
|
#include "connection_or.h"
|
||||||
|
#include "conscache.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "directory.h"
|
#include "directory.h"
|
||||||
#include "dirserv.h"
|
#include "dirserv.h"
|
||||||
|
@ -3392,6 +3393,9 @@ spooled_resource_new(dir_spool_source_t source,
|
||||||
default:
|
default:
|
||||||
spooled->spool_eagerly = 1;
|
spooled->spool_eagerly = 1;
|
||||||
break;
|
break;
|
||||||
|
case DIR_SPOOL_CONSENSUS_CACHE_ENTRY:
|
||||||
|
tor_assert_unreached();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
tor_assert(digestlen <= sizeof(spooled->digest));
|
tor_assert(digestlen <= sizeof(spooled->digest));
|
||||||
if (digest)
|
if (digest)
|
||||||
|
@ -3399,6 +3403,33 @@ spooled_resource_new(dir_spool_source_t source,
|
||||||
return spooled;
|
return spooled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new spooled_resource_t to spool the contents of <b>entry</b> to
|
||||||
|
* the user. Return the spooled object on success, or NULL on failure (which
|
||||||
|
* is probably caused by a failure to map the body of the item from disk).
|
||||||
|
*
|
||||||
|
* Adds a reference to entry's reference counter.
|
||||||
|
*/
|
||||||
|
spooled_resource_t *
|
||||||
|
spooled_resource_new_from_cache_entry(consensus_cache_entry_t *entry)
|
||||||
|
{
|
||||||
|
spooled_resource_t *spooled = tor_malloc_zero(sizeof(spooled_resource_t));
|
||||||
|
spooled->spool_source = DIR_SPOOL_CONSENSUS_CACHE_ENTRY;
|
||||||
|
spooled->spool_eagerly = 0;
|
||||||
|
consensus_cache_entry_incref(entry);
|
||||||
|
spooled->consensus_cache_entry = entry;
|
||||||
|
|
||||||
|
int r = consensus_cache_entry_get_body(entry,
|
||||||
|
&spooled->cce_body,
|
||||||
|
&spooled->cce_len);
|
||||||
|
if (r == 0) {
|
||||||
|
return spooled;
|
||||||
|
} else {
|
||||||
|
spooled_resource_free(spooled);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Release all storage held by <b>spooled</b>. */
|
/** Release all storage held by <b>spooled</b>. */
|
||||||
void
|
void
|
||||||
spooled_resource_free(spooled_resource_t *spooled)
|
spooled_resource_free(spooled_resource_t *spooled)
|
||||||
|
@ -3410,6 +3441,10 @@ spooled_resource_free(spooled_resource_t *spooled)
|
||||||
cached_dir_decref(spooled->cached_dir_ref);
|
cached_dir_decref(spooled->cached_dir_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (spooled->consensus_cache_entry) {
|
||||||
|
consensus_cache_entry_decref(spooled->consensus_cache_entry);
|
||||||
|
}
|
||||||
|
|
||||||
tor_free(spooled);
|
tor_free(spooled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3456,6 +3491,9 @@ spooled_resource_estimate_size(const spooled_resource_t *spooled,
|
||||||
return bodylen;
|
return bodylen;
|
||||||
} else {
|
} else {
|
||||||
cached_dir_t *cached;
|
cached_dir_t *cached;
|
||||||
|
if (spooled->consensus_cache_entry) {
|
||||||
|
return spooled->cce_len;
|
||||||
|
}
|
||||||
if (spooled->cached_dir_ref) {
|
if (spooled->cached_dir_ref) {
|
||||||
cached = spooled->cached_dir_ref;
|
cached = spooled->cached_dir_ref;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3505,7 +3543,8 @@ spooled_resource_flush_some(spooled_resource_t *spooled,
|
||||||
return SRFS_DONE;
|
return SRFS_DONE;
|
||||||
} else {
|
} else {
|
||||||
cached_dir_t *cached = spooled->cached_dir_ref;
|
cached_dir_t *cached = spooled->cached_dir_ref;
|
||||||
if (cached == NULL) {
|
consensus_cache_entry_t *cce = spooled->consensus_cache_entry;
|
||||||
|
if (cached == NULL && cce == NULL) {
|
||||||
/* The cached_dir_t hasn't been materialized yet. So let's look it up. */
|
/* The cached_dir_t hasn't been materialized yet. So let's look it up. */
|
||||||
cached = spooled->cached_dir_ref =
|
cached = spooled->cached_dir_ref =
|
||||||
spooled_resource_lookup_cached_dir(spooled, NULL);
|
spooled_resource_lookup_cached_dir(spooled, NULL);
|
||||||
|
@ -3517,22 +3556,34 @@ spooled_resource_flush_some(spooled_resource_t *spooled,
|
||||||
tor_assert_nonfatal(spooled->cached_dir_offset == 0);
|
tor_assert_nonfatal(spooled->cached_dir_offset == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BUG(!cached && !cce))
|
||||||
|
return SRFS_DONE;
|
||||||
|
|
||||||
|
int64_t total_len;
|
||||||
|
const char *ptr;
|
||||||
|
if (cached) {
|
||||||
|
total_len = cached->dir_z_len;
|
||||||
|
ptr = cached->dir_z;
|
||||||
|
} else {
|
||||||
|
total_len = spooled->cce_len;
|
||||||
|
ptr = (const char *)spooled->cce_body;
|
||||||
|
}
|
||||||
/* How many bytes left to flush? */
|
/* How many bytes left to flush? */
|
||||||
int64_t remaining = 0;
|
int64_t remaining;
|
||||||
remaining = cached->dir_z_len - spooled->cached_dir_offset;
|
remaining = total_len - spooled->cached_dir_offset;
|
||||||
if (BUG(remaining < 0))
|
if (BUG(remaining < 0))
|
||||||
return SRFS_ERR;
|
return SRFS_ERR;
|
||||||
ssize_t bytes = (ssize_t) MIN(DIRSERV_CACHED_DIR_CHUNK_SIZE, remaining);
|
ssize_t bytes = (ssize_t) MIN(DIRSERV_CACHED_DIR_CHUNK_SIZE, remaining);
|
||||||
if (conn->compress_state) {
|
if (conn->compress_state) {
|
||||||
connection_write_to_buf_compress(
|
connection_write_to_buf_compress(
|
||||||
cached->dir_z + spooled->cached_dir_offset,
|
ptr + spooled->cached_dir_offset,
|
||||||
bytes, conn, 0);
|
bytes, conn, 0);
|
||||||
} else {
|
} else {
|
||||||
connection_write_to_buf(cached->dir_z + spooled->cached_dir_offset,
|
connection_write_to_buf(ptr + spooled->cached_dir_offset,
|
||||||
bytes, TO_CONN(conn));
|
bytes, TO_CONN(conn));
|
||||||
}
|
}
|
||||||
spooled->cached_dir_offset += bytes;
|
spooled->cached_dir_offset += bytes;
|
||||||
if (spooled->cached_dir_offset >= (off_t)cached->dir_z_len) {
|
if (spooled->cached_dir_offset >= (off_t)total_len) {
|
||||||
return SRFS_DONE;
|
return SRFS_DONE;
|
||||||
} else {
|
} else {
|
||||||
return SRFS_MORE;
|
return SRFS_MORE;
|
||||||
|
@ -3608,6 +3659,7 @@ spooled_resource_lookup_body(const spooled_resource_t *spooled,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case DIR_SPOOL_NETWORKSTATUS:
|
case DIR_SPOOL_NETWORKSTATUS:
|
||||||
|
case DIR_SPOOL_CONSENSUS_CACHE_ENTRY:
|
||||||
default:
|
default:
|
||||||
/* LCOV_EXCL_START */
|
/* LCOV_EXCL_START */
|
||||||
tor_assert_nonfatal_unreached();
|
tor_assert_nonfatal_unreached();
|
||||||
|
|
|
@ -38,6 +38,7 @@ typedef enum dir_spool_source_t {
|
||||||
DIR_SPOOL_EXTRA_BY_DIGEST, DIR_SPOOL_EXTRA_BY_FP,
|
DIR_SPOOL_EXTRA_BY_DIGEST, DIR_SPOOL_EXTRA_BY_FP,
|
||||||
DIR_SPOOL_MICRODESC,
|
DIR_SPOOL_MICRODESC,
|
||||||
DIR_SPOOL_NETWORKSTATUS,
|
DIR_SPOOL_NETWORKSTATUS,
|
||||||
|
DIR_SPOOL_CONSENSUS_CACHE_ENTRY,
|
||||||
} dir_spool_source_t;
|
} dir_spool_source_t;
|
||||||
#define dir_spool_source_bitfield_t ENUM_BF(dir_spool_source_t)
|
#define dir_spool_source_bitfield_t ENUM_BF(dir_spool_source_t)
|
||||||
|
|
||||||
|
@ -74,8 +75,15 @@ typedef struct spooled_resource_t {
|
||||||
*/
|
*/
|
||||||
struct cached_dir_t *cached_dir_ref;
|
struct cached_dir_t *cached_dir_ref;
|
||||||
/**
|
/**
|
||||||
* The current offset into cached_dir. Only used when spool_eagerly is
|
* A different kind of large object that we might be spooling. Also
|
||||||
* false */
|
* reference-counted. Also only used when spool_eagerly is false.
|
||||||
|
*/
|
||||||
|
struct consensus_cache_entry_t *consensus_cache_entry;
|
||||||
|
const uint8_t *cce_body;
|
||||||
|
size_t cce_len;
|
||||||
|
/**
|
||||||
|
* The current offset into cached_dir or cce_body. Only used when
|
||||||
|
* spool_eagerly is false */
|
||||||
off_t cached_dir_offset;
|
off_t cached_dir_offset;
|
||||||
} spooled_resource_t;
|
} spooled_resource_t;
|
||||||
|
|
||||||
|
@ -184,6 +192,8 @@ int dirserv_read_guardfraction_file(const char *fname,
|
||||||
spooled_resource_t *spooled_resource_new(dir_spool_source_t source,
|
spooled_resource_t *spooled_resource_new(dir_spool_source_t source,
|
||||||
const uint8_t *digest,
|
const uint8_t *digest,
|
||||||
size_t digestlen);
|
size_t digestlen);
|
||||||
|
spooled_resource_t *spooled_resource_new_from_cache_entry(
|
||||||
|
struct consensus_cache_entry_t *entry);
|
||||||
void spooled_resource_free(spooled_resource_t *spooled);
|
void spooled_resource_free(spooled_resource_t *spooled);
|
||||||
void dirserv_spool_remove_missing_and_guess_size(dir_connection_t *conn,
|
void dirserv_spool_remove_missing_and_guess_size(dir_connection_t *conn,
|
||||||
time_t cutoff,
|
time_t cutoff,
|
||||||
|
|
Loading…
Add table
Reference in a new issue