diff -r 9a8be24c5037 -r 1296a0283271 servlib/bundling/BPQBlock.cc --- a/servlib/bundling/BPQBlock.cc Tue Oct 18 11:52:07 2011 +0100 +++ b/servlib/bundling/BPQBlock.cc Mon Oct 24 18:28:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright 2006 Intel Corporation + * Copyright 2010-2011 Trinity College Dublin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,50 +25,38 @@ namespace dtn { -// Setup our logging information -static const char* LOG = "/dtn/bundle/extblock/bpq"; - -BPQBlock::BPQBlock(Bundle* bundle) +BPQBlock::BPQBlock(const Bundle* bundle) + : Logger("BPQBlock", "/dtn/bundle/bpq") { - log_info_p(LOG, "BPQBlock::constructor()"); + log_info("constructor()"); if( bundle->recv_blocks(). has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) { - log_debug_p(LOG, "BPQBlock found in Recv Block Vec => created remotly"); + log_debug("BPQBlock found in Recv Block Vec => created remotely"); initialise( const_cast (bundle->recv_blocks(). - find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) ); + find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)), + true, bundle); - } else if( bundle->api_blocks()-> + } else if( const_cast(bundle)->api_blocks()-> has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) { - log_debug_p(LOG, "BPQBlock found in API Block Vec => created locally"); - initialise( const_cast (bundle->api_blocks()-> - find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) ); + log_debug("BPQBlock found in API Block Vec => created locally"); + initialise( const_cast (const_cast(bundle)->api_blocks()-> + find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)), + true, bundle); } else { - log_err_p(LOG, "BPQ Block not found in bundle"); + log_err("BPQ Block not found in bundle"); } - log_info_p(LOG, "leaving constructor"); -} - -//---------------------------------------------------------------------- -BPQBlock::BPQBlock(BlockInfo* block) -{ - log_info_p(LOG, "BPQBlock::constructor()"); - - ASSERT( block->type() == BundleProtocol::QUERY_EXTENSION_BLOCK); - - initialise(block); - - log_info_p(LOG, "leaving constructor"); + log_info("leaving constructor"); } //---------------------------------------------------------------------- BPQBlock::~BPQBlock() { - log_info_p(LOG, "BPQBlock: destructor"); + log_info("BPQBlock: destructor"); if ( query_val_ != NULL ){ free(query_val_); query_val_ = NULL; @@ -94,12 +82,44 @@ else return -1; + // timestamp secs SDNV + if ( i < len && + (encoding_len = SDNV::encode (creation_ts_.seconds_, &(buf[i]), len -i)) >= 0 ) { + i += encoding_len; + } else { + log_err("Error encoding BPQ creation timestamp secs"); + return -1; + } + + // timestamp seqno SDNV + if ( i < len && + (encoding_len = SDNV::encode (creation_ts_.seqno_, &(buf[i]), len -i)) >= 0 ) { + i += encoding_len; + } else { + log_err("Error encoding BPQ creation timestamp seqno"); + return -1; + } + + // source eid length SDNV + if ( i < len && + (encoding_len = SDNV::encode (source_.length(), &(buf[i]), len -i)) >= 0 ) { + i += encoding_len; + } else { + log_err("Error encoding BPQ source EID length"); + return -1; + } + + // source eid n-bytes + const char* src_eid = source_.c_str(); + for (j=0; src_eid != NULL && i < len && j < source_.length(); i++, j++) + buf[i] = src_eid[j]; + // query-length SDNV if ( i < len && (encoding_len = SDNV::encode (query_len_, &(buf[i]), len -i)) >= 0 ) { i += encoding_len; } else { - log_err_p(LOG, "Error encoding _BPQ query length"); + log_err("Error encoding BPQ query length"); return -1; } @@ -112,7 +132,7 @@ (encoding_len = SDNV::encode (frag_len(), &(buf[i]), len -i)) >= 0 ) { i += encoding_len; } else { - log_err_p(LOG, "Error encoding _BPQ fragment length"); + log_err("Error encoding BPQ fragment length"); return -1; } @@ -126,7 +146,7 @@ (encoding_len = SDNV::encode (iter->offset(), &(buf[i]), len -i)) >= 0 ) { i += encoding_len; } else { - log_err_p(LOG, "Error encoding _BPQ individual fragment offset"); + log_err("Error encoding BPQ individual fragment offset"); return -1; } @@ -134,7 +154,7 @@ (encoding_len = SDNV::encode (iter->length(), &(buf[i]), len -i)) >= 0 ) { i += encoding_len; } else { - log_err_p(LOG, "Error encoding _BPQ individual fragment length"); + log_err("Error encoding BPQ individual fragment length"); return -1; } } @@ -151,10 +171,15 @@ // initial size {kind, matching rule} u_int len = 2; + len += SDNV::encoding_len(creation_ts_.seconds_); + len += SDNV::encoding_len(creation_ts_.seqno_); + len += SDNV::encoding_len(source_.length()); + len += source_.length(); + len += SDNV::encoding_len(query_len_); len += query_len_; + len += SDNV::encoding_len(frag_len()); - BPQFragmentVec::const_iterator iter; for (iter = fragments_.begin(); iter != fragments_.end(); @@ -171,166 +196,272 @@ bool BPQBlock::match(const BPQBlock* other) const { - return query_len_ == other->query_len() && + return matching_rule_ == other->matching_rule() && + query_len_ == other->query_len() && strncmp( (char*)query_val_, (char*)other->query_val(), query_len_ ) == 0; } //---------------------------------------------------------------------- int -BPQBlock::initialise(BlockInfo* b) +BPQBlock::initialise(BlockInfo* block, bool created_locally, const Bundle* bundle) { - ASSERT ( b != NULL); +#define TRY(fn) \ + if(!fn) { \ + return BP_FAIL; \ + } + + ASSERT ( block != NULL); + + u_int buf_index = 0; + u_int buf_length = block->data_length(); + const u_char* buf = block->data(); + + log_block_info(block); + TRY (extract_kind(buf, &buf_index, buf_length)); + TRY (extract_matching_rule(buf, &buf_index, buf_length)); - int decoding_len=0; - u_int i=0, j=0, offset=0, length=0, full_len=0; - u_int frag_count=0, frag_off=0, frag_len=0; - u_char* buf = 0; - BlockInfo* block = b; + if (created_locally) { + creation_ts_.seconds_ = bundle->creation_ts().seconds_; + creation_ts_.seqno_ = bundle->creation_ts().seqno_; + source_.assign(bundle->source()); + } else { + TRY (extract_creation_ts(buf, &buf_index, buf_length)); + TRY (extract_source(buf, &buf_index, buf_length)); + } + + TRY (extract_query(buf, &buf_index, buf_length)); + TRY (extract_fragments(buf, &buf_index, buf_length)); + + return BP_SUCCESS; - /************************************************************************** - * Begin extracting block length with lots of logging - *************************************************************************/ - log_debug_p(LOG, "block: data_length() = %d", block->data_length()); - log_debug_p(LOG, "block: data_offset() = %d", block->data_offset()); - log_debug_p(LOG, "block: full_length() = %d", block->full_length()); - log_debug_p(LOG, "block: complete() = %s", +#undef TRY +} + +//---------------------------------------------------------------------- +void +BPQBlock::log_block_info(BlockInfo* block) +{ + ASSERT ( block != NULL); + + log_debug("block: data_length() = %d", block->data_length()); + log_debug("block: data_offset() = %d", block->data_offset()); + log_debug("block: full_length() = %d", block->full_length()); + log_debug("block: complete() = %s", (block->complete()) ? "true" : "false" ); - log_debug_p(LOG, "block: reloaded() = %s", + log_debug("block: reloaded() = %s", (block->reloaded()) ? "true" : "false" ); - if ( b->source() != NULL ) { - BlockInfo* block_src = const_cast(b->source());; + if ( block->source() != NULL ) { + BlockInfo* block_src = const_cast(block->source()); - log_debug_p(LOG, "block_src: data_length() = %d", block_src->data_length()); - log_debug_p(LOG, "block_src: data_offset() = %d", block_src->data_offset()); - log_debug_p(LOG, "block_src: full_length() = %d", block_src->full_length()); - log_debug_p(LOG, "block_src: complete() = %s", + log_debug("block_src: data_length() = %d", block_src->data_length()); + log_debug("block_src: data_offset() = %d", block_src->data_offset()); + log_debug("block_src: full_length() = %d", block_src->full_length()); + log_debug("block_src: complete() = %s", (block_src->complete()) ? "true" : "false" ); - - log_debug_p(LOG, "block_src: reloaded() = %s", + + log_debug("block_src: reloaded() = %s", (block_src->reloaded()) ? "true" : "false" ); } - - offset = block->data_offset(); - length = block->data_length(); - full_len = block->full_length(); - - if ( full_len != offset + length ) { - log_err_p(LOG, "BPQBlock::initialise: full_len != offset + length"); + if ( block->full_length() != block->data_offset() + block->data_length() ) { + log_err("BPQBlock: full_len != offset + length"); } - if ( block->writable_contents()->buf_len() < full_len ){ - log_err_p(LOG, "BPQBlock::initialise: buf_len() < full_len"); - log_err_p(LOG, "BPQBlock::initialise: buf_len() = %zu", - block->writable_contents()->buf_len()); - - log_debug_p(LOG, "BPQBlock::initialise: reserving space in buffer %zu", - full_len); - - block->writable_contents()->reserve(full_len); - log_debug_p(LOG, "BPQBlock::initialise: new buf_len() = %zu", + if ( block->writable_contents()->buf_len() < block->full_length() ){ + log_err("BPQBlock: buf_len() < full_len"); + log_err("BPQBlock: buf_len() = %zu", block->writable_contents()->buf_len()); } - buf = block->data(); - - - // BPQ Kind must be 0 or 1 - if ( *(block->data()) != 0 && - *(block->data()) != 1 ) { - log_err_p(LOG, "BPQBlock::initialise: block->data() = %c (should be 0|1)", + if ( *(block->data()) != KIND_QUERY || + *(block->data()) != KIND_RESPONSE || + *(block->data()) != KIND_RESPONSE_DO_NOT_CACHE_FRAG ) { + log_err("BPQBlock: block->data() = %c (should be 0|1|2)", *(block->data())); - return BP_FAIL; } - - /************************************************************************** - * Begin extracting block info - *************************************************************************/ +} - // BPQ-kind 1-byte - if ( i < length ) { - log_debug_p(LOG, "BPQBlock::initialise: extracting kind"); - kind_ = (kind_t) buf[i++]; - log_debug_p(LOG, "BPQBlock::initialise: kind = %d", kind_); - } else { - log_err_p(LOG, "Error decoding BPQ kind"); - return BP_FAIL; - } +//---------------------------------------------------------------------- +int +BPQBlock::extract_kind (const u_char* buf, u_int* buf_index, u_int buf_length) +{ + if ( *buf_index < buf_length ) { + kind_ = (kind_t) buf[*buf_index++]; + log_debug("BPQBlock::extract_kind: kind = %d", kind_); + return BP_SUCCESS; - // matching rule type 1-byte - if ( i < length ) { - matching_rule_ = (u_int) buf[i++]; - log_debug_p(LOG, "BPQBlock::initialise: matching rule = %u", matching_rule_); - } else { - log_err_p(LOG, "Error decoding BPQ matching rule"); - return BP_FAIL; - } - - // query-len SDNV - if ( i < length && - (decoding_len = SDNV::decode(&(buf[i]), length - i, &query_len_)) >= 0 ) { - i += decoding_len; - log_debug_p(LOG, "BPQBlock::initialise: query len = %u", query_len_); - } else { - log_err_p(LOG, "Error decoding BPQ query length"); - return BP_FAIL; - } + } else { + log_err("Error decoding kind"); + return BP_FAIL; + } +} - // query-value n-bytes - if ( (i+query_len_) < length ) { - query_val_ = (u_char*) malloc ( sizeof(u_char) * query_len_ ); - - for (j=0; query_val_ != NULL && i < length && j < query_len_; i++, j++) - query_val_[j] = buf[i]; +//---------------------------------------------------------------------- +int +BPQBlock::extract_matching_rule (const u_char* buf, u_int* buf_index, u_int buf_length) +{ + if ( *buf_index < buf_length ) { + matching_rule_ = (kind_t) buf[*buf_index++]; + log_debug("BPQBlock::extract_matching_rule: matching rule = %d", matching_rule_); + return BP_SUCCESS; - log_debug_p(LOG, "BPQBlock::initialise: query val = %s", query_val_); - - } else { - query_val_ = NULL; - log_err_p(LOG, "Error extracting BPQ query value"); - return BP_FAIL; - } + } else { + log_err("Error decoding matching rule"); + return BP_FAIL; + } +} - if ( i < length && - (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_count)) >= 0 ) { - i += decoding_len; - log_debug_p(LOG, "BPQBlock::initialise: frag count = %u", frag_count); - } else { - log_err_p(LOG, "Error decoding BPQ fragment count"); - return BP_FAIL; - } - - - for (j=0; i < length && j < frag_count; j++) { - - if ( (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_off)) >= 0 ) { - i += decoding_len; - log_debug_p(LOG, "BPQBlock::initialise: frag offset = %u", frag_off); - } else { - log_err_p(LOG, "Error decoding BPQ fragment offset"); - return BP_FAIL; - } - - if ( (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_len)) >= 0 ) { - i += decoding_len; - log_debug_p(LOG, "BPQBlock::initialise: frag length = %u", frag_len); - } else { - log_err_p(LOG, "Error decoding BPQ fragment length"); - return BP_FAIL; - } - - - BPQFragment frag(frag_off, frag_len); - add_fragment(frag); +//---------------------------------------------------------------------- +int +BPQBlock::extract_creation_ts (const u_char* buf, u_int* buf_index, u_int buf_length) +{ + int decoding_len = 0; + if (*buf_index < buf_length && + (decoding_len = SDNV::decode( &(buf[*buf_index]), + buf_length - *buf_index, + &(creation_ts_.seconds_)) ) >= 0 ) { + *buf_index += decoding_len; + log_debug("BPQBlock::extract_creation_ts: timestamp seconds = %llu", + creation_ts_.seconds_); + } else { + log_err("Error decoding timestamp seconds"); + return BP_FAIL; } + if (*buf_index < buf_length && + (decoding_len = SDNV::decode( &(buf[*buf_index]), + buf_length - *buf_index, + &(creation_ts_.seqno_)) ) >= 0 ) { + *buf_index += decoding_len; + log_debug("BPQBlock::extract_creation_ts: timestamp sequence number = %llu", + creation_ts_.seqno_); + } else { + log_err("Error decoding timestamp sequence number"); + return BP_FAIL; + } + + return BP_SUCCESS; +} + +//---------------------------------------------------------------------- +int +BPQBlock::extract_source (const u_char* buf, u_int* buf_index, u_int buf_length) +{ + int decoding_len = 0; + u_int src_eid_len = 0; + + if (*buf_index < buf_length && + (decoding_len = SDNV::decode( &(buf[*buf_index]), + buf_length - *buf_index, + &src_eid_len)) >= 0 ) { + *buf_index += decoding_len; + log_debug("BPQBlock::extract_source: Source EID length = %u", src_eid_len); + } else { + log_err("Error decoding Source EID length"); + return BP_FAIL; + } + + if ((*buf_index + src_eid_len) < buf_length && + source_.assign((const char*) &(buf[*buf_index]), src_eid_len) ) { + + *buf_index += src_eid_len; + log_debug("BPQBlock::extract_source: Source EID = %s", source_.c_str()); + + } else { + log_err("Error extracting Source EID"); + return BP_FAIL; + } return BP_SUCCESS; } +//---------------------------------------------------------------------- +int +BPQBlock::extract_query (const u_char* buf, u_int* buf_index, u_int buf_length) +{ + int decoding_len = 0; + + if (*buf_index < buf_length && + (decoding_len = SDNV::decode( &(buf[*buf_index]), + buf_length - *buf_index, + &query_len_)) >= 0 ) { + *buf_index += decoding_len; + log_debug("BPQBlock::extract_query: query length = %u", query_len_); + } else { + log_err("Error decoding BPQ query length"); + return BP_FAIL; + } + + if ((*buf_index + query_len_) < buf_length) { + query_val_ = (u_char*) malloc ( sizeof(u_char) * query_len_ ); + + memcpy(query_val_, &(buf[*buf_index]), query_len_); + + *buf_index += query_len_; + log_debug("BPQBlock::extract_query: query value = %s", query_val_); + + } else { + log_err("Error extracting query value"); + return BP_FAIL; + } + + return BP_SUCCESS; +} + +//---------------------------------------------------------------------- +int +BPQBlock::extract_fragments (const u_char* buf, u_int* buf_index, u_int buf_length) +{ + int decoding_len = 0; + u_int i; + u_int frag_count = 0; + u_int frag_off = 0; + u_int frag_len = 0; + + if (*buf_index < buf_length && + (decoding_len = SDNV::decode( &(buf[*buf_index]), + buf_length - *buf_index, + &frag_count)) >= 0 ) { + *buf_index += decoding_len; + log_debug("BPQBlock::extract_fragments: number of fragments = %u", frag_count); + } else { + log_err("Error decoding number of fragments"); + return BP_FAIL; + } + + for (i=0; i < frag_count; i++) { + + if (*buf_index < buf_length && + (decoding_len = SDNV::decode( &(buf[*buf_index]), + buf_length - *buf_index, + &frag_off)) >= 0 ) { + *buf_index += decoding_len; + log_debug("BPQBlock::extract_fragments: fragment [%u] offset = %u", i, frag_off); + } else { + log_err("Error decoding fragment [%u] offset", i); + return BP_FAIL; + } + + if (*buf_index < buf_length && + (decoding_len = SDNV::decode( &(buf[*buf_index]), + buf_length - *buf_index, + &frag_len)) >= 0 ) { + *buf_index += decoding_len; + log_debug("BPQBlock::extract_fragments: fragment [%u] length = %u", i, frag_len); + } else { + log_err("Error decoding fragment [%u] length", i); + return BP_FAIL; + } + + BPQFragment frag(frag_off, frag_len); + this->add_fragment(frag); + } + + return BP_SUCCESS; +} + } // namespace dtn -