Implementing content store using Boost.MultiIndex container
Adding .SetGroupName("Ccnx") call to Ccnx-related objects (probably
missed some). This call is advisory, but it is nice to give users
information about Ccnx-related objects (this information is accessible
via --PrintGroup=Ccnx command line argument)
diff --git a/in-progress/ccn/README b/in-progress/ccn/README
deleted file mode 100644
index 6b9ef69..0000000
--- a/in-progress/ccn/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This directory contains files borrowed and adapted from CCNx implementation
-
diff --git a/in-progress/ccn/ccn.h b/in-progress/ccn/ccn.h
deleted file mode 100644
index af9dcae..0000000
--- a/in-progress/ccn/ccn.h
+++ /dev/null
@@ -1,407 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-/*
- * ccn_ccn.h
- * Abstraction
- *
- * Created by Ilya on 7/29/11.
- * Copyright 2011 __MyCompanyName__. All rights reserved.
- *
- */
-
-#ifndef CCN_CCN_DEFINED
-#define CCN_CCN_DEFINED
-
-#include <stdint.h>
-#include "ccn_coding.h"
-#include "ccn_charbuf.h"
-#include "ccn_indexbuf.h"
-
-/***********************************
- * Writing Names
- * Names for interests are constructed in charbufs using
- * the following routines.
- */
-
-/*
- * ccn_name_init: reset charbuf to represent an empty Name in binary format
- * Return value is 0, or -1 for error.
- */
-int ccn_name_init(struct ccn_charbuf *c);
-
-/*
- * ccn_name_append: add a Component to a Name
- * The component is an arbitrary string of n octets, no escaping required.
- * Return value is 0, or -1 for error.
- */
-int ccn_name_append(struct ccn_charbuf *c, const void *component, size_t n);
-
-/*
- * ccn_name_append_str: add a Component that is a \0 terminated string.
- * The component added is the bytes of the string without the \0.
- * This function is convenient for those applications that construct
- * component names from simple strings.
- * Return value is 0, or -1 for error
- */
-int ccn_name_append_str(struct ccn_charbuf *c, const char *s);
-
-/*
- * ccn_name_append_components: add sequence of ccnb-encoded Components
- * to a ccnb-encoded Name
- * start and stop are offsets from ccnb
- * Return value is 0, or -1 for obvious error
- */
-int ccn_name_append_components(struct ccn_charbuf *c,
- const unsigned char *ccnb,
- size_t start, size_t stop);
-
-enum ccn_marker {
- CCN_MARKER_NONE = -1,
- CCN_MARKER_SEQNUM = 0x00, /**< consecutive block sequence numbers */
- CCN_MARKER_CONTROL = 0xC1, /**< commands, etc. */
- CCN_MARKER_OSEQNUM = 0xF8, /**< deprecated */
- CCN_MARKER_BLKID = 0xFB, /**< nonconsecutive block ids */
- CCN_MARKER_VERSION = 0xFD /**< timestamp-based versioning */
-};
-
-/*
- * ccn_name_append_numeric: add binary Component to ccnb-encoded Name
- * These are special components used for marking versions, fragments, etc.
- * Return value is 0, or -1 for error
- * see doc/technical/NameConventions.html
- */
-int ccn_name_append_numeric(struct ccn_charbuf *c,
- enum ccn_marker tag, uintmax_t value);
-
-/*
- * ccn_name_append_nonce: add nonce Component to ccnb-encoded Name
- * Uses %C1.N.n marker.
- * see doc/technical/NameConventions.html
- */
-int ccn_name_append_nonce(struct ccn_charbuf *c);
-
-/*
- * ccn_name_split: find Component boundaries in a ccnb-encoded Name
- * Thin veneer over ccn_parse_Name().
- * returns -1 for error, otherwise the number of Components
- * components arg may be NULL to just do a validity check
- */
-int ccn_name_split(const struct ccn_charbuf *c,
- struct ccn_indexbuf* components);
-
-/*
- * ccn_name_chop: Chop the name down to n components.
- * returns -1 for error, otherwise the new number of Components
- * components arg may be NULL; if provided it must be consistent with
- * some prefix of the name, and is updated accordingly.
- * n may be negative to say how many components to remove instead of how
- * many to leave, e.g. -1 will remove just the last component.
- */
-int ccn_name_chop(struct ccn_charbuf *c,
- struct ccn_indexbuf* components, int n);
-
-
-
-
-/*********** Interest parsing ***********/
-
-/*
- * The parse of an interest results in an array of offsets into the
- * wire representation, with the start and end of each major element and
- * a few of the inportant sub-elements. The following enum allows those
- * array items to be referred to symbolically. The *_B_* indices correspond
- * to beginning offsets and the *_E_* indices correspond to ending offsets.
- * An omitted element has its beginning and ending offset equal to each other.
- * Normally these offsets will end up in non-decreasing order.
- * Some aliasing tricks may be played here, e.g. since
- * offset[CCN_PI_E_ComponentLast] is always equal to
- * offset[CCN_PI_E_LastPrefixComponent],
- * we may define CCN_PI_E_ComponentLast = CCN_PI_E_LastPrefixComponent.
- * However, code should not rely on that,
- * since it may change from time to time as the
- * interest schema evolves.
- */
-enum ccn_parsed_interest_offsetid {
- CCN_PI_B_Name,
- CCN_PI_B_Component0,
- CCN_PI_B_LastPrefixComponent,
- CCN_PI_E_LastPrefixComponent,
- CCN_PI_E_ComponentLast = CCN_PI_E_LastPrefixComponent,
- CCN_PI_E_Name,
- CCN_PI_B_MinSuffixComponents,
- CCN_PI_E_MinSuffixComponents,
- CCN_PI_B_MaxSuffixComponents,
- CCN_PI_E_MaxSuffixComponents,
- CCN_PI_B_PublisherID, // XXX - rename
- CCN_PI_B_PublisherIDKeyDigest,
- CCN_PI_E_PublisherIDKeyDigest,
- CCN_PI_E_PublisherID,
- CCN_PI_B_Exclude,
- CCN_PI_E_Exclude,
- CCN_PI_B_ChildSelector,
- CCN_PI_E_ChildSelector,
- CCN_PI_B_AnswerOriginKind,
- CCN_PI_E_AnswerOriginKind,
- CCN_PI_B_Scope,
- CCN_PI_E_Scope,
- CCN_PI_B_InterestLifetime,
- CCN_PI_E_InterestLifetime,
- CCN_PI_B_Nonce,
- CCN_PI_E_Nonce,
- CCN_PI_B_OTHER,
- CCN_PI_E_OTHER,
- CCN_PI_E
-};
-
-
-struct ccn_parsed_interest {
- int magic;
- int prefix_comps;
- int min_suffix_comps;
- int max_suffix_comps;
- int orderpref;
- int answerfrom;
- int scope;
- unsigned short offset[CCN_PI_E+1];
-};
-
-/*
- * Bitmasks for AnswerOriginKind
- */
-#define CCN_AOK_CS 0x1 /* Answer from content store */
-#define CCN_AOK_NEW 0x2 /* OK to produce new content */
-#define CCN_AOK_DEFAULT (CCN_AOK_CS | CCN_AOK_NEW)
-#define CCN_AOK_STALE 0x4 /* OK to answer with stale data */
-#define CCN_AOK_EXPIRE 0x10 /* Mark as stale (must have Scope 0) */
-
-/***********************************
- * Low-level binary formatting
- */
-
-/*
- * Append a ccnb start marker
- *
- * This forms the basic building block of ccnb-encoded data.
- * c is the buffer to append to.
- * Return value is 0, or -1 for error.
- */
-int ccn_charbuf_append_tt(struct ccn_charbuf *c, size_t val, enum ccn_tt tt);
-
-/**
- * Append a CCN_CLOSE
- *
- * Use this to close off an element in ccnb-encoded data.
- * @param c is the buffer to append to.
- * @returns 0 for success or -1 for error.
- */
-int ccn_charbuf_append_closer(struct ccn_charbuf *c);
-
-/***********************************
- * Slightly higher level binary formatting
- */
-
-/*
- * Append a non-negative integer as a UDATA.
- */
-int ccnb_append_number(struct ccn_charbuf *c, int nni);
-
-/*
- * Append a binary timestamp
- * as a BLOB using the ccn binary Timestamp representation (12-bit fraction).
- */
-int ccnb_append_timestamp_blob(struct ccn_charbuf *c,
- enum ccn_marker marker,
- long long secs, int nsecs);
-
-/*
- * Append a binary timestamp, using the current time.
- */
-int ccnb_append_now_blob(struct ccn_charbuf *c, enum ccn_marker marker);
-
-/*
- * Append a start-of-element marker.
- */
-int ccnb_element_begin(struct ccn_charbuf *c, enum ccn_dtag dtag);
-
-/*
- * Append an end-of-element marker.
- * This is the same as ccn_charbuf_append_closer()
- */
-int ccnb_element_end(struct ccn_charbuf *c);
-
-/*
- * Append a tagged BLOB
- */
-int ccnb_append_tagged_blob(struct ccn_charbuf *c, enum ccn_dtag dtag,
- const void *data, size_t size);
-
-/*
- * Append a tagged UDATA string, with printf-style formatting
- */
-int ccnb_tagged_putf(struct ccn_charbuf *c, enum ccn_dtag dtag,
- const char *fmt, ...);
-
-
-
-/***********************************
- * Binary decoding
- * These routines require that the whole binary object be buffered.
- */
-
-struct ccn_buf_decoder {
- struct ccn_skeleton_decoder decoder;
- const unsigned char *buf;
- size_t size;
-};
-
-struct ccn_buf_decoder *ccn_buf_decoder_start(struct ccn_buf_decoder *d,
- const unsigned char *buf, size_t size);
-
-void ccn_buf_advance(struct ccn_buf_decoder *d);
-int ccn_buf_advance_past_element(struct ccn_buf_decoder *d);
-
-/* The match routines return a boolean - true for match */
-int ccn_buf_match_dtag(struct ccn_buf_decoder *d, enum ccn_dtag dtag);
-
-int ccn_buf_match_some_dtag(struct ccn_buf_decoder *d);
-
-int ccn_buf_match_some_blob(struct ccn_buf_decoder *d);
-int ccn_buf_match_blob(struct ccn_buf_decoder *d,
- const unsigned char **bufp, size_t *sizep);
-
-int ccn_buf_match_udata(struct ccn_buf_decoder *d, const char *s);
-
-int ccn_buf_match_attr(struct ccn_buf_decoder *d, const char *s);
-
-/* On error, the parse routines enter an error state and return a negative value. */
-/*int ccn_parse_required_tagged_BLOB(struct ccn_buf_decoder *d,
- enum ccn_dtag dtag,
- int minlen, int maxlen);
-int ccn_parse_optional_tagged_BLOB(struct ccn_buf_decoder *d,
- enum ccn_dtag dtag,
- int minlen, int maxlen);
-int ccn_parse_nonNegativeInteger(struct ccn_buf_decoder *d);
-int ccn_parse_optional_tagged_nonNegativeInteger(struct ccn_buf_decoder *d,
- enum ccn_dtag dtag);
-int ccn_parse_uintmax(struct ccn_buf_decoder *d, uintmax_t *result);
-int ccn_parse_tagged_string(struct ccn_buf_decoder *d,
- enum ccn_dtag dtag, struct ccn_charbuf *store);*/
-/* check the decoder error state for these two - result can't be negative */
-/*uintmax_t ccn_parse_required_tagged_binary_number(struct ccn_buf_decoder *d,
- enum ccn_dtag dtag,
- int minlen, int maxlen);
-uintmax_t ccn_parse_optional_tagged_binary_number(struct ccn_buf_decoder *d,
- enum ccn_dtag dtag,
- int minlen, int maxlen,
- uintmax_t default_value);*/
-
-/**
- * Enter an error state if element closer not found.
- */
-void ccn_buf_check_close(struct ccn_buf_decoder *d);
-
-/*
- * ccn_ref_tagged_BLOB: Get address & size associated with blob-valued element
- * Returns 0 for success, negative value for error.
- */
-int ccn_ref_tagged_BLOB(enum ccn_dtag tt,
- const unsigned char *buf,
- size_t start, size_t stop,
- const unsigned char **presult, size_t *psize);
-
-/*
- * ccn_parse_Name: Parses a ccnb-encoded name
- * components may be NULL, otherwise is filled in with Component boundary offsets
- * Returns the number of Components in the Name, or -1 if there is an error.
- */
-int ccn_parse_Name(struct ccn_buf_decoder *d, struct ccn_indexbuf *components);
-
-/***********************************
- * Authenticators and signatures for content are constructed in charbufs
- * using the following routines.
- */
-
-enum ccn_content_type {
- CCN_CONTENT_DATA = 0x0C04C0,
- CCN_CONTENT_ENCR = 0x10D091,
- CCN_CONTENT_GONE = 0x18E344,
- CCN_CONTENT_KEY = 0x28463F,
- CCN_CONTENT_LINK = 0x2C834A,
- CCN_CONTENT_NACK = 0x34008A
-};
-
-
-/*********** ContentObject parsing ***********/
-/* Analogous to enum ccn_parsed_interest_offsetid, but for content */
-enum ccn_parsed_content_object_offsetid {
- CCN_PCO_B_Signature,
- CCN_PCO_B_DigestAlgorithm,
- CCN_PCO_E_DigestAlgorithm,
- CCN_PCO_B_Witness,
- CCN_PCO_E_Witness,
- CCN_PCO_B_SignatureBits,
- CCN_PCO_E_SignatureBits,
- CCN_PCO_E_Signature,
- CCN_PCO_B_Name,
- CCN_PCO_B_Component0,
- CCN_PCO_E_ComponentN,
- CCN_PCO_E_ComponentLast = CCN_PCO_E_ComponentN,
- CCN_PCO_E_Name,
- CCN_PCO_B_SignedInfo,
- CCN_PCO_B_PublisherPublicKeyDigest,
- CCN_PCO_E_PublisherPublicKeyDigest,
- CCN_PCO_B_Timestamp,
- CCN_PCO_E_Timestamp,
- CCN_PCO_B_Type,
- CCN_PCO_E_Type,
- CCN_PCO_B_FreshnessSeconds,
- CCN_PCO_E_FreshnessSeconds,
- CCN_PCO_B_FinalBlockID,
- CCN_PCO_E_FinalBlockID,
- CCN_PCO_B_KeyLocator,
- /* Exactly one of Key, Certificate, or KeyName will be present */
- CCN_PCO_B_Key_Certificate_KeyName,
- CCN_PCO_B_KeyName_Name,
- CCN_PCO_E_KeyName_Name,
- CCN_PCO_B_KeyName_Pub,
- CCN_PCO_E_KeyName_Pub,
- CCN_PCO_E_Key_Certificate_KeyName,
- CCN_PCO_E_KeyLocator,
- CCN_PCO_E_SignedInfo,
- CCN_PCO_B_Content,
- CCN_PCO_E_Content,
- CCN_PCO_E
-};
-
-struct ccn_parsed_ContentObject {
- int magic;
- enum ccn_content_type type;
- int name_ncomps;
- unsigned short offset[CCN_PCO_E+1];
- unsigned char digest[32]; /* Computed only when needed */
- int digest_bytes;
-};
-
-int ccn_encode_ContentObject(struct ccn_charbuf *buf,
- const struct ccn_charbuf *Name,
- const void *data,
- size_t size);
-#endif
diff --git a/in-progress/ccn/ccn_buf_decoder.cc b/in-progress/ccn/ccn_buf_decoder.cc
deleted file mode 100644
index eeb51fa..0000000
--- a/in-progress/ccn/ccn_buf_decoder.cc
+++ /dev/null
@@ -1,930 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include "ccn.h"
-#include "ccn_charbuf.h"
-#include "ccn_coding.h"
-#include "ccn_indexbuf.h"
-
-
-struct ccn_buf_decoder *
-ccn_buf_decoder_start(struct ccn_buf_decoder *d,
- const unsigned char *buf, size_t size)
-{
- memset(&d->decoder, 0, sizeof(d->decoder));
- d->decoder.state |= CCN_DSTATE_PAUSE;
- d->buf = buf;
- d->size = size;
- ccn_skeleton_decode(&d->decoder, buf, size);
- return(d);
-}
-
-void
-ccn_buf_advance(struct ccn_buf_decoder *d)
-{
- ccn_skeleton_decode(&d->decoder,
- d->buf + d->decoder.index,
- d->size - d->decoder.index);
-}
-
-int
-ccn_buf_match_dtag(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
-{
- return (d->decoder.state >= 0 &&
- CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_DTAG &&
- (int)d->decoder.numval == dtag);
-}
-
-int
-ccn_buf_match_some_dtag(struct ccn_buf_decoder *d)
-{
- return(d->decoder.state >= 0 &&
- CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_DTAG);
-}
-
-int
-ccn_buf_match_some_blob(struct ccn_buf_decoder *d)
-{
- return(d->decoder.state >= 0 &&
- CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_BLOB);
-}
-
-int
-ccn_buf_match_blob(struct ccn_buf_decoder *d,
- const unsigned char **bufp, size_t *sizep)
-{
- if (ccn_buf_match_some_blob(d)) {
- if (bufp != NULL)
- *bufp = d->buf + d->decoder.index;
- if (sizep != NULL)
- *sizep = d->decoder.numval;
- return (1);
- }
- if (bufp != NULL)
- *bufp = d->buf + d->decoder.token_index;
- if (sizep != NULL)
- *sizep = 0;
- return(0);
-}
-
-int
-ccn_buf_match_udata(struct ccn_buf_decoder *d, const char *s)
-{
- size_t len = strlen(s);
- return (d->decoder.state >= 0 &&
- CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA &&
- d->decoder.numval == len &&
- 0 == memcmp(d->buf + d->decoder.index, s, len));
-}
-
-int
-ccn_buf_match_attr(struct ccn_buf_decoder *d, const char *s)
-{
- size_t len = strlen(s);
- return (d->decoder.state >= 0 &&
- CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_ATTR &&
- d->decoder.numval == len &&
- 0 == memcmp(d->buf + d->decoder.index, s, len));
-}
-
-void
-ccn_buf_check_close(struct ccn_buf_decoder *d)
-{
- if (d->decoder.state >= 0) {
- if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) != CCN_NO_TOKEN)
- d->decoder.state = CCN_DSTATE_ERR_NEST;
- else
- ccn_buf_advance(d);
- }
-}
-
-int
-ccn_buf_advance_past_element(struct ccn_buf_decoder *d)
-{
- enum ccn_tt tt;
- int nest;
- if (d->decoder.state < 0)
- return(d->decoder.state);
- tt = (ccn_tt)CCN_GET_TT_FROM_DSTATE(d->decoder.state);
- if (tt == CCN_DTAG || tt == CCN_TAG) {
- nest = d->decoder.nest;
- ccn_buf_advance(d);
- while (d->decoder.state >= 0 && d->decoder.nest >= nest)
- ccn_buf_advance(d);
- /* The nest decrements before the closer is consumed */
- ccn_buf_check_close(d);
- }
- else
- return(-1);
- if (d->decoder.state < 0)
- return(d->decoder.state);
- return (0);
-}
-
-int
-ccn_parse_required_tagged_BLOB(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
- int minlen, int maxlen)
-{
- int res = -1;
- size_t len = 0;
- if (ccn_buf_match_dtag(d, dtag)) {
- res = d->decoder.element_index;
- ccn_buf_advance(d);
- if (ccn_buf_match_some_blob(d)) {
- len = d->decoder.numval;
- ccn_buf_advance(d);
- }
- ccn_buf_check_close(d);
- if ((int)len < minlen || (maxlen >= 0 && (int)len > maxlen)) {
- d->decoder.state = -__LINE__;
- }
- }
- else
- d->decoder.state = -__LINE__;
- if (d->decoder.state < 0)
- return (d->decoder.state);
- return(res);
-}
-
-int
-ccn_parse_optional_tagged_BLOB(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
- int minlen, int maxlen)
-{
- if (ccn_buf_match_dtag(d, dtag))
- return(ccn_parse_required_tagged_BLOB(d, dtag, minlen, maxlen));
- return(-1);
-}
-
-uintmax_t
-ccn_parse_required_tagged_binary_number(struct ccn_buf_decoder *d,
- enum ccn_dtag dtag,
- int minlen, int maxlen)
-{
- uintmax_t value = 0;
- const unsigned char *p = NULL;
- size_t len = 0;
- int i;
- if (0 <= minlen && minlen <= maxlen && maxlen <= (int)sizeof(value) &&
- ccn_buf_match_dtag(d, dtag)) {
- ccn_buf_advance(d);
- if (ccn_buf_match_blob(d, &p, &len))
- ccn_buf_advance(d);
- ccn_buf_check_close(d);
- if (d->decoder.state < 0)
- return(value);
- if (minlen <= (int)len && (int)len <= maxlen)
- for (i = 0; i < (int)len; i++)
- value = (value << 8) + p[i];
- else
- d->decoder.state = -__LINE__;
- }
- else
- d->decoder.state = -__LINE__;
- return(value);
-}
-
-uintmax_t
-ccn_parse_optional_tagged_binary_number(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
- int minlen, int maxlen, uintmax_t default_value)
-{
- if (ccn_buf_match_dtag(d, dtag))
- return(ccn_parse_required_tagged_binary_number(d, dtag, minlen, maxlen));
- return(default_value);
-}
-
-int
-ccn_parse_required_tagged_UDATA(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
-{
- int res = -1;
- if (ccn_buf_match_dtag(d, dtag)) {
- res = d->decoder.element_index;
- ccn_buf_advance(d);
- if (d->decoder.state >= 0 &&
- CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA)
- ccn_buf_advance(d);
- else
- d->decoder.state = -__LINE__;
- ccn_buf_check_close(d);
- }
- else
- d->decoder.state = -__LINE__;
- if (d->decoder.state < 0)
- return (-1);
- return(res);
-}
-
-int
-ccn_parse_optional_tagged_UDATA(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
-{
- if (ccn_buf_match_dtag(d, dtag))
- return(ccn_parse_required_tagged_UDATA(d, dtag));
- return(-1);
-}
-
-/**
- * Parses a ccnb-encoded element expected to contain a UDATA string.
- * @param d is the decoder
- * @param dtag is the expected dtag value
- * @param store - on success, the string value is appended to store,
- * with null termination.
- * @returns the offset into the store buffer of the copied value, or -1 for error.
- * If a parse error occurs, d->decoder.state is set to a negative value.
- * If the element is not present, -1 is returned but no parse error
- * is indicated.
- */
-int
-ccn_parse_tagged_string(struct ccn_buf_decoder *d, enum ccn_dtag dtag, struct ccn_charbuf *store)
-{
- const unsigned char *p = NULL;
- size_t size = 0;
- int res;
-
- if (ccn_buf_match_dtag(d, dtag)) {
- ccn_buf_advance(d);
- if (d->decoder.state >= 0 &&
- CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
- res = store->length;
- p = d->buf + d->decoder.index;
- size = d->decoder.numval;
- ccn_buf_advance(d);
- }
- ccn_buf_check_close(d);
- if (d->decoder.state >= 0) {
- // XXX - should check for valid utf-8 data.
- res = store->length;
- if (size > 0)
- ccn_charbuf_append(store, p, size);
- ccn_charbuf_append_value(store, 0, 1);
- return(res);
- }
- }
- return(-1);
-}
-
-/**
- * Parses a ccnb-encoded name
- * @param d is the decoder
- * @param components may be NULL, otherwise is filled in with the
- * Component boundary offsets
- * @returns the number of Components in the Name, or -1 if there is an error.
- */
-int
-ccn_parse_Name(struct ccn_buf_decoder *d, struct ccn_indexbuf *components)
-{
- int ncomp = 0;
- if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
- if (components != NULL) components->n = 0;
- ccn_buf_advance(d);
- while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
- if (components != NULL)
- ccn_indexbuf_append_element(components, d->decoder.token_index);
- ncomp += 1;
- ccn_buf_advance(d);
- if (ccn_buf_match_blob(d, NULL, NULL))
- ccn_buf_advance(d);
- ccn_buf_check_close(d);
- }
- if (components != NULL)
- ccn_indexbuf_append_element(components, d->decoder.token_index);
- ccn_buf_check_close(d);
- }
- else
- d->decoder.state = -__LINE__;
- if (d->decoder.state < 0)
- return(-1);
- else
- return(ncomp);
-}
-
-int
-ccn_parse_PublisherID(struct ccn_buf_decoder *d, struct ccn_parsed_interest *pi)
-{
- int res = -1;
- int iskey = 0;
- unsigned pubstart = d->decoder.token_index;
- unsigned keystart = pubstart;
- unsigned keyend = pubstart;
- unsigned pubend = pubstart;
- iskey = ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest);
- if (iskey ||
- ccn_buf_match_dtag(d, CCN_DTAG_PublisherCertificateDigest) ||
- ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerKeyDigest) ||
- ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerCertificateDigest)) {
- res = d->decoder.element_index;
- ccn_buf_advance(d);
- keystart = d->decoder.token_index;
- if (!ccn_buf_match_some_blob(d))
- return (d->decoder.state = -__LINE__);
- ccn_buf_advance(d);
- keyend = d->decoder.token_index;
- ccn_buf_check_close(d);
- pubend = d->decoder.token_index;
- }
- if (d->decoder.state < 0)
- return (d->decoder.state);
- if (pi != NULL) {
- pi->offset[CCN_PI_B_PublisherID] = pubstart;
- pi->offset[CCN_PI_B_PublisherIDKeyDigest] = keystart;
- pi->offset[CCN_PI_E_PublisherIDKeyDigest] = iskey ? keyend : keystart;
- pi->offset[CCN_PI_E_PublisherID] = pubend;
- }
- return(res);
-}
-
-static int
-ccn_parse_optional_Any_or_Bloom(struct ccn_buf_decoder *d)
-{
- int res;
- res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Bloom, 1, 1024+8);
- if (res >= 0)
- return(res);
- if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
- ccn_buf_advance(d);
- ccn_buf_check_close(d);
- res = 0;
- }
- if (d->decoder.state < 0)
- return (d->decoder.state);
- return(res);
-}
-
-int
-ccn_parse_Exclude(struct ccn_buf_decoder *d)
-{
- int res = -1;
- if (ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) {
- res = d->decoder.element_index;
- ccn_buf_advance(d);
- ccn_parse_optional_Any_or_Bloom(d);
- while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
- ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Component, 0, -1);
- ccn_parse_optional_Any_or_Bloom(d);
- }
- ccn_buf_check_close(d);
- }
- if (d->decoder.state < 0)
- return (d->decoder.state);
- return(res);
-}
-
-
-
-int
-ccn_parse_nonNegativeInteger(struct ccn_buf_decoder *d)
-{
- const unsigned char *p;
- int i;
- int n;
- int val;
- int newval;
- unsigned char c;
- if (d->decoder.state < 0)
- return(d->decoder.state);
- if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
- p = d->buf + d->decoder.index;
- n = d->decoder.numval;
- if (n < 1)
- return(d->decoder.state = -__LINE__);
- val = 0;
- for (i = 0; i < n; i++) {
- c = p[i];
- if ('0' <= c && c <= '9') {
- newval = val * 10 + (c - '0');
- if (newval < val)
- return(d->decoder.state = -__LINE__);
- val = newval;
- }
- else
- return(d->decoder.state = -__LINE__);
- }
- ccn_buf_advance(d);
- return(val);
- }
- return(d->decoder.state = -__LINE__);
-}
-
-/**
- * Parse a potentially large non-negative integer.
- *
- * @returns 0 for success, and the value is place in *result; for an error
- * a negative value is returned and *result is unchanged.
- */
-int
-ccn_parse_uintmax(struct ccn_buf_decoder *d, uintmax_t *result)
-{
- const unsigned char *p;
- int i;
- int n;
- uintmax_t val;
- uintmax_t newval;
- unsigned char c;
- if (d->decoder.state < 0)
- return(d->decoder.state);
- if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
- p = d->buf + d->decoder.index;
- n = d->decoder.numval;
- if (n < 1)
- return(d->decoder.state = -__LINE__);
- val = 0;
- for (i = 0; i < n; i++) {
- c = p[i];
- if ('0' <= c && c <= '9') {
- newval = val * 10 + (c - '0');
- if (newval < val)
- return(d->decoder.state = -__LINE__);
- val = newval;
- }
- else
- return(d->decoder.state = -__LINE__);
- }
- ccn_buf_advance(d);
- *result = val;
- return(0);
- }
- return(d->decoder.state = -__LINE__);
-}
-
-int
-ccn_parse_timestamp(struct ccn_buf_decoder *d)
-{
- const unsigned char dlm[] = "--T::.Z";
- const unsigned char *p;
- int i;
- int k;
- int n;
- if (d->decoder.state < 0)
- return(d->decoder.state);
- if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_BLOB) {
- /* New-style binary timestamp, 12-bit fraction */
- n = d->decoder.numval;
- if (n < 3 || n > 7)
- return(d->decoder.state = -__LINE__);
- ccn_buf_advance(d);
- return(0);
- }
- if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
- /* This is for some temporary back-compatibility */
- p = d->buf + d->decoder.index;
- n = d->decoder.numval;
- if (n < 8 || n > 40)
- return(d->decoder.state = -__LINE__);
- if (p[n - 1] != 'Z')
- return(d->decoder.state = -__LINE__);
- for (i = 0, k = 0; i < n && '0' <= p[i] && p[i] <= '9';) {
- i++;
- if (i < n && p[i] == dlm[k]) {
- if (dlm[k++] == 0)
- return(d->decoder.state = -__LINE__);
- i++;
- }
- }
- if (k < 5)
- return(d->decoder.state = -__LINE__);
- if (!(i == n || i == n - 1))
- return(d->decoder.state = -__LINE__);
- ccn_buf_advance(d);
- return(0);
- }
- return(d->decoder.state = -__LINE__);
-}
-
-int
-ccn_parse_required_tagged_timestamp(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
-{
- int res = -1;
- if (ccn_buf_match_dtag(d, dtag)) {
- res = d->decoder.element_index;
- ccn_buf_advance(d);
- ccn_parse_timestamp(d);
- ccn_buf_check_close(d);
- }
- else
- d->decoder.state = -__LINE__;
- if (d->decoder.state < 0)
- return (-1);
- return(res);
-}
-
-int
-ccn_parse_optional_tagged_nonNegativeInteger(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
-{
- int res = -1;
- if (ccn_buf_match_dtag(d, dtag)) {
- ccn_buf_advance(d);
- res = ccn_parse_nonNegativeInteger(d);
- ccn_buf_check_close(d);
- }
- if (d->decoder.state < 0)
- return (d->decoder.state);
- return(res);
-}
-
-int
-ccn_fetch_tagged_nonNegativeInteger(enum ccn_dtag tt,
- const unsigned char *buf,
- size_t start, size_t stop)
-{
- struct ccn_buf_decoder decoder;
- struct ccn_buf_decoder *d;
- int result = -1;
- if (stop < start) return(-1);
- d = ccn_buf_decoder_start(&decoder, buf + start, stop - start);
- if (ccn_buf_match_dtag(d, tt)) {
- ccn_buf_advance(d);
- result = ccn_parse_nonNegativeInteger(d);
- ccn_buf_check_close(d);
- }
- if (result < 0)
- return(-1);
- return(result);
-}
-
-
-int
-ccn_parse_interest(const unsigned char *msg, size_t size,
- struct ccn_parsed_interest *interest,
- struct ccn_indexbuf *components)
-{
- struct ccn_buf_decoder decoder;
- struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size);
- int magic = 0;
- int ncomp = 0;
- int res;
- if (ccn_buf_match_dtag(d, CCN_DTAG_Interest)) {
- if (components == NULL) {
- /* We need to have the component offsets. */
- components = ccn_indexbuf_create();
- if (components == NULL) return(-1);
- res = ccn_parse_interest(msg, size, interest, components);
- ccn_indexbuf_destroy(&components);
- return(res);
- }
- ccn_buf_advance(d);
- interest->offset[CCN_PI_B_Name] = d->decoder.element_index;
- interest->offset[CCN_PI_B_Component0] = d->decoder.index;
- ncomp = ccn_parse_Name(d, components);
- if (d->decoder.state < 0) {
- memset(interest->offset, 0, sizeof(interest->offset));
- return(d->decoder.state);
- }
- interest->offset[CCN_PI_E_ComponentLast] = d->decoder.token_index - 1;
- interest->offset[CCN_PI_E_Name] = d->decoder.token_index;
- interest->prefix_comps = ncomp;
- interest->offset[CCN_PI_B_LastPrefixComponent] = components->buf[(ncomp > 0) ? (ncomp - 1) : 0];
- interest->offset[CCN_PI_E_LastPrefixComponent] = components->buf[ncomp];
- /* optional MinSuffixComponents, MaxSuffixComponents */
- interest->min_suffix_comps = 0;
- interest->max_suffix_comps = 32767;
- interest->offset[CCN_PI_B_MinSuffixComponents] = d->decoder.token_index;
- res = ccn_parse_optional_tagged_nonNegativeInteger(d,
- CCN_DTAG_MinSuffixComponents);
- interest->offset[CCN_PI_E_MinSuffixComponents] = d->decoder.token_index;
- if (res >= 0)
- interest->min_suffix_comps = res;
- interest->offset[CCN_PI_B_MaxSuffixComponents] = d->decoder.token_index;
- res = ccn_parse_optional_tagged_nonNegativeInteger(d,
- CCN_DTAG_MaxSuffixComponents);
- interest->offset[CCN_PI_E_MaxSuffixComponents] = d->decoder.token_index;
- if (res >= 0)
- interest->max_suffix_comps = res;
- if (interest->max_suffix_comps < interest->min_suffix_comps)
- return (d->decoder.state = -__LINE__);
- /* optional PublisherID */
- res = ccn_parse_PublisherID(d, interest);
- /* optional Exclude element */
- interest->offset[CCN_PI_B_Exclude] = d->decoder.token_index;
- res = ccn_parse_Exclude(d);
- interest->offset[CCN_PI_E_Exclude] = d->decoder.token_index;
- /* optional ChildSelector */
- interest->offset[CCN_PI_B_ChildSelector] = d->decoder.token_index;
- res = ccn_parse_optional_tagged_nonNegativeInteger(d,
- CCN_DTAG_ChildSelector);
- if (res < 0)
- res = 0;
- interest->orderpref = res;
- interest->offset[CCN_PI_E_ChildSelector] = d->decoder.token_index;
- if (interest->orderpref > 5)
- return (d->decoder.state = -__LINE__);
- /* optional AnswerOriginKind */
- interest->offset[CCN_PI_B_AnswerOriginKind] = d->decoder.token_index;
- interest->answerfrom = ccn_parse_optional_tagged_nonNegativeInteger(d,
- CCN_DTAG_AnswerOriginKind);
- interest->offset[CCN_PI_E_AnswerOriginKind] = d->decoder.token_index;
- if (interest->answerfrom == -1)
- interest->answerfrom = CCN_AOK_DEFAULT;
- else if ((interest->answerfrom & CCN_AOK_NEW) != 0 &&
- (interest->answerfrom & CCN_AOK_CS) == 0)
- return (d->decoder.state = -__LINE__);
- /* optional Scope */
- interest->offset[CCN_PI_B_Scope] = d->decoder.token_index;
- interest->scope = ccn_parse_optional_tagged_nonNegativeInteger(d,
- CCN_DTAG_Scope);
- interest->offset[CCN_PI_E_Scope] = d->decoder.token_index;
- if (interest->scope > 9)
- return (d->decoder.state = -__LINE__);
- if ((interest->answerfrom & CCN_AOK_EXPIRE) != 0 &&
- interest->scope != 0)
- return (d->decoder.state = -__LINE__);
- /* optional InterestLifetime */
- interest->offset[CCN_PI_B_InterestLifetime] = d->decoder.token_index;
- res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_InterestLifetime, 1, 8);
- if (res >= 0)
- magic |= 20100401;
- interest->offset[CCN_PI_E_InterestLifetime] = d->decoder.token_index;
- /* optional Nonce */
- interest->offset[CCN_PI_B_Nonce] = d->decoder.token_index;
- res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Nonce, 4, 64);
- interest->offset[CCN_PI_E_Nonce] = d->decoder.token_index;
- /* Allow for no experimental stuff */
- interest->offset[CCN_PI_B_OTHER] = d->decoder.token_index;
- interest->offset[CCN_PI_E_OTHER] = d->decoder.token_index;
- ccn_buf_check_close(d);
- interest->offset[CCN_PI_E] = d->decoder.index;
- }
- else
- return (d->decoder.state = -__LINE__);
- if (d->decoder.state < 0)
- return (d->decoder.state);
- if (d->decoder.index != (int)size || !CCN_FINAL_DSTATE(d->decoder.state))
- return (CCN_DSTATE_ERR_CODING);
- if (magic == 0)
- magic = 20090701;
- if (!(magic == 20090701 || magic == 20100401))
- return (d->decoder.state = -__LINE__);
- interest->magic = magic;
- return (ncomp);
-}
-
-struct parsed_KeyName {
- int Name;
- int endName;
- int PublisherID;
- int endPublisherID;
-};
-
-static int
-ccn_parse_KeyName(struct ccn_buf_decoder *d, struct parsed_KeyName *x)
-{
- int res = -1;
- if (ccn_buf_match_dtag(d, CCN_DTAG_KeyName)) {
- res = d->decoder.element_index;
- ccn_buf_advance(d);
- x->Name = d->decoder.token_index;
- ccn_parse_Name(d, NULL);
- x->endName = d->decoder.token_index;
- x->PublisherID = ccn_parse_PublisherID(d, NULL);
- x->endPublisherID = d->decoder.token_index;
- ccn_buf_check_close(d);
- }
- else
- d->decoder.state = -__LINE__;
- if (d->decoder.state < 0)
- return (d->decoder.state);
- return(res);
-}
-
-static int
-ccn_parse_Signature(struct ccn_buf_decoder *d, struct ccn_parsed_ContentObject *x)
-{
- int res = -1;
- int i;
- struct ccn_parsed_ContentObject dummy;
- if (x == NULL)
- x = &dummy;
- for (i = CCN_PCO_B_Signature; i <= CCN_PCO_E_Signature; i++) {
- x->offset[i] = d->decoder.token_index;
- }
- if (ccn_buf_match_dtag(d, CCN_DTAG_Signature)) {
- res = d->decoder.element_index;
- ccn_buf_advance(d);
- x->offset[CCN_PCO_B_DigestAlgorithm] = d->decoder.token_index;
- ccn_parse_optional_tagged_UDATA(d, CCN_DTAG_DigestAlgorithm);
- x->offset[CCN_PCO_E_DigestAlgorithm] = d->decoder.token_index;
- x->offset[CCN_PCO_B_Witness] = d->decoder.token_index;
- ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Witness, 8, -1);
- x->offset[CCN_PCO_E_Witness] = d->decoder.token_index;
- x->offset[CCN_PCO_B_SignatureBits] = d->decoder.token_index;
- ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SignatureBits, 16, -1);
- x->offset[CCN_PCO_E_SignatureBits] = d->decoder.token_index;
- ccn_buf_check_close(d);
- x->offset[CCN_PCO_E_Signature] = d->decoder.token_index;
- }
- if (d->decoder.state < 0)
- return (d->decoder.state);
- return(res);
-}
-
-static int
-ccn_parse_SignedInfo(struct ccn_buf_decoder *d, struct ccn_parsed_ContentObject *x)
-{
- x->offset[CCN_PCO_B_SignedInfo] = d->decoder.token_index;
- if (ccn_buf_match_dtag(d, CCN_DTAG_SignedInfo)) {
- ccn_buf_advance(d);
- x->offset[CCN_PCO_B_PublisherPublicKeyDigest] = d->decoder.token_index;
- ccn_parse_required_tagged_BLOB(d, CCN_DTAG_PublisherPublicKeyDigest, 16, 64);
- x->offset[CCN_PCO_E_PublisherPublicKeyDigest] = d->decoder.token_index;
-
- x->offset[CCN_PCO_B_Timestamp] = d->decoder.token_index;
- ccn_parse_required_tagged_timestamp(d, CCN_DTAG_Timestamp);
- x->offset[CCN_PCO_E_Timestamp] = d->decoder.token_index;
-
- x->offset[CCN_PCO_B_Type] = d->decoder.token_index;
- x->type = CCN_CONTENT_DATA;
- x->type = (ccn_content_type)ccn_parse_optional_tagged_binary_number(d, CCN_DTAG_Type, 3, 3, CCN_CONTENT_DATA);
- x->offset[CCN_PCO_E_Type] = d->decoder.token_index;
-
- x->offset[CCN_PCO_B_FreshnessSeconds] = d->decoder.token_index;
- ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds);
- x->offset[CCN_PCO_E_FreshnessSeconds] = d->decoder.token_index;
-
- x->offset[CCN_PCO_B_FinalBlockID] = d->decoder.token_index;
- ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_FinalBlockID, 1, -1);
- x->offset[CCN_PCO_E_FinalBlockID] = d->decoder.token_index;
-
- x->offset[CCN_PCO_B_KeyLocator] = d->decoder.token_index;
- x->offset[CCN_PCO_B_Key_Certificate_KeyName] = d->decoder.token_index;
- x->offset[CCN_PCO_E_Key_Certificate_KeyName] = d->decoder.token_index;
- x->offset[CCN_PCO_B_KeyName_Name] = d->decoder.token_index;
- x->offset[CCN_PCO_E_KeyName_Name] = d->decoder.token_index;
- x->offset[CCN_PCO_B_KeyName_Pub] = d->decoder.token_index;
- x->offset[CCN_PCO_E_KeyName_Pub] = d->decoder.token_index;
- if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator)) {
- ccn_buf_advance(d);
- x->offset[CCN_PCO_B_Key_Certificate_KeyName] = d->decoder.token_index;
- if (ccn_buf_match_dtag(d, CCN_DTAG_Key)) {
- (void)ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Key, 0, -1);
- }
- else if (ccn_buf_match_dtag(d, CCN_DTAG_Certificate)) {
- (void)ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Certificate, 0, -1);
- }
- else {
- struct parsed_KeyName keyname = {-1, -1, -1, -1};
- if (ccn_parse_KeyName(d, &keyname) >= 0) {
- if (keyname.Name >= 0) {
- x->offset[CCN_PCO_B_KeyName_Name] = keyname.Name;
- x->offset[CCN_PCO_E_KeyName_Name] = keyname.endName;
- }
- if (keyname.PublisherID >= 0) {
- x->offset[CCN_PCO_B_KeyName_Pub] = keyname.PublisherID;
- x->offset[CCN_PCO_E_KeyName_Pub] = keyname.endPublisherID;
- }
- }
- }
- x->offset[CCN_PCO_E_Key_Certificate_KeyName] = d->decoder.token_index;
- ccn_buf_check_close(d);
- }
- x->offset[CCN_PCO_E_KeyLocator] = d->decoder.token_index;
- ccn_buf_check_close(d);
- }
- else
- d->decoder.state = -__LINE__;
- x->offset[CCN_PCO_E_SignedInfo] = d->decoder.token_index;
- if (d->decoder.state < 0)
- return (d->decoder.state);
- return(0);
-}
-
-int
-ccn_parse_ContentObject(const unsigned char *msg, size_t size,
- struct ccn_parsed_ContentObject *x,
- struct ccn_indexbuf *components)
-{
- struct ccn_buf_decoder decoder;
- struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size);
- int res;
- x->magic = 20090415;
- x->digest_bytes = 0;
- if (ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) {
- ccn_buf_advance(d);
- res = ccn_parse_Signature(d, x);
- x->offset[CCN_PCO_B_Name] = d->decoder.token_index;
- x->offset[CCN_PCO_B_Component0] = d->decoder.index;
- res = ccn_parse_Name(d, components);
- if (res < 0)
- d->decoder.state = -__LINE__;
- x->name_ncomps = res;
- x->offset[CCN_PCO_E_ComponentLast] = d->decoder.token_index - 1;
- x->offset[CCN_PCO_E_Name] = d->decoder.token_index;
- ccn_parse_SignedInfo(d, x);
- x->offset[CCN_PCO_B_Content] = d->decoder.token_index;
- ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Content, 0, -1);
- x->offset[CCN_PCO_E_Content] = d->decoder.token_index;
- ccn_buf_check_close(d);
- x->offset[CCN_PCO_E] = d->decoder.index;
- }
- else
- d->decoder.state = -__LINE__;
- if (d->decoder.index != (int)size || !CCN_FINAL_DSTATE(d->decoder.state))
- return (CCN_DSTATE_ERR_CODING);
- return(0);
-}
-
-int
-ccn_ref_tagged_BLOB(enum ccn_dtag tt,
- const unsigned char *buf, size_t start, size_t stop,
- const unsigned char **presult, size_t *psize)
-{
- struct ccn_buf_decoder decoder;
- struct ccn_buf_decoder *d;
- if (stop < start) return(-1);
- d = ccn_buf_decoder_start(&decoder, buf + start, stop - start);
- if (ccn_buf_match_dtag(d, tt)) {
- ccn_buf_advance(d);
- if (ccn_buf_match_blob(d, presult, psize))
- ccn_buf_advance(d);
- ccn_buf_check_close(d);
- }
- else
- return(-1);
- if (d->decoder.index != (int)d->size || !CCN_FINAL_DSTATE(d->decoder.state))
- return (CCN_DSTATE_ERR_CODING);
- return(0);
-}
-
-static struct ccn_buf_decoder *
-ccn_buf_decoder_start_at_components(struct ccn_buf_decoder *d,
- const unsigned char *buf, size_t buflen)
-{
- ccn_buf_decoder_start(d, buf, buflen);
- while (ccn_buf_match_dtag(d, CCN_DTAG_Name) ||
- ccn_buf_match_dtag(d, CCN_DTAG_Interest) ||
- ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)
- ) {
- ccn_buf_advance(d);
- ccn_parse_Signature(d, NULL);
- }
- return(d);
-}
-
-int
-ccn_content_get_value(const unsigned char *data, size_t data_size,
- const struct ccn_parsed_ContentObject *content,
- const unsigned char **value, size_t *value_size)
-{
- int res;
- res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, data,
- content->offset[CCN_PCO_B_Content],
- content->offset[CCN_PCO_E_Content],
- value, value_size);
- return(res);
-}
-
-int
-ccn_compare_names(const unsigned char *a, size_t asize,
- const unsigned char *b, size_t bsize)
-{
- struct ccn_buf_decoder a_decoder;
- struct ccn_buf_decoder b_decoder;
- struct ccn_buf_decoder *aa =
- ccn_buf_decoder_start_at_components(&a_decoder, a, asize);
- struct ccn_buf_decoder *bb =
- ccn_buf_decoder_start_at_components(&b_decoder, b, bsize);
- const unsigned char *acp = NULL;
- const unsigned char *bcp = NULL;
- size_t acsize;
- size_t bcsize;
- int cmp = 0;
- int more_a;
- for (;;) {
- more_a = ccn_buf_match_dtag(aa, CCN_DTAG_Component);
- cmp = more_a - ccn_buf_match_dtag(bb, CCN_DTAG_Component);
- if (more_a == 0 || cmp != 0)
- break;
- ccn_buf_advance(aa);
- ccn_buf_advance(bb);
- acsize = bcsize = 0;
- if (ccn_buf_match_blob(aa, &acp, &acsize))
- ccn_buf_advance(aa);
- if (ccn_buf_match_blob(bb, &bcp, &bcsize))
- ccn_buf_advance(bb);
- cmp = acsize - bcsize;
- if (cmp != 0)
- break;
- cmp = memcmp(acp, bcp, acsize);
- if (cmp != 0)
- break;
- ccn_buf_check_close(aa);
- ccn_buf_check_close(bb);
- }
- return (cmp);
-}
-
diff --git a/in-progress/ccn/ccn_buf_encoder.cc b/in-progress/ccn/ccn_buf_encoder.cc
deleted file mode 100644
index d0d157b..0000000
--- a/in-progress/ccn/ccn_buf_encoder.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include "ccn.h"
-#include "ccn_charbuf.h"
-#include "ccn_coding.h"
-#include "ccn_indexbuf.h"
-
-/**
- * Encode and sign a ContentObject.
- * @param buf is the output buffer where encoded object is written.
- * @param Name is the ccnb-encoded name from ccn_name_init and friends.
- * @param SignedInfo is the ccnb-encoded info from ccn_signed_info_create.
- * @param data pintes to the raw data to be encoded.
- * @param size is the size, in bytes, of the raw data to be encoded.
- * @param digest_algorithm may be NULL for default.
- * @param private_key is the private key to use for signing.
- * @returns 0 for success or -1 for error.
- */
-int
-ccn_encode_ContentObject(struct ccn_charbuf *buf,
- const struct ccn_charbuf *Name,
- /*const struct ccn_charbuf *SignedInfo,*/
- const void *data,
- size_t size
- /*const char *digest_algorithm,
- const struct ccn_pkey *private_key*/
- )
-{
- int res = 0;
-
- res |= ccn_charbuf_append_tt(buf, CCN_DTAG_ContentObject, CCN_DTAG);
- //res |= ccn_encode_Signature(buf, digest_algorithm,
- // NULL, 0, signature, signature_size);
- res |= ccn_charbuf_append_charbuf(buf, Name);
- //res |= ccn_charbuf_append_charbuf(buf, SignedInfo);
- res |= ccnb_append_tagged_blob(buf, CCN_DTAG_Content, data, size);
- res |= ccn_charbuf_append_closer(buf);
- //free(signature);
- ccn_charbuf_destroy(&content_header);
- return(res == 0 ? 0 : -1);
-}
-
-/**
- * Append a tagged BLOB
- *
- * This is a ccnb-encoded element with containing the BLOB as content
- * @param c is the buffer to append to.
- * @param dtag is the element's dtab
- * @param data points to the binary data
- * @param size is the size of the data, in bytes
- * @returns 0 for success or -1 for error.
- */
-int
-ccnb_append_tagged_blob(struct ccn_charbuf *c,
- enum ccn_dtag dtag,
- const void *data,
- size_t size)
-{
- int res;
-
- res = ccn_charbuf_append_tt(c, dtag, CCN_DTAG);
- if (size != 0) {
- res |= ccn_charbuf_append_tt(c, size, CCN_BLOB);
- res |= ccn_charbuf_append(c, data, size);
- }
- res |= ccn_charbuf_append_closer(c);
- return(res == 0 ? 0 : -1);
-}
diff --git a/in-progress/ccn/ccn_charbuf.cc b/in-progress/ccn/ccn_charbuf.cc
deleted file mode 100644
index 06c6544..0000000
--- a/in-progress/ccn/ccn_charbuf.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ccn_charbuf.h"
-
-/**
- * @file ccn_charbuf.c
- * @brief Support expandable buffer for counted sequences of arbitrary bytes.
- *
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008, 2009 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include "ccn_coding.h"
-
-struct ccn_charbuf *
-ccn_charbuf_create(void)
-{
- struct ccn_charbuf *c;
- c = (ccn_charbuf*)calloc(1, sizeof(*c));
- return(c);
-}
-
-void
-ccn_charbuf_destroy(struct ccn_charbuf **cbp)
-{
- struct ccn_charbuf *c = *cbp;
- if (c != NULL) {
- if (c->buf != NULL)
- free(c->buf);
- free(c);
- *cbp = NULL;
- }
-}
-
-/*
- * ccn_charbuf_reserve: expand buffer as necessary to hold n more chars
- */
-unsigned char *
-ccn_charbuf_reserve(struct ccn_charbuf *c, size_t n)
-{
- size_t newsz = n + c->length;
- unsigned char *buf = c->buf;
- if (newsz < n)
- return(NULL);
- if (newsz > c->limit) {
- if (2 * c->limit > newsz)
- newsz = 2 * c->limit;
- buf = (unsigned char*)realloc(c->buf, newsz);
- if (buf == NULL)
- return(NULL);
- memset(buf + c->limit, 0, newsz - c->limit);
- c->buf = buf;
- c->limit = newsz;
- }
- buf += c->length;
- return(buf);
-}
-
-void ccn_charbuf_reset(struct ccn_charbuf *c)
-{
- if (c == NULL) {
- return;
- }
- c->length = 0;
-}
-
-int
-ccn_charbuf_append(struct ccn_charbuf *c, const void *p, size_t n)
-{
- unsigned char *dst = ccn_charbuf_reserve(c, n);
- if (dst == NULL)
- return(-1);
- memcpy(dst, p, n);
- c->length += n;
- return(0);
-}
-
-int
-ccn_charbuf_append_value(struct ccn_charbuf *c, unsigned val, unsigned n)
-{
- unsigned char *dst;
- unsigned i;
- if (n > sizeof(val))
- return(-1);
- dst = ccn_charbuf_reserve(c, n);
- if (dst == NULL)
- return(-1);
- for (i = 0; i < n; i++)
- dst[i] = (unsigned char)(val >> (8 * (n-1-i)));
- c->length += n;
- return(0);
-}
-
-int
-ccn_charbuf_append_charbuf(struct ccn_charbuf *c, const struct ccn_charbuf *in)
-{
- return(ccn_charbuf_append(c, in->buf, in->length));
-}
-
-int
-ccn_charbuf_append_string(struct ccn_charbuf *c, const char *s)
-{
- return(ccn_charbuf_append(c, s, strlen(s)));
-}
-
-int
-ccn_charbuf_putf(struct ccn_charbuf *c, const char *fmt, ...)
-{
- int sz;
- va_list ap;
- char *buf;
- buf = (char *)ccn_charbuf_reserve(c, strlen(fmt) + 10); /* estimate */
- if (buf == NULL) return(-1);
- va_start(ap, fmt);
- sz = vsnprintf(buf, c->limit - c->length, fmt, ap);
- va_end(ap);
- if (sz < 0)
- return(sz);
- if (c->length + sz < c->limit) {
- c->length += sz;
- return(sz);
- }
- va_end(ap);
- buf = (char *)ccn_charbuf_reserve(c, sz + 1); /* accurate */
- if (buf == NULL) return(-1);
- va_start(ap, fmt);
- sz = vsnprintf(buf, c->limit - c->length, fmt, ap);
- va_end(ap);
- if (c->length + sz < c->limit) {
- c->length += sz;
- return(sz);
- }
- return(-1);
-}
-
-/* This formats time into xs:dateTime format */
-int
-ccn_charbuf_append_datetime(struct ccn_charbuf *c, time_t secs, int nsecs)
-{
- char timestring[32];
- int timelen;
- struct tm time_tm;
- int res;
-
- timelen = strftime(timestring, sizeof(timestring),
- "%FT%T", gmtime_r(&secs, &time_tm));
- if (timelen >= (int)sizeof(timestring))
- return(-1);
- if (nsecs != 0) {
- if (nsecs < 0 || nsecs >= 1000000000)
- return(-1);
- timelen += snprintf(×tring[timelen], sizeof(timestring) - timelen,
- ".%09d", nsecs);
- if (timelen >= (int)sizeof(timestring))
- return(-1);
- while (timestring[timelen - 1] == '0') timelen--;
- }
- timestring[timelen++] = 'Z';
- res = ccn_charbuf_append(c, timestring, timelen);
- return (res);
-}
-
-char *
-ccn_charbuf_as_string(struct ccn_charbuf *c)
-{
- unsigned char *r;
- r = ccn_charbuf_reserve(c, 1);
- if (r == NULL)
- return(NULL);
- r[0] = 0;
- return((char *)c->buf);
-}
-
-int
-ccn_charbuf_append_closer(struct ccn_charbuf *c)
-{
- int res;
- const unsigned char closer = CCN_CLOSE;
- res = ccn_charbuf_append(c, &closer, 1);
- return(res);
-}
diff --git a/in-progress/ccn/ccn_charbuf.h b/in-progress/ccn/ccn_charbuf.h
deleted file mode 100644
index 066eda2..0000000
--- a/in-progress/ccn/ccn_charbuf.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-/**
- * @file ccn/charbuf.h
- *
- * Expandable character buffer for counted sequences of arbitrary octets.
- *
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008, 2009 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef CCN_CHARBUF_DEFINED
-#define CCN_CHARBUF_DEFINED
-
-#include <stddef.h>
-#include <time.h>
-
-struct ccn_charbuf {
- size_t length;
- size_t limit;
- unsigned char *buf;
-};
-
-/*
- * ccn_charbuf_create: allocate a new charbuf
- * ccn_charbuf_destroy: destroy a charbuf
- */
-struct ccn_charbuf *ccn_charbuf_create(void);
-void ccn_charbuf_destroy(struct ccn_charbuf **cbp);
-
-/*
- * ccn_charbuf_reserve: reserve some space in the buffer
- * Grows c->buf if needed and returns a pointer to the new region.
- * Does not modify c->length
- */
-unsigned char *ccn_charbuf_reserve(struct ccn_charbuf *c, size_t n);
-
-/*
- * ccn_charbuf_reset: reset to empty for reuse
- * Sets c->length to 0
- */
-void ccn_charbuf_reset(struct ccn_charbuf *c);
-
-/*
- * ccn_charbuf_append: append character content
- */
-int ccn_charbuf_append(struct ccn_charbuf *c, const void *p, size_t n);
-
-/*
- * ccn_charbuf_append: append n bytes of val
- * The n low-order bytes are appended in network byte order (big-endian)
- */
-int ccn_charbuf_append_value(struct ccn_charbuf *c, unsigned val, unsigned n);
-
-
-/*
- * ccn_charbuf_append_charbuf: append content from another charbuf
- */
-int ccn_charbuf_append_charbuf(struct ccn_charbuf *c, const struct ccn_charbuf *i);
-
-/*
- * ccn_charbuf_append: append a string
- * Sometimes you have a null-terminated string in hand...
- */
-int ccn_charbuf_append_string(struct ccn_charbuf *c, const char *s);
-
-/*
- * ccn_charbuf_putf: formatting output
- * Use this in preference to snprintf to simplify bookkeeping.
- */
-int ccn_charbuf_putf(struct ccn_charbuf *c, const char *fmt, ...);
-
-/*
- * ccn_charbuf_append_datetime: append a date/time string
- * Appends a dateTime string in canonical form according to
- * http://www.w3.org/TR/xmlschema-2/
- * Return value is 0, or -1 for error.
- * example: 2008-07-22T17:33:14.109Z
- */
-int ccn_charbuf_append_datetime(struct ccn_charbuf *c, time_t secs, int nsecs);
-
-/*
- * ccn_charbuf_append_datetime_now: append a date/time string
- * Appends a dateTime string representing the current date and time
- * in canonical form according to
- * http://www.w3.org/TR/xmlschema-2/
- * precision, a non-negative number, indicates the maximum number
- * of fractional digits in the seconds. Only values 0..6 have
- * any effect, at this times, since the gettimeofday() function
- * is defined to return microsecond resolution.
- * Return value is 0, or -1 for error.
- * example: 2008-07-22T17:33:14.109Z
- */
-#define CCN_DATETIME_PRECISION_USEC 6
-#define CCN_DATETIME_PRECISION_MAX 6
-int ccn_charbuf_append_datetime_now(struct ccn_charbuf *c, int precision);
-
-/*
- * ccn_charbuf_as_string: view charbuf contents as a string
- * This assures that c->buf has a null termination, and simply
- * returns the pointer into the buffer. If the result needs to
- * persist beyond the next operation on c, the caller is
- * responsible for copying it.
- */
-char *ccn_charbuf_as_string(struct ccn_charbuf *c);
-
-#endif
diff --git a/in-progress/ccn/ccn_indexbuf.cc b/in-progress/ccn/ccn_indexbuf.cc
deleted file mode 100644
index 034c5db..0000000
--- a/in-progress/ccn/ccn_indexbuf.cc
+++ /dev/null
@@ -1,247 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ccn_indexbuf.h"
-
-/**
- * @file ccn_indexbuf.c
- * @brief Support for expandable buffer of non-negative values.
- *
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008, 2009 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define ELEMENT size_t
-
-/**
- * Create a new indexbuf.
- */
-struct ccn_indexbuf *
-ccn_indexbuf_create(void)
-{
- struct ccn_indexbuf *c;
- c = (ccn_indexbuf*)calloc(1, sizeof(*c));
- return(c);
-}
-
-/**
- * Deallocate indexbuf.
- */
-void
-ccn_indexbuf_destroy(struct ccn_indexbuf **cbp)
-{
- struct ccn_indexbuf *c = *cbp;
- if (c != NULL) {
- if (c->buf != NULL) {
- free(c->buf);
- }
- free(c);
- *cbp = NULL;
- }
-}
-
-/**
- * Expand buffer as necessary to hold at least n more values.
- * @returns pointer to reserved space
- */
-ELEMENT *
-ccn_indexbuf_reserve(struct ccn_indexbuf *c, size_t n)
-{
- size_t newlim = n + c->n;
- size_t oldlim = c->limit;
- ELEMENT *buf = c->buf;
- if (newlim < n)
- return(NULL);
- if (newlim > oldlim) {
- if (2 * oldlim > newlim)
- newlim = 2 * oldlim;
- buf = (size_t*)realloc(c->buf, newlim * sizeof(ELEMENT));
- if (buf == NULL)
- return(NULL);
- memset(buf + oldlim, 0, (newlim - oldlim) * sizeof(ELEMENT));
- c->buf = buf;
- c->limit = newlim;
- }
- buf += c->n;
- return(buf);
-}
-
-/**
- * Append multiple elements to the indexbuf.
- * @returns 0 for success, -1 for failure.
- */
-int
-ccn_indexbuf_append(struct ccn_indexbuf *c, const ELEMENT *p, size_t n)
-{
- ELEMENT *dst = ccn_indexbuf_reserve(c, n);
- if (dst == NULL)
- return(-1);
- memcpy(dst, p, n * sizeof(ELEMENT));
- c->n += n;
- return(0);
-}
-
-/**
- * Append v to the indexbuf
- * @returns 0 for success, -1 for failure.
- */
-int
-ccn_indexbuf_append_element(struct ccn_indexbuf *c, ELEMENT v)
-{
- ELEMENT *dst = ccn_indexbuf_reserve(c, 1);
- if (dst == NULL)
- return(-1);
- *dst = v;
- c->n += 1;
- return(0);
-}
-
-/**
- * @returns index at which the element was found or appended, or -1 if not found.
- */
-int
-ccn_indexbuf_member(struct ccn_indexbuf *x, ELEMENT val)
-{
- int i;
- if (x == NULL)
- return (-1);
- for (i = x->n - 1; i >= 0; i--)
- if (x->buf[i] == val)
- return(i);
- return(-1);
-}
-
-/**
- * Removes up to one instance of val from the indexbuf.
- * Order of elements not preserved.
- */
-void
-ccn_indexbuf_remove_element(struct ccn_indexbuf *x, ELEMENT val)
-{
- int i;
- if (x == NULL) return;
- for (i = x->n - 1; i >= 0; i--)
- if (x->buf[i] == val) {
- x->buf[i] = x->buf[--x->n]; /* move last element into vacant spot */
- return;
- }
-}
-
-/**
- * @returns index at which the element was found or appended,
- * or -1 in case of error.
- */
-int
-ccn_indexbuf_set_insert(struct ccn_indexbuf *x, ELEMENT val)
-{
- int i;
- if (x == NULL)
- return (-1);
- for (i = 0; i < (int)x->n; i++)
- if (x->buf[i] == val)
- return(i);
- if (ccn_indexbuf_append_element(x, val) < 0)
- return(-1);
- return(i);
-}
-
-/**
- * Removes first occurrence of val, preserving order
- * @returns index at which the element was found,
- * or -1 if the element was not found.
- */
-int
-ccn_indexbuf_remove_first_match(struct ccn_indexbuf *x, ELEMENT val)
-{
- int i;
- int n;
- if (x == NULL)
- return (-1);
- for (i = 0, n = x->n; i < n; i++) {
- if (x->buf[i] == val) {
- if (i + 1 < n)
- memmove(&(x->buf[i]),
- &(x->buf[i + 1]),
- sizeof(x->buf[i]) * (n - i - 1));
- x->n--;
- return(i);
- }
- }
- return(-1);
-}
-
-/**
- * If val is present in the indexbuf, move it to the final place.
- */
-void
-ccn_indexbuf_move_to_end(struct ccn_indexbuf *x, ELEMENT val)
-{
- int i;
- int n;
- if (x == NULL)
- return;
- for (i = 0, n = x->n; i + 1 < n; i++) {
- if (x->buf[i] == val) {
- memmove(&(x->buf[i]),
- &(x->buf[i + 1]),
- sizeof(x->buf[i]) * (n - i - 1));
- x->buf[n - 1] = val;
- return;
- }
- }
-}
-
-/**
- * If val is present in the indexbuf, move it to the first place.
- */
-void
-ccn_indexbuf_move_to_front(struct ccn_indexbuf *x, ELEMENT val)
-{
- int i;
- int n;
- if (x == NULL)
- return;
- for (i = 0, n = x->n; i < n; i++) {
- if (x->buf[i] == val) {
- memmove(&(x->buf[1]),
- &(x->buf[0]),
- sizeof(x->buf[i]) * i);
- x->buf[0] = val;
- return;
- }
- }
-
-}
-
diff --git a/in-progress/ccn/ccn_indexbuf.h b/in-progress/ccn/ccn_indexbuf.h
deleted file mode 100644
index 3e133c3..0000000
--- a/in-progress/ccn/ccn_indexbuf.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-/**
- * @file ccn/indexbuf.h
- *
- * Expandable buffer of non-negative values.
- *
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008, 2009 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef CCN_INDEXBUF_DEFINED
-#define CCN_INDEXBUF_DEFINED
-
-#include <stddef.h>
-
-struct ccn_indexbuf {
- size_t n;
- size_t limit;
- size_t *buf;
-};
-
-struct ccn_indexbuf *ccn_indexbuf_create(void);
-void ccn_indexbuf_destroy(struct ccn_indexbuf **cbp);
-size_t *ccn_indexbuf_reserve(struct ccn_indexbuf *c, size_t n);
-int ccn_indexbuf_append(struct ccn_indexbuf *c, const size_t *p, size_t n);
-int ccn_indexbuf_append_element(struct ccn_indexbuf *c, size_t v);
-int ccn_indexbuf_member(struct ccn_indexbuf *x, size_t val);
-void ccn_indexbuf_remove_element(struct ccn_indexbuf *x, size_t val);
-int ccn_indexbuf_set_insert(struct ccn_indexbuf *x, size_t val);
-int ccn_indexbuf_remove_first_match(struct ccn_indexbuf *x, size_t val);
-void ccn_indexbuf_move_to_end(struct ccn_indexbuf *x, size_t val);
-void ccn_indexbuf_move_to_front(struct ccn_indexbuf *x, size_t val);
-
-#endif
diff --git a/in-progress/ccn/ccn_name_util.cc b/in-progress/ccn/ccn_name_util.cc
deleted file mode 100644
index 64405ce..0000000
--- a/in-progress/ccn/ccn_name_util.cc
+++ /dev/null
@@ -1,326 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ccn_name_util.h"
-#include "ccn_coding.h"
-#include "ccn_charbuf.h"
-#include "ccn_indexbuf.h"
-#include <string.h>
-#include <stdlib.h>
-#include "ccn_random.h"
-#include "ccn.h"
-
-/**
- * @file ccn_name_util.c
- * @brief Support for manipulating ccnb-encoded Names.
- *
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008-2010 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-//#include <ccn/ccn.h>
-
-/**
- * Reset charbuf to represent an empty Name in binary format.
- * @returns 0, or -1 for error.
- */
-int
-ccn_name_init(struct ccn_charbuf *c)
-{
- int res;
- c->length = 0;
- res = ccn_charbuf_append_tt(c, CCN_DTAG_Name, CCN_DTAG);
- if (res == -1) return(res);
- res = ccn_charbuf_append_closer(c);
- return(res);
-}
-
-/**
- * Add a Component to a Name.
- *
- * The component is an arbitrary string of n octets, no escaping required.
- * @returns 0, or -1 for error.
- */
-int
-ccn_name_append(struct ccn_charbuf *c, const void *component, size_t n)
-{
- int res;
- const unsigned char closer[2] = {CCN_CLOSE, CCN_CLOSE};
- if (c->length < 2 || c->buf[c->length-1] != closer[1])
- return(-1);
- c->length -= 1;
- ccn_charbuf_reserve(c, n + 8);
- res = ccn_charbuf_append_tt(c, CCN_DTAG_Component, CCN_DTAG);
- if (res == -1) return(res);
- res = ccn_charbuf_append_tt(c, n, CCN_BLOB);
- if (res == -1) return(res);
- res = ccn_charbuf_append(c, component, n);
- if (res == -1) return(res);
- res = ccn_charbuf_append(c, closer, sizeof(closer));
- return(res);
-}
-
-/**
- * Add a Component that is a NUL-terminated string.
- *
- * The component added consists of the bytes of the string without the NUL.
- * This function is convenient for those applications that construct
- * component names from simple strings.
- * @returns 0, or -1 for error.
- */
-int
-ccn_name_append_str(struct ccn_charbuf *c, const char *s)
-{
- return(ccn_name_append(c, s, strlen(s)));
-}
-
-/**
- * Add a binary Component to a ccnb-encoded Name
- *
- * These are special components used for marking versions, fragments, etc.
- * @returns 0, or -1 for error
- * see doc/technical/NameConventions.html
- */
-int
-ccn_name_append_numeric(struct ccn_charbuf *c,
- enum ccn_marker marker, unsigned long long value)
-{
- //uintmax_t v;
- unsigned long long v;
- int i;
- char b[32];
-
- for (v = value, i = sizeof(b); v != 0 && i > 0; i--, v >>= 8)
- b[i-1] = v & 0xff;
- if (i < 1)
- return(-1);
- if (marker >= 0)
- b[--i] = marker;
- return(ccn_name_append(c, b + i, sizeof(b) - i));
-}
-
-/**
- * Add nonce Component to ccnb-encoded Name
- *
- * Uses %C1.N namespace.
- * @returns 0, or -1 for error
- * see doc/technical/NameConventions.html
- */
-int
-ccn_name_append_nonce(struct ccn_charbuf *c)
-{
- const unsigned char pre[4] = { CCN_MARKER_CONTROL, '.', 'N', 0 };
- unsigned char b[15];
-
- memcpy(b, pre, sizeof(pre));
- ccn_random_bytes(b + sizeof(pre), sizeof(b) - sizeof(pre));
- return(ccn_name_append(c, b, sizeof(b)));
-}
-
-/**
- * Add sequence of ccnb-encoded Components to a ccnb-encoded Name.
- *
- * start and stop are offsets from ccnb
- * @returns 0, or -1 for obvious error
- */
-int
-ccn_name_append_components(struct ccn_charbuf *c,
- const unsigned char *ccnb,
- size_t start, size_t stop)
-{
- int res;
- if (c->length < 2 || start > stop)
- return(-1);
- c->length -= 1;
- ccn_charbuf_reserve(c, stop - start + 1);
- res = ccn_charbuf_append(c, ccnb + start, stop - start);
- if (res == -1) return(res);
- res = ccn_charbuf_append_closer(c);
- return(res);
-}
-
-/**
- * Extract a pointer to and size of component at
- * given index i. The first component is index 0.
- * @returns 0, or -1 for error.
- */
-int
-ccn_name_comp_get(const unsigned char *data,
- const struct ccn_indexbuf *indexbuf,
- unsigned int i,
- const unsigned char **comp, size_t *size)
-{
- int len;
- struct ccn_buf_decoder decoder;
- struct ccn_buf_decoder *d;
- /* indexbuf should have an extra value marking end of last component,
- so we need to use last 2 values */
- if (indexbuf->n < 2 || i > indexbuf->n - 2) {
- /* There isn't a component at this index */
- return(-1);
- }
- len = indexbuf->buf[i + 1]-indexbuf->buf[i];
- d = ccn_buf_decoder_start(&decoder, data + indexbuf->buf[i], len);
- if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
- ccn_buf_advance(d);
- if (ccn_buf_match_blob(d, comp, size))
- return(0);
- *comp = d->buf + d->decoder.index;
- *size = 0;
- ccn_buf_check_close(d);
- if (d->decoder.state >= 0)
- return(0);
- }
- return(-1);
-}
-
-int
-ccn_name_comp_strcmp(const unsigned char *data,
- const struct ccn_indexbuf *indexbuf,
- unsigned int i, const char *val)
-{
- const unsigned char *comp_ptr;
- size_t comp_size;
-
- // XXX - We probably want somewhat different semantics in the API -
- // comparing a string against a longer string with a 0 byte should
- // not claim equality.
- if (ccn_name_comp_get(data, indexbuf, i, &comp_ptr, &comp_size) == 0)
- return(strncmp(val, (const char *)comp_ptr, comp_size));
- /* Probably no such component, say query is greater-than */
- return(1);
-}
-
-/**
- * Find Component boundaries in a ccnb-encoded Name.
- *
- * Thin veneer over ccn_parse_Name().
- * components arg may be NULL to just do a validity check
- *
- * @returns -1 for error, otherwise the number of Components.
- */
-int
-ccn_name_split(const struct ccn_charbuf *c, struct ccn_indexbuf *components)
-{
- struct ccn_buf_decoder decoder;
- struct ccn_buf_decoder *d;
- d = ccn_buf_decoder_start(&decoder, c->buf, c->length);
- return(ccn_parse_Name(d, components));
-}
-
-/**
- * Chop the name down to n components.
- * @param c contains a ccnb-encoded Name
- * @param components may be NULL; if provided it must be consistent with
- * some prefix of the name, and is updated accordingly.
- * @param n is the number or components to leave, or, if negative, specifies
- * how many components to remove,
- e.g. -1 will remove just the last component.
- * @returns -1 for error, otherwise the new number of Components
- */
-int
-ccn_name_chop(struct ccn_charbuf *c, struct ccn_indexbuf *components, int n)
-{
- if (components == NULL) {
- int res;
- components = ccn_indexbuf_create();
- if (components == NULL)
- return(-1);
- res = ccn_name_split(c, components);
- if (res >= 0)
- res = ccn_name_chop(c, components, n);
- ccn_indexbuf_destroy(&components);
- return(res);
- }
- /* Fix up components if needed. We could be a little smarter about this. */
- if (components->n == 0 || components->buf[components->n-1] + 1 != c->length)
- if (ccn_name_split(c, components) < 0)
- return(-1);
- if (n < 0)
- n += (components->n - 1); /* APL-style indexing */
- if (n < 0)
- return(-1);
- if (n < (int)(components->n)) {
- c->length = components->buf[n];
- ccn_charbuf_append_value(c, CCN_CLOSE, 1);
- components->n = n + 1;
- return(n);
- }
- return(-1);
-}
-
-/**
- * Advance the last Component of a Name to the next possible value.
- * @param c contains a ccnb-encoded Name to be updated.
- * @returns -1 for error, otherwise the number of Components
- */
-int
-ccn_name_next_sibling(struct ccn_charbuf *c)
-{
- int res = -1;
- struct ccn_indexbuf *ndx;
- unsigned char *lastcomp = NULL;
- size_t lastcompsize = 0;
- size_t i;
- int carry;
- struct ccn_charbuf *newcomp;
-
- ndx = ccn_indexbuf_create();
- if (ndx == NULL) goto Finish;
- res = ccn_name_split(c, ndx);
- if (res <= 0) {
- res = -1;
- goto Finish;
- }
- res = ccn_ref_tagged_BLOB(CCN_DTAG_Component, c->buf,
- ndx->buf[res-1], ndx->buf[res],
- (const unsigned char **)&lastcomp,
- &lastcompsize);
- if (res < 0) goto Finish;
- for (carry = 1, i = lastcompsize; carry && i > 0; i--) {
- carry = (((++lastcomp[i-1]) & 0xFF) == 0x00);
- }
- if (carry) {
- newcomp = ccn_charbuf_create();
- res |= ccn_charbuf_append_value(newcomp, 0, 1);
- res |= ccn_charbuf_append(newcomp, lastcomp, lastcompsize);
- res |= ccn_name_chop(c, ndx, ndx->n - 2);
- res |= ccn_name_append(c, newcomp->buf, newcomp->length);
- ccn_charbuf_destroy(&newcomp);
- if (res < 0) goto Finish;
- }
- res = ndx->n - 1;
-Finish:
- ccn_indexbuf_destroy(&ndx);
- return(res);
-}
-
diff --git a/in-progress/ccn/ccn_name_util.h b/in-progress/ccn/ccn_name_util.h
deleted file mode 100644
index 6e5fda7..0000000
--- a/in-progress/ccn/ccn_name_util.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
diff --git a/in-progress/ccn/ccn_random.cc b/in-progress/ccn/ccn_random.cc
deleted file mode 100644
index 6176c79..0000000
--- a/in-progress/ccn/ccn_random.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ccn_random.h"
-#include <openssl/rand.h>
-//#include <openssl/rand.c>
-
-/**
- * Generate pseudo-random bytes.
- *
- * @param buf is the destination buffer
- * @param size is in bytes
- */
-void
-ccn_random_bytes(unsigned char *buf, size_t size)
-{
- int num = size;
-
- if (num < 0 || num != (int)size)
- abort();
- RAND_bytes(buf, num);
-}
-
-/**
- * Feed some entropy to the random number generator.
- *
- * @param buf is the source buffer
- * @param size is in bytes
- * @param bits_of_entropy is an estimate; use 0 to make me guess
- */
-void
-ccn_add_entropy(const void *buf, size_t size, int bits_of_entropy)
-{
- int num = size;
-
- if (num < 0 || num != (int)size)
- abort();
- /* Supply a hopefully conservative estimate of entropy. */
- if (bits_of_entropy <= 0)
- bits_of_entropy = (num < 32) ? 1 : num / 32;
- RAND_add((unsigned char *)buf, num, bits_of_entropy * 0.125);
-}
diff --git a/in-progress/ccn/ccn_random.h b/in-progress/ccn/ccn_random.h
deleted file mode 100644
index ddd0a38..0000000
--- a/in-progress/ccn/ccn_random.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-/**
- * @file random.h
- * @brief Pseudo-random number generation
- *
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2010 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef CCN_RANDOM_DEFINED
-#define CCN_RANDOM_DEFINED
-
-#include <stddef.h>
-#include <openssl/rand.h>
-
-void ccn_random_bytes(unsigned char *buf, size_t size);
-void ccn_add_entropy(const void *buf, size_t size, int bits_of_entropy);
-
-#endif
diff --git a/in-progress/ccnx-contentstore.cc b/in-progress/ccnx-contentstore.cc
deleted file mode 100644
index 61d6452..0000000
--- a/in-progress/ccnx-contentstore.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ndn_contentstore.h"
-
-namespace ns3
-{
-namespace NDNabstraction
-{
-
-ContentStore::ContentStore( int maxSize )
-: m_maxSize(maxSize) { }
-
-
-ContentStore::~ContentStore( )
-{ }
-
-//Find corresponding CS entry for the given content name
-CsEntry*
-ContentStore::Lookup(const char *prefix )
-{
- CriticalSection section(m_csMutex);
-
- struct CsEntry *result = NULL;
-
- HASH_FIND_STR (m_contentStore, prefix, result);
-
- if(result != NULL)
- Promote (*result);
-
- return result;
-}
-
-
-
-//Add entry to content store, if content store is full, use LRU replacement
-void
-ContentStore::Add( const char *contentName, int contentSize )
-{
- CriticalSection section(m_csMutex);
-
- // removing the old record
- struct CsEntry *tmp = NULL;
- HASH_FIND_STR (m_contentStore, contentName, tmp);
- HASH_DELETE (hh, m_contentStore,tmp);
- //free(tmp);
-
- int size = (int)HASH_COUNT(m_contentStore);
-
- if(size == m_maxSize )
- {
- CsEntry *entry = m_LRU.back();
- HASH_DELETE (hh, m_contentStore,entry);//_cs.erase( entry->contentName );
- m_LRU.pop_back( );
- }
-
- struct CsEntry *ce = (struct CsEntry*)malloc(sizeof(struct CsEntry));
- ce->contentName = (char*)contentName;
- ce->contentSize = contentSize;
-
- //_cs[ contentName ] = ce;
- HASH_ADD_KEYPTR (hh, m_contentStore, ce->contentName, strlen(ce->contentName), ce);
-
- //CsEntry *ce_in_hash = &(_cs[ contentName ]);
- struct CsEntry *ce_in_hash = NULL;
- HASH_FIND_STR (m_contentStore, contentName, ce_in_hash);
- m_LRU.push_front( ce_in_hash );
- ce_in_hash->lruPosition = m_LRU.begin( );
-}
-
-
-//move the given CS entry to the head of the list
-void
-ContentStore::Promote(CsEntry &ce )
-{
- // should not lock mutex. Otherwise deadlocks will be welcome
- if( m_LRU.front() == &ce ) return;
-
- //assert( *(ce.lruPosition)==&ce ); // should point to the same object
-
- // swaping positions in _lru
- m_LRU.erase( ce.lruPosition );
- m_LRU.push_front( &ce );
- ce.lruPosition = m_LRU.begin( );
-
- //assert( *(ce.lruPosition)==&ce ); // should point to the same object
-}
-
-void
-ContentStore::Dump()
-{
- CriticalSection section(m_csMutex);
-
- struct CsEntry *s, *tmp;
-
- HASH_ITER(hh, m_contentStore, s, tmp)
- {
- printf("-%s-", s->contentName);
- /* ... it is safe to delete and free s here */
- }
-
- printf("\n");
-
-}
-}
-}
diff --git a/in-progress/ccnx-contentstore.h b/in-progress/ccnx-contentstore.h
deleted file mode 100644
index 7e49fb6..0000000
--- a/in-progress/ccnx-contentstore.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#ifndef ndn_contentstore_h
-#define ndn_contentstore_h
-
-#include <ns3/system-mutex.h>
-#include <list>
-#include <string>
-#include "uthash.h"
-
-using namespace std;
-
-//size of content store
-#define NDN_CONTENT_STORE_SIZE 100
-
-namespace ns3
-{
-namespace NDNabstraction
-{
-
-class CsEntry;
-typedef list<CsEntry*>::iterator CsLruIterator;
-
-//structure for CS entry
-struct CsEntry
-{
- char *contentName;
- int contentSize;
-
- CsLruIterator lruPosition;
- UT_hash_handle hh; /* makes this structure hashable */
-};
-
-
-class ContentStore
-{
-public:
- ContentStore( int max_size=NDN_CONTENT_STORE_SIZE );
- virtual ~ContentStore( );
-
- // Find corresponding CS entry for the given content name
- CsEntry* Lookup( const char *prefix );
- //bool isValid( const CsIterator &it ) { return it!=_cs.end(); }
-
- // Add new content to the content store. Old content will be replaced
- void Add( const char *contentName, int contentSize );
-
- // Dump content store entries
- void Dump( );
-
-protected:
- //move the given CS entry to the head of the list
- void Promote( CsEntry &entry );
-
-private:
- int m_maxSize; // maximum number of entries in cache
-
- struct CsEntry *m_contentStore; // actual content store
- list<CsEntry*> m_LRU; // LRU index of the content store
- SystemMutex m_csMutex; // just to make sure we are not
-};
-
-}
-}
-#endif
diff --git a/in-progress/ccnx-cs.cpp b/in-progress/ccnx-cs.cpp
deleted file mode 100644
index c102cd5..0000000
--- a/in-progress/ccnx-cs.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * File: ndn_cs.cpp
- * Author: cawka
- *
- * Created on December 15, 2010, 2:17 PM
- */
-
-#include "ndn_cs.h"
-
-NdnCs::NdnCs( int maxSize )
-: _maxSize(maxSize) { }
-
-//NdnCs::NdnCs( constNdnCs& orig ) { }
-
-NdnCs::~NdnCs( ) { }
-
-//Find corresponding CS entry for the given content name
-CsIterator NdnCs::lookup( const string &prefix )
-{
- QNThreadLock lock( &_csMutex );
-
- CsIterator entry=_cs.find( prefix );
- if( entry!=_cs.end() ) promote( entry->second );
- return entry;
-}
-
-
-
-//Add entry to content store, if content store is full, use LRU replacement
-void NdnCs::add( const string &contentName, int contentSize )
-{
- QNThreadLock lock( &_csMutex );
-
- _cs.erase( contentName ); // removing the old record
-
- if( _cs.size()==_maxSize )
- {
- CsEntry *entry=_lru.back();
- _cs.erase( entry->contentName );
- _lru.pop_back( );
- }
-
- CsEntry ce;
- ce.contentName = contentName;
- ce.contentSize = contentSize;
-
- _cs[ contentName ] = ce;
-
- CsEntry *ce_in_hash = &(_cs[ contentName ]);
- _lru.push_front( ce_in_hash );
- ce_in_hash->lruPosition = _lru.begin( );
-}
-
-
-//move the given CS entry to the head of the list
-void NdnCs::promote( CsEntry &ce )
-{
- // should not lock mutex. Otherwise deadlocks will be welcome
- if( _lru.front() == &ce ) return;
-
- assert( *(ce.lruPosition)==&ce ); // should point to the same object
-
- // swaping positions in _lru
- _lru.erase( ce.lruPosition );
- _lru.push_front( &ce );
- ce.lruPosition = _lru.begin( );
-
- assert( *(ce.lruPosition)==&ce ); // should point to the same object
-}
-
-void NdnCs::dump()
-{
- QNThreadLock lock( &_csMutex );
-
- for( CsRangeIterator it=_cs.begin(); it!=_cs.end(); ++it )
- {
- printf("-%s-", it->second.contentName.c_str() );
- }
-
- printf("\n");
-// list<CsEntry *>::reverse_iterator rit;
-//
-// for (rit = contentList->rbegin(); rit != contentList->rend(); rit ++)
-// {
-// temp = *rit;
-// printf("=%s=", temp->contentName);
-// }
-//
-// printf("\n");
-}
diff --git a/in-progress/ccnx-cs.h b/in-progress/ccnx-cs.h
deleted file mode 100644
index 096b0c0..0000000
--- a/in-progress/ccnx-cs.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * File: ndn_cs.h
- * Author: cawka
- *
- * Created on December 15, 2010, 2:17 PM
- */
-
-#ifndef NDN_CS_H
-#define NDN_CS_H
-
-#include "ndn_common.h"
-#include "hash_helper.h"
-#include <qualnet_mutex.h>
-#include <list>
-#include <string>
-
-using namespace std;
-
-class CsEntry;
-typedef list<CsEntry*>::iterator CsLruIterator;
-
-//structure for CS entry
-struct CsEntry
-{
- string contentName;
- int contentSize;
-
- CsLruIterator lruPosition;
-};
-
-typedef string_key_hash_t<CsEntry>::point_iterator CsIterator;
-typedef string_key_hash_t<CsEntry>::iterator CsRangeIterator;
-
-// class implementing NDN content store
-class NdnCs
-{
-public:
- NdnCs( int max_size=NDN_CONTENT_STORE_SIZE );
- virtual ~NdnCs( );
-
- // Find corresponding CS entry for the given content name
- CsIterator lookup( const string &prefix );
- bool isValid( const CsIterator &it ) { return it!=_cs.end(); }
-
- // Add new content to the content store. Old content will be replaced
- void add( const string &contentName, int contentSize );
-
- // Dump content store entries
- void dump( );
-
-protected:
- //move the given CS entry to the head of the list
- void promote( CsEntry &entry );
-
-private:
- int _maxSize; // maximum number of entries in cache
-
- string_key_hash_t<CsEntry> _cs; // actual content store
-
- list<CsEntry*> _lru; // LRU index of the content store
- QNThreadMutex _csMutex; // just to make sure we are not
- // getting problems with multiple threads
-};
-
-#endif /* NDN_CS_H */
diff --git a/in-progress/ccnx-fib.cpp b/in-progress/ccnx-fib.cpp
deleted file mode 100644
index a8adbd0..0000000
--- a/in-progress/ccnx-fib.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * File: ndn_fib.cpp
- * Author: cawka
- *
- * Created on December 15, 2010, 1:54 PM
- */
-
-#include "ndn.h"
-#include "ndn_fib.h"
-
-#include <node.h>
-#include <buffer.h>
-#include <network_ip.h>
-#include <partition.h>
-#include <routing_ospfv2.h>
-#include <routing_bgp.h>
-
-//#define NDN_DEBUG_OSPF 0
-//#define NDN_DEBUG_OSPF_NODES 0
-
-//#define NDN_DUMP_FIB 0
-
-
-NdnFib::NdnFib( Ndn &node ) : _node(node) { }
-
-NdnFib::~NdnFib( ) { }
-
-
-//Find corresponding FIB entry for the given content name
-//Longest match is performed
-FibIterator NdnFib::lookup( const string &name )
-{
- string prefix=name;
-
- FibIterator entry;
- do
- {
- entry=_fib.find( prefix );
-
- prefix = GetLongestNamePrefix( prefix );
- } while( !isValid(entry) && prefix.size()>0 );
-
- return entry;
-}
-
-bool NdnFibNexthopSorter::operator()( const FibNexthop &first, const FibNexthop &second )
-{
- // Right now is a very simple logic.
- // Probably this logic should be changed later
- if( first. cost==NETWORK_UNREACHABLE && second.cost>=0 ) return false;
- if( second.cost==NETWORK_UNREACHABLE && first. cost>=0 ) return true;
- return first.cost < second.cost;
-}
-
-/**
- * Update FIB entry
- * If the entry exists, metric will be updated. Otherwise, new entry will be created
- *
- * @param name Prefix
- * @param interfaceIndex Forwarding interface
- * @param metric Routing metric
- * @param nextHop Nexthop node address (IPv4)
- * @return true if a new entry created, false otherwise
- */
-bool NdnFib::update( const string &name, int interfaceIndex, int metric, NodeAddress nextHop )
-{
- FibIterator entry = _fib.find( name );
- if( isValid(entry) )
- {
- FibNexthopIterator nh = VALUE(entry).findNexthop( interfaceIndex );
-
- if( !VALUE(entry).isValid(nh) )
- {
- nh = VALUE(entry).forwardingList.insert( VALUE(entry).forwardingList.begin(),
- FibNexthop(interfaceIndex,nextHop,metric) );
- }
- else
- {
- nh->cost = metric;
- nh->nextHop = nextHop;
- }
-
- VALUE(entry).forwardingList.sort( NdnFibNexthopSorter() );
-
- return false;
- }
-
- FibEntry &new_entry = _fib[name];
- new_entry.forwardingList.push_back( FibNexthop(interfaceIndex,nextHop,metric) );
-
- for( int interface=0; interface < _node.getNode()->numberInterfaces; interface++ )
- {
- NodeAddress src = NetworkIpGetInterfaceAddress( _node.getNode(), interface );
-
- if( isValidLink(src) && interface!=interfaceIndex )
- {
- new_entry.forwardingList.push_back( FibNexthop(interface,0,NETWORK_UNREACHABLE) );
- }
- }
-
- return true;
-}
-
-// helper for update call
-bool NdnFib::update( NodeAddress nodeId, int metric, NodeAddress nextHop )
-{
- ostringstream os;
- os << (int)nodeId;
-
- int interface = NetworkIpGetInterfaceIndexForNextHop( _node.getNode(), nextHop );
-
- return update( os.str(), interface, metric, nextHop );
-}
-
-// helper for update call
-bool NdnFib::update( NodeAddress nodeId, int interfaceIndex, int metric, NodeAddress nextHop )
-{
- ostringstream os;
- os << (int)nodeId;
-
- int interface = NetworkIpGetInterfaceIndexForNextHop( _node.getNode(), nextHop );
-
- return update( os.str(), interface, metric, nextHop ); //unknown metric
-}
-
-/**
- * Invalidate entries in FIB
- */
-void NdnFib::invalidate( )
-{
- for( FibRangeIterator fib=_fib.begin(); fib!=_fib.end(); fib++ )
- {
- for( FibNexthopIterator nh=VALUE(fib).forwardingList.begin(); nh!=VALUE(fib).forwardingList.end(); nh++ )
- {
- nh->cost = NETWORK_UNREACHABLE;
- }
- }
-}
-
-//compute and update STO value for Fib Entry (similar to RFC 2988)
-//for now we pick the maximum rto of all forwardings
-void FibEntry::updateSto( )
-{
- assert( forwardingList.size() > 0 );
-
- clocktype max = 0;
-
- for( FibNexthopIterator it = forwardingList.begin();
- it != forwardingList.end();
- it++ )
- {
- clocktype sto = it->srtt + NDN_RTO_K * it->rttvar;
-
- if( sto > max )
- max = sto;
- }
-
- this->sto = max;
-}
-
-
-/**
- * Updating FIB using data from OSPF
- * @param node
- * @param interface -2 Invalid OSPF (to purge FIB)
- * -1 Normal OSPF
- * 0-N SPF was calcylated using only interface `interface'
- *
- * @bug All local networks will always appear in routing table with cost == 1
- */
-void NdnFib::updateFibFromOSPFv2( int interface )
-{
- Ospfv2Data* ospf = (Ospfv2Data*)NetworkIpGetRoutingProtocol(_node.getNode(), ROUTING_PROTOCOL_OSPFv2);
-
- if( interface==-2 ) invalidate( );
-
-#ifdef NDN_DEBUG_OSPF
- if( interface==-1 ) printf( "Routing/interface costs\n" );
-#endif // NDN_DEBUG_OSPF
-
-#ifdef NDN_DEBUG_OSPF_NODES
- printf( "-- Node %d (interface %d) --\n", _node.getNode()->nodeId, interface );
-#endif // NDN_DEBUG_OSPF_NODES
-
- Ospfv2RoutingTableRow* rowPtr = (Ospfv2RoutingTableRow*)
- BUFFER_GetData(&ospf->routingTable.buffer);
-
- for (int i = 0; i < ospf->routingTable.numRows; i++)
- {
- NodeAddress destNodeId = Ipv4ToNodeId( rowPtr[i].destAddr );
-
- if( destNodeId!=-1 ) update( destNodeId, rowPtr[i].metric, rowPtr[i].nextHop );
- }
-
-#ifdef NDN_DUMP_FIB
- if( interface==-1 ) dump( );
-#endif
-}
-
-void NdnFib::updateFibFromBGP( )
-{
- BgpData* bgp=(BgpData*)_node.getNode()->appData.exteriorGatewayVar;
-
- assert( bgp->ip_version == NETWORK_IPV4 );
-
- invalidate( );
-
- int i=0;
- int numEntriesInAdjRibIn=BUFFER_GetCurrentSize( &( bgp->adjRibIn ) )
- / sizeof(BgpRoutingInformationBase );
-
- BgpRoutingInformationBase* adjRibInPtr=(BgpRoutingInformationBase*)
- BUFFER_GetData( &( bgp->adjRibIn ) );
-
- for( i=0; i < numEntriesInAdjRibIn; i++ )
- {
- assert( adjRibInPtr[i].nextHop.networkType == NETWORK_IPV4 );
-
- NodeAddress destNodeId = Ipv4ToNodeId( GetIPv4Address(adjRibInPtr[i].destAddress.prefix) );
-
- if( destNodeId!=-1 && adjRibInPtr[i].isValid != FALSE )
- {
- char destNodeStr[NDN_MAX_NAME_LENGTH];
- memset(destNodeStr, 0, NDN_MAX_NAME_LENGTH);
- sprintf(destNodeStr, "%d", destNodeId);
-
- update( destNodeId,
- adjRibInPtr[i].asPathList->pathSegmentLength / 2,
- GetIPv4Address(adjRibInPtr[i].nextHop) );
- }
- }
-
-#ifdef NDN_DUMP_FIB
- dump( );
-#endif
-}
-
-void NdnFib::updateFibFromIpRouting( )
-{
- invalidate( );
-
- for (int i = 0; i < _node.getNode()->partitionData->numNodes; i ++)
- {
- if( !_node.getNode()->networkData.networkVar->ndnEnabled ) continue;
-
- NodeAddress destNode = _node.getNode()->partitionData->nodeData[i]->nodeId;
- NodeAddress ipv4subnet = NodeIdToIpv4( destNode );
-
- int interfaceIndex;
- NodeAddress nextHopAddr;
- NetworkGetInterfaceAndNextHopFromForwardingTable(
- _node.getNode(), ipv4subnet, &interfaceIndex, &nextHopAddr );
-
- if( interfaceIndex != NETWORK_UNREACHABLE )
- {
- update( destNode, interfaceIndex, 1, nextHopAddr );
- }
- }
-}
-
-
-
-void NdnFib::dump( )
-{
- if( _node.getNode()->numberInterfaces==1 ) return; // do not dump FIB for `virtual' nodes
-
- printf( "Node %s: FIB\n", _node.getPrefix().c_str() );
- printf( " Dest prefix Interfaces(Costs) \n" );
- printf( "+-------------+--------------------------------------+\n" );
-
- for( FibRangeIterator fib=_fib.begin(); fib!=_fib.end(); fib++ )
- {
- dump( fib );
- }
-}
-
-void NdnFib::dump( const FibIterator &fib )
-{
- printf( " %8s ", fib->first.c_str() );
- for( FibNexthopIterator nh=VALUE(fib).forwardingList.begin(); nh!=VALUE(fib).forwardingList.end(); nh++ )
- {
- if( nh!=VALUE(fib).forwardingList.begin() ) printf( "," );
- printf( "i%d(%d)", nh->interfaceIndex, nh->cost );
- }
- printf( "\n" );
-}
-
-void NdnFib::resetProbing()
-{
- for(FibRangeIterator fib = _fib.begin(); fib != _fib.end(); fib++)
- VALUE(fib).needsProbing = true;
-}
-
-void NdnFib::updateInterfaceStatus( int interface, int status )
-{
- for( FibRangeIterator fib = _fib.begin(); fib!=_fib.end(); fib++ )
- {
- VALUE(fib).updateStatus( interface, status );
- }
-}
\ No newline at end of file
diff --git a/in-progress/ccnx-fib.h b/in-progress/ccnx-fib.h
deleted file mode 100644
index 9a1c3d6..0000000
--- a/in-progress/ccnx-fib.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * File: ndn_fib.h
- * Author: cawka
- *
- * Created on December 15, 2010, 1:54 PM
- */
-
-#ifndef NDN_FIB_H
-#define NDN_FIB_H
-
-#include "hash_helper.h"
-#include <clock.h>
-#include <main.h>
-
-class Ndn;
-
-const int NDN_FIB_GREEN = 1;
-const int NDN_FIB_YELLOW = 2;
-const int NDN_FIB_RED = 3;
-
-//structure for Fib outgoing interface
-struct FibNexthop
-{
- int interfaceIndex; //interface index of the node
- NodeAddress nextHop; //next-hop
- int cost; //routing protocol cost to route an interest via this interface
- int packetCount; //record the number of packets forwarded using this interface
-
- clocktype srtt; //smoothed round-trip time
- clocktype rttvar; //round-trip time variation
-
- int status; // Status of the next hop:
- // - #NDN_FIB_GREEN
- // - #NDN_FIB_YELLOW
- // - #NDN_FIB_RED
-
- bool operator==( int interface ) const { return interfaceIndex==interface; }
- FibNexthop( ) {}
- FibNexthop( int _interface, int _nextHop, int _cost )
- : interfaceIndex(_interface), nextHop(_nextHop), cost(_cost)
- , packetCount(1), srtt(0), rttvar(0), status(NDN_FIB_YELLOW) { }
-};
-
-typedef list<FibNexthop>::iterator FibNexthopIterator;
-typedef list<FibNexthop>::const_iterator FibNexthopConstIterator;
-
-//structure for FIB table entry
-struct FibEntry
-{
- list<FibNexthop> forwardingList;
- clocktype sto; //retransmission time out
-
- bool needsProbing; //set to true when probing timer goes out
-
- FibEntry( ) : sto(0), needsProbing(false) { }
-
- // Find nexthop record
- inline FibNexthopIterator findNexthop( int interfaceIndex );
- bool isValid( const FibNexthopIterator &nh )
- { return nh!=forwardingList.end(); }
-
- // Compute and update RTO value for Fib Entry (RFC 2988)
- // (for now we pick the maximum RTO of all forwardings)
- void updateSto( );
-
- // Update status of FIB next hop
- inline void updateStatus( int interface, int status );
-};
-
-typedef string_key_hash_t<FibEntry>::point_iterator FibIterator;
-typedef string_key_hash_t<FibEntry>::iterator FibRangeIterator;
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
-// Class implementing FIB functionality
-class NdnFib
-{
-public:
- NdnFib( Ndn &node );
- virtual ~NdnFib( );
-
- // Invalidate entries in FIB
- // Will leave FIB records in hash, but assign metric=NETWORK_UNREACHABLE
- void invalidate( );
-
- //Find corresponding FIB entry for the given content name
- //Longest match is performed
- FibIterator lookup( const string &name );
- bool isValid( const FibIterator &it ) { return it!=_fib.end(); }
-
- /**
- * Update FIB entry
- * If the entry exists, metric will be updated. Otherwise, new entry will be created
- *
- * Entries in FIB never deleted. They can be invalidated with metric==NETWORK_UNREACHABLE
- *
- * @param name Prefix
- * @param interfaceIndex Forwarding interface
- * @param metric Routing metric
- * @param nextHop Nexthop node address (IPv4)
- * @return true if a new entry created, false otherwise
- */
- bool update( const string &name, int interfaceIndex, int metric, NodeAddress nextHop );
- bool update( NodeAddress nodeId, int interfaceIndex, int metric, NodeAddress nextHop );
- bool update( NodeAddress nodeId, int metric, NodeAddress nextHop );
-
- // Update Fib from OSPF routing table (through a hack in OSPF algorithm)
- void updateFibFromOSPFv2( int interface );
-
- // Update Fib from BGP routing table (using info from RibIn)
- void updateFibFromBGP( );
-
- // Update Fib from IP routing table
- void updateFibFromIpRouting( );
-
- // Update the status for all FIB records for the specified interface
- void updateInterfaceStatus( int interface, int status );
-
- void dump( );
- void dump( const FibIterator &fib );
-
- void resetProbing(); //reset needsProbing field for every FibEntry
-private:
-
-private:
- Ndn &_node;
-
- string_key_hash_t<FibEntry> _fib;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
-class NdnFibNexthopSorter
-{
-public:
- bool operator()( const FibNexthop &first, const FibNexthop &second );
-};
-
-FibNexthopIterator FibEntry::findNexthop( int interfaceIndex )
-{
- return find( forwardingList.begin( ),
- forwardingList.end( ),
- interfaceIndex );
-}
-
-//inline FibNexthopIterator FibEntry::findBestNexthop( int bestNum, int excludeInterface )
-//{
-// // First adjust number of available interfaces (to make sure we have correct ranking function)
-// int num_valid_interfaces = forwardingList.size();
-// FibNexthopIterator nh;
-// for( nh=forwardingList.begin(); nh!=forwardingList.end(); nh++ )
-// {
-// if( nh->interfaceIndex==excludeInterface ) num_valid_interfaces--;
-// }
-//
-// if( num_valid_interfaces==0 ) return forwardingList.end();
-//
-// bestNum = bestNum % num_valid_interfaces;
-// int i=0;
-// for( nh=forwardingList.begin(); nh!=forwardingList.end(); nh++ ) // skip bestNum % size() FIB records
-// {
-// if( nh->interfaceIndex==excludeInterface ) continue;
-// if( i==bestNum ) break;
-//
-// i++;
-// }
-//
-// if( nh!=forwardingList.end() )
-// {
-// assert( nh->interfaceIndex!=excludeInterface );
-//// printf( "%d best => i%d\n", bestNum, nh->interfaceIndex );
-// }
-//// else
-//// {
-//// printf( "No other hops available\n" );
-//// }
-//
-//
-// return nh;
-//}
-
-void FibEntry::updateStatus( int interface, int status )
-{
- FibNexthopIterator nh = findNexthop( interface );
- if( isValid(nh) )
- {
- nh->status = status;
- }
-}
-
-#endif /* NDN_FIB_H */
diff --git a/in-progress/ccnx-pit.cpp b/in-progress/ccnx-pit.cpp
deleted file mode 100644
index 5d10b90..0000000
--- a/in-progress/ccnx-pit.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-//
-// Copyright (c) 2010,2011 UCLA
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author:
-//
-
-#include "ccnx-pit.h"
-#include <algorithm>
-
-CcnxPit::CcnxPit( Ccnx &node )
-: _node(node)
-{
-};
-
-CcnxPit::~CcnxPit( ) { }
-
-//Find corresponding CS entry for the given content name
-PitIterator CcnxPit::lookup( const string &prefix )
-{
- QNThreadLock lock( &_pitMutex );
-
- PitIterator entry=_pit.find( prefix );
- return entry;
-}
-
-// add new PIT entry
-bool CcnxPit::add( const string &name, const PitIncomingInterest &interest )
-{
- QNThreadLock lock( &_pitMutex );
-
- PitEntry *entry=NULL;
-
- PitIterator existent_entry = _pit.find( name );
- if( isValid(existent_entry) )
- {
- if( VALUE(existent_entry).timerExpired )
- {
- _node.fillAvailableInterfacesInPitEntry( VALUE(existent_entry) );
- }
-
- add( VALUE(existent_entry), interest );
- }
- else
- {
- PitEntry &entry = _pit[ name ];
- entry.contentName = name;
-
- _node.fillAvailableInterfacesInPitEntry( entry );
-
- add( entry, interest );
- }
-}
-
-// Remove expired records from PIT
-void CcnxPit::cleanExpired( clocktype time )
-{
- QNThreadLock lock( &_pitMutex );
-
- while( !_pitExpirationList.empty() )
- {
- PitExpirationIterator entry = _pitExpirationList.begin( );
-
- if( VALUE(entry)->expireTime <= time )
- {
- deleteIncomingInterest( *(KEY(entry)), VALUE(entry)->interfaceIndex );
-
- // delete entry if all incoming interests expired
- if( KEY(entry)->incomingInterests.size()==0 )
- {
- _pit.erase( KEY(entry)->contentName );
- }
- }
- else
- break;
- }
-}
-
-//delete PIT entry
-void CcnxPit::erase( const string &name )
-{
- // should not call `lookup' method !!!
-
- QNThreadLock lock( &_pitMutex );
-
- PitIterator pe = _pit.find( name );
-
- if( !isValid(pe) ) return;
-
- if( VALUE(pe).timerMsg ) MESSAGE_CancelSelfMsg( _node.getNode(), VALUE(pe).timerMsg );
-
- PitIncomingIterator it = VALUE(pe).incomingInterests.begin();
- while( it!=VALUE(pe).incomingInterests.end() )
- {
- deleteIncomingInterest( VALUE(pe), it );
-
- it = VALUE(pe).incomingInterests.begin();
- }
-
- resetPendingState( VALUE(pe) );
-
- _pit.erase( name );
-}
-
-//delete incoming interest from PIT entry
-//return 0 if interest does not exist, 1 otherwise
-bool CcnxPit::deleteIncomingInterest( PitEntry &pe, int interfaceIndex )
-{
- // should not lock thread !!! Otherwise there will be a deadlock
- if( pe.incomingInterests.size()==0 ) return false; //nothing to delete. Can happen when duplicate data arrives to the node
-
- PitIncomingIterator it = findIncoming( pe, interfaceIndex );
-
- if( !isValid(pe, it) ) return false;
-
- deleteIncomingInterest( pe, it );
-
- return true;
-}
-
-void CcnxPit::deleteAllIncomingInterests( PitEntry &pe )
-{
- PitIncomingIterator it = pe.incomingInterests.begin();
- while( it!=pe.incomingInterests.end() )
- {
- deleteIncomingInterest( pe, it );
-
- it = pe.incomingInterests.begin();
- }
-}
-
-void CcnxPit::deleteIncomingInterest( PitEntry &pe, PitIncomingIterator it )
-{
- assert( KEY(it->expirationPosition)==&pe );
- assert( VALUE(it->expirationPosition)->interfaceIndex==it->interfaceIndex );
-
- _pitExpirationList.erase( it->expirationPosition );
- pe.incomingInterests.erase( it );
-}
-
-//add new incoming interest to PIT entry
-//returns false if interface already exists, true otherwise
-bool CcnxPit::add( PitEntry &pe, const PitIncomingInterest &interest )
-{
- pe.availableInterfaces.remove( interest.interfaceIndex );
-
- PitIncomingIterator it=findIncoming( pe, interest.interfaceIndex );
-
- if( isValid(pe, it) )
- {
- //update expiration time
- it->expireTime = interest.expireTime;
- it->nonce = interest.nonce;
-
- //move Interest to the end of the node's Interest list
- _pitExpirationList.erase( it->expirationPosition );
- _pitExpirationList.push_back( PitExpirationEntry(&pe,&(*it)) );
-
- it->expirationPosition = --_pitExpirationList.end();
- return false;
- }
-
- pe.incomingInterests.push_back( interest );
- PitIncomingInterest *incoming = &pe.incomingInterests.back();
-
- //Add to the end of the node's Interest list
- _pitExpirationList.push_back( PitExpirationEntry(&pe,incoming) );
- incoming->expirationPosition = -- _pitExpirationList.end();
-
- return true;
-}
-
-//add new outgoing interest to PIT entry
-//returns false interface limit reached or interest exists and is still marked as outstanding (nonce will not be changed)
-// true otherwise
-int CcnxPit::add( PitEntry &pe, const PitOutgoingInterest &interest )
-{
- if( _node.isRateLimit && _bucketsPerInterface[interest.interfaceIndex]+1.0 >= maxBucketsPerInterface[interest.interfaceIndex] )
- {
-// printf( "DEBUG: bucket overflow. Should not forward anything to interface %d\n", interest.interfaceIndex );
- return false;
- }
-
- _bucketsPerInterface[interest.interfaceIndex] = _bucketsPerInterface[interest.interfaceIndex] + 1.0;
- pe.availableInterfaces.remove( interest.interfaceIndex );
-
- PitOutgoingIterator it = findOutgoing(pe, interest.interfaceIndex);
- if( isValid(pe, it) )
- {
- if( it->outstanding ) return false;
-
- it->retxNum ++;
- it->nonce = interest.nonce;
- it->outstanding = true;
- it->waitingInVain = false;
- }
- else
- {
- //add to the head of the list
- pe.outgoingInterests.push_front( interest );
- }
-
- return true;
-}
-
-void CcnxPit::resetPendingState( PitEntry &pe )
-{
- for( PitOutgoingIterator it = pe.outgoingInterests.begin();
- it != pe.outgoingInterests.end();
- it++ )
- {
- it->outstanding = false;
- }
-}
-
-void CcnxPit::leakBuckets( )
-{
- for( PitBucketIterator it=_bucketsPerInterface.begin();
- it != _bucketsPerInterface.end();
- it++ )
- {
- it->second = max( 0.0, it->second - leakSize[it->first] );
- }
-}
-
-void CcnxPit::leakBucket( int interface, int amount )
-{
- _bucketsPerInterface[interface] =
- max( 0.0, _bucketsPerInterface[interface] - amount );
-}
diff --git a/in-progress/ccnx-pit.h b/in-progress/ccnx-pit.h
deleted file mode 100644
index 83fad09..0000000
--- a/in-progress/ccnx-pit.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-//
-// Copyright (c) 2010,2011 UCLA
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Author:
-//
-
-#ifndef CCNX_PIT_H
-#define CCNX_PIT_H
-
-#include "ns3/nstime.h"
-#include "hash-helper.h"
-#include <list>
-
-namespace ns3 {
-
-class Ccnx;
-class PitEntry;
-class PitIncomingInterest;
-typedef pair<PitEntry*,PitIncomingInterest*> PitExpirationEntry;
-typedef list<PitExpirationEntry>::iterator PitExpirationIterator;
-
-struct PitIncomingInterest
-{
- int interfaceIndex; // interface index of the incoming Interest
- Time expireTime; // life time of the incoming Interest
- int nonce; // nonce of the last received incoming Interest on this interface
-
- PitExpirationIterator expirationPosition;
-
-public:
-PitIncomingInterest( int _interface, clocktype _expire, int _nonce )
-: interfaceIndex(_interface)
-, expireTime(_expire)
- , nonce(_nonce)
- { };
-
- bool operator==( const PitIncomingInterest &dst ) { return interfaceIndex==dst.interfaceIndex; }
- bool operator==( int interface ) { return interfaceIndex==interface; }
-};
-
-struct PitOutgoingInterest
-{
- int interfaceIndex;
- clocktype sendTime; //time when the first outgoing interest is sent
- int retxNum; //number of retransmission
- int nonce; //nonce of the outgoing Interest
- bool outstanding; //flag to indicate that this interest is currently pending
- bool waitingInVain; //when flag is set, we do not expect data for this interest, only a small hope that it will happen
-
-public:
-PitOutgoingInterest( int interface, clocktype time, int nonce )
-: interfaceIndex(interface)
-, sendTime( time )
- , retxNum( 0 )
- , nonce( nonce )
- , outstanding( true )
- , waitingInVain( false )
- { };
-
- bool operator==( const PitIncomingInterest &dst ) { return interfaceIndex==dst.interfaceIndex; }
- bool operator==( int interface ) { return interfaceIndex==interface; }
-};
-
-
-//structure for PIT entry
-struct PitEntry
-{
- string contentName;
- list<PitIncomingInterest> incomingInterests;
- list<PitOutgoingInterest> outgoingInterests;
-
- bool timerExpired;
- int counterExpirations; //whether timer is expired (+ number of times timer expired)
-
- /**
- * This variable provides a list of interfaces that will be tried to propagate interest
- *
- * It should be initialized with all available interfaces upon reception of first or
- * any retransmitted (i.e., after STO expired), but not duplicate interests
- *
- * Reaction to duplicate interests depends on strategy.
- *
- * In case of flooding, this variable should always be empty (it is filled initially with
- * all avaialble interfaces and then immediately emptied by interest flooding)
- *
- * In case of routing strategies, this list will guide (and limit) the local recovery process
- */
- list<int> availableInterfaces;
-
- Message *timerMsg; //the timer message, used to cancel message if data is received
-
- // Changing PIT removal policy. From now on it will be deleted only when all outgoing
- // interests are satisfied
- //
- // bool dontDeleteOnFirstData; //don't delete when first data packet comes
- // //(PIT will be deleted only upon timeout or reception data
- // //packets or prunes for all outgoing interests)
-
-public:
-PitEntry()
-: timerExpired( false )
-, counterExpirations( 0 )
- , timerMsg( NULL )
- { }
-
- inline void fillAvailableInterfacesFromFIB( const FibEntry &fe );
-
- // Find best candidate, skipping `skip' first candidates (modulo availableInterfaces.size())
- // !!! assert( availableInterfaces.size()>0 ) !!!
- inline int findBestCandidate( int skip = 0 );
-
- // Get number of outgoing interests that we're expecting data from
- inline size_t numberOfPromisingInterests( ) const;
-};
-
-typedef string_key_hash_t<PitEntry>::point_iterator PitIterator;
-typedef string_key_hash_t<PitEntry>::iterator PitRangeIterator;
-
-typedef list<PitIncomingInterest>::iterator PitIncomingIterator;
-typedef list<PitOutgoingInterest>::iterator PitOutgoingIterator;
-typedef list<PitOutgoingInterest>::const_iterator PitOutgoingConstIterator;
-
-typedef map<int,int> PitCounter;
-typedef map<int,int>::iterator PitCounterIterator;
-
-typedef map<int,double> PitBucket;
-typedef map<int,double>::iterator PitBucketIterator;
-
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-// class implementing Pending Interests Table
-class CcnxPit
-{
- public:
- /**
- * PIT constructor
- */
- CcnxPit( Ccnx &node );
- virtual ~CcnxPit( );
-
- //Find corresponding PIT entry for the given content name
- PitIterator lookup( const string &prefix );
- bool isValid( const PitIterator &it ) { return it!=_pit.end(); }
-
- inline PitIncomingIterator findIncoming( PitEntry &pe, int interfaceIndex );
- inline bool isValid( PitEntry &pe, PitIncomingIterator it );
- inline PitOutgoingIterator findOutgoing( PitEntry &pe, int interfaceIndex );
- inline bool isValid( PitEntry &pe, PitOutgoingIterator it );
-
- // Add a new PIT entry and a correspondent new incoming interest
- bool add( const string &contentName, const PitIncomingInterest &interest );
-
- // Add a new outgoing interest
- int add( PitEntry &pe, const PitOutgoingInterest &interest );
-
- // remove a PIT entry
- void erase( const string &contentName );
-
- // inline bool InterestAlreadyForwarded( PitEntry &pe, int interfaceIndex );
-
- // Remove expired records from PIT
- void cleanExpired( clocktype time );
-
- // Dump content store entries
- void dump( );
-
- // Reset pending state in outgoing interests
- void resetPendingState( PitEntry &pe );
-
- // // Check if there are any interfaces that we haven't sent data to yet
- // bool areFreeInterfaces( PitEntry &pe, int interface );
-
- // Periodically generate pre-calculated number of tokens (leak buckets)
- void leakBuckets( );
-
- // Selectively leak a bucket
- void leakBucket( int interface, int amount );
-
- // Delete incoming interest for the interface
- bool deleteIncomingInterest( PitEntry &pe, int interfaceIndex );
-
- // Remove all incoming interests
- void deleteAllIncomingInterests( PitEntry &pe );
-
- public:
- PitBucket maxBucketsPerInterface; // maximum number of buckets. Automatically computed based on link capacity
- // averaging over 1 second (bandwidth * 1second)
- PitBucket leakSize; // size of a periodic bucket leak
-
- private:
- bool add( PitEntry &pe, const PitIncomingInterest &interest );
- void deleteIncomingInterest( PitEntry &pe, PitIncomingIterator it );
-
- private:
- Ccnx &_node;
-
- string_key_hash_t<PitEntry> _pit;
-
- list<PitExpirationEntry> _pitExpirationList; //list of incoming Interests sorted by expiration time
-
- PitBucket _bucketsPerInterface; // pending interface counter per interface
-
- QNThreadMutex _pitMutex; // just to make sure
-};
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-PitIncomingIterator CcnxPit::findIncoming( PitEntry &pe, int interfaceIndex )
-{
- return find( pe.incomingInterests.begin( ),
- pe.incomingInterests.end( ),
- interfaceIndex );
-}
-
-PitOutgoingIterator CcnxPit::findOutgoing( PitEntry &pe, int interfaceIndex )
-{
- return find( pe.outgoingInterests.begin( ),
- pe.outgoingInterests.end( ),
- interfaceIndex );
-}
-
-bool CcnxPit::isValid( PitEntry &pe, PitIncomingIterator it )
-{
- return it!=pe.incomingInterests.end( );
-}
-
-bool CcnxPit::isValid( PitEntry &pe, PitOutgoingIterator it )
-{
- return it!=pe.outgoingInterests.end( );
-}
-
-int PitEntry::findBestCandidate( int skip/* = 0*/ )
-{
- assert( availableInterfaces.size()>0 );
-
- skip = skip % availableInterfaces.size();
- list<int>::iterator candidate = availableInterfaces.begin( );
- while( skip>0 /* && candidate!=availableInterfaces.end() */ ) { skip--; candidate++; }
-
- return *candidate;
-}
-
-size_t PitEntry::numberOfPromisingInterests( ) const
-{
- size_t count = 0;
-
- for( PitOutgoingConstIterator i = outgoingInterests.begin();
- i!=outgoingInterests.end();
- i++ )
- {
- if( !i->waitingInVain ) count++;
- }
-
- return count;
-}
-
-} // namespace ns3
-
-#endif /* CCNX_PIT_H */
diff --git a/in-progress/ccnx-rit.cpp b/in-progress/ccnx-rit.cpp
deleted file mode 100644
index b84f9d0..0000000
--- a/in-progress/ccnx-rit.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * File: ndn_rit.cpp
- * Author: cawka
- *
- * Created on December 15, 2010, 2:02 PM
- */
-
-#include "ndn_rit.h"
-
-NdnRit::NdnRit( ) { }
-
-NdnRit::~NdnRit( ) { }
-
-
-//find corresponding RIT entry for the given nonce
-RitIterator NdnRit::lookup( int nonce )
-{
- QNThreadLock lock( &_ritMutex );
-
- RitIterator entry=_rit.find( nonce );
- return entry;
-}
-
-
-// add new RIT entry
-// returns false if entry already exists, otherwise returns true
-bool NdnRit::add( int nonce, clocktype expire )
-{
- QNThreadLock lock( &_ritMutex );
-
- RitIterator entry=_rit.find( nonce );
- if( isValid(entry) ) return false;
-
- RitEntry re;
- re.nonce = nonce;
- re.expireTime = expire;
-
- _rit[ nonce ] = re;
-
- _ritExpirationList.push_back( &(_rit[nonce]) );
-}
-
-
-void NdnRit::cleanExpired( clocktype time )
-{
- QNThreadLock lock( &_ritMutex );
-
- while( !_ritExpirationList.empty() )
- {
- RitEntry *head = _ritExpirationList.front( );
-
- if( head->expireTime <= time )
- {
- //delete the head RIT entry
- _rit.erase( head->nonce );
- _ritExpirationList.pop_front( );
- }
- else
- break;
- }
- //printf("Node %d: RIT entries\n", node->nodeId);
- //PrintRitEntries(ndn->riList);
-}
-
diff --git a/in-progress/ccnx-rit.h b/in-progress/ccnx-rit.h
deleted file mode 100644
index 4a03bda..0000000
--- a/in-progress/ccnx-rit.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * File: ndn_rit.h
- * Author: cawka
- *
- * Created on December 15, 2010, 2:02 PM
- */
-
-#ifndef NDN_RIT_H
-#define NDN_RIT_H
-
-#include "hash_helper.h"
-#include <qualnet_mutex.h>
-#include <clock.h>
-#include <list>
-using namespace std;
-
-//recent interest
-struct RitEntry
-{
- int nonce;
- clocktype expireTime; //RIT entries will stay in the table for a while before being cleaned out
-};
-
-typedef int_key_hash_t<RitEntry>::point_iterator RitIterator;
-typedef int_key_hash_t<RitEntry>::iterator RitRangeIterator;
-
-class NdnRit
-{
-public:
- NdnRit( );
- virtual ~NdnRit( );
-
- //Find corresponding RIT entry for the given content name
- RitIterator lookup( int nonce );
- bool isValid( const RitIterator &it ) { return it!=_rit.end(); }
-
- //add new RIT entry
- bool add( int nonce, clocktype expireTime );
-
- // Delete expired records
- void cleanExpired( clocktype time );
-
-private:
- int_key_hash_t<RitEntry> _rit;
-
- list<RitEntry*> _ritExpirationList;
-
- QNThreadMutex _ritMutex;
-};
-
-#endif /* NdnRit_H */
-
diff --git a/model/ccnx-content-object-header.cc b/model/ccnx-content-object-header.cc
index e567207..d1ad0cf 100644
--- a/model/ccnx-content-object-header.cc
+++ b/model/ccnx-content-object-header.cc
@@ -37,6 +37,7 @@
CcnxContentObjectHeader::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::CcnxContentObjectHeader")
+ .SetGroupName ("Ccnx")
.SetParent<Header> ()
.AddConstructor<CcnxContentObjectHeader> ()
;
diff --git a/model/ccnx-content-object-header.h b/model/ccnx-content-object-header.h
index c26052b..97a8d3d 100644
--- a/model/ccnx-content-object-header.h
+++ b/model/ccnx-content-object-header.h
@@ -24,6 +24,7 @@
#include "ns3/integer.h"
#include "ns3/header.h"
+#include "ns3/trailer.h"
#include <string>
#include <vector>
@@ -101,7 +102,7 @@
* ContentObjectTail should always be 2 bytes, representing two closing tags:
* "</Content><ContentObject>"
*/
-class CcnxContentObjectTail : public Header
+class CcnxContentObjectTail : public Trailer
{
public:
CcnxContentObjectTail ();
diff --git a/model/ccnx-content-store.cc b/model/ccnx-content-store.cc
index 31a9fb3..4633000 100644
--- a/model/ccnx-content-store.cc
+++ b/model/ccnx-content-store.cc
@@ -16,88 +16,135 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "ccnx-content-store.h"
#include "ns3/log.h"
-
+#include "ns3/packet.h"
+#include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-content-object-header.h"
+#include "ns3/uinteger.h"
NS_LOG_COMPONENT_DEFINE ("CcnxContentStore");
namespace ns3
{
-
-CcnxContentStore::CcnxContentStore( int maxSize )
- : m_maxSize(maxSize) { }
+
+NS_OBJECT_ENSURE_REGISTERED (CcnxContentStore);
+
+using namespace __ccnx_private;
+
+TypeId
+CcnxContentStore::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::CcnxContentStore")
+ .SetGroupName ("Ccnx")
+ .SetParent<Object> ()
+ .AddConstructor<CcnxContentStore> ()
+ .AddAttribute ("Size",
+ "Maximum number of packets that content storage can hold",
+ UintegerValue (100),
+ MakeUintegerAccessor (&CcnxContentStore::SetMaxSize,
+ &CcnxContentStore::GetMaxSize),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+
+ return tid;
+}
+
+CcnxContentObjectTail CcnxContentStoreEntry::m_tail;
+
+CcnxContentStoreEntry::CcnxContentStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet)
+ : m_header (header)
+{
+ m_packet = packet->Copy ();
+ m_packet->RemoveHeader (*header);
+ m_packet->RemoveTrailer (m_tail);
+}
+
+Ptr<Packet>
+CcnxContentStoreEntry::GetFullyFormedCcnxPacket () const
+{
+ Ptr<Packet> packet = m_packet->Copy ();
+ packet->AddHeader (*m_header);
+ packet->AddTrailer (m_tail);
+ return packet;
+}
+
+// /// Disabled copy constructor
+// CcnxContentStoreEntry::CcnxContentStoreEntry (const CcnxContentStoreEntry &o)
+// {
+// }
+
+// /// Disables copy operator
+// CcnxContentStoreEntry& CcnxContentStoreEntry::operator= (const CcnxContentStoreEntry &o)
+// {
+// return *this;
+// }
+
+
+
+CcnxContentStore::CcnxContentStore( )
+ : m_maxSize(100) { } // this value shouldn't matter, NS-3 should call SetSize with default value specified in AddAttribute earlier
CcnxContentStore::~CcnxContentStore( )
- { }
+{ }
-//Find corresponding CS entry for the given content name
-CsEntry*
-CcnxContentStore::Lookup(const string prefix )
+/// Disabled copy constructor
+CcnxContentStore::CcnxContentStore (const CcnxContentStore &o)
{
- CriticalSection section(m_csMutex);
-
- CsEntry *result = &(m_contentStore.at(prefix));
-
- if(result != NULL)
- Promote (*result);
-
- return result;
+}
+
+/// Disables copy operator
+CcnxContentStore& CcnxContentStore::operator= (const CcnxContentStore &o)
+{
+ return *this;
+}
+
+
+Ptr<Packet>
+CcnxContentStore::Lookup (Ptr<const CcnxInterestHeader> interest)
+{
+ CcnxContentStoreContainer::type::iterator it = m_contentStore.get<hash> ().find (interest->GetName ());
+ if (it != m_contentStore.end ())
+ {
+ // promote entry to the top
+ m_contentStore.get<mru> ().relocate (m_contentStore.get<mru> ().begin (),
+ m_contentStore.project<mru> (it));
+
+ // return fully formed CCNx packet
+ return it->GetFullyFormedCcnxPacket ();
+ }
+ return 0;
}
-//move the given CS entry to the head of the list
void
-CcnxContentStore::Promote(CsEntry &ce )
+CcnxContentStore::Add (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet)
{
- // should not lock mutex. Otherwise deadlocks will be welcome
- if( m_LRU.front() == &ce ) return;
-
- //assert( *(ce.lruPosition)==&ce ); // should point to the same object
-
- // swaping positions in _lru
- m_LRU.erase( ce.lruPosition );
- m_LRU.push_front( &ce );
- ce.lruPosition = m_LRU.begin( );
-
- //assert( *(ce.lruPosition)==&ce ); // should point to the same object
-}
-
-//Add entry to content store, if content store is full, use LRU replacement
-void
-CcnxContentStore::Add( const string contentName, int contentSize )
-{
- CriticalSection section(m_csMutex);
-
- m_contentStore.erase(m_contentStore.find(contentName));
-
- if((int)m_contentStore.size() == m_maxSize )
- {
- CsEntry *entry = m_LRU.back();
- m_contentStore.erase(m_contentStore.find(entry->contentName));
- m_LRU.pop_back( );
+ CcnxContentStoreContainer::type::iterator it = m_contentStore.get<hash> ().find (header->GetName ());
+ if (it == m_contentStore.end ())
+ { // add entry to the top
+ m_contentStore.get<mru> ().push_front (CcnxContentStoreEntry (header, packet));
}
-
- CsEntry ce;
- ce.contentName = contentName;
- ce.contentSize = contentSize;
-
- m_contentStore[contentName] = ce;
-
- CsEntry *ce_in_hash = &(m_contentStore.at(contentName));
- m_LRU.push_front( ce_in_hash );
- ce_in_hash->lruPosition = m_LRU.begin( );
-}
-
-void
-CcnxContentStore::Dump()
-{
- CriticalSection section(m_csMutex);
-
- BOOST_FOREACH(string_key_hash_t<CsEntry>::value_type i, m_contentStore)
+ else
{
- NS_LOG_INFO ("Key = " << i.first << " Value = " << i.second.contentName);
+ // promote entry to the top
+ m_contentStore.get<mru> ().relocate (m_contentStore.get<mru> ().begin (),
+ m_contentStore.project<mru> (it));
}
}
-}
\ No newline at end of file
+
+void
+CcnxContentStore::Print() const
+{
+ for( DUMP_INDEX::type::iterator it=m_contentStore.get<DUMP_INDEX_TAG> ().begin ();
+ it != m_contentStore.get<DUMP_INDEX_TAG> ().end ();
+ it++
+ )
+ {
+ NS_LOG_INFO (it->GetName ());
+ }
+}
+
+} // namespace ns3
diff --git a/model/ccnx-content-store.h b/model/ccnx-content-store.h
index 58e060e..ee29f81 100644
--- a/model/ccnx-content-store.h
+++ b/model/ccnx-content-store.h
@@ -18,60 +18,327 @@
* Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
*/
-#ifndef ccnx_content_store_h
-#define ccnx_content_store_h
+#ifndef CCNX_CONTENT_STORE_H
+#define CCNX_CONTENT_STORE_H
-#include <ns3/system-mutex.h>
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+
#include <list>
#include <string>
-#include "hash-helper.h"
+#include <iostream>
-using namespace std;
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/tag.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/mem_fun.hpp>
+
+#include "hash-helper.h"
+#include "ccnx-content-object-header.h"
+#include "ccnx-interest-header.h"
+#include "name-components.h"
namespace ns3
{
-
-class CsEntry;
-typedef list<CsEntry*>::iterator CsLruIterator;
-
-//structure for CS entry
-struct CsEntry
-{
- string contentName;
- int contentSize;
-
- CsLruIterator lruPosition;
-};
-
-typedef string_key_hash_t<CsEntry>::iterator CsIterator;
-typedef string_key_hash_t<CsEntry>::iterator CsRangeIterator;
-
-class CcnxContentStore
+class Packet;
+
+/**
+ * \ingroup ccnx
+ * \brief NDN content store entry
+ *
+ * Content store entry stores separately pseudo header and content of
+ * ContentObject packet. It is responsibility of the caller to
+ * construct a fully formed CcnxPacket by calling Copy(), AddHeader(),
+ * AddTail() on the packet received by GetPacket() method.
+ *
+ * GetFullyFormedCcnxPacket method provided as a convenience
+ */
+class CcnxContentStoreEntry
{
public:
- CcnxContentStore( int max_size=NDN_CONTENT_STORE_SIZE );
- virtual ~CcnxContentStore( );
+ /**
+ * \brief Construct content store entry
+ *
+ * \param header Parsed CcnxContentObject header
+ * \param packet Original CCNx packet
+ *
+ * The constructor will make a copy of the supplied packet and calls
+ * RemoveHeader and RemoveTail on the copy.
+ */
+ CcnxContentStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
+
+ /**
+ * \brief Get prefix of the stored entry
+ * \returns prefix of the stored entry
+ */
+ inline const Name::Components&
+ GetName () const;
+
+ /**
+ * \brief Get CcnxContentObjectHeader of the stored entry
+ * \returns CcnxContentObjectHeader of the stored entry
+ */
+ inline Ptr<const CcnxContentObjectHeader>
+ GetHeader () const;
+
+ /**
+ * \brief Get content of the stored entry
+ * \returns content of the stored entry
+ */
+ inline Ptr<const Packet>
+ GetPacket () const;
+
+ /**
+ * \brief Convenience method to create a fully formed CCNx packet from stored header and content
+ * \returns A read-write copy of the packet with CcnxContentObjectHeader and CcxnContentObjectTail
+ */
+ Ptr<Packet>
+ GetFullyFormedCcnxPacket () const;
+
+// Copy constructor is required by the container. Though, we're
+// storing only two pointers, so shouldn't be a problem
+// private:
+// CcnxContentStoreEntry (const CcnxContentStoreEntry &); ///< disabled copy constructor
+// CcnxContentStoreEntry& operator= (const CcnxContentStoreEntry&); ///< disabled copy operator
+
+private:
+ Ptr<CcnxContentObjectHeader> m_header; ///< \brief non-modifiable CcnxContentObjectHeader
+ Ptr<Packet> m_packet; ///< \brief non-modifiable content of the ContentObject packet
+
+ static CcnxContentObjectTail m_tail; ///< \internal for optimization purposes
+};
+
+/// \brief Private namespace for CCNx implementation
+namespace __ccnx_private
+{
+class hash {}; ///< tag for Boost.Multiindex container (hashed prefix)
+class mru {}; ///< tag for Boost.Multiindex container (most recent used index)
+#ifdef _DEBUG
+class ordered {}; ///< tag for Boost.MultiIndex container (ordered by prefix)
+#endif
+};
+
+/**
+ * \ingroup ccnx
+ * \brief Typedef for content store container implemented as a Boost.MultiIndex container
+ *
+ * - First index (tag<prefix>) is a unique hash index based on NDN prefix of the stored content.
+ * - Second index (tag<mru>) is a sequential index used to maintain up to m_maxSize most recent used (MRU) entries in the content store
+ * - Third index (tag<ordered>) is just a helper to provide stored prefixes in ordered way. Should be disabled in production build
+ *
+ * \see http://www.boost.org/doc/libs/1_46_1/libs/multi_index/doc/ for more information on Boost.MultiIndex library
+ */
+struct CcnxContentStoreContainer
+{
+ typedef
+ boost::multi_index::multi_index_container<
+ CcnxContentStoreEntry,
+ boost::multi_index::indexed_by<
+ boost::multi_index::hashed_unique<
+ boost::multi_index::tag<__ccnx_private::hash>,
+ boost::multi_index::const_mem_fun<CcnxContentStoreEntry,
+ const Name::Components&,
+ &CcnxContentStoreEntry::GetName>,
+ CcnxPrefixHash>,
+ boost::multi_index::sequenced<boost::multi_index::tag<__ccnx_private::mru> >
+#ifdef _DEBUG
+ ,
+ boost::multi_index::ordered_unique<
+ boost::multi_index::tag<__ccnx_private::ordered>,
+ boost::multi_index::const_mem_fun<CcnxContentStoreEntry,
+ const Name::Components&,
+ &CcnxContentStoreEntry::GetName>
+ >
+#endif
+ >
+ > type;
+};
+
+/**
+ * \ingroup ccnx
+ * \brief Typedef for hash index of content store container
+ */
+struct CcnxContentStoreByPrefix
+{
+ typedef
+ CcnxContentStoreContainer::type::index<__ccnx_private::hash>::type
+ type;
+};
+
+/**
+ * \ingroup ccnx
+ * \brief Typedef for MRU index of content store container
+ */
+struct CcnxContentStoreByMru
+{
+ typedef
+ CcnxContentStoreContainer::type::index<__ccnx_private::mru>::type
+ type;
+};
+
+#ifdef _DEBUG
+#define DUMP_INDEX_TAG ordered
+#define DUMP_INDEX CcnxContentStoreOrderedPrefix
+/**
+ * \ingroup ccnx
+ * \brief Typedef for ordered index of content store container
+ */
+struct CcnxContentStoreOrderedPrefix
+{
+ typedef
+ CcnxContentStoreContainer::type::index<__ccnx_private::ordered>::type
+ type;
+};
+#else
+#define DUMP_INDEX_TAG mru
+#define DUMP_INDEX CcnxContentStoreByMru
+#endif
+
+/**
+ * \ingroup ccnx
+ * \brief NDN content store entry
+ */
+class CcnxContentStore : public Object
+{
+public:
+ /**
+ * \brief Interface ID
+ *
+ * \return interface ID
+ */
+ static TypeId GetTypeId ();
+
+ // typedef string_key_hash_t<CsEntry>::iterator CsIterator;
+ // typedef string_key_hash_t<CsEntry>::iterator CsRangeIterator;
+
+ /**
+ * Default constructor
+ */
+ CcnxContentStore( );
+ virtual ~CcnxContentStore( );
- // Find corresponding CS entry for the given content name
- CsEntry* Lookup( const string prefix );
- //bool isValid( const CsIterator &it ) { return it!=_cs.end(); }
+ /**
+ * \brief Find corresponding CS entry for the given interest
+ *
+ * \param interest Interest for which matching content store entry
+ * will be searched
+ *
+ * If an entry is found, it is promoted to the top of most recent
+ * used entries index, \see m_contentStore
+ */
+ Ptr<Packet>
+ Lookup (Ptr<const CcnxInterestHeader> interest);
- // Add new content to the content store. Old content will be replaced
- void Add( const string contentName, int contentSize );
-
- // Dump content store entries
- void Dump( );
+ /**
+ * \brief Add a new content to the content store.
+ *
+ * \param header Fully parsed CcnxContentObjectHeader
+ * \param packet Fully formed CCNx packet to add to content store
+ * (will be copied and stripped down of headers)
+ *
+ * If entry with the same prefix exists, the old entry will be
+ * promoted to the top of the MRU hash
+ */
+ void
+ Add (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
+
+ /**
+ * \brief Set maximum size of content store
+ *
+ * \param size size in packets
+ */
+ inline void
+ SetMaxSize (uint32_t maxSize);
+
+ /**
+ * \brief Get maximum size of content store
+ *
+ * \returns size in packets
+ */
+ inline uint32_t
+ GetMaxSize () const;
+
+ /**
+ * \brief Print out content store entries
+ *
+ * Debug build provides dumping of content store entries in
+ * lexicographical order of corresponding prefixes
+ *
+ * Release build dumps everything in MRU order
+ */
+ void Print () const;
protected:
- //move the given CS entry to the head of the list
- void Promote( CsEntry &entry );
-
+ // /**
+ // * \brief Move the given CS entry to the head of the list
+ // *
+ // * \param entry Content Store entry
+ // */
+ // void Promote( CsEntry &entry );
+
+ /**
+ * \todo Alex: DoDispose and NotifyNewAggregate are seem to be very
+ * important, but I'm not yet sure what exactly they are supposed to
+ * do
+ */
+ // virtual void DoDispose ();
+ // virtual void NotifyNewAggregate ();
+
private:
- int m_maxSize; // maximum number of entries in cache
-
- string_key_hash_t<CsEntry> m_contentStore; // actual content store
- list<CsEntry*> m_LRU; // LRU index of the content store
- SystemMutex m_csMutex; // just to make sure we are not
+ CcnxContentStore (const CcnxContentStore &o); ///< Disabled copy constructor
+ CcnxContentStore& operator= (const CcnxContentStore &o); ///< Disabled copy operator
+
+private:
+ int m_maxSize; ///< \brief maximum number of entries in cache \internal
+ // string_key_hash_t<CsEntry> m_contentStore; ///< \brief actual content store \internal
+
+ /**
+ * \brief Content store implemented as a Boost.MultiIndex container
+ * \internal
+ */
+ CcnxContentStoreContainer::type m_contentStore;
};
+
+inline std::ostream&
+operator<< (std::ostream &os, const CcnxContentStore &cs)
+{
+ cs.Print ();
+ return os;
}
-#endif
+
+const Name::Components&
+CcnxContentStoreEntry::GetName () const
+{
+ return m_header->GetName ();
+}
+
+Ptr<const CcnxContentObjectHeader>
+CcnxContentStoreEntry::GetHeader () const
+{
+ return m_header;
+}
+
+Ptr<const Packet>
+CcnxContentStoreEntry::GetPacket () const
+{
+ return m_packet;
+}
+
+
+inline void
+CcnxContentStore::SetMaxSize (uint32_t maxSize)
+{
+ m_maxSize = maxSize;
+}
+
+inline uint32_t
+CcnxContentStore::GetMaxSize () const
+{
+ return m_maxSize;
+}
+
+} //namespace ns3
+
+#endif // CCNX_CONTENT_STORE_H
diff --git a/model/ccnx-face.cc b/model/ccnx-face.cc
index e19dc57..3250355 100644
--- a/model/ccnx-face.cc
+++ b/model/ccnx-face.cc
@@ -34,6 +34,7 @@
CcnxFace::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::CcnxFace")
+ .SetGroupName ("Ccnx")
.SetParent<Object> ()
;
return tid;
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index 6d4b045..7159109 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -28,6 +28,7 @@
TypeId CcnxForwardingStrategy::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::CcnxForwardingStrategy")
+ .SetGroupName ("Ccnx")
.SetParent<Object> ()
;
return tid;
diff --git a/model/ccnx-interest-header.cc b/model/ccnx-interest-header.cc
index 02ad9af..330e2f4 100644
--- a/model/ccnx-interest-header.cc
+++ b/model/ccnx-interest-header.cc
@@ -40,6 +40,7 @@
CcnxInterestHeader::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::CcnxInterestHeader")
+ .SetGroupName ("Ccnx")
.SetParent<Header> ()
.AddConstructor<CcnxInterestHeader> ()
;
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index ff3f926..8b7cccd 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -37,6 +37,7 @@
#include "ccnx-forwarding-strategy.h"
#include "ccnx-interest-header.h"
#include "ccnx-content-object-header.h"
+#include "ccnx-content-store.h"
#include <boost/foreach.hpp>
@@ -53,6 +54,7 @@
{
static TypeId tid = TypeId ("ns3::CcnxL3Protocol")
.SetParent<Ccnx> ()
+ .SetGroupName ("Ccnx")
.AddConstructor<CcnxL3Protocol> ()
// .AddTraceSource ("Tx", "Send ccnx packet to outgoing interface.",
// MakeTraceSourceAccessor (&CcnxL3Protocol::m_txTrace))
@@ -179,6 +181,12 @@
void
CcnxL3Protocol::Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p)
{
+ if (face->IsUp ())
+ {
+ NS_LOG_LOGIC ("Dropping received packet -- interface is down");
+ // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
+ return;
+ }
NS_LOG_LOGIC ("Packet from face " << &face << " received on node " << m_node->GetId ());
Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
@@ -198,16 +206,11 @@
const Ptr<CcnxInterestHeader> &header,
const Ptr<Packet> &packet)
{
- if (incomingFace->IsUp ())
- {
- NS_LOG_LOGIC ("Dropping received packet -- interface is down");
- // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
- return;
- }
-
- NS_LOG_LOGIC ("Receiving interest from " << incomingFace);
+ NS_LOG_LOGIC ("Receiving interest from " << &incomingFace);
// m_rxTrace (packet, m_node->GetObject<Ccnx> (), incomingFace);
+ /// \todo Processing of Interest packets
+
// NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
// if (!m_forwardingStrategy->RouteInput (packet, incomingFace,
// MakeCallback (&CcnxL3Protocol::Send, this),
@@ -224,14 +227,9 @@
const Ptr<CcnxContentObjectHeader> &header,
const Ptr<Packet> &packet)
{
- if (incomingFace->IsUp ())
- {
- NS_LOG_LOGIC ("Dropping received packet -- interface is down");
- // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
- return;
- }
+ NS_LOG_LOGIC ("Receiving contentObject from " << &incomingFace);
- NS_LOG_LOGIC ("Receiving contentObject from " << incomingFace);
+ /// \todo Processing of ContentObject packets
}
// fake method
@@ -245,27 +243,21 @@
void
CcnxL3Protocol::Send (const Ptr<CcnxFace> &face, const Ptr<Packet> &packet)
{
- // NS_LOG_FUNCTION (this << "packet: " << packet << ", route: "<< route);
-
- // if (route == 0)
- // {
- // NS_LOG_WARN ("No route to host. Drop.");
- // // m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), 0);
- // return;
- // }
- // Ptr<CcnxFace> outFace = route->GetOutputFace ();
+ NS_LOG_FUNCTION (this << "packet: " << &packet << ", face: "<< &face); //
- // if (outFace->IsUp ())
- // {
- // NS_LOG_LOGIC ("Sending via face " << *outFace);
- // // m_txTrace (packet, m_node->GetObject<Ccnx> (), outFace);
- // outFace->Send (packet);
- // }
- // else
- // {
- // NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << *outFace);
- // // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), outFace);
- // }
+ NS_ASSERT_MSG (face != 0, "Face should never be NULL");
+
+ if (face->IsUp ())
+ {
+ NS_LOG_LOGIC ("Sending via face " << &face); //
+ m_txTrace (packet, m_node->GetObject<Ccnx> (), face);
+ face->Send (packet);
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << &face);
+ m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), face);
+ }
}
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index 145051f..6167fd0 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -41,7 +41,8 @@
class Header;
class CcnxInterestHeader;
class CcnxContentObjectHeader;
-
+class CcnxContentStore;
+
/**
* \ingroup ccnx
* \brief Actual implementation of the Ccnx network layer
@@ -160,15 +161,25 @@
Ptr<Node> m_node; ///< \brief node on which ccnx stack is installed
Ptr<CcnxForwardingStrategy> m_forwardingStrategy; ///< \brief smart pointer to the selected forwarding strategy
- // TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_sendOutgoingTrace;
- // TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_unicastForwardTrace;
- // TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_localDeliverTrace;
+ Ptr<CcnxContentStore> m_contentStore;
+
+ /**
+ * \brief Trace of transmitted packets, including all headers
+ * \internal
+ */
+ TracedCallback<Ptr<const Packet>, Ptr<Ccnx>, Ptr<const CcnxFace> > m_txTrace;
- // // The following two traces pass a packet with an IP header
- // TracedCallback<Ptr<const Packet>, Ptr<Ccnx>, Ptr<const CcnxFace> > m_txTrace;
- // TracedCallback<Ptr<const Packet>, Ptr<Ccnx>, Ptr<const CcnxFace> > m_rxTrace;
- // // <ip-header, payload, reason, ifindex> (ifindex not valid if reason is DROP_NO_ROUTE)
- // TracedCallback<Ptr<const Packet>, DropReason, Ptr<const Ccnx>, Ptr<const CcnxFace> > m_dropTrace;
+ /**
+ * \brief Trace of received packets, including all headers
+ * \internal
+ */
+ TracedCallback<Ptr<const Packet>, Ptr<Ccnx>, Ptr<const CcnxFace> > m_rxTrace;
+
+ /**
+ * \brief Trace of dropped packets, including reason and all headers
+ * \internal
+ */
+ TracedCallback<Ptr<const Packet>, DropReason, Ptr<const Ccnx>, Ptr<const CcnxFace> > m_dropTrace;
};
} // Namespace ns3
diff --git a/model/ccnx-local-face.cc b/model/ccnx-local-face.cc
index ea2a84b..80b0b52 100644
--- a/model/ccnx-local-face.cc
+++ b/model/ccnx-local-face.cc
@@ -37,6 +37,7 @@
CcnxLocalFace::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::CcnxLocalFace")
+ .SetGroupName ("Ccnx")
.SetParent<CcnxFace> ()
;
return tid;
diff --git a/model/ccnx-net-device-face.cc b/model/ccnx-net-device-face.cc
index b5816a4..9bdcd43 100644
--- a/model/ccnx-net-device-face.cc
+++ b/model/ccnx-net-device-face.cc
@@ -38,6 +38,7 @@
CcnxNetDeviceFace::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::CcnxNetDeviceFace")
+ .SetGroupName ("Ccnx")
.SetParent<CcnxFace> ()
;
return tid;
diff --git a/model/ccnx.cc b/model/ccnx.cc
index a940c36..0fe4b31 100644
--- a/model/ccnx.cc
+++ b/model/ccnx.cc
@@ -32,6 +32,7 @@
Ccnx::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::Ccnx")
+ .SetGroupName ("Ccnx")
.SetParent<Object> ()
;
return tid;
diff --git a/model/hash-helper.h b/model/hash-helper.h
index 880a217..36a9ee8 100644
--- a/model/hash-helper.h
+++ b/model/hash-helper.h
@@ -18,48 +18,50 @@
* Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
*/
-#ifndef ccnx_hash_helper_h
-#define ccnx_hash_helper_h
+#ifndef CCNX_HASH_HELPER_H
+#define CCNX_HASH_HELPER_H
#include <string>
-#include <boost/unordered_map.hpp>
-#include <boost/functional/hash.hpp>
#include <boost/foreach.hpp>
+#include "name-components.h"
-//size of content store
-#define NDN_CONTENT_STORE_SIZE 100
-//maximum length of content name
-#define NDN_MAX_NAME_LENGTH 30
-
-//using namespace std;
-
-#define KEY(x) x->first
-#define VALUE(x) x->second
-
-
-/*template<typename T>
-struct hash : public std::unary_function<T, std::size_t> {
- std::size_t operator()(T const&) const;
-};*/
-
-struct string_hash : public std::unary_function<std::string, std::size_t>
+namespace ns3
{
- inline std::size_t operator( )( std::string str ) const
- {
- std::size_t hash = str.size() + 23;
- for( std::string::const_iterator it = str.begin( ); it!=str.end(); it++ )
- {
- hash = ((hash << 6) ^ (hash >> 27)) + static_cast<std::size_t>( *it );
- }
-
- return boost::hash_value(hash); //hash;
- }
-};
-// A collision-chaining hash table mapping strings to ints.
-template<typename Value>
-class string_key_hash_t : public boost::unordered_map<std::string,Value, string_hash, std::equal_to<std::string>,std::allocator<std::string> >
+/**
+ * \ingroup ccnx-helpers
+ * \brief Helper providing hash value for the name prefix
+ *
+ * The whole prefix is considered as a long string with '/' delimiters
+ *
+ * \todo Testing is required to determine if this hash function
+ * actually provides good hash results
+ */
+struct CcnxPrefixHash : public std::unary_function<Name::Components, std::size_t>
{
+ std::size_t
+ operator() (const Name::Components &prefix) const
+ {
+ std::size_t hash = 23;
+ BOOST_FOREACH (const std::string &str, prefix.GetComponents ())
+ {
+ hash += str.size ();
+ hash = ((hash << 6) ^ (hash >> 27)) + '/';
+ BOOST_FOREACH (char c, str)
+ {
+ hash = ((hash << 6) ^ (hash >> 27)) + c;
+ }
+ }
+ return hash;
+ }
};
+
+// // A collision-chaining hash table mapping strings to ints.
+// template<typename Value>
+// class string_key_hash_t : public boost::unordered_map<std::string,Value, string_hash, std::equal_to<std::string>,std::allocator<std::string> >
+// {
+// };
-#endif
\ No newline at end of file
+} // namespace ns3
+
+#endif // CCNX_HASH_HELPER_H
diff --git a/model/name-components.h b/model/name-components.h
index 0ea4821..95d2347 100644
--- a/model/name-components.h
+++ b/model/name-components.h
@@ -24,6 +24,7 @@
#include "ns3/simple-ref-count.h"
#include <string>
+#include <algorithm>
#include <list>
namespace ns3 {
@@ -58,6 +59,12 @@
inline size_t
size () const;
+
+ inline bool
+ operator== (const Components &prefix) const;
+
+ inline bool
+ operator< (const Components &prefix) const;
private:
std::list<std::string> m_prefix;
@@ -79,8 +86,20 @@
{
(*this) (s);
}
-
-
+
+bool
+Components::operator== (const Components &prefix) const
+{
+ return std::equal (m_prefix.begin (), m_prefix.end (), prefix.m_prefix.begin ());
+}
+
+bool
+Components::operator< (const Components &prefix) const
+{
+ return std::lexicographical_compare (m_prefix.begin (), m_prefix.end (),
+ prefix.m_prefix.begin (), prefix.m_prefix.end ());
+}
+
} // Namespace Name
} // namespace ns3