rhizome_bid_t

Consistent type for internal binary representation of Rhizome Bundle ID
(aka Manifest ID)
This commit is contained in:
Andrew Bettison 2013-10-03 23:16:45 +09:30
parent d18e48868d
commit ab31420faf
16 changed files with 330 additions and 304 deletions

View File

@ -1336,10 +1336,15 @@ int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_context *co
rhizome_manifest_free(m);
return WHY("Manifest file could not be loaded -- not added to rhizome");
}
} else if(manifestid && *manifestid) {
} else if (manifestid && *manifestid) {
if (config.debug.rhizome)
DEBUGF("Reading manifest from database");
if (rhizome_retrieve_manifest(manifestid, m)){
rhizome_bid_t bid;
if (str_to_rhizome_bid_t(&bid, manifestid) == -1) {
rhizome_manifest_free(m);
return WHYF("Invalid bundle ID: %s", alloca_str_toprint(manifestid));
}
if (rhizome_retrieve_manifest(&bid, m)){
rhizome_manifest_free(m);
return WHY("Existing manifest could not be loaded -- not added to rhizome");
}
@ -1398,10 +1403,8 @@ int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_context *co
cli_put_string(context, service, "\n");
}
{
char bid[RHIZOME_MANIFEST_ID_STRLEN + 1];
rhizome_bytes_to_hex_upper(mout->cryptoSignPublic, bid, RHIZOME_MANIFEST_ID_BYTES);
cli_field_name(context, "manifestid", ":");
cli_put_string(context, bid, "\n");
cli_put_string(context, alloca_tohex_rhizome_bid_t(mout->cryptoSignPublic), "\n");
}
{
char secret[RHIZOME_BUNDLE_KEY_STRLEN + 1];
@ -1508,7 +1511,7 @@ int app_rhizome_import_bundle(const struct cli_parsed *parsed, struct cli_contex
}
{
cli_field_name(context, "manifestid", ":");
cli_put_string(context, alloca_tohex(m->cryptoSignPublic, RHIZOME_MANIFEST_ID_BYTES), "\n");
cli_put_string(context, alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), "\n");
}
{
char secret[RHIZOME_BUNDLE_KEY_STRLEN + 1];
@ -1596,17 +1599,15 @@ int app_rhizome_delete(const struct cli_parsed *parsed, struct cli_context *cont
} else {
if (!manifestid)
return WHY("missing <manifestid> argument");
unsigned char manifest_id[RHIZOME_MANIFEST_ID_BYTES];
if (fromhexstr(manifest_id, manifestid, RHIZOME_MANIFEST_ID_BYTES) == -1)
rhizome_bid_t bid;
if (str_to_rhizome_bid_t(&bid, manifestid) == -1)
return WHY("Invalid manifest ID");
char manifestIdUpper[RHIZOME_MANIFEST_ID_STRLEN + 1];
tohex(manifestIdUpper, manifest_id, RHIZOME_MANIFEST_ID_BYTES);
if (cli_arg(parsed, "bundle", NULL, NULL, NULL) == 0)
ret = rhizome_delete_bundle(manifestIdUpper);
ret = rhizome_delete_bundle(&bid);
else if (cli_arg(parsed, "manifest", NULL, NULL, NULL) == 0)
ret = rhizome_delete_manifest(manifestIdUpper);
ret = rhizome_delete_manifest(&bid);
else if (cli_arg(parsed, "payload", NULL, NULL, NULL) == 0)
ret = rhizome_delete_payload(manifestIdUpper);
ret = rhizome_delete_payload(&bid);
else
return WHY("unrecognised command");
}
@ -1656,13 +1657,10 @@ int app_rhizome_extract(const struct cli_parsed *parsed, struct cli_context *con
int ret=0;
unsigned char manifest_id[RHIZOME_MANIFEST_ID_BYTES];
if (fromhexstr(manifest_id, manifestid, RHIZOME_MANIFEST_ID_BYTES) == -1)
rhizome_bid_t bid;
if (str_to_rhizome_bid_t(&bid, manifestid) == -1)
return WHY("Invalid manifest ID");
char manifestIdUpper[RHIZOME_MANIFEST_ID_STRLEN + 1];
tohex(manifestIdUpper, manifest_id, RHIZOME_MANIFEST_ID_BYTES);
// treat empty string the same as null
if (bskhex && !*bskhex)
bskhex=NULL;
@ -1675,7 +1673,7 @@ int app_rhizome_extract(const struct cli_parsed *parsed, struct cli_context *con
if (m==NULL)
return WHY("Out of manifests");
ret = rhizome_retrieve_manifest(manifestIdUpper, m);
ret = rhizome_retrieve_manifest(&bid, m);
if (ret==0){
// ignore errors
@ -1683,7 +1681,7 @@ int app_rhizome_extract(const struct cli_parsed *parsed, struct cli_context *con
const char *blob_service = rhizome_manifest_get(m, "service", NULL, 0);
cli_field_name(context, "service", ":"); cli_put_string(context, blob_service, "\n");
cli_field_name(context, "manifestid", ":"); cli_put_string(context, manifestIdUpper, "\n");
cli_field_name(context, "manifestid", ":"); cli_put_string(context, alloca_tohex_rhizome_bid_t(bid), "\n");
cli_field_name(context, "version", ":"); cli_put_long(context, m->version, "\n");
cli_field_name(context, "inserttime", ":"); cli_put_long(context, m->inserttime, "\n");
if (m->haveSecret) {

View File

@ -27,8 +27,7 @@ int cmp_sid_t(const sid_t *a, const sid_t *b)
return memcmp(a, b, sizeof a->binary);
}
int str_to_sid_t(sid_t *sid, const char *hex)
{
int str_to_sid_t(sid_t *sid, const char *hex) {
if (strcmp(hex, "broadcast") == 0) {
*sid = SID_BROADCAST;
return 0;
@ -73,6 +72,28 @@ int strn_is_subscriber_id(const char *sid, size_t *lenp)
return 0;
}
int cmp_rhizome_bid_t(const rhizome_bid_t *a, const rhizome_bid_t *b)
{
return memcmp(a, b, sizeof a->binary);
}
int str_to_rhizome_bid_t(rhizome_bid_t *bid, const char *hex)
{
return fromhexstr(bid->binary, hex, sizeof bid->binary);
}
int strn_to_rhizome_bid_t(rhizome_bid_t *bid, const char *hex, const char **endp)
{
rhizome_bid_t tmp;
int n = fromhex(tmp.binary, hex, sizeof tmp.binary);
if (n != sizeof tmp.binary)
return -1;
*bid = tmp;
if (endp)
*endp = hex + sizeof bid->binary * 2;
return 0;
}
int rhizome_strn_is_manifest_id(const char *id)
{
return is_xsubstring(id, RHIZOME_MANIFEST_ID_STRLEN);

View File

@ -11,7 +11,7 @@
// the manifest details for one half of a conversation
struct ply{
char bundle_id[RHIZOME_MANIFEST_ID_STRLEN+1];
rhizome_bid_t bundle_id;
uint64_t version;
uint64_t tail;
uint64_t size;
@ -134,14 +134,19 @@ static int get_database_conversations(const sid_t *my_sid, const sid_t *their_si
DEBUGF("Looking for conversations for %s, %s", my_sid_hex, their_sid_hex);
}
while (sqlite_step_retry(&retry, statement) == SQLITE_ROW) {
const char *id = (const char *)sqlite3_column_text(statement, 0);
const char *id_hex = (const char *)sqlite3_column_text(statement, 0);
long long version = sqlite3_column_int64(statement, 1);
long long size = sqlite3_column_int64(statement, 2);
long long tail = sqlite3_column_int64(statement, 3);
const char *sender = (const char *)sqlite3_column_text(statement, 4);
const char *recipient = (const char *)sqlite3_column_text(statement, 5);
if (config.debug.meshms)
DEBUGF("found id %s, sender %s, recipient %s", id, sender, recipient);
DEBUGF("found id %s, sender %s, recipient %s", id_hex, sender, recipient);
rhizome_bid_t bid;
if (str_to_rhizome_bid_t(&bid, id_hex) == -1) {
WHYF("invalid Bundle ID hex: %s -- skipping", alloca_str_toprint(id_hex));
continue;
}
const char *them = recipient;
sid_t their_sid;
if (str_to_sid_t(&their_sid, them) == -1) {
@ -166,7 +171,7 @@ static int get_database_conversations(const sid_t *my_sid, const sid_t *their_si
ptr->found_my_ply=1;
p=&ptr->my_ply;
}
strncpy(p->bundle_id, id, RHIZOME_MANIFEST_ID_STRLEN+1);
p->bundle_id = bid;
p->version = version;
p->tail = tail;
p->size = size;
@ -194,12 +199,10 @@ static int create_ply(const sid_t *my_sid, struct conversations *conv, rhizome_m
rhizome_manifest_set(m, "sender", my_sidhex);
rhizome_manifest_set(m, "recipient", their_sidhex);
rhizome_manifest_set_ll(m, "tail", m->journalTail);
if (rhizome_fill_manifest(m, NULL, my_sid, NULL))
return -1;
rhizome_manifest_get(m, "id", conv->my_ply.bundle_id, sizeof(conv->my_ply.bundle_id));
conv->found_my_ply=1;
conv->my_ply.bundle_id = m->cryptoSignPublic;
conv->found_my_ply = 1;
return 0;
}
@ -209,14 +212,15 @@ static int append_footer(unsigned char *buffer, char type, int payload_len){
return 2;
}
static int ply_read_open(struct ply_read *ply, const char *id, rhizome_manifest *m){
static int ply_read_open(struct ply_read *ply, const rhizome_bid_t *bid, rhizome_manifest *m)
{
if (config.debug.meshms)
DEBUGF("Opening ply %s", id);
if (rhizome_retrieve_manifest(id, m))
DEBUGF("Opening ply %s", alloca_tohex_rhizome_bid_t(*bid));
if (rhizome_retrieve_manifest(bid, m))
return -1;
int ret = rhizome_open_decrypt_read(m, NULL, &ply->read);
if (ret>0)
WARNF("Payload was not found for manifest %s, %"PRId64, alloca_tohex_bid(m->cryptoSignPublic), m->version);
WARNF("Payload was not found for manifest %s, %"PRId64, alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version);
if (ret)
return ret;
ply->read.offset = ply->read.length = m->fileLength;
@ -297,7 +301,7 @@ static int append_meshms_buffer(const sid_t *my_sid, struct conversations *conv,
goto end;
if (conv->found_my_ply){
if (rhizome_retrieve_manifest(conv->my_ply.bundle_id, m))
if (rhizome_retrieve_manifest(&conv->my_ply.bundle_id, m))
goto end;
// set the author of the manifest as we should already know that
bcopy(my_sid->binary, m->author, sizeof(m->author));
@ -347,10 +351,10 @@ static int update_conversation(const sid_t *my_sid, struct conversations *conv){
DEBUG("Locating their last message");
// find the offset of their last message
if (rhizome_retrieve_manifest(conv->their_ply.bundle_id, m_theirs))
if (rhizome_retrieve_manifest(&conv->their_ply.bundle_id, m_theirs))
goto end;
if (ply_read_open(&ply, conv->their_ply.bundle_id, m_theirs))
if (ply_read_open(&ply, &conv->their_ply.bundle_id, m_theirs))
goto end;
ret = ply_find_next(&ply, MESHMS_BLOCK_TYPE_MESSAGE);
@ -382,10 +386,10 @@ static int update_conversation(const sid_t *my_sid, struct conversations *conv){
m_ours = rhizome_new_manifest();
if (!m_ours)
goto end;
if (rhizome_retrieve_manifest(conv->my_ply.bundle_id, m_ours))
if (rhizome_retrieve_manifest(&conv->my_ply.bundle_id, m_ours))
goto end;
if (ply_read_open(&ply, conv->my_ply.bundle_id, m_ours))
if (ply_read_open(&ply, &conv->my_ply.bundle_id, m_ours))
goto end;
ret = ply_find_next(&ply, MESHMS_BLOCK_TYPE_ACK);
@ -767,7 +771,7 @@ int app_meshms_list_messages(const struct cli_parsed *parsed, struct cli_context
m_ours = rhizome_new_manifest();
if (!m_ours)
goto end;
if (ply_read_open(&read_ours, conv->my_ply.bundle_id, m_ours))
if (ply_read_open(&read_ours, &conv->my_ply.bundle_id, m_ours))
goto end;
uint64_t their_last_ack=0;
@ -778,7 +782,7 @@ int app_meshms_list_messages(const struct cli_parsed *parsed, struct cli_context
m_theirs = rhizome_new_manifest();
if (!m_theirs)
goto end;
if (ply_read_open(&read_theirs, conv->their_ply.bundle_id, m_theirs))
if (ply_read_open(&read_theirs, &conv->their_ply.bundle_id, m_theirs))
goto end;
// find their last ACK so we know if messages have been received

View File

@ -577,7 +577,7 @@ int monitor_announce_bundle(rhizome_manifest *m)
char msg[1024];
int len = snprintf(msg,1024,"\n*%d:BUNDLE:%s\n",
m->manifest_all_bytes,
alloca_tohex_bid(m->cryptoSignPublic));
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
bcopy(m->manifestdata, &msg[len], m->manifest_all_bytes);
len+=m->manifest_all_bytes;
msg[len++]='\n';

View File

@ -29,7 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "crypto.h"
#include "log.h"
int rhizome_mdp_send_block(struct subscriber *dest, unsigned char *id, uint64_t version, uint64_t fileOffset, uint32_t bitmap, uint16_t blockLength)
int rhizome_mdp_send_block(struct subscriber *dest, const rhizome_bid_t *bid, uint64_t version, uint64_t fileOffset, uint32_t bitmap, uint16_t blockLength)
{
IN();
if (!is_rhizome_mdp_server_running())
@ -38,7 +38,7 @@ int rhizome_mdp_send_block(struct subscriber *dest, unsigned char *id, uint64_t
RETURN(WHYF("Invalid block length %d", blockLength));
if (config.debug.rhizome_tx)
DEBUGF("Requested blocks for %s @%"PRIx64" bitmap %x", alloca_tohex_bid(id), fileOffset, bitmap);
DEBUGF("Requested blocks for %s @%"PRIx64" bitmap %x", alloca_tohex_rhizome_bid_t(*bid), fileOffset, bitmap);
overlay_mdp_frame reply;
bzero(&reply,sizeof(reply));
@ -69,7 +69,7 @@ int rhizome_mdp_send_block(struct subscriber *dest, unsigned char *id, uint64_t
reply.out.queue=OQ_OPPORTUNISTIC;
reply.out.payload[0]='B'; // reply contains blocks
// include 16 bytes of BID prefix for identification
bcopy(id, &reply.out.payload[1], 16);
bcopy(bid->binary, &reply.out.payload[1], 16);
// and version of manifest (in the correct byte order)
// bcopy(&version, &reply.out.payload[1+16], sizeof(uint64_t));
write_uint64(&reply.out.payload[1+16],version);
@ -87,7 +87,7 @@ int rhizome_mdp_send_block(struct subscriber *dest, unsigned char *id, uint64_t
write_uint64(&reply.out.payload[1+16+8], offset);
int bytes_read = rhizome_read_cached(id, version, gettime_ms()+5000, offset, &reply.out.payload[1+16+8+8], blockLength);
int bytes_read = rhizome_read_cached(bid, version, gettime_ms()+5000, offset, &reply.out.payload[1+16+8+8], blockLength);
if (bytes_read<=0)
break;
@ -108,16 +108,12 @@ int rhizome_mdp_send_block(struct subscriber *dest, unsigned char *id, uint64_t
int overlay_mdp_service_rhizomerequest(struct overlay_frame *frame, overlay_mdp_frame *mdp)
{
uint64_t version=
read_uint64(&mdp->out.payload[RHIZOME_MANIFEST_ID_BYTES]);
uint64_t fileOffset=
read_uint64(&mdp->out.payload[RHIZOME_MANIFEST_ID_BYTES+8]);
uint32_t bitmap=
read_uint32(&mdp->out.payload[RHIZOME_MANIFEST_ID_BYTES+8+8]);
uint16_t blockLength=
read_uint16(&mdp->out.payload[RHIZOME_MANIFEST_ID_BYTES+8+8+4]);
return rhizome_mdp_send_block(frame->source, &mdp->out.payload[0], version, fileOffset, bitmap, blockLength);
const rhizome_bid_t *bidp = (const rhizome_bid_t *) &mdp->out.payload[0];
uint64_t version = read_uint64(&mdp->out.payload[sizeof bidp->binary]);
uint64_t fileOffset = read_uint64(&mdp->out.payload[sizeof bidp->binary + 8]);
uint32_t bitmap = read_uint32(&mdp->out.payload[sizeof bidp->binary + 8 + 8]);
uint16_t blockLength = read_uint16(&mdp->out.payload[sizeof bidp->binary + 8 + 8 + 4]);
return rhizome_mdp_send_block(frame->source, bidp, version, fileOffset, bitmap, blockLength);
}
int overlay_mdp_service_rhizomeresponse(overlay_mdp_frame *mdp)
@ -353,30 +349,23 @@ end:
RETURN(ret);
}
static int overlay_mdp_service_manifest_requests(struct overlay_frame *frame, overlay_mdp_frame *mdp){
static int overlay_mdp_service_manifest_requests(struct overlay_frame *frame, overlay_mdp_frame *mdp)
{
int offset=0;
char id_hex[RHIZOME_MANIFEST_ID_STRLEN];
while (offset<mdp->out.payload_length){
unsigned char *bar=&mdp->out.payload[offset];
tohex(id_hex, &bar[RHIZOME_BAR_PREFIX_OFFSET], RHIZOME_BAR_PREFIX_BYTES);
strcat(id_hex, "%");
while (offset<mdp->out.payload_length) {
rhizome_manifest *m = rhizome_new_manifest();
if (!m)
return WHY("Unable to allocate manifest");
if (!rhizome_retrieve_manifest(id_hex, m)){
unsigned char *bar = &mdp->out.payload[offset];
if (!rhizome_retrieve_manifest_by_prefix(&bar[RHIZOME_BAR_PREFIX_OFFSET], RHIZOME_BAR_PREFIX_BYTES, m)){
rhizome_advertise_manifest(frame->source, m);
// pre-emptively send the payload if it will fit in a single packet
if (m->fileLength > 0 && m->fileLength <= 1024){
rhizome_mdp_send_block(frame->source, m->cryptoSignPublic, m->version,
0, 0, m->fileLength);
}
if (m->fileLength > 0 && m->fileLength <= 1024)
rhizome_mdp_send_block(frame->source, &m->cryptoSignPublic, m->version, 0, 0, m->fileLength);
}
rhizome_manifest_free(m);
offset+=RHIZOME_BAR_BYTES;
}
return 0;
}

View File

@ -229,7 +229,7 @@ int rhizome_manifest_bind_id(rhizome_manifest *m_in)
return WHYF("Failed to obtain RS for %s to calculate BK",
alloca_tohex_sid(m_in->author));
}
if (!rhizome_secret2bk(m_in->cryptoSignPublic,rs,rs_len,bkbytes,m_in->cryptoSignSecret)) {
if (!rhizome_secret2bk(&m_in->cryptoSignPublic, rs, rs_len, bkbytes, m_in->cryptoSignSecret)) {
char bkhex[RHIZOME_BUNDLE_KEY_STRLEN + 1];
(void) tohex(bkhex, bkbytes, RHIZOME_BUNDLE_KEY_BYTES);
if (config.debug.rhizome) DEBUGF("set BK=%s", bkhex);

View File

@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# endif
#endif
// TODO Rename MANIFEST_ID to BUNDLE_ID
#define RHIZOME_MANIFEST_ID_BYTES crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES
#define RHIZOME_MANIFEST_ID_STRLEN (RHIZOME_MANIFEST_ID_BYTES * 2)
#define RHIZOME_BUNDLE_KEY_BYTES (crypto_sign_edwards25519sha512batch_SECRETKEYBYTES-crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES)
@ -51,6 +52,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define RHIZOME_HTTP_PORT 4110
#define RHIZOME_HTTP_PORT_MAX 4150
typedef struct rhizome_bid_binary {
unsigned char binary[RHIZOME_MANIFEST_ID_BYTES];
} rhizome_bid_t;
#define RHIZOME_BID_ZERO ((rhizome_bid_t){{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}})
#define RHIZOME_BID_MAX ((rhizome_bid_t){{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}})
#define rhizome_bid_t_is_zero(bid) is_all_matching((bid).binary, sizeof (*(rhizome_bid_t*)0).binary, 0)
#define rhizome_bid_t_is_max(bid) is_all_matching((bid).binary, sizeof (*(rhizome_bid_t*)0).binary, 0xff)
#define alloca_tohex_rhizome_bid_t(bid) alloca_tohex((bid).binary, sizeof (*(rhizome_bid_t*)0).binary)
int cmp_rhizome_bid_t(const rhizome_bid_t *a, const rhizome_bid_t *b);
int str_to_rhizome_bid_t(rhizome_bid_t *bid, const char *hex);
int strn_to_rhizome_bid_t(rhizome_bid_t *bid, const char *hex, const char **endp);
typedef struct rhizome_bk_binary {
unsigned char binary[RHIZOME_BUNDLE_KEY_BYTES];
} rhizome_bk_t;
@ -106,7 +120,7 @@ typedef struct rhizome_manifest {
The filename as distributed on Rhizome will be the public key
of this pair, thus ensuring that noone can tamper with a bundle
except the creator. */
unsigned char cryptoSignPublic[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES];
rhizome_bid_t cryptoSignPublic;
unsigned char cryptoSignSecret[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES];
/* Whether we have the secret for this manifest on hand */
int haveSecret;
@ -227,8 +241,6 @@ int rhizome_str_is_bundle_crypt_key(const char *text);
int rhizome_strn_is_file_hash(const char *text);
int rhizome_str_is_file_hash(const char *text);
#define alloca_tohex_bid(bid) alloca_tohex((bid), RHIZOME_MANIFEST_ID_BYTES)
int http_header_complete(const char *buf, size_t len, size_t read_since_last_call);
typedef struct sqlite_retry_state {
@ -310,7 +322,7 @@ enum sqlbind_type {
STATIC_BLOB, // const void *blob, int bytes
ZEROBLOB, // int bytes
SID_T, // const sid_t *sidp
BUNDLE_ID_T, // const unsigned char bid_binary[RHIZOME_BUNDLE_ID_BYTES]
RHIZOME_BID_T, // const rhizome_bid_t *bidp
FILEHASH_T, // const unsigned char hash_binary[RHIZOME_FILEHASH_BYTES]
TOHEX, // const unsigned char *binary, unsigned bytes
TEXT_TOUPPER, // const char *text,
@ -372,11 +384,12 @@ int rhizome_is_manifest_interesting(rhizome_manifest *m);
int rhizome_list_manifests(struct cli_context *context, const char *service, const char *name,
const char *sender_sid, const char *recipient_sid,
int limit, int offset, char count_rows);
int rhizome_retrieve_manifest(const char *manifestid, rhizome_manifest *m);
int rhizome_retrieve_manifest(const rhizome_bid_t *bid, rhizome_manifest *m);
int rhizome_retrieve_manifest_by_prefix(const unsigned char *prefix, unsigned prefix_len, rhizome_manifest *m);
int rhizome_advertise_manifest(struct subscriber *dest, rhizome_manifest *m);
int rhizome_delete_bundle(const char *manifestid);
int rhizome_delete_manifest(const char *manifestid);
int rhizome_delete_payload(const char *manifestid);
int rhizome_delete_bundle(const rhizome_bid_t *bidp);
int rhizome_delete_manifest(const rhizome_bid_t *bidp);
int rhizome_delete_payload(const rhizome_bid_t *bidp);
int rhizome_delete_file(const char *fileid);
#define RHIZOME_DONTVERIFY 0
@ -386,25 +399,25 @@ int rhizome_fetching_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
int monitor_announce_bundle(rhizome_manifest *m);
int rhizome_find_secret(const unsigned char *authorSid, int *rs_len, const unsigned char **rs);
int rhizome_bk_xor_stream(
const unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES],
const rhizome_bid_t *bidp,
const unsigned char *rs,
const size_t rs_len,
unsigned char *xor_stream,
int xor_stream_byte_count);
int rhizome_bk2secret(rhizome_manifest *m,
const unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES],
const rhizome_bid_t *bidp,
const unsigned char *rs, const size_t rs_len,
/* The BK need only be the length of the secret half of the secret key */
const unsigned char bkin[RHIZOME_BUNDLE_KEY_BYTES],
unsigned char secret[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES]
);
int rhizome_secret2bk(
const unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES],
const rhizome_bid_t *bidp,
const unsigned char *rs, const size_t rs_len,
/* The BK need only be the length of the secret half of the secret key */
unsigned char bkout[RHIZOME_BUNDLE_KEY_BYTES],
const unsigned char secret[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES]
);
);
unsigned char *rhizome_bundle_shared_secret(rhizome_manifest *m);
int rhizome_extract_privatekey(rhizome_manifest *m, rhizome_bk_t *bsk);
int rhizome_extract_privatekey_required(rhizome_manifest *m, rhizome_bk_t *bsk);
@ -572,7 +585,7 @@ struct http_response {
const char * body;
};
int rhizome_received_content(unsigned char *bidprefix,uint64_t version,
int rhizome_received_content(const unsigned char *bidprefix,uint64_t version,
uint64_t offset,int count,unsigned char *bytes,
int type);
int64_t rhizome_database_create_blob_for(const char *filehashhex_or_tempid,
@ -599,16 +612,16 @@ int is_rhizome_http_server_running();
typedef struct rhizome_direct_bundle_cursor {
/* Where the current fill started */
int64_t start_size_high;
unsigned char start_bid_low[RHIZOME_MANIFEST_ID_BYTES];
rhizome_bid_t start_bid_low;
/* Limit of where this cursor may traverse */
int64_t limit_size_high;
unsigned char limit_bid_high[RHIZOME_MANIFEST_ID_BYTES];
rhizome_bid_t limit_bid_high;
int64_t size_low;
int64_t size_high;
unsigned char bid_low[RHIZOME_MANIFEST_ID_BYTES];
unsigned char bid_high[RHIZOME_MANIFEST_ID_BYTES];
rhizome_bid_t bid_low;
rhizome_bid_t bid_high;
unsigned char *buffer;
int buffer_size;
int buffer_used;
@ -627,10 +640,10 @@ int rhizome_direct_bundle_iterator_unpickle_range(rhizome_direct_bundle_cursor *
int rhizome_direct_bundle_iterator_fill(rhizome_direct_bundle_cursor *c,
int max_bars);
void rhizome_direct_bundle_iterator_free(rhizome_direct_bundle_cursor **c);
int rhizome_direct_get_bars(const unsigned char bid_low[RHIZOME_MANIFEST_ID_BYTES],
unsigned char bid_high[RHIZOME_MANIFEST_ID_BYTES],
int rhizome_direct_get_bars(const rhizome_bid_t *bid_low,
rhizome_bid_t *bid_high,
int64_t size_low, int64_t size_high,
const unsigned char bid_max[RHIZOME_MANIFEST_ID_BYTES],
const rhizome_bid_t *bid_max,
unsigned char *bars_out,
int bars_requested);
int rhizome_direct_process_post_multipart_bytes
@ -756,7 +769,7 @@ int rhizome_read_close(struct rhizome_read *read);
int rhizome_open_decrypt_read(rhizome_manifest *m, rhizome_bk_t *bsk, struct rhizome_read *read_state);
int rhizome_extract_file(rhizome_manifest *m, const char *filepath, rhizome_bk_t *bsk);
int rhizome_dump_file(const char *id, const char *filepath, int64_t *length);
int rhizome_read_cached(unsigned char *bundle_id, uint64_t version, time_ms_t timeout,
int rhizome_read_cached(const rhizome_bid_t *bid, uint64_t version, time_ms_t timeout,
uint64_t fileOffset, unsigned char *buffer, int length);
int rhizome_cache_close();

View File

@ -51,15 +51,15 @@ int rhizome_manifest_verify(rhizome_manifest *m)
/* Make sure that id variable is correct */
{
unsigned char manifest_id[RHIZOME_MANIFEST_ID_BYTES];
rhizome_bid_t bid;
char *id = rhizome_manifest_get(m,"id",NULL,0);
if (!id) {
WARN("Manifest lacks 'id' field");
m->errors++;
} else if (fromhexstr(manifest_id, id, RHIZOME_MANIFEST_ID_BYTES) == -1) {
} else if (str_to_rhizome_bid_t(&bid, id) == -1) {
WARN("Invalid manifest 'id' field");
m->errors++;
} else if (m->sig_count == 0 || memcmp(m->signatories[0], manifest_id, RHIZOME_MANIFEST_ID_BYTES) != 0) {
} else if (m->sig_count == 0 || memcmp(m->signatories[0], bid.binary, sizeof bid.binary) != 0) {
if (config.debug.rhizome) {
if (m->sig_count>0) {
DEBUGF("Manifest id variable does not match first signature block (signature key is %s)",
@ -159,7 +159,7 @@ int rhizome_manifest_parse(rhizome_manifest *m)
if (strcasecmp(var, "id") == 0) {
have_id = 1;
if (fromhexstr(m->cryptoSignPublic, value, RHIZOME_MANIFEST_ID_BYTES) == -1) {
if (str_to_rhizome_bid_t(&m->cryptoSignPublic, value) == -1) {
if (config.debug.rejecteddata)
WARNF("Invalid manifest id: %s", value);
m->errors++;

View File

@ -38,16 +38,16 @@ unsigned char *rhizome_bundle_shared_secret(rhizome_manifest *m)
int rhizome_manifest_createid(rhizome_manifest *m)
{
if (crypto_sign_edwards25519sha512batch_keypair(m->cryptoSignPublic,m->cryptoSignSecret))
if (crypto_sign_edwards25519sha512batch_keypair(m->cryptoSignPublic.binary, m->cryptoSignSecret))
return WHY("Failed to create keypair for manifest ID.");
rhizome_manifest_set(m, "id", alloca_tohex_bid(m->cryptoSignPublic));
rhizome_manifest_set(m, "id", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
m->haveSecret = NEW_BUNDLE_ID;
return 0;
}
struct signing_key{
unsigned char Private[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES];
unsigned char Public[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES];
rhizome_bid_t Public;
};
/* generate a keypair from a given seed string */
@ -58,7 +58,7 @@ static int generate_keypair(const char *seed, struct signing_key *key)
// The first 256 bits of the hash will be used as the private key of the BID.
bcopy(hash, key->Private, sizeof(key->Private));
if (crypto_sign_compute_public_key(key->Private, key->Public))
if (crypto_sign_compute_public_key(key->Private, key->Public.binary))
return WHY("Could not generate public key");
return 0;
}
@ -71,17 +71,15 @@ int rhizome_get_bundle_from_seed(rhizome_manifest *m, const char *seed)
if (generate_keypair(seed, &key))
return -1;
char *id = alloca_tohex_bid(key.Public);
int ret=rhizome_retrieve_manifest(id, m);
int ret=rhizome_retrieve_manifest(&key.Public, m);
if (ret<0)
return -1;
m->haveSecret=(ret==0)?EXISTING_BUNDLE_ID:NEW_BUNDLE_ID;
bcopy(key.Public, m->cryptoSignPublic, sizeof(m->cryptoSignPublic));
bcopy(key.Private, m->cryptoSignSecret, sizeof(m->cryptoSignSecret));
m->cryptoSignPublic = key.Public;
bcopy(key.Private, m->cryptoSignSecret, sizeof m->cryptoSignSecret);
if (ret>0)
rhizome_manifest_set(m, "id", alloca_tohex_bid(m->cryptoSignPublic));
rhizome_manifest_set(m, "id", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
return ret;
}
@ -93,7 +91,7 @@ int rhizome_get_bundle_from_seed(rhizome_manifest *m, const char *seed)
* @author Paul Gardner-Stephen <paul@servalproject.org>
*/
int rhizome_bk_xor_stream(
const unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES],
const rhizome_bid_t *bidp,
const unsigned char *rs,
const size_t rs_len,
unsigned char *xor_stream,
@ -107,7 +105,7 @@ int rhizome_bk_xor_stream(
int combined_len = rs_len + crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES;
unsigned char buffer[combined_len];
bcopy(&rs[0], &buffer[0], rs_len);
bcopy(&bid[0], &buffer[rs_len], crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES);
bcopy(&bidp->binary[0], &buffer[rs_len], crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES);
unsigned char hash[crypto_hash_sha512_BYTES];
crypto_hash_sha512(hash,buffer,combined_len);
bcopy(hash,xor_stream,xor_stream_byte_count);
@ -121,7 +119,7 @@ int rhizome_bk_xor_stream(
second half of the secret key. The public key is the BID, so this simplifies
the BK<-->SECRET conversion processes. */
int rhizome_bk2secret(rhizome_manifest *m,
const unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES],
const rhizome_bid_t *bidp,
const unsigned char *rs, const size_t rs_len,
/* The BK need only be the length of the secret half of the secret key */
const unsigned char bkin[RHIZOME_BUNDLE_KEY_BYTES],
@ -130,7 +128,7 @@ int rhizome_bk2secret(rhizome_manifest *m,
{
IN();
unsigned char xor_stream[RHIZOME_BUNDLE_KEY_BYTES];
if (rhizome_bk_xor_stream(bid,rs,rs_len,xor_stream,RHIZOME_BUNDLE_KEY_BYTES))
if (rhizome_bk_xor_stream(bidp,rs,rs_len,xor_stream,RHIZOME_BUNDLE_KEY_BYTES))
RETURN(WHY("rhizome_bk_xor_stream() failed"));
int i;
@ -140,16 +138,16 @@ int rhizome_bk2secret(rhizome_manifest *m,
secret[i] = bkin[i] ^ xor_stream[i];
/* Copy BID as public-key part of secret key */
for(;i!=crypto_sign_edwards25519sha512batch_SECRETKEYBYTES;++i)
secret[i]=bid[i-RHIZOME_BUNDLE_KEY_BYTES];
secret[i] = bidp->binary[i - RHIZOME_BUNDLE_KEY_BYTES];
bzero(xor_stream, sizeof xor_stream);
RETURN(rhizome_verify_bundle_privatekey(m,secret,bid));
RETURN(rhizome_verify_bundle_privatekey(m, secret, bidp->binary));
OUT();
}
int rhizome_secret2bk(
const unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES],
const rhizome_bid_t *bidp,
const unsigned char *rs, const size_t rs_len,
/* The BK need only be the length of the secret half of the secret key */
unsigned char bkout[RHIZOME_BUNDLE_KEY_BYTES],
@ -158,7 +156,7 @@ int rhizome_secret2bk(
{
IN();
unsigned char xor_stream[RHIZOME_BUNDLE_KEY_BYTES];
if (rhizome_bk_xor_stream(bid,rs,rs_len,xor_stream,RHIZOME_BUNDLE_KEY_BYTES))
if (rhizome_bk_xor_stream(bidp,rs,rs_len,xor_stream,RHIZOME_BUNDLE_KEY_BYTES))
RETURN(WHY("rhizome_bk_xor_stream() failed"));
int i;
@ -268,8 +266,7 @@ int rhizome_extract_privatekey(rhizome_manifest *m, rhizome_bk_t *bsk)
const unsigned char *rs;
result = rhizome_find_secret(m->author, &rs_len, &rs);
if (result==0)
result = rhizome_bk2secret(m,m->cryptoSignPublic,rs,rs_len,
bkBytes,m->cryptoSignSecret);
result = rhizome_bk2secret(m, &m->cryptoSignPublic, rs, rs_len, bkBytes, m->cryptoSignSecret);
}
if (result == 0 && bsk && !rhizome_is_bk_none(bsk)){
@ -280,10 +277,9 @@ int rhizome_extract_privatekey(rhizome_manifest *m, rhizome_bk_t *bsk)
}
}else if(bsk && !rhizome_is_bk_none(bsk)){
bcopy(m->cryptoSignPublic, &m->cryptoSignSecret[RHIZOME_BUNDLE_KEY_BYTES], sizeof(m->cryptoSignPublic));
bcopy(m->cryptoSignPublic.binary, &m->cryptoSignSecret[RHIZOME_BUNDLE_KEY_BYTES], sizeof m->cryptoSignPublic.binary);
bcopy(bsk, m->cryptoSignSecret, RHIZOME_BUNDLE_KEY_BYTES);
if (rhizome_verify_bundle_privatekey(m,m->cryptoSignSecret,
m->cryptoSignPublic))
if (rhizome_verify_bundle_privatekey(m, m->cryptoSignSecret, m->cryptoSignPublic.binary))
result=5;
else
result=0;
@ -363,8 +359,7 @@ int rhizome_find_bundle_author(rhizome_manifest *m)
RETURN(WHYF("invalid Rhizome Secret: length=%d", rs_len));
const unsigned char *rs = keyring->contexts[cn]->identities[in]->keypairs[rkp]->private_key;
if (!rhizome_bk2secret(m,m->cryptoSignPublic,rs,rs_len,
bkBytes,m->cryptoSignSecret)) {
if (!rhizome_bk2secret(m, &m->cryptoSignPublic, rs, rs_len, bkBytes, m->cryptoSignSecret)) {
m->haveSecret=EXISTING_BUNDLE_ID;
if (memcmp(m->author, authorSid, sizeof m->author)){
@ -406,11 +401,11 @@ int rhizome_verify_bundle_privatekey(rhizome_manifest *m,
crypto_sign_compute_public_key(sk,pk);
for (i = 0;i < 32;++i)
if (pkin[i] != pk[i]) {
if (m&&sk==m->cryptoSignSecret&&pkin==m->cryptoSignPublic)
if (m&&sk==m->cryptoSignSecret&&pkin==m->cryptoSignPublic.binary)
m->haveSecret=0;
RETURN(-1);
}
if (m&&sk==m->cryptoSignSecret&&pkin==m->cryptoSignPublic) {
if (m&&sk==m->cryptoSignSecret&&pkin==m->cryptoSignPublic.binary) {
if (config.debug.rhizome)
DEBUGF("We have the private key for this bundle.");
m->haveSecret=EXISTING_BUNDLE_ID;
@ -426,7 +421,7 @@ int rhizome_sign_hash(rhizome_manifest *m,
if (!m->haveSecret && rhizome_extract_privatekey_required(m, NULL))
RETURN(-1);
int ret=rhizome_sign_hash_with_key(m,m->cryptoSignSecret,m->cryptoSignPublic,out);
int ret=rhizome_sign_hash_with_key(m, m->cryptoSignSecret, m->cryptoSignPublic.binary, out);
RETURN(ret);
OUT();
}
@ -691,10 +686,10 @@ int rhizome_derive_key(rhizome_manifest *m, rhizome_bk_t *bsk)
// journal bundles must always have the same nonce, regardless of version.
// otherwise, generate nonce from version#bundle id#version;
unsigned char raw_nonce[8+8+sizeof(m->cryptoSignPublic)];
unsigned char raw_nonce[8 + 8 + sizeof m->cryptoSignPublic.binary];
write_uint64(&raw_nonce[0], m->journalTail>=0?0:m->version);
bcopy(m->cryptoSignPublic, &raw_nonce[8], sizeof(m->cryptoSignPublic));
write_uint64(&raw_nonce[8+sizeof(m->cryptoSignPublic)], m->journalTail>=0?0:m->version);
bcopy(m->cryptoSignPublic.binary, &raw_nonce[8], sizeof m->cryptoSignPublic.binary);
write_uint64(&raw_nonce[8 + sizeof m->cryptoSignPublic.binary], m->journalTail>=0?0:m->version);
unsigned char hash[crypto_hash_sha512_BYTES];

View File

@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <assert.h>
#include "serval.h"
#include "conf.h"
#include "rhizome.h"
@ -30,9 +31,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
static char rhizome_thisdatastore_path[256];
static int rhizome_delete_manifest_retry(sqlite_retry_state *retry, const char *manifestid);
static int rhizome_delete_manifest_retry(sqlite_retry_state *retry, const rhizome_bid_t *bidp);
static int rhizome_delete_file_retry(sqlite_retry_state *retry, const char *fileid);
static int rhizome_delete_payload_retry(sqlite_retry_state *retry, const char *manifestid);
static int rhizome_delete_payload_retry(sqlite_retry_state *retry, const rhizome_bid_t *bidp);
const char *rhizome_datastore_path()
{
@ -611,9 +612,10 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state
BIND_RETRY(sqlite3_bind_text, sid_hex, SID_STRLEN, SQLITE_TRANSIENT);
}
break;
case BUNDLE_ID_T: {
const char *bid_hex = alloca_tohex(va_arg(ap, const unsigned char *), RHIZOME_MANIFEST_ID_BYTES);
BIND_DEBUG(BUNDLE_ID_T, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", bid_hex, RHIZOME_MANIFEST_ID_STRLEN);
case RHIZOME_BID_T: {
const rhizome_bid_t *bidp = va_arg(ap, const rhizome_bid_t *);
const char *bid_hex = alloca_tohex_rhizome_bid_t(*bidp);
BIND_DEBUG(RHIZOME_BID_T, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", bid_hex, RHIZOME_MANIFEST_ID_STRLEN);
BIND_RETRY(sqlite3_bind_text, bid_hex, RHIZOME_MANIFEST_ID_STRLEN, SQLITE_TRANSIENT);
}
break;
@ -1288,7 +1290,7 @@ int rhizome_store_bundle(rhizome_manifest *m)
const char *service = rhizome_manifest_get(m, "service", NULL, 0);
INFOF("RHIZOME ADD MANIFEST service=%s bid=%s version=%"PRId64,
service ? service : "NULL",
alloca_tohex_sid(m->cryptoSignPublic),
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic),
m->version
);
monitor_announce_bundle(m);
@ -1448,7 +1450,7 @@ int rhizome_list_manifests(struct cli_context *context, const char *service, con
cli_put_long(context, rowid, ":");
cli_put_string(context, blob_service, ":");
cli_put_hexvalue(context, m->cryptoSignPublic, RHIZOME_MANIFEST_ID_BYTES, ":");
cli_put_hexvalue(context, m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary, ":");
cli_put_long(context, blob_version, ":");
cli_put_long(context, blob_date, ":");
cli_put_long(context, q_inserttime, ":");
@ -1613,62 +1615,85 @@ next:
return ret;
}
/* Retrieve a manifest from the database, given its manifest ID.
static int unpack_manifest_row(rhizome_manifest *m, sqlite3_stmt *statement)
{
const char *q_id = (const char *) sqlite3_column_text(statement, 0);
const char *q_blob = (char *) sqlite3_column_blob(statement, 1);
int64_t q_version = sqlite3_column_int64(statement, 2);
int64_t q_inserttime = sqlite3_column_int64(statement, 3);
const char *q_author = (const char *) sqlite3_column_text(statement, 4);
size_t q_blobsize = sqlite3_column_bytes(statement, 1); // must call after sqlite3_column_blob()
if (rhizome_read_manifest_file(m, q_blob, q_blobsize))
return WHYF("Manifest %s exists but is invalid", q_id);
if (q_author) {
if (stowSid(m->author, 0, q_author) == -1)
WARNF("manifest id=%s contains invalid author=%s -- ignored", q_id, alloca_str_toprint(q_author));
}
if (m->version != q_version)
WARNF("Version mismatch, manifest is %"PRId64", database is %"PRId64, m->version, q_version);
m->inserttime = q_inserttime;
return 0;
}
/* Retrieve a manifest from the database, given its Bundle ID.
*
* Returns 0 if manifest is found
* Returns 1 if manifest is not found
* Returns -1 on error
* Caller is responsible for allocating and freeing rhizome_manifest
*/
int rhizome_retrieve_manifest(const char *manifestid, rhizome_manifest *m)
int rhizome_retrieve_manifest(const rhizome_bid_t *bid, rhizome_manifest *m)
{
int ret=0;
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
sqlite3_stmt *statement = sqlite_prepare_bind(&retry,
"SELECT manifest, version, inserttime, author FROM manifests WHERE id like ?",
TEXT_TOUPPER, manifestid,
"SELECT id, manifest, version, inserttime, author FROM manifests WHERE id = ?",
RHIZOME_BID_T, bid,
END);
if (!statement)
return -1;
if (sqlite_step_retry(&retry, statement) == SQLITE_ROW){
const char *manifestblob = (char *) sqlite3_column_blob(statement, 0);
int64_t q_version = sqlite3_column_int64(statement, 1);
int64_t q_inserttime = sqlite3_column_int64(statement, 2);
const char *q_author = (const char *) sqlite3_column_text(statement, 3);
size_t manifestblobsize = sqlite3_column_bytes(statement, 0); // must call after sqlite3_column_blob()
if (rhizome_read_manifest_file(m, manifestblob, manifestblobsize)){
ret=WHYF("Manifest %s exists but is invalid", manifestid);
goto done;
}
if (q_author){
if (stowSid(m->author, 0, q_author) == -1)
WARNF("Manifest %s contains invalid author=%s -- ignored", manifestid, alloca_str_toprint(q_author));
}
if (m->version!=q_version)
WARNF("Version mismatch, manifest is %"PRId64", database is %"PRId64, m->version, q_version);
m->inserttime = q_inserttime;
}else{
INFOF("Manifest %s was not found", manifestid);
ret=1;
}
done:
int ret = 1;
if (sqlite_step_retry(&retry, statement) == SQLITE_ROW)
ret = unpack_manifest_row(m, statement);
else
INFOF("Manifest id=%s not found", alloca_tohex_rhizome_bid_t(*bid));
sqlite3_finalize(statement);
return ret;
return ret;
}
static int rhizome_delete_manifest_retry(sqlite_retry_state *retry, const char *manifestid)
/* Retrieve any manifest from the database whose Bundle ID starts with the given prefix.
*
* Returns 0 if a manifest is found
* Returns 1 if no manifest is found
* Returns -1 on error
* Caller is responsible for allocating and freeing rhizome_manifest
*/
int rhizome_retrieve_manifest_by_prefix(const unsigned char *prefix, unsigned prefix_len, rhizome_manifest *m)
{
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
char like[prefix_len * 2 + 2];
tohex(like, prefix, prefix_len);
like[prefix_len * 2] = '%';
like[prefix_len * 2 + 1] = '\0';
sqlite3_stmt *statement = sqlite_prepare_bind(&retry,
"SELECT id, manifest, version, inserttime, author FROM manifests WHERE id like ?",
TEXT, like,
END);
if (!statement)
return -1;
int ret = 1;
if (sqlite_step_retry(&retry, statement) == SQLITE_ROW)
ret = unpack_manifest_row(m, statement);
else
INFOF("Manifest with id prefix=`%s` not found", like);
sqlite3_finalize(statement);
return ret;
}
static int rhizome_delete_manifest_retry(sqlite_retry_state *retry, const rhizome_bid_t *bidp)
{
sqlite3_stmt *statement = sqlite_prepare_bind(retry,
"DELETE FROM manifests WHERE id = ?",
TEXT_TOUPPER, manifestid,
RHIZOME_BID_T, bidp,
END);
if (!statement)
return -1;
@ -1690,10 +1715,10 @@ static int rhizome_delete_file_retry(sqlite_retry_state *retry, const char *file
return ret == -1 ? -1 : sqlite3_changes(rhizome_db) ? 0 : 1;
}
static int rhizome_delete_payload_retry(sqlite_retry_state *retry, const char *manifestid)
static int rhizome_delete_payload_retry(sqlite_retry_state *retry, const rhizome_bid_t *bidp)
{
strbuf fh = strbuf_alloca(RHIZOME_FILEHASH_STRLEN + 1);
int rows = sqlite_exec_strbuf_retry(retry, fh, "SELECT filehash FROM manifests WHERE id = ?", TEXT_TOUPPER, manifestid, END);
int rows = sqlite_exec_strbuf_retry(retry, fh, "SELECT filehash FROM manifests WHERE id = ?", RHIZOME_BID_T, bidp, END);
if (rows == -1)
return -1;
if (rows && rhizome_delete_file_retry(retry, strbuf_str(fh)) == -1)
@ -1709,12 +1734,12 @@ static int rhizome_delete_payload_retry(sqlite_retry_state *retry, const char *m
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
int rhizome_delete_bundle(const char *manifestid)
int rhizome_delete_bundle(const rhizome_bid_t *bidp)
{
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
if (rhizome_delete_payload_retry(&retry, manifestid) == -1)
if (rhizome_delete_payload_retry(&retry, bidp) == -1)
return -1;
if (rhizome_delete_manifest_retry(&retry, manifestid) == -1)
if (rhizome_delete_manifest_retry(&retry, bidp) == -1)
return -1;
return 0;
}
@ -1728,10 +1753,10 @@ int rhizome_delete_bundle(const char *manifestid)
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
int rhizome_delete_manifest(const char *manifestid)
int rhizome_delete_manifest(const rhizome_bid_t *bidp)
{
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
return rhizome_delete_manifest_retry(&retry, manifestid);
return rhizome_delete_manifest_retry(&retry, bidp);
}
/* Remove a bundle's payload (file) from the database, given its manifest ID, leaving its manifest
@ -1743,10 +1768,10 @@ int rhizome_delete_manifest(const char *manifestid)
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
int rhizome_delete_payload(const char *manifestid)
int rhizome_delete_payload(const rhizome_bid_t *bidp)
{
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
return rhizome_delete_payload_retry(&retry, manifestid);
return rhizome_delete_payload_retry(&retry, bidp);
}
/* Remove a file from the database, given its file hash.

View File

@ -191,22 +191,19 @@ int rhizome_direct_continue_sync_request(rhizome_direct_sync_request *r)
if (r->cursor->size_high>=r->cursor->limit_size_high)
{
DEBUG("Out of bins");
if (memcmp(r->cursor->bid_low,r->cursor->limit_bid_high,
RHIZOME_MANIFEST_ID_BYTES)>=0)
{
DEBUG("out of BIDs");
/* Sync has finished.
The transport may have initiated one or more transfers, so
we cannot declare the sync complete until we know the transport
has finished transferring. */
if (!r->bundle_transfers_in_progress)
{
/* seems that all is done */
DEBUG("All done");
return rhizome_direct_conclude_sync_request(r);
} else
DEBUG("Stuck on in-progress transfers");
} else
if (cmp_rhizome_bid_t(&r->cursor->bid_low, &r->cursor->limit_bid_high) >= 0) {
DEBUG("out of BIDs");
/* Sync has finished.
The transport may have initiated one or more transfers, so
we cannot declare the sync complete until we know the transport
has finished transferring. */
if (!r->bundle_transfers_in_progress) {
/* seems that all is done */
DEBUG("All done");
return rhizome_direct_conclude_sync_request(r);
} else
DEBUG("Stuck on in-progress transfers");
} else
DEBUGF("bid_low<limit_bid_high");
}
@ -411,21 +408,17 @@ rhizome_manifest *rhizome_direct_get_manifest(unsigned char *bid_prefix,int pref
Easiest way is to select with a BID range. We could instead have an extra
database column with the prefix.
*/
assert(prefix_length>=0);
assert(prefix_length<=RHIZOME_MANIFEST_ID_BYTES);
unsigned char low[RHIZOME_MANIFEST_ID_BYTES];
unsigned char high[RHIZOME_MANIFEST_ID_BYTES];
memset(low,0x00,RHIZOME_MANIFEST_ID_BYTES);
memset(high,0xff,RHIZOME_MANIFEST_ID_BYTES);
bcopy(bid_prefix,low,prefix_length);
bcopy(bid_prefix,high,prefix_length);
rhizome_bid_t low = RHIZOME_BID_ZERO;
rhizome_bid_t high = RHIZOME_BID_MAX;
assert(prefix_length >= 0);
assert(prefix_length <= sizeof(rhizome_bid_t));
bcopy(bid_prefix, low.binary, prefix_length);
bcopy(bid_prefix, high.binary, prefix_length);
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
sqlite3_stmt *statement = sqlite_prepare_bind(&retry,
"SELECT manifest, rowid FROM MANIFESTS WHERE id >= ? AND id <= ?",
BUNDLE_ID_T, low,
BUNDLE_ID_T, high,
RHIZOME_BID_T, low,
RHIZOME_BID_T, high,
END);
sqlite3_blob *blob=NULL;
if (sqlite_step_retry(&retry, statement) == SQLITE_ROW)
@ -563,9 +556,8 @@ rhizome_direct_bundle_cursor *rhizome_direct_bundle_iterator(int buffer_size)
void rhizome_direct_bundle_iterator_unlimit(rhizome_direct_bundle_cursor *r)
{
assert(r!=NULL);
r->limit_size_high=1LL<<48LL;
memset(r->limit_bid_high,0xff,RHIZOME_MANIFEST_ID_BYTES);
r->limit_bid_high = RHIZOME_BID_MAX;
return;
}
@ -598,13 +590,13 @@ int rhizome_direct_bundle_iterator_pickle_range(rhizome_direct_bundle_cursor *r,
v=r->start_size_high;
while(v>1) { ltwov++; v=v>>1; }
pickled[0]=ltwov;
for(v=0;v<4;v++) pickled[1+v]=r->start_bid_low[v];
for(v=0;v<4;v++) pickled[1+v]=r->start_bid_low.binary[v];
v=r->size_high;
DEBUGF("pickling size_high=%"PRId64,r->size_high);
ltwov=0;
while(v>1) { ltwov++; v=v>>1; }
pickled[1+4]=ltwov;
for(v=0;v<4;v++) pickled[1+4+1+v]=r->bid_high[v];
for(v=0;v<4;v++) pickled[1+4+1+v]=r->bid_high.binary[v];
return 1+4+1+4;
}
@ -625,13 +617,13 @@ int rhizome_direct_bundle_iterator_unpickle_range(rhizome_direct_bundle_cursor *
r->size_high=1LL<<pickled[0];
r->size_low=(r->size_high/2)+1;
if (r->size_high<=1024) r->size_low=0;
for(v=0;v<4;v++) r->bid_low[v]=pickled[1+v];
for(;v<RHIZOME_MANIFEST_ID_BYTES;v++) r->bid_low[v]=0x00;
r->bid_low = RHIZOME_BID_ZERO;
for (v=0;v<4;v++) r->bid_low.binary[v]=pickled[1+v];
/* Get end of range */
r->limit_size_high=1LL<<pickled[1+4];
for(v=0;v<4;v++) r->limit_bid_high[v]=pickled[1+4+1+v];
for(;v<RHIZOME_MANIFEST_ID_BYTES;v++) r->limit_bid_high[v]=0xff;
r->limit_bid_high = RHIZOME_BID_MAX;
for (v=0;v<4;v++) r->limit_bid_high.binary[v]=pickled[1+4+1+v];
return 0;
}
@ -653,7 +645,7 @@ int rhizome_direct_bundle_iterator_fill(rhizome_direct_bundle_cursor *c,int max_
*/
/* This is the only information required to remember where we started: */
c->start_size_high=c->size_high;
bcopy(c->bid_low,c->start_bid_low,RHIZOME_MANIFEST_ID_BYTES);
c->start_bid_low = c->bid_low;
c->buffer_offset_bytes=1+4+1+4; /* space for pickled cursor range */
/* -1 is magic value for fill right up */
@ -674,17 +666,15 @@ int rhizome_direct_bundle_iterator_fill(rhizome_direct_bundle_cursor *c,int max_
If we are not yet at the bundle data size limit, then any bundle is okay.
If we are at the bundle data size limit, then we need to honour
c->limit_bid_high. */
unsigned char bid_max[RHIZOME_MANIFEST_ID_BYTES];
if (c->size_high==c->limit_size_high)
bcopy(c->limit_bid_high,bid_max,RHIZOME_MANIFEST_ID_BYTES);
rhizome_bid_t bid_max;
if (c->size_high == c->limit_size_high)
bid_max = c->limit_bid_high;
else
memset(bid_max,0xff,RHIZOME_MANIFEST_ID_BYTES);
int stuffed_now=rhizome_direct_get_bars(c->bid_low,c->bid_high,
c->size_low,c->size_high,
bid_max,
&c->buffer[c->buffer_used
+c->buffer_offset_bytes],
bid_max = RHIZOME_BID_MAX;
int stuffed_now=rhizome_direct_get_bars(&c->bid_low, &c->bid_high,
c->size_low, c->size_high,
&bid_max,
&c->buffer[c->buffer_used + c->buffer_offset_bytes],
stuffable);
bundles_stuffed+=stuffed_now;
c->buffer_used+=RHIZOME_BAR_BYTES*stuffed_now;
@ -695,20 +685,19 @@ int rhizome_direct_bundle_iterator_fill(rhizome_direct_bundle_cursor *c,int max_
if (c->size_high<=1024) c->size_low=0;
DEBUGF("size=%"PRId64"..%"PRId64,c->size_low,c->size_high);
/* Record that we covered to the end of that size bin */
memset(c->bid_high,0xff,RHIZOME_MANIFEST_ID_BYTES);
c->bid_high = RHIZOME_BID_MAX;
if (c->size_high>c->limit_size_high)
memset(c->bid_low,0xff,RHIZOME_MANIFEST_ID_BYTES);
c->bid_low = RHIZOME_BID_MAX;
else
memset(c->bid_low,0x00,RHIZOME_MANIFEST_ID_BYTES);
c->bid_low = RHIZOME_BID_ZERO;
} else {
/* Continue from next BID */
bcopy(c->bid_high,c->bid_low,RHIZOME_MANIFEST_ID_BYTES);
c->bid_low = c->bid_high;
int i;
for(i=RHIZOME_BAR_BYTES-1;i>=0;i--)
{
c->bid_low[i]++;
if (c->bid_low[i]) break;
}
for(i=RHIZOME_BAR_BYTES-1;i>=0;i--) {
if (++c->bid_low.binary[i])
break;
}
if (i<0) break;
}
}
@ -742,10 +731,10 @@ void rhizome_direct_bundle_iterator_free(rhizome_direct_bundle_cursor **c)
it is possible to make provably complete comparison of the contents
of the respective rhizome databases.
*/
int rhizome_direct_get_bars(const unsigned char bid_low[RHIZOME_MANIFEST_ID_BYTES],
unsigned char bid_high[RHIZOME_MANIFEST_ID_BYTES],
int rhizome_direct_get_bars(const rhizome_bid_t *bid_low,
rhizome_bid_t *bid_high,
int64_t size_low, int64_t size_high,
const unsigned char bid_max[RHIZOME_MANIFEST_ID_BYTES],
const rhizome_bid_t *bid_max,
unsigned char *bars_out,
int bars_requested)
{
@ -757,8 +746,8 @@ int rhizome_direct_get_bars(const unsigned char bid_low[RHIZOME_MANIFEST_ID_BYTE
" ORDER BY bar LIMIT ?;",
INT64, size_low,
INT64, size_high,
BUNDLE_ID_T, bid_low,
BUNDLE_ID_T, bid_high,
RHIZOME_BID_T, bid_low,
RHIZOME_BID_T, bid_high,
INT, bars_requested,
// The following formulation doesn't remove the weird returning of
// bundles with out of range filesize values
@ -808,9 +797,7 @@ int rhizome_direct_get_bars(const unsigned char bid_low[RHIZOME_MANIFEST_ID_BYTE
/* Remember the BID so that we cant write it into bid_high so that the
caller knows how far we got. */
fromhex(bid_high,
(const char *)sqlite3_column_text(statement, 2),
RHIZOME_MANIFEST_ID_BYTES);
str_to_rhizome_bid_t(bid_high, (const char *)sqlite3_column_text(statement, 2));
bars_written++;
break;
@ -826,4 +813,4 @@ int rhizome_direct_get_bars(const unsigned char bid_low[RHIZOME_MANIFEST_ID_BYTE
return bars_written;
}

View File

@ -1046,10 +1046,10 @@ void rhizome_direct_http_dispatch(rhizome_direct_sync_request *r)
c->size_high,c->limit_size_high);
DEBUGF("c->buffer_size=%d",c->buffer_size);
r->cursor->size_low=c->limit_size_high;
bcopy(c->limit_bid_high,r->cursor->bid_low,4);
/* Set tail of BID to all high, as we assume the far end has returned all
BIDs with the specified prefix. */
memset(&r->cursor->bid_low[4],0xff,RHIZOME_MANIFEST_ID_BYTES);
r->cursor->bid_low = RHIZOME_BID_MAX;
bcopy(c->limit_bid_high.binary, r->cursor->bid_low.binary, 4);
}
rhizome_direct_bundle_iterator_free(&c);
#endif

View File

@ -76,7 +76,7 @@ struct rhizome_fetch_slot {
int manifest_bytes;
/* MDP transport specific elements */
unsigned char bid[RHIZOME_MANIFEST_ID_BYTES];
rhizome_bid_t bid;
int64_t bidVersion;
int prefix_length;
int mdpIdleTimeout;
@ -263,7 +263,7 @@ static struct rhizome_fetch_slot *fetch_search_slot(const unsigned char *id, int
struct rhizome_fetch_queue *q = &rhizome_fetch_queues[i];
if (q->active.state != RHIZOME_FETCH_FREE &&
memcmp(id, q->active.manifest->cryptoSignPublic, prefix_length) == 0)
memcmp(id, q->active.manifest->cryptoSignPublic.binary, prefix_length) == 0)
return &q->active;
}
return NULL;
@ -279,7 +279,7 @@ static struct rhizome_fetch_candidate *fetch_search_candidate(const unsigned cha
struct rhizome_fetch_candidate *c = &q->candidate_queue[j];
if (!c->manifest)
continue;
if (memcmp(c->manifest->cryptoSignPublic, id, prefix_length))
if (memcmp(c->manifest->cryptoSignPublic.binary, id, prefix_length))
continue;
return c;
}
@ -478,8 +478,8 @@ static int schedule_fetch(struct rhizome_fetch_slot *slot)
slot->write_state.blob_rowid=-1;
if (slot->manifest) {
bcopy(slot->manifest->cryptoSignPublic,slot->bid,RHIZOME_MANIFEST_ID_BYTES);
slot->prefix_length=RHIZOME_MANIFEST_ID_BYTES;
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. */
@ -493,8 +493,7 @@ static int schedule_fetch(struct rhizome_fetch_slot *slot)
// if we're fetching a journal bundle, work out how many bytes we have of a previous version
// and therefore what range of bytes we should ask for
slot->previous = rhizome_new_manifest();
const char *id = rhizome_manifest_get(slot->manifest, "id", NULL, 0);
if (rhizome_retrieve_manifest(id, slot->previous)){
if (rhizome_retrieve_manifest(&slot->manifest->cryptoSignPublic, slot->previous)){
rhizome_manifest_free(slot->previous);
slot->previous=NULL;
@ -519,7 +518,7 @@ static int schedule_fetch(struct rhizome_fetch_slot *slot)
RETURN(-1);
} else {
strbuf r = strbuf_local(slot->request, sizeof slot->request);
strbuf_sprintf(r, "GET /rhizome/manifestbyprefix/%s HTTP/1.0\r\n\r\n", alloca_tohex(slot->bid, slot->prefix_length));
strbuf_sprintf(r, "GET /rhizome/manifestbyprefix/%s HTTP/1.0\r\n\r\n", alloca_tohex(slot->bid.binary, slot->prefix_length));
if (strbuf_overrun(r))
RETURN(WHY("request overrun"));
slot->request_len = strbuf_len(r);
@ -631,8 +630,6 @@ rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m, const struct
if (slot->state != RHIZOME_FETCH_FREE)
RETURN(SLOTBUSY);
const char *bid = alloca_tohex_bid(m->cryptoSignPublic);
/* Do the quick rejection tests first, before the more expensive ones,
like querying the database for manifests.
@ -650,7 +647,7 @@ rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m, const struct
if (config.debug.rhizome_rx)
DEBUGF("Fetching bundle slot=%d bid=%s version=%"PRId64" size=%"PRId64" peerip=%s",
slotno(slot),
bid,
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic),
m->version,
m->fileLength,
alloca_sockaddr(peerip, sizeof(struct sockaddr_in))
@ -671,7 +668,7 @@ rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m, const struct
* being published faster than we can fetch them.
*/
{
struct rhizome_fetch_slot *as = fetch_search_slot(m->cryptoSignPublic, RHIZOME_MANIFEST_ID_BYTES);
struct rhizome_fetch_slot *as = fetch_search_slot(m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary);
if (as){
const rhizome_manifest *am = as->manifest;
if (am->version < m->version) {
@ -746,7 +743,7 @@ rhizome_fetch_request_manifest_by_prefix(const struct sockaddr_in *peerip,
slot->peer_ipandport = *peerip;
slot->manifest = NULL;
bcopy(peersid,slot->peer_sid,SID_SIZE);
bcopy(prefix,slot->bid,prefix_length);
bcopy(prefix, slot->bid.binary, prefix_length);
slot->prefix_length=prefix_length;
/* Don't stream into a file blob in the database, because it is a manifest.
@ -860,7 +857,8 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
int priority=100; /* normal priority */
if (config.debug.rhizome_rx)
DEBUGF("Considering import bid=%s version=%"PRId64" size=%"PRId64" priority=%d:", alloca_tohex_bid(m->cryptoSignPublic), m->version, m->fileLength, priority);
DEBUGF("Considering import bid=%s version=%"PRId64" size=%"PRId64" priority=%d:",
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version, m->fileLength, priority);
if (!rhizome_is_manifest_interesting(m)) {
if (config.debug.rhizome_rx)
@ -871,7 +869,7 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
if (config.debug.rhizome_rx) {
int64_t stored_version;
if (sqlite_exec_int64(&stored_version, "SELECT version FROM MANIFESTS WHERE id = ?", BUNDLE_ID_T, m->cryptoSignPublic, END) > 0)
if (sqlite_exec_int64(&stored_version, "SELECT version FROM MANIFESTS WHERE id = ?", RHIZOME_BID_T, m->cryptoSignPublic, END) > 0)
DEBUGF(" is new (have version %"PRId64")", stored_version);
}
@ -879,8 +877,7 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
if (rhizome_manifest_verify(m) != 0) {
WHY("Error verifying manifest when considering for import");
/* Don't waste time looking at this manifest again for a while */
rhizome_queue_ignore_manifest(m->cryptoSignPublic,
crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES, 60000);
rhizome_queue_ignore_manifest(m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary, 60000);
rhizome_manifest_free(m);
RETURN(-1);
}
@ -907,7 +904,7 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
for (j = 0; j < q->candidate_queue_size; ) {
struct rhizome_fetch_candidate *c = &q->candidate_queue[j];
if (c->manifest) {
if (memcmp(m->cryptoSignPublic, c->manifest->cryptoSignPublic, RHIZOME_MANIFEST_ID_BYTES) == 0) {
if (cmp_rhizome_bid_t(&m->cryptoSignPublic, &c->manifest->cryptoSignPublic) == 0) {
if (c->manifest->version >= m->version) {
rhizome_manifest_free(m);
RETURN(0);
@ -915,8 +912,7 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
if (!m->selfSigned && rhizome_manifest_verify(m)) {
WHY("Error verifying manifest when considering queuing for import");
/* Don't waste time looking at this manifest again for a while */
rhizome_queue_ignore_manifest(m->cryptoSignPublic,
crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES, 60000);
rhizome_queue_ignore_manifest(m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary, 60000);
rhizome_manifest_free(m);
RETURN(-1);
}
@ -942,8 +938,7 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
if (!m->selfSigned && rhizome_manifest_verify(m)) {
WHY("Error verifying manifest when considering queuing for import");
/* Don't waste time looking at this manifest again for a while */
rhizome_queue_ignore_manifest(m->cryptoSignPublic,
crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES, 60000);
rhizome_queue_ignore_manifest(m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary, 60000);
rhizome_manifest_free(m);
RETURN(-1);
}
@ -965,7 +960,7 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
break;
DEBUGF("%d:%d manifest=%p bid=%s priority=%d size=%lld", i, j,
c->manifest,
alloca_tohex_bid(c->manifest->cryptoSignPublic),
alloca_tohex_rhizome_bid_t(c->manifest->cryptoSignPublic),
c->priority,
(long long) c->manifest->fileLength
);
@ -1079,8 +1074,8 @@ static int rhizome_fetch_mdp_requestblocks(struct rhizome_fetch_slot *slot)
mdp.packetTypeAndFlags=MDP_TX;
mdp.out.queue=OQ_ORDINARY;
mdp.out.payload_length=RHIZOME_MANIFEST_ID_BYTES+8+8+4+2;
bcopy(slot->bid,&mdp.out.payload[0],RHIZOME_MANIFEST_ID_BYTES);
mdp.out.payload_length= sizeof slot->bid.binary + 8 + 8 + 4 + 2;
bcopy(slot->bid.binary, &mdp.out.payload[0], sizeof slot->bid.binary);
uint32_t bitmap=0;
int requests=32;
@ -1098,11 +1093,11 @@ static int rhizome_fetch_mdp_requestblocks(struct rhizome_fetch_slot *slot)
}
offset+=slot->mdpRXBlockLength;
}
write_uint64(&mdp.out.payload[RHIZOME_MANIFEST_ID_BYTES], slot->bidVersion);
write_uint64(&mdp.out.payload[RHIZOME_MANIFEST_ID_BYTES+8], slot->write_state.file_offset);
write_uint32(&mdp.out.payload[RHIZOME_MANIFEST_ID_BYTES+8+8], bitmap);
write_uint16(&mdp.out.payload[RHIZOME_MANIFEST_ID_BYTES+8+8+4], slot->mdpRXBlockLength);
write_uint64(&mdp.out.payload[sizeof slot->bid.binary], slot->bidVersion);
write_uint64(&mdp.out.payload[sizeof slot->bid.binary + 8], slot->write_state.file_offset);
write_uint32(&mdp.out.payload[sizeof slot->bid.binary + 8 + 8], bitmap);
write_uint16(&mdp.out.payload[sizeof slot->bid.binary + 8 + 8 + 4], slot->mdpRXBlockLength);
if (config.debug.rhizome_tx)
DEBUGF("src sid=%s, dst sid=%s, mdpRXWindowStart=0x%"PRIx64", slot->bidVersion=0x%"PRIx64,
@ -1296,7 +1291,7 @@ int rhizome_write_complete(struct rhizome_fetch_slot *slot)
rhizome_manifest_free(m);
} else {
if (config.debug.rhizome_rx){
DEBUGF("All looks good for importing manifest id=%s", alloca_tohex_bid(m->cryptoSignPublic));
DEBUGF("All looks good for importing manifest id=%s", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
dump("slot->peerip",&slot->peer_ipandport,sizeof(slot->peer_ipandport));
dump("slot->peersid",&slot->peer_sid,sizeof(slot->peer_sid));
}
@ -1354,7 +1349,7 @@ int rhizome_write_content(struct rhizome_fetch_slot *slot, unsigned char *buffer
OUT();
}
int rhizome_received_content(unsigned char *bidprefix,
int rhizome_received_content(const unsigned char *bidprefix,
uint64_t version, uint64_t offset,
int count,unsigned char *bytes,int type)
{

View File

@ -497,13 +497,13 @@ static int manifest_by_prefix_page(rhizome_http_request *r, const char *remainde
{
if (!is_rhizome_http_enabled())
return 1;
char id_hex[RHIZOME_MANIFEST_ID_STRLEN+1];
strncpy(id_hex, remainder, sizeof id_hex -1);
str_toupper_inplace(id_hex);
strcat(id_hex, "%");
rhizome_bid_t prefix;
const char *endp = NULL;
unsigned prefix_len = strn_fromhex(prefix.binary, sizeof prefix.binary, remainder, &endp);
if (endp == NULL || *endp != '\0' || prefix_len < 1)
return 1; // not found
rhizome_manifest *m = rhizome_new_manifest();
int ret = rhizome_retrieve_manifest(id_hex, m);
int ret = rhizome_retrieve_manifest_by_prefix(prefix.binary, prefix_len, m);
if (ret==0)
rhizome_server_http_response(r, 200, "application/binary", (const char *)m->manifestdata, m->manifest_all_bytes);
rhizome_manifest_free(m);

View File

@ -84,7 +84,7 @@ int rhizome_manifest_to_bar(rhizome_manifest *m,unsigned char *bar)
/* Manifest prefix */
for(i=0;i<RHIZOME_BAR_PREFIX_BYTES;i++)
bar[RHIZOME_BAR_PREFIX_OFFSET+i]=m->cryptoSignPublic[i];
bar[RHIZOME_BAR_PREFIX_OFFSET+i]=m->cryptoSignPublic.binary[i];
/* file length */
bar[RHIZOME_BAR_FILESIZE_OFFSET]=log2ll(m->fileLength);
/* Version */
@ -268,7 +268,7 @@ int rhizome_advertise_manifest(struct subscriber *dest, rhizome_manifest *m){
if (overlay_payload_enqueue(frame)) goto error;
if (config.debug.rhizome_ads)
DEBUGF("Advertising manifest %s %"PRId64" to %s",
alloca_tohex_bid(m->cryptoSignPublic), m->version, dest?alloca_tohex_sid(dest->sid):"broadcast");
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version, dest?alloca_tohex_sid(dest->sid):"broadcast");
return 0;
error:
@ -339,7 +339,7 @@ int overlay_rhizome_saw_advertisements(int i, struct decode_context *context, st
(that is the only use of this */
if (config.debug.rhizome_ads){
long long version = rhizome_manifest_get_ll(m, "version");
DEBUGF("manifest id=%s version=%lld", alloca_tohex_bid(m->cryptoSignPublic), version);
DEBUGF("manifest id=%s version=%lld", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), version);
}
/* Crude signature presence test */
@ -352,10 +352,10 @@ int overlay_rhizome_saw_advertisements(int i, struct decode_context *context, st
goto next;
}
if (rhizome_ignore_manifest_check(m->cryptoSignPublic, RHIZOME_MANIFEST_ID_BYTES)){
if (rhizome_ignore_manifest_check(m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary)){
/* Ignoring manifest that has caused us problems recently */
if (config.debug.rhizome_ads)
DEBUGF("Ignoring manifest with errors: %s", alloca_tohex_bid(m->cryptoSignPublic));
DEBUGF("Ignoring manifest with errors: %s", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
goto next;
}
@ -364,14 +364,13 @@ int overlay_rhizome_saw_advertisements(int i, struct decode_context *context, st
DEBUG("Unverified manifest has errors - so not processing any further.");
/* Don't waste any time on this manifest in future attempts for at least
a minute. */
rhizome_queue_ignore_manifest(m->cryptoSignPublic,
RHIZOME_MANIFEST_ID_BYTES, 60000);
rhizome_queue_ignore_manifest(m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary, 60000);
goto next;
}
/* Manifest is okay, so see if it is worth storing */
// are we already fetching this bundle [or later]?
rhizome_manifest *mf=rhizome_fetch_search(m->cryptoSignPublic, RHIZOME_MANIFEST_ID_BYTES);
rhizome_manifest *mf=rhizome_fetch_search(m->cryptoSignPublic.binary, sizeof m->cryptoSignPublic.binary);
if (mf && mf->version >= m->version)
goto next;

View File

@ -640,7 +640,7 @@ static int rhizome_write_derive_key(rhizome_manifest *m, rhizome_bk_t *bsk, stru
return -1;
if (config.debug.rhizome)
DEBUGF("Encrypting payload contents for %s, %"PRId64, alloca_tohex_bid(m->cryptoSignPublic), m->version);
DEBUGF("Encrypting payload contents for %s, %"PRId64, alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version);
write->crypt=1;
if (m->journalTail>0)
@ -882,18 +882,18 @@ int rhizome_read_close(struct rhizome_read *read)
struct cache_entry{
struct cache_entry *_left;
struct cache_entry *_right;
unsigned char bundle_id[RHIZOME_MANIFEST_ID_BYTES];
rhizome_bid_t bundle_id;
uint64_t version;
struct rhizome_read read_state;
time_ms_t expires;
};
struct cache_entry *root;
static struct cache_entry ** find_entry_location(struct cache_entry **ptr, unsigned char *bundle_id, uint64_t version)
static struct cache_entry ** find_entry_location(struct cache_entry **ptr, const rhizome_bid_t *bundle_id, uint64_t version)
{
while(*ptr){
struct cache_entry *entry = *ptr;
int cmp = memcmp(bundle_id, entry->bundle_id, sizeof entry->bundle_id);
int cmp = cmp_rhizome_bid_t(bundle_id, &entry->bundle_id);
if (cmp==0){
if (entry->version==version)
break;
@ -931,7 +931,7 @@ static time_ms_t close_entries(struct cache_entry **entry, time_ms_t timeout)
// re-add both children to the tree
*entry=left;
if (right){
entry = find_entry_location(entry, right->bundle_id, right->version);
entry = find_entry_location(entry, &right->bundle_id, right->version);
*entry=right;
}
}else{
@ -980,16 +980,16 @@ int rhizome_cache_count()
}
// read a block of data, caching meta data for reuse
int rhizome_read_cached(unsigned char *bundle_id, uint64_t version, time_ms_t timeout,
int rhizome_read_cached(const rhizome_bid_t *bidp, uint64_t version, time_ms_t timeout,
uint64_t fileOffset, unsigned char *buffer, int length)
{
// look for a cached entry
struct cache_entry **ptr = find_entry_location(&root, bundle_id, version);
struct cache_entry **ptr = find_entry_location(&root, bidp, version);
struct cache_entry *entry = *ptr;
// if we don't have one yet, create one and open it
if (!entry){
char *id_str = alloca_tohex_bid(bundle_id);
char *id_str = alloca_tohex_rhizome_bid_t(*bidp);
char filehash[SHA512_DIGEST_STRING_LENGTH];
if (rhizome_database_filehash_from_id(id_str, version, filehash)<=0)
@ -1001,7 +1001,7 @@ int rhizome_read_cached(unsigned char *bundle_id, uint64_t version, time_ms_t ti
free(entry);
return WHYF("Payload %s not found", filehash);
}
bcopy(bundle_id, entry->bundle_id, sizeof(entry->bundle_id));
entry->bundle_id = *bidp;
entry->version = version;
*ptr = entry;
}
@ -1065,7 +1065,7 @@ static int read_derive_key(rhizome_manifest *m, rhizome_bk_t *bsk, struct rhizom
return WHY("Unable to decrypt bundle, valid key not found");
}
if (config.debug.rhizome)
DEBUGF("Decrypting payload contents for %s, %"PRId64, alloca_tohex_bid(m->cryptoSignPublic), m->version);
DEBUGF("Decrypting payload contents for %s, %"PRId64, alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version);
if (m->journalTail>0)
read_state->tail = m->journalTail;