Skip to content

Commit

Permalink
meshms.h
Browse files Browse the repository at this point in the history
Rename exposed MeshMS types and functions by adding "meshms_" prefix

Check binary tree integrity during meshms_free_conversations()
  • Loading branch information
quixotique committed Jan 22, 2014
1 parent e3e3e1e commit cb420c6
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 81 deletions.
1 change: 1 addition & 0 deletions headerfiles.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ HDRS= fifo.h \
overlay_interface.h \
rhizome.h \
rhizome_http.h \
meshms.h \
serval.h \
keyring.h \
socket.h \
Expand Down
126 changes: 45 additions & 81 deletions meshms.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <assert.h>
#include "serval.h"
#include "rhizome.h"
#include "meshms.h"
#include "log.h"
#include "conf.h"
#include "crypto.h"
Expand All @@ -31,45 +32,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define MESHMS_BLOCK_TYPE_MESSAGE 0x02
#define MESHMS_BLOCK_TYPE_BID_REFERENCE 0x03

// the manifest details for one half of a conversation
struct ply {
rhizome_bid_t bundle_id;
uint64_t version;
uint64_t tail;
uint64_t size;
};

struct conversations {
// binary tree
struct conversations *_left;
struct conversations *_right;
// keeping a pointer to parent node here means the traversal iterator does not need a stack, so
// there is no fixed limit on the tree depth
struct conversations *_parent;

// who are we talking to?
sid_t them;

char found_my_ply;
struct ply my_ply;

char found_their_ply;
struct ply their_ply;

// what is the offset of their last message
uint64_t their_last_message;
// what is the last message we marked as read
uint64_t read_offset;
// our cached value for the last known size of their ply
uint64_t their_size;
};

struct conversation_iterator {
struct conversations *current;
};

