blob: 6b0443c8b27e9c48d44b055a9ed0f7f31eba5bf8 [file] [log] [blame]
/* -*- 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