--- 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<BlockInfo*> (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*>(bundle)->api_blocks()->
has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) {
- log_debug_p(LOG, "BPQBlock found in API Block Vec => created locally");
- initialise( const_cast<BlockInfo*> (bundle->api_blocks()->
- find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) );
+ log_debug("BPQBlock found in API Block Vec => created locally");
+ initialise( const_cast<BlockInfo*> (const_cast<Bundle*>(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<BlockInfo*>(b->source());;
+ if ( block->source() != NULL ) {
+ BlockInfo* block_src = const_cast<BlockInfo*>(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
-