// cursor state for reading one half of a conversation
struct ply_read{
struct ply_read {
// rhizome payload
struct rhizome_read read;
// block buffer
Expand All @@ -84,15 +48,15 @@ struct ply_read{
unsigned char *buffer;
};

static int meshms_conversations_list(const sid_t *my_sid, const sid_t *their_sid, struct conversations **conv);

static void free_conversations(struct conversations *conv)
void meshms_free_conversations(struct meshms_conversations *conv)
{
if (!conv)
return;
free_conversations(conv->_left);
free_conversations(conv->_right);
free(conv);
if (conv) {
if (conv->_parent && conv != conv->_parent->_left && conv != conv->_parent->_right)
WHYF("deformed MeshMS conversation tree");
meshms_free_conversations(conv->_left);
meshms_free_conversations(conv->_right);
free(conv);
}
}

static int get_my_conversation_bundle(const sid_t *my_sidp, rhizome_manifest *m)
Expand All @@ -101,7 +65,7 @@ static int get_my_conversation_bundle(const sid_t *my_sidp, rhizome_manifest *m)
unsigned cn=0, in=0, kp=0;
if (!keyring_find_sid(keyring,&cn,&in,&kp,my_sidp))
return WHYF("SID was not found in keyring: %s", alloca_tohex_sid_t(*my_sidp));

char seed[1024];
snprintf(seed, sizeof(seed),
"incorrection%sconcentrativeness",
Expand Down Expand Up @@ -135,10 +99,10 @@ static int get_my_conversation_bundle(const sid_t *my_sidp, rhizome_manifest *m)
return 0;
}

static struct conversations *add_conv(struct conversations **conv, const sid_t *them)
static struct meshms_conversations *add_conv(struct meshms_conversations **conv, const sid_t *them)
{
struct conversations **ptr = conv;
struct conversations *parent = NULL;
struct meshms_conversations **ptr = conv;
struct meshms_conversations *parent = NULL;
while (*ptr) {
int cmp = cmp_sid_t(&(*ptr)->them, them);
if (cmp == 0)
Expand All @@ -150,7 +114,7 @@ static struct conversations *add_conv(struct conversations **conv, const sid_t *
ptr = &(*ptr)->_right;
}
if (!*ptr){
*ptr = emalloc_zero(sizeof(struct conversations));
*ptr = emalloc_zero(sizeof(struct meshms_conversations));
(*ptr)->_parent = parent;
if (*ptr)
(*ptr)->them = *them;
Expand All @@ -160,7 +124,7 @@ static struct conversations *add_conv(struct conversations **conv, const sid_t *

// find matching conversations
// if their_sid == my_sid, return all conversations with any recipient
static int get_database_conversations(const sid_t *my_sid, const sid_t *their_sid, struct conversations **conv)
static int get_database_conversations(const sid_t *my_sid, const sid_t *their_sid, struct meshms_conversations **conv)
{
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
sqlite3_stmt *statement = sqlite_prepare_bind(&retry,
Expand Down Expand Up @@ -208,10 +172,10 @@ static int get_database_conversations(const sid_t *my_sid, const sid_t *their_si
continue;
}
}
struct conversations *ptr = add_conv(conv, &their_sid);
struct meshms_conversations *ptr = add_conv(conv, &their_sid);
if (!ptr)
break;
struct ply *p;
struct meshms_ply *p;
if (them==sender){
ptr->found_their_ply=1;
p=&ptr->their_ply;
Expand All @@ -228,17 +192,17 @@ static int get_database_conversations(const sid_t *my_sid, const sid_t *their_si
return 0;
}

static struct conversations * find_or_create_conv(const sid_t *my_sid, const sid_t *their_sid)
static struct meshms_conversations * find_or_create_conv(const sid_t *my_sid, const sid_t *their_sid)
{
struct conversations *conv=NULL;
struct meshms_conversations *conv=NULL;
if (meshms_conversations_list(my_sid, their_sid, &conv))
return NULL;
if (!conv && (conv = emalloc_zero(sizeof(struct conversations))))
if (!conv && (conv = emalloc_zero(sizeof(struct meshms_conversations))))
conv->them = *their_sid;
return conv;
}

static int create_ply(const sid_t *my_sid, struct conversations *conv, rhizome_manifest *m)
static int create_ply(const sid_t *my_sid, struct meshms_conversations *conv, rhizome_manifest *m)
{
if (config.debug.meshms)
DEBUGF("Creating ply for my_sid=%s them=%s",
Expand Down Expand Up @@ -355,7 +319,7 @@ static int ply_find_next(struct ply_read *ply, char type){
}
}

static int append_meshms_buffer(const sid_t *my_sid, struct conversations *conv, unsigned char *buffer, int len)
static int append_meshms_buffer(const sid_t *my_sid, struct meshms_conversations *conv, unsigned char *buffer, int len)
{
int ret=-1;
rhizome_manifest *mout = NULL;
Expand Down Expand Up @@ -416,7 +380,7 @@ static int append_meshms_buffer(const sid_t *my_sid, struct conversations *conv,

// update if any conversations are unread or need to be acked.
// return -1 for failure, 1 if the conversation index needs to be saved.
static int update_conversation(const sid_t *my_sid, struct conversations *conv)
static int update_conversation(const sid_t *my_sid, struct meshms_conversations *conv)
{
if (config.debug.meshms)
DEBUG("Checking if conversation needs to be acked");
Expand Down Expand Up @@ -521,7 +485,7 @@ static int update_conversation(const sid_t *my_sid, struct conversations *conv)
}

// update conversations, and return 1 if the conversation index should be saved
static int update_conversations(const sid_t *my_sid, struct conversations *conv)
static int update_conversations(const sid_t *my_sid, struct meshms_conversations *conv)
{
if (!conv)
return 0;
Expand All @@ -542,7 +506,7 @@ static int update_conversations(const sid_t *my_sid, struct conversations *conv)

// read our cached conversation list from our rhizome payload
// if we can't load the existing data correctly, just ignore it.
static int read_known_conversations(rhizome_manifest *m, const sid_t *their_sid, struct conversations **conv)
static int read_known_conversations(rhizome_manifest *m, const sid_t *their_sid, struct meshms_conversations **conv)
{
if (m->haveSecret==NEW_BUNDLE_ID)
return 0;
Expand Down Expand Up @@ -575,7 +539,7 @@ static int read_known_conversations(rhizome_manifest *m, const sid_t *their_sid,
DEBUGF("Reading existing conversation for %s", alloca_tohex_sid_t(sid));
if (their_sid && cmp_sid_t(&sid, their_sid) != 0)
continue;
struct conversations *ptr = add_conv(conv, &sid);
struct meshms_conversations *ptr = add_conv(conv, &sid);
if (!ptr)
goto end;
unsigned char details[8*3];
Expand Down Expand Up @@ -604,7 +568,7 @@ static int read_known_conversations(rhizome_manifest *m, const sid_t *their_sid,
return ret;
}

static ssize_t write_conversation(struct rhizome_write *write, struct conversations *conv)
static ssize_t write_conversation(struct rhizome_write *write, struct meshms_conversations *conv)
{
size_t len=0;
if (!conv)
Expand Down Expand Up @@ -646,7 +610,7 @@ static ssize_t write_conversation(struct rhizome_write *write, struct conversati
return len;
}

static int write_known_conversations(rhizome_manifest *m, struct conversations *conv)
static int write_known_conversations(rhizome_manifest *m, struct meshms_conversations *conv)
{
rhizome_manifest *mout=NULL;

Expand Down Expand Up @@ -713,7 +677,7 @@ static int write_known_conversations(rhizome_manifest *m, struct conversations *
}

// read information about existing conversations from a rhizome payload
static int meshms_conversations_list(const sid_t *my_sid, const sid_t *their_sid, struct conversations **conv)
int meshms_conversations_list(const sid_t *my_sid, const sid_t *their_sid, struct meshms_conversations **conv)
{
int ret=-1;
rhizome_manifest *m = rhizome_new_manifest();
Expand Down Expand Up @@ -744,7 +708,7 @@ static int meshms_conversations_list(const sid_t *my_sid, const sid_t *their_sid
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
static void conversation_iterator_start(struct conversation_iterator *it, struct conversations *conv)
void meshms_conversation_iterator_start(struct meshms_conversation_iterator *it, struct meshms_conversations *conv)
{
assert(conv->_parent == NULL); // can only iterate over whole tree
it->current = conv;
Expand All @@ -757,7 +721,7 @@ static void conversation_iterator_start(struct conversation_iterator *it, struct
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
static void conversation_iterator_advance(struct conversation_iterator *it)
void meshms_conversation_iterator_advance(struct meshms_conversation_iterator *it)
{
assert(it->current != NULL); // do not call on a finished iterator
if (it->current->_right) {
Expand All @@ -767,7 +731,7 @@ static void conversation_iterator_advance(struct conversation_iterator *it)
}
else {
while (1) {
struct conversations *conv = it->current;
struct meshms_conversations *conv = it->current;
it->current = it->current->_parent;
if (it->current == NULL || conv == it->current->_left)
break;
Expand Down Expand Up @@ -800,7 +764,7 @@ int app_meshms_conversations(const struct cli_parsed *parsed, struct cli_context
return -1;
}

struct conversations *conv=NULL;
struct meshms_conversations *conv=NULL;
if (meshms_conversations_list(&sid, NULL, &conv)){
keyring_free(keyring);
return -1;
Expand All @@ -812,10 +776,10 @@ int app_meshms_conversations(const struct cli_parsed *parsed, struct cli_context
cli_columns(context, 5, names);
int rows = 0;
if (conv) {
struct conversation_iterator it;
for (conversation_iterator_start(&it, conv);
struct meshms_conversation_iterator it;
for (meshms_conversation_iterator_start(&it, conv);
it.current && (count < 0 || rows < offset + count);
conversation_iterator_advance(&it), ++rows
meshms_conversation_iterator_advance(&it), ++rows
) {
if (rows >= offset) {
cli_put_long(context, rows, ":");
Expand All @@ -828,7 +792,7 @@ int app_meshms_conversations(const struct cli_parsed *parsed, struct cli_context
}
cli_row_count(context, rows);

free_conversations(conv);
meshms_free_conversations(conv);
keyring_free(keyring);
return 0;
}
Expand All @@ -855,7 +819,7 @@ int app_meshms_send_message(const struct cli_parsed *parsed, struct cli_context
return WHY("invalid sender SID");
if (str_to_sid_t(&their_sid, their_sidhex) == -1)
return WHY("invalid recipient SID");
struct conversations *conv = find_or_create_conv(&my_sid, &their_sid);
struct meshms_conversations *conv = find_or_create_conv(&my_sid, &their_sid);
if (!conv) {
keyring_free(keyring);
return -1;
Expand All @@ -869,7 +833,7 @@ int app_meshms_send_message(const struct cli_parsed *parsed, struct cli_context
message_len+=append_footer(buffer+message_len, MESHMS_BLOCK_TYPE_MESSAGE, message_len);
int ret = append_meshms_buffer(&my_sid, conv, buffer, message_len);

free_conversations(conv);
meshms_free_conversations(conv);
keyring_free(keyring);
return ret;
}
Expand Down Expand Up @@ -898,7 +862,7 @@ int app_meshms_list_messages(const struct cli_parsed *parsed, struct cli_context
keyring_free(keyring);
return WHY("invalid recipient SID");
}
struct conversations *conv=find_or_create_conv(&my_sid, &their_sid);
struct meshms_conversations *conv=find_or_create_conv(&my_sid, &their_sid);
if (!conv){
keyring_free(keyring);
return -1;
Expand Down Expand Up @@ -1031,12 +995,12 @@ int app_meshms_list_messages(const struct cli_parsed *parsed, struct cli_context
rhizome_manifest_free(m_theirs);
ply_read_close(&read_theirs);
}
free_conversations(conv);
meshms_free_conversations(conv);
keyring_free(keyring);
return ret;
}

static int mark_read(struct conversations *conv, const sid_t *their_sid, const char *offset_str)
static int mark_read(struct meshms_conversations *conv, const sid_t *their_sid, const char *offset_str)
{
int ret=0;
if (conv){
Expand Down Expand Up @@ -1091,7 +1055,7 @@ int app_meshms_mark_read(const struct cli_parsed *parsed, struct cli_context *UN
fromhex(their_sid.binary, their_sidhex, sizeof(their_sid.binary));

int ret=-1;
struct conversations *conv=NULL;
struct meshms_conversations *conv=NULL;
rhizome_manifest *m = rhizome_new_manifest();
if (!m)
goto end;
Expand Down Expand Up @@ -1121,7 +1085,7 @@ int app_meshms_mark_read(const struct cli_parsed *parsed, struct cli_context *UN
end:
if (m)
rhizome_manifest_free(m);
free_conversations(conv);
meshms_free_conversations(conv);
keyring_free(keyring);
return ret;
}
Loading

0 comments on commit cb420c6

Please sign in to comment.