Use malloc / free for manifest structs

This commit is contained in:
Jeremy Lakeman 2016-03-23 10:14:32 +10:30
parent 76be37a04e
commit c625a598d9
6 changed files with 28 additions and 125 deletions

View File

@ -673,9 +673,9 @@ enum rhizome_bundle_status rhizome_manifest_check_stored(rhizome_manifest *m, rh
enum rhizome_bundle_status rhizome_add_manifest_to_store(rhizome_manifest *m, rhizome_manifest **mout)
{
if (mout == NULL)
DEBUGF(rhizome, "%s(m=manifest[%d](%p), mout=NULL)", __func__, m->manifest_record_number, m);
DEBUGF(rhizome, "%s(m=manifest %p, mout=NULL)", __func__, m);
else
DEBUGF(rhizome, "%s(m=manifest[%d](%p), *mout=manifest[%d](%p))", __func__, m->manifest_record_number, m, *mout ? (*mout)->manifest_record_number : -1, *mout);
DEBUGF(rhizome, "%s(m=manifest %p, *mout=manifest %p)", __func__, m, *mout);
if (!m->finalised && !rhizome_manifest_validate(m))
return RHIZOME_BUNDLE_STATUS_INVALID;
assert(m->finalised);

View File

@ -57,7 +57,6 @@ extern time_ms_t rhizome_voice_timeout;
typedef struct rhizome_manifest
{
int manifest_record_number;
/* CryptoSign key pair for this manifest. The public key is the Bundle ID
* (aka Manifest ID).
@ -125,10 +124,6 @@ typedef struct rhizome_manifest
*/
bool_t selfSigned;
/* If set, unlink(2) the associated file when freeing the manifest.
*/
bool_t dataFileUnlinkOnFree;
/* Set if the ID field (cryptoSignPublic) contains a bundle ID.
*/
bool_t has_id;
@ -170,9 +165,6 @@ typedef struct rhizome_manifest
AUTHOR_AUTHENTIC // a local identity is the verified author
} authorship;
/* Absolute path of the file associated with the manifest */
const char *dataFileName;
/* Whether the paylaod is encrypted or not */
enum rhizome_manifest_crypt {
PAYLOAD_CRYPT_UNKNOWN = 0,
@ -694,10 +686,6 @@ int rhizome_list_next(struct rhizome_list_cursor *);
void rhizome_list_commit(struct rhizome_list_cursor *);
void rhizome_list_release(struct rhizome_list_cursor *);
/* one manifest is required per candidate, plus a few spare.
so MAX_RHIZOME_MANIFESTS must be > MAX_CANDIDATES.
*/
#define MAX_RHIZOME_MANIFESTS 40
#define MAX_CANDIDATES 32
int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct socket_address *addr, const struct subscriber *peer);

View File

@ -57,7 +57,7 @@ static uint64_t rhizome_manifest_get_ui64(rhizome_manifest *m, const char *var)
*/
static int _rhizome_manifest_del(struct __sourceloc __whence, rhizome_manifest *m, const char *var)
{
DEBUGF(rhizome_manifest, "DEL manifest[%d].%s", m->manifest_record_number, var);
DEBUGF(rhizome_manifest, "DEL manifest %p %s", m, var);
int ret = 0;
unsigned i;
for (i = 0; i < m->var_count; ++i)
@ -81,7 +81,7 @@ static int _rhizome_manifest_del(struct __sourceloc __whence, rhizome_manifest *
static const char *_rhizome_manifest_set(struct __sourceloc __whence, rhizome_manifest *m, const char *var, const char *value)
{
DEBUGF(rhizome_manifest, "SET manifest[%d].%s = %s", m->manifest_record_number, var, alloca_str_toprint(value));
DEBUGF(rhizome_manifest, "SET manifest %p %s = %s", m, var, alloca_str_toprint(value));
unsigned i;
for(i=0;i<m->var_count;i++)
if (strcmp(m->vars[i],var) == 0) {
@ -375,13 +375,13 @@ void _rhizome_manifest_set_crypt(struct __sourceloc __whence, rhizome_manifest *
void _rhizome_manifest_set_rowid(struct __sourceloc __whence, rhizome_manifest *m, uint64_t rowid)
{
DEBUGF(rhizome_manifest, "SET manifest[%d].rowid = %"PRIu64, m->manifest_record_number, rowid);
DEBUGF(rhizome_manifest, "SET manifest %p rowid = %"PRIu64, m, rowid);
m->rowid = rowid;
}
void _rhizome_manifest_set_inserttime(struct __sourceloc __whence, rhizome_manifest *m, time_ms_t time)
{
DEBUGF(rhizome_manifest, "SET manifest[%d].inserttime = %"PRItime_ms_t, m->manifest_record_number, time);
DEBUGF(rhizome_manifest, "SET manifest %p inserttime = %"PRItime_ms_t, m, time);
m->inserttime = time;
}
@ -389,7 +389,7 @@ void _rhizome_manifest_set_author(struct __sourceloc __whence, rhizome_manifest
{
if (sidp) {
if (m->authorship == ANONYMOUS || cmp_sid_t(&m->author, sidp) != 0) {
DEBUGF(rhizome_manifest, "SET manifest[%d] author = %s", m->manifest_record_number, alloca_tohex_sid_t(*sidp));
DEBUGF(rhizome_manifest, "SET manifest %p author = %s", m, alloca_tohex_sid_t(*sidp));
m->author = *sidp;
m->authorship = AUTHOR_NOT_CHECKED;
}
@ -400,7 +400,7 @@ void _rhizome_manifest_set_author(struct __sourceloc __whence, rhizome_manifest
void _rhizome_manifest_del_author(struct __sourceloc __whence, rhizome_manifest *m)
{
if (m->authorship != ANONYMOUS) {
DEBUGF(rhizome_manifest, "DEL manifest[%d] author", m->manifest_record_number);
DEBUGF(rhizome_manifest, "DEL manifest %p author", m);
m->author = SID_ANY;
m->authorship = ANONYMOUS;
}
@ -978,7 +978,7 @@ int _rhizome_manifest_overwrite(struct __sourceloc __whence, rhizome_manifest *m
for (i = 0; i < NELS(rhizome_manifest_fields); ++i) {
struct rhizome_manifest_field_descriptor *desc = &rhizome_manifest_fields[i];
if (desc->test(srcm)) {
DEBUGF(rhizome_manifest, "COPY manifest[%d].%s to:", srcm->manifest_record_number, desc->label);
DEBUGF(rhizome_manifest, "COPY manifest %p %s to:", srcm, desc->label);
desc->copy(__whence, m, srcm);
}
}
@ -1076,7 +1076,7 @@ rhizome_manifest_parse_field(rhizome_manifest *m, const char *field_label, size_
} else if (rhizome_manifest_set(m, label, value) == NULL)
status = RHIZOME_MANIFEST_ERROR;
if (status != RHIZOME_MANIFEST_OK) {
DEBUGF(rhizome_manifest, "SKIP manifest[%d].%s = %s (status=%d)", m->manifest_record_number, label, alloca_str_toprint(value), status);
DEBUGF(rhizome_manifest, "SKIP manifest %p %s = %s (status=%d)", m, label, alloca_str_toprint(value), status);
}
return status;
}
@ -1217,106 +1217,25 @@ int rhizome_hash_file(rhizome_manifest *m, const char *path, rhizome_filehash_t
return 0;
}
rhizome_manifest manifests[MAX_RHIZOME_MANIFESTS];
char manifest_free[MAX_RHIZOME_MANIFESTS];
int manifest_first_free=-1;
struct __sourceloc manifest_alloc_whence[MAX_RHIZOME_MANIFESTS];
struct __sourceloc manifest_free_whence[MAX_RHIZOME_MANIFESTS];
static unsigned _count_free_manifests()
{
unsigned count_free = 0;
unsigned i;
for (i = 0; i != MAX_RHIZOME_MANIFESTS; ++i)
if (manifest_free[i])
++count_free;
return count_free;
}
rhizome_manifest *_rhizome_new_manifest(struct __sourceloc __whence)
{
if (manifest_first_free<0) {
/* Setup structures */
unsigned i;
for(i=0;i<MAX_RHIZOME_MANIFESTS;i++) {
manifest_alloc_whence[i]=__NOWHERE__;
manifest_free_whence[i]=__NOWHERE__;
manifest_free[i]=1;
}
manifest_first_free=0;
rhizome_manifest *m=emalloc_zero(sizeof(rhizome_manifest));
if (m){
DEBUGF(rhizome_manifest, "NEW manifest %p", m);
// Set global defaults for a manifest (which are not zero)
rhizome_manifest_clear(m);
}
/* No free manifests */
if (manifest_first_free>=MAX_RHIZOME_MANIFESTS)
{
unsigned i;
WHYF("%s(): no free manifest records, this probably indicates a memory leak", __FUNCTION__);
WHYF(" Slot# | Last allocated by");
for(i=0;i<MAX_RHIZOME_MANIFESTS;i++) {
WHYF(" %-5d | %s:%d in %s()",
i,
manifest_alloc_whence[i].file,
manifest_alloc_whence[i].line,
manifest_alloc_whence[i].function
);
}
return NULL;
}
rhizome_manifest *m=&manifests[manifest_first_free];
bzero(m,sizeof(rhizome_manifest));
m->manifest_record_number=manifest_first_free;
/* Indicate where manifest was allocated, and that it is no longer
free. */
manifest_alloc_whence[manifest_first_free]=__whence;
manifest_free[manifest_first_free]=0;
manifest_free_whence[manifest_first_free]=__NOWHERE__;
/* Work out where next free manifest record lives */
for (; manifest_first_free < MAX_RHIZOME_MANIFESTS && !manifest_free[manifest_first_free]; ++manifest_first_free)
;
DEBUGF(rhizome_manifest, "NEW manifest[%d], count_free=%u", m->manifest_record_number, _count_free_manifests());
// Set global defaults for a manifest (which are not zero)
rhizome_manifest_clear(m);
return m;
}
void _rhizome_manifest_free(struct __sourceloc __whence, rhizome_manifest *m)
{
if (!m) return;
int mid=m->manifest_record_number;
if (m!=&manifests[mid])
FATALF("%s(): manifest at %p claims to be manifest[%d] (%p) but isn't",
__FUNCTION__, m, mid, &manifests[mid]
);
if (manifest_free[mid])
FATALF("%s(): manifest[%d] (%p) was already freed at %s:%d:%s()",
__FUNCTION__, mid, m,
manifest_free_whence[mid].file,
manifest_free_whence[mid].line,
manifest_free_whence[mid].function
);
DEBUGF(rhizome_manifest, "FREE manifest %p", m);
/* Free variable and signature blocks. */
rhizome_manifest_clear(m);
if (m->dataFileName) {
if (m->dataFileUnlinkOnFree && unlink(m->dataFileName) == -1)
WARNF_perror("unlink(%s)", alloca_str_toprint(m->dataFileName));
free((char *) m->dataFileName);
m->dataFileName = NULL;
}
manifest_free[mid]=1;
manifest_free_whence[mid]=__whence;
if (mid<manifest_first_free) manifest_first_free=mid;
DEBUGF(rhizome_manifest, "FREE manifest[%d], count_free=%u", m->manifest_record_number, _count_free_manifests());
return;
}
@ -1631,7 +1550,7 @@ int rhizome_lookup_author(rhizome_manifest *m)
case AUTHOR_AUTHENTIC:
RETURN(1);
case AUTHOR_NOT_CHECKED:
DEBUGF(rhizome, "manifest[%d] lookup author=%s", m->manifest_record_number, alloca_tohex_sid_t(m->author));
DEBUGF(rhizome, "manifest %p lookup author=%s", m, alloca_tohex_sid_t(m->author));
keyring_iterator_start(keyring, &it);
if (keyring_find_sid(&it, &m->author)) {
DEBUGF(rhizome, "found author");
@ -1641,7 +1560,7 @@ int rhizome_lookup_author(rhizome_manifest *m)
// fall through
case ANONYMOUS:
if (m->has_sender) {
DEBUGF(rhizome, "manifest[%d] lookup sender=%s", m->manifest_record_number, alloca_tohex_sid_t(m->sender));
DEBUGF(rhizome, "manifest %p lookup sender=%s", m, alloca_tohex_sid_t(m->sender));
keyring_iterator_start(keyring, &it);
if (keyring_find_sid(&it, &m->sender)) {
DEBUGF(rhizome, "found sender");

View File

@ -220,12 +220,12 @@ void rhizome_authenticate_author(rhizome_manifest *m)
DEBUGF(rhizome, "authenticate author for bid=%s", m->has_id ? alloca_tohex_rhizome_bid_t(m->cryptoSignPublic) : "(none)");
switch (m->authorship) {
case ANONYMOUS:
DEBUGF(rhizome, " manifest[%d] author unknown", m->manifest_record_number);
DEBUGF(rhizome, " manifest %p author unknown", m);
rhizome_find_bundle_author_and_secret(m);
RETURNVOID;
case AUTHOR_NOT_CHECKED:
case AUTHOR_LOCAL: {
DEBUGF(rhizome, " manifest[%d] authenticate author=%s", m->manifest_record_number, alloca_tohex_sid_t(m->author));
DEBUGF(rhizome, " manifest %p authenticate author=%s", m, alloca_tohex_sid_t(m->author));
size_t rs_len;
const unsigned char *rs;
enum rhizome_secret_disposition d = find_rhizome_secret(&m->author, &rs_len, &rs);
@ -283,7 +283,7 @@ void rhizome_authenticate_author(rhizome_manifest *m)
int rhizome_apply_bundle_secret(rhizome_manifest *m, const rhizome_bk_t *bsk)
{
IN();
DEBUGF(rhizome, "manifest[%d] bsk=%s", m->manifest_record_number, bsk ? alloca_tohex_rhizome_bk_t(*bsk) : "NULL");
DEBUGF(rhizome, "manifest %p bsk=%s", m, bsk ? alloca_tohex_rhizome_bk_t(*bsk) : "NULL");
assert(m->haveSecret == SECRET_UNKNOWN);
assert(is_all_matching(m->cryptoSignSecret, sizeof m->cryptoSignSecret, 0));
assert(m->has_id);
@ -621,7 +621,7 @@ int rhizome_derive_payload_key(rhizome_manifest *m)
crypto_hash_sha512(hash, raw_key, sizeof(raw_key));
}
bcopy(hash, m->payloadKey, RHIZOME_CRYPT_KEY_BYTES);
DEBUGF(rhizome_manifest, "SET manifest[%d].payloadKey = %s", m->manifest_record_number, alloca_tohex(m->payloadKey, sizeof m->payloadKey));
DEBUGF(rhizome_manifest, "SET manifest %p payloadKey = %s", m, alloca_tohex(m->payloadKey, sizeof m->payloadKey));
// journal bundles must always have the same nonce, regardless of version.
// otherwise, generate nonce from version#bundle id#version;
@ -633,7 +633,7 @@ int rhizome_derive_payload_key(rhizome_manifest *m)
DEBUGF(rhizome, "derived payload nonce from bid=%s version=%"PRIu64, alloca_tohex_sid_t(m->cryptoSignPublic), nonce_version);
crypto_hash_sha512(hash, raw_nonce, sizeof(raw_nonce));
bcopy(hash, m->payloadNonce, sizeof(m->payloadNonce));
DEBUGF(rhizome_manifest, "SET manifest[%d].payloadNonce = %s", m->manifest_record_number, alloca_tohex(m->payloadNonce, sizeof m->payloadNonce));
DEBUGF(rhizome_manifest, "SET manifest %p payloadNonce = %s", m, alloca_tohex(m->payloadNonce, sizeof m->payloadNonce));
return 1;
}

View File

@ -506,10 +506,6 @@ schedule_fetch(struct rhizome_fetch_slot *slot)
slot->bid = slot->manifest->cryptoSignPublic;
slot->prefix_length = sizeof slot->bid.binary;
slot->bidVersion = slot->manifest->version;
/* Don't provide a filename, because we will stream the file straight into
the database. */
slot->manifest->dataFileName = NULL;
slot->manifest->dataFileUnlinkOnFree = 0;
strbuf r = strbuf_local_buf(slot->request);
strbuf_sprintf(r, "GET /rhizome/file/%s HTTP/1.0\r\n", alloca_tohex_rhizome_filehash_t(slot->manifest->filehash));

View File

@ -913,8 +913,8 @@ enum rhizome_payload_status rhizome_stat_payload_file(rhizome_manifest *m, const
if (m->filesize == RHIZOME_SIZE_UNSET)
rhizome_manifest_set_filesize(m, size);
else if (size != m->filesize) {
DEBUGF(rhizome_store, "payload file %s (size=%"PRIu64") does not match manifest[%d].filesize=%"PRIu64,
alloca_str_toprint(filepath), size, m->manifest_record_number, m->filesize);
DEBUGF(rhizome_store, "payload file %s (size=%"PRIu64") does not match manifest %p filesize=%"PRIu64,
alloca_str_toprint(filepath), size, m, m->filesize);
return RHIZOME_PAYLOAD_STATUS_WRONG_SIZE;
}
return size ? RHIZOME_PAYLOAD_STATUS_NEW : RHIZOME_PAYLOAD_STATUS_EMPTY;
@ -1602,7 +1602,7 @@ enum rhizome_payload_status rhizome_write_open_journal(struct rhizome_write *wri
// Call to finish any payload store operation
enum rhizome_payload_status rhizome_finish_store(struct rhizome_write *write, rhizome_manifest *m, enum rhizome_payload_status status)
{
DEBUGF(rhizome, "write=%p m=manifest[%d], status=%d %s", write, m->manifest_record_number, status, rhizome_payload_status_message_nonnull(status));
DEBUGF(rhizome, "write=%p m=manifest %p, status=%d %s", write, m, status, rhizome_payload_status_message_nonnull(status));
switch (status) {
case RHIZOME_PAYLOAD_STATUS_NEW:
break;