int ccn_ref_tagged_string(enum ccn_dtag dtag, 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; const unsigned char *result = NULL; size_t size = 0; if (stop < start) return(-1); d = ccn_buf_decoder_start(&decoder, buf + start, stop - start); 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) { result = d->buf + d->decoder.index; size = d->decoder.numval; ccn_buf_advance(d); } ccn_buf_check_close(d); } else return(-1); if (d->decoder.index != d->size || !CCN_FINAL_DSTATE(d->decoder.state)) return (CCN_DSTATE_ERR_CODING); if (presult) *presult = result; if (psize) *psize = size; return(0); }
// extractNode parses and creates a sync tree node from an upcall info // returns NULL if there was any kind of error static struct SyncNodeComposite * extractNode(struct SyncRootStruct *root, struct ccn_upcall_info *info) { // first, find the content char *here = "sync_track.extractNode"; const unsigned char *cp = NULL; size_t cs = 0; size_t ccnb_size = info->pco->offset[CCN_PCO_E]; const unsigned char *ccnb = info->content_ccnb; int res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &cp, &cs); if (res < 0 || cs < DEFAULT_HASH_BYTES) { SyncNoteFailed(root, here, "ccn_content_get_value", __LINE__); return NULL; } // second, parse the object struct SyncNodeComposite *nc = SyncAllocComposite(root->base); struct ccn_buf_decoder ds; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&ds, cp, cs); res |= SyncParseComposite(nc, d); if (res < 0) { // failed, so back out of the allocations SyncNoteFailed(root, here, "bad parse", -res); SyncFreeComposite(nc); nc = NULL; } return nc; }
static int ccn_pubid_matches(const unsigned char *content_object, struct ccn_parsed_ContentObject *pc, const unsigned char *interest_msg, const struct ccn_parsed_interest *pi) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; int pubidstart; int pubidbytes; int contentpubidstart = 0; int contentpubidbytes = 0; pubidstart = pi->offset[CCN_PI_B_PublisherIDKeyDigest]; pubidbytes = pi->offset[CCN_PI_E_PublisherIDKeyDigest] - pubidstart; if (pubidbytes > 0) { d = ccn_buf_decoder_start(&decoder, content_object + pc->offset[CCN_PCO_B_PublisherPublicKeyDigest], (pc->offset[CCN_PCO_E_PublisherPublicKeyDigest] - pc->offset[CCN_PCO_B_PublisherPublicKeyDigest])); ccn_buf_advance(d); if (ccn_buf_match_some_blob(d)) { contentpubidstart = d->decoder.token_index; ccn_buf_advance(d); contentpubidbytes = d->decoder.token_index - contentpubidstart; } if (pubidbytes != contentpubidbytes) return(0); // This is fishy if (0 != memcmp(interest_msg + pubidstart, d->buf + contentpubidstart, pubidbytes)) return(0); } return(1); }
/* * utility, may need to be exported, to parse the buffer into a given slice * structure. */ static int slice_parse(struct ccns_slice *s, const unsigned char *p, size_t size) { int res = 0; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); uintmax_t version; int op; int start; struct ccn_charbuf *clause = NULL; if (!ccn_buf_match_dtag(d, CCN_DTAG_SyncConfigSlice)) return (-1); ccn_buf_advance(d); if (!ccn_buf_match_dtag(d, CCN_DTAG_SyncVersion)) return (-1); ccn_buf_advance(d); ccn_parse_uintmax(d, &version); ccn_buf_check_close(d); if (version != SLICE_VERSION) return (-1); start = d->decoder.token_index; if (ccn_parse_Name(d, NULL) < 0) return(-1); ccn_charbuf_reset(s->topo); res = ccn_charbuf_append(s->topo, p + start, d->decoder.token_index - start); if (res < 0) return(-1); start = d->decoder.token_index; if (ccn_parse_Name(d, NULL) < 0) return(-1); ccn_charbuf_reset(s->prefix); res = ccn_charbuf_append(s->prefix, p + start, d->decoder.token_index - start); if (res < 0) return(-1); if (!ccn_buf_match_dtag(d, CCN_DTAG_SyncConfigSliceList)) return(-1); ccn_buf_advance(d); clause = ccn_charbuf_create(); if (clause == NULL) return(-1); while (ccn_buf_match_dtag(d, CCN_DTAG_SyncConfigSliceOp)) { ccn_buf_advance(d); op = ccn_parse_nonNegativeInteger(d); // op is a small integer ccn_buf_check_close(d); if (op != 0) break; ccn_charbuf_reset(clause); start = d->decoder.token_index; if (ccn_parse_Name(d, NULL) < 0) break; res = ccn_charbuf_append(clause, p + start, d->decoder.token_index - start); ccns_slice_add_clause(s, clause); } ccn_charbuf_destroy(&clause); ccn_buf_check_close(d); /* </SyncConfigSliceList> */ ccn_buf_check_close(d); /* </SyncConfigSlice> */ if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) return(-1); 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 != size || !CCN_FINAL_DSTATE(d->decoder.state)) return (CCN_DSTATE_ERR_CODING); return(0); }
int gen_test(struct ccn_charbuf **name, struct ccn_indexbuf **comps) { int res; intmax_t secs = 1234567890; int nsecs = 6000000; *name = ccn_charbuf_create(); ccn_name_init(*name); res = ccn_create_version(NULL, *name, 0, secs, nsecs); if (res < 0) { printf("Unable to create version\n"); return(-__LINE__); } *comps = ccn_indexbuf_create(); struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = &decoder; ccn_buf_decoder_start(d, (*name)->buf, (*name)->length); res = ccn_parse_Name(d, *comps); if (res < 0) { printf("Unable to parse name\n"); return(-__LINE__); } return(0); }
extern int SyncCacheEntryFetch(struct SyncHashCacheEntry *ce) { // causes the cache entry to fetched from the repo char *here = "Sync.SyncCacheEntryFetch"; int res = 0; if (ce == NULL) { // not an entry res = -1; } else if (ce->ncL != NULL) { // it's already here res = 0; } else if ((ce->state & SyncHashState_stored) == 0) { // it's never been stored, fail quietly res = -1; } else { // at this point we try to fetch it from the local repo // a failure should complain struct SyncRootStruct *root = ce->head->root; struct SyncBaseStruct *base = root->base; struct ccn_charbuf *name = SyncNameForLocalNode(root, ce->hash); struct ccn_charbuf *content = ccn_charbuf_create(); char *why = "no fetch"; struct ccn_parsed_ContentObject pcos; res = SyncLocalRepoFetch(base, name, content, &pcos); if (res >= 0) { // parse the object const unsigned char *xp = NULL; size_t xs = 0; // get the encoded node res = ccn_content_get_value(content->buf, content->length, &pcos, &xp, &xs); if (res < 0) why = "ccn_content_get_value failed"; else { struct ccn_buf_decoder ds; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&ds, xp, xs); struct SyncNodeComposite *nc = SyncAllocComposite(root->base); res |= SyncParseComposite(nc, d); if (res < 0) { // failed, so back out of the allocations why = "bad parse"; SyncFreeComposite(nc); nc = NULL; } else { res = 1; SyncNodeIncRC(nc); ce->ncL = nc; ce->state |= SyncHashState_stored; } } } if (res < 0) if (root->base->debug >= CCNL_ERROR) SyncNoteUri(root, here, why, name); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&content); } return res; }
int ccn_dhcp_content_parse(const unsigned char *p, size_t size, struct ccn_dhcp_entry *tail) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); int i; int count; struct ccn_dhcp_entry *de = tail; if (ccn_buf_match_dtag(d, CCN_DTAG_Entry)) { ccn_buf_advance(d); count = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_Count); for (i = 0; i < count; i ++) { struct ccn_charbuf *store = ccn_charbuf_create(); size_t start; size_t end; int host_off = -1; int port_off = -1; de->next = calloc(1, sizeof(*de)); de = de->next; memset(de, 0, sizeof(*de)); de->store = store; de->next = NULL; if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) { de->name_prefix = ccn_charbuf_create(); start = d->decoder.token_index; ccn_parse_Name(d, NULL); end = d->decoder.token_index; ccn_charbuf_append(de->name_prefix, p + start, end - start); } else de->name_prefix = NULL; host_off = ccn_parse_tagged_string(d, CCN_DTAG_Host, store); port_off = ccn_parse_tagged_string(d, CCN_DTAG_Port, store); char *b = (char *)store->buf; char *h = b + host_off; char *p = b + port_off; if (host_off >= 0) memcpy((void *)de->address, h, strlen(h)); if (port_off >= 0) memcpy((void *)de->port, p, strlen(p)); } } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) ccn_dhcp_content_destroy(tail->next); return count; }
/** * Append Components from a ccnb-encoded Name to a flatname * * The ccnb encoded input may be a ContentObject, Interest, Prefix, * or Component instead of simply a Name. * @param dst is the destination, which should hold a ccnb-encoded Name * @param ccnb points to first byte of Name * @param size is the number of bytes in ccnb * @param skip is the number of components at the front of flatname to skip * @param count is the maximum number of componebts to append, or -1 for all * @returns number of appended components, or -1 if there is an error. */ int ccn_flatname_append_from_ccnb(struct ccn_charbuf *dst, const unsigned char *ccnb, size_t size, int skip, int count) { int ans = 0; int ncomp = 0; const unsigned char *comp = NULL; size_t compsize = 0; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, ccnb, size); int checkclose = 0; int res; if (ccn_buf_match_dtag(d, CCN_DTAG_Interest) || ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) { ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Signature)) ccn_buf_advance_past_element(d); } if ((ccn_buf_match_dtag(d, CCN_DTAG_Name) || ccn_buf_match_dtag(d, CCN_DTAG_Prefix))) { checkclose = 1; ccn_buf_advance(d); } else if (count != 0) count = 1; while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { if (ans == count) return(ans); ccn_buf_advance(d); compsize = 0; if (ccn_buf_match_blob(d, &comp, &compsize)) ccn_buf_advance(d); ccn_buf_check_close(d); if (d->decoder.state < 0) return(-1); ncomp += 1; if (ncomp > skip) { res = ccn_flatname_append_component(dst, comp, compsize); if (res < 0) return(-1); ans++; } } if (checkclose) ccn_buf_check_close(d); if (d->decoder.state < 0) return (-1); return(ans); }
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); }
struct ccn_proxy * ccn_proxy_init(const char *filter_uri, const char *prefix_uri) { struct ccn_proxy *proxy = calloc(1, sizeof(struct ccn_proxy)); struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = &decoder; int res; DEBUG_PRINT("IN %d %s\n", __LINE__, __func__); /* Convert URI to name this proxy is responsible for */ proxy->prefix = ccn_charbuf_create(); res = ccn_name_from_uri(proxy->prefix, prefix_uri); if (res < 0) { DEBUG_PRINT("ABORT %d %s bad ccn URI: %s\n", __LINE__, __func__, prefix_uri); abort(); } d = ccn_buf_decoder_start(d, proxy->prefix->buf, proxy->prefix->length); proxy->prefix_comps = ccn_indexbuf_create(); proxy->prefix_ncomps = ccn_parse_Name(d, proxy->prefix_comps); proxy->filter = ccn_charbuf_create(); res = ccn_name_from_uri(proxy->filter, filter_uri); if (res < 0) { DEBUG_PRINT("ABORT %d %s bad ccn URI: %s\n", __LINE__, __func__, filter_uri); abort(); } /* Initialization should be done by ccn_proxy_connect() */ proxy->handle_name = ccn_charbuf_create(); ccn_charbuf_append_string(proxy->handle_name, "in/outb"); DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__); return(proxy); }
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 != d->size || !CCN_FINAL_DSTATE(d->decoder.state)) return (CCN_DSTATE_ERR_CODING); return(0); }
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_name_last_component_offset(const unsigned char *ccnb, size_t size) //CONET was static { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, ccnb, size); int res = -1; if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) { ccn_buf_advance(d); res = d->decoder.token_index; /* in case of 0 components */ while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { res = d->decoder.token_index; ccn_buf_advance(d); if (ccn_buf_match_blob(d, NULL, NULL)) ccn_buf_advance(d); ccn_buf_check_close(d); } ccn_buf_check_close(d); } return ((d->decoder.state >= 0) ? res : -1); }
int ccn_uri_append(struct ccn_charbuf *c, const unsigned char *ccnb, size_t size, int includescheme) { int ncomp = 0; const unsigned char *comp = NULL; size_t compsize = 0; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, ccnb, size); if (ccn_buf_match_dtag(d, CCN_DTAG_Interest) || ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) { ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Signature)) ccn_buf_advance_past_element(d); } if (!ccn_buf_match_dtag(d, CCN_DTAG_Name)) return(-1); if (includescheme) ccn_charbuf_append_string(c, "ccnx:"); ccn_buf_advance(d); while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); compsize = 0; if (ccn_buf_match_blob(d, &comp, &compsize)) ccn_buf_advance(d); ccn_buf_check_close(d); if (d->decoder.state < 0) return(d->decoder.state); ncomp += 1; ccn_charbuf_append(c, "/", 1); ccn_uri_append_percentescaped(c, comp, compsize); } ccn_buf_check_close(d); if (d->decoder.state < 0) return (d->decoder.state); if (ncomp == 0) ccn_charbuf_append(c, "/", 1); return(ncomp); }
/** * Test for a match between a ContentObject and an Interest * * @param content_object ccnb-encoded ContentObject * @param content_object_size its size in bytes * @param implicit_content_digest boolean indicating whether the * final name component is implicit (as in * the on-wire format) or explicit (as within * ccnd's content store). * @param pc Valid parse information may be provided to * speed things up. If NULL it will be * reconstructed internally. * @param interest_msg ccnb-encoded Interest * @param interest_msg_size its size in bytes * @param pi see _pc_ * * @result 1 if the ccnb-encoded content_object matches the * ccnb-encoded interest_msg, otherwise 0. */ int ccn_content_matches_interest(const unsigned char *content_object, size_t content_object_size, int implicit_content_digest, struct ccn_parsed_ContentObject *pc, const unsigned char *interest_msg, size_t interest_msg_size, const struct ccn_parsed_interest *pi) { struct ccn_parsed_ContentObject pc_store; struct ccn_parsed_interest pi_store; int res; int ncomps; int prefixstart; int prefixbytes; int namecompstart; int namecompbytes; int checkdigest = 0; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; const unsigned char *nextcomp; size_t nextcomp_size = 0; const unsigned char *comp; size_t comp_size = 0; const unsigned char *bloom; size_t bloom_size = 0; unsigned char match_any[2] = "-"; if (pc == NULL) { res = ccn_parse_ContentObject(content_object, content_object_size, &pc_store, NULL); if (res < 0) return(0); pc = &pc_store; } if (pi == NULL) { res = ccn_parse_interest(interest_msg, interest_msg_size, &pi_store, NULL); if (res < 0) return(0); pi = &pi_store; } if (!ccn_pubid_matches(content_object, pc, interest_msg, pi)) return(0); ncomps = pc->name_ncomps + (implicit_content_digest ? 1 : 0); if (ncomps < pi->prefix_comps + pi->min_suffix_comps) return(0); if (ncomps > pi->prefix_comps + pi->max_suffix_comps) return(0); prefixstart = pi->offset[CCN_PI_B_Component0]; prefixbytes = pi->offset[CCN_PI_E_LastPrefixComponent] - prefixstart; namecompstart = pc->offset[CCN_PCO_B_Component0]; namecompbytes = pc->offset[CCN_PCO_E_ComponentLast] - namecompstart; if (prefixbytes > namecompbytes) { /* * The only way for this to be a match is if the implicit * content digest name component comes into play. */ if (implicit_content_digest && pi->offset[CCN_PI_B_LastPrefixComponent] - prefixstart == namecompbytes && (pi->offset[CCN_PI_E_LastPrefixComponent] - pi->offset[CCN_PI_B_LastPrefixComponent]) == 1 + 2 + 32 + 1) { prefixbytes = namecompbytes; checkdigest = 1; } else return(0); } if (0 != memcmp(interest_msg + prefixstart, content_object + namecompstart, prefixbytes)) return(0); if (checkdigest) { /* * The Exclude by next component is not relevant in this case, * since there is no next component present. */ ccn_digest_ContentObject(content_object, pc); d = ccn_buf_decoder_start(&decoder, interest_msg + pi->offset[CCN_PI_B_LastPrefixComponent], (pi->offset[CCN_PI_E_LastPrefixComponent] - pi->offset[CCN_PI_B_LastPrefixComponent])); comp_size = 0; if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); ccn_buf_match_blob(d, &comp, &comp_size); } if (comp_size != pc->digest_bytes) abort(); if (0 != memcmp(comp, pc->digest, comp_size)) return(0); } else if (pi->offset[CCN_PI_E_Exclude] > pi->offset[CCN_PI_B_Exclude]) { if (prefixbytes < namecompbytes) { /* pick out the next component in the content object name */ d = ccn_buf_decoder_start(&decoder, content_object + (namecompstart + prefixbytes), pc->offset[CCN_PCO_E_ComponentLast] - (namecompstart + prefixbytes)); if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); ccn_buf_match_blob(d, &nextcomp, &nextcomp_size); } else return(0); } else if (!implicit_content_digest) goto exclude_checked; else if (prefixbytes == namecompbytes) { /* use the digest name as the next component */ ccn_digest_ContentObject(content_object, pc); nextcomp_size = pc->digest_bytes; nextcomp = pc->digest; } else abort(); /* bug - should have returned already */ d = ccn_buf_decoder_start(&decoder, interest_msg + pi->offset[CCN_PI_B_Exclude], pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]); if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) abort(); ccn_buf_advance(d); bloom = NULL; bloom_size = 0; if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); bloom = match_any; ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_buf_check_close(d); } while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); comp_size = 0; if (ccn_buf_match_blob(d, &comp, &comp_size)) ccn_buf_advance(d); ccn_buf_check_close(d); if (comp_size > nextcomp_size) break; if (comp_size == nextcomp_size) { res = memcmp(comp, nextcomp, comp_size); if (res == 0) return(0); /* One of the explicit excludes */ if (res > 0) break; } bloom = NULL; bloom_size = 0; if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); bloom = match_any; ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_buf_check_close(d); } } /* * Now we have isolated the applicable filter (Any or Bloom or none). */ if (bloom == match_any) return(0); else if (bloom_size != 0) { const struct ccn_bloom_wire *f = ccn_bloom_validate_wire(bloom, bloom_size); /* If not a valid filter, treat like a false positive */ if (f == NULL) return(0); if (ccn_bloom_match_wire(f, nextcomp, nextcomp_size)) return(0); } exclude_checked: {} } /* * At this point the prefix matches and exclude-by-next-component is done. */ // test any other qualifiers here return(1); }
PUBLIC struct content_entry * r_store_find_first_match_candidate(struct ccnr_handle *h, const unsigned char *interest_msg, const struct ccn_parsed_interest *pi) { int res; size_t start = pi->offset[CCN_PI_B_Name]; size_t end = pi->offset[CCN_PI_E_Name]; struct ccn_charbuf *namebuf = NULL; struct ccn_charbuf *flatname = NULL; struct content_entry *content = NULL; flatname = ccn_charbuf_create(); ccn_flatname_from_ccnb(flatname, interest_msg, pi->offset[CCN_PI_E]); if (pi->offset[CCN_PI_B_Exclude] < pi->offset[CCN_PI_E_Exclude]) { /* Check for <Exclude><Any/><Component>... fast case */ struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; size_t ex1start; size_t ex1end; d = ccn_buf_decoder_start(&decoder, interest_msg + pi->offset[CCN_PI_B_Exclude], pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]); ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_buf_check_close(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ex1start = pi->offset[CCN_PI_B_Exclude] + d->decoder.token_index; ccn_buf_advance_past_element(d); ex1end = pi->offset[CCN_PI_B_Exclude] + d->decoder.token_index; if (d->decoder.state >= 0) { namebuf = ccn_charbuf_create(); ccn_charbuf_append(namebuf, interest_msg + start, end - start); namebuf->length--; ccn_charbuf_append(namebuf, interest_msg + ex1start, ex1end - ex1start); ccn_charbuf_append_closer(namebuf); res = ccn_flatname_append_from_ccnb(flatname, interest_msg + ex1start, ex1end - ex1start, 0, 1); if (res != 1) ccnr_debug_ccnb(h, __LINE__, "fastex_bug", NULL, namebuf->buf, namebuf->length); if (CCNSHOULDLOG(h, LM_8, CCNL_FINER)) ccnr_debug_ccnb(h, __LINE__, "fastex", NULL, namebuf->buf, namebuf->length); } } } } content = r_store_look(h, flatname->buf, flatname->length); ccn_charbuf_destroy(&namebuf); ccn_charbuf_destroy(&flatname); return(content); }
int main(int argc, char *argv[]) { struct ccn_charbuf *buffer; struct ccn_charbuf *signed_info = ccn_charbuf_create(); struct ccn_skeleton_decoder dd = {0}; ssize_t res; char *outname = NULL; int result = 0; char * contents[] = {"INVITE sip:[email protected] SIP/2.0\nVia: SIP/2.0/UDP 127.0.0.1:5060;rport;branch=z9hG4bK519044721\nFrom: <sip:[email protected]>;tag=2105643453\nTo: Test User <sip:[email protected]>\nCall-ID: [email protected]\nCSeq: 20 INVITE\nContact: <sip:[email protected]:5060>\nMax-Forwards: 70\nUser-Agent: Linphone-1.7.1/eXosip\nSubject: Phone call\nExpires: 120\nAllow: INVITE, ACK, CANCEL, BYE, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE\nContent-Type: application/sdp\nContent-Length: 448\n\nv=0\no=jthornto 123456 654321 IN IP4 127.0.0.1\ns=A conversation\nc=IN IP4 127.0.0.1\nt=0 0\nm=audio 7078 RTP/AVP 111 110 0 3 8 101\na=rtpmap:111 speex/16000/1\na=rtpmap:110 speex/8000/1\na=rtpmap:0 PCMU/8000/1\na=rtpmap:3 GSM/8000/1\na=rtpmap:8 PCMA/8000/1\na=rtpmap:101 telephone-event/8000\na=fmtp:101 0-11\nm=video 9078 RTP/AVP 97 98 99\na=rtpmap:97 theora/90000\na=rtpmap:98 H263-1998/90000\na=fmtp:98 CIF=1;QCIF=1\na=rtpmap:99 MP4V-ES/90000\n", "Quaer #%2d zjduer badone", "", NULL}; char * paths[] = { "/sip/protocol/parc.com/domain/foo/principal/invite/verb/[email protected]/id", "/d/e/f", "/zero/length/content", NULL}; struct path * cur_path = NULL; struct ccn_keystore *keystore = ccn_keystore_create(); struct ccn_keystore *aes_keystore = ccn_aes_keystore_create(); char *keystore_name = NULL; char *keystore_password = NULL; char *aes_keystore_name = NULL; unsigned char keybuf[32]; int i; while ((i = getopt(argc, argv, "a:k:p:o:")) != -1) { switch (i) { case 'a': aes_keystore_name = optarg; break; case 'k': keystore_name = optarg; break; case 'p': keystore_password = optarg; break; case 'o': outname = optarg; break; default: printf("Usage: %s [-k <keystore>] [-o <outfilename>]\n", argv[0]); exit(1); } } if (keystore_name == NULL) keystore_name = "test.keystore"; if (aes_keystore_name == NULL) aes_keystore_name = "test.aeskeystore"; if (keystore_password == NULL) keystore_password = "******"; res = ccn_keystore_init(keystore, keystore_name, keystore_password); if (res != 0) { printf ("Initializing keystore in %s\n", keystore_name); res = ccn_keystore_file_init(keystore_name, keystore_password, "ccnxuser", 0, 3650); if (res != 0) { fprintf (stderr, "Cannot create keystore [%s]", keystore_name); return res; } res = ccn_keystore_init(keystore, keystore_name, keystore_password); if (res != 0) { printf("Failed to initialize keystore\n"); exit(1); } } res = ccn_aes_keystore_init(aes_keystore, aes_keystore_name, keystore_password); if (res != 0) { printf ("Initializing AES keystore in %s\n", aes_keystore_name); ccn_generate_symmetric_key(keybuf, 256); res = ccn_aes_keystore_file_init(aes_keystore_name, keystore_password, keybuf, 256); if (res != 0) { fprintf (stderr, "Cannot create keystore [%s]", keystore_name); return res; } res = ccn_aes_keystore_init(aes_keystore, aes_keystore_name, keystore_password); if (res != 0) { printf("Failed to initialize keystore\n"); exit(1); } } printf("Creating signed_info\n"); res = ccn_signed_info_create(signed_info, /*pubkeyid*/ccn_keystore_key_digest(keystore), /*publisher_key_id_size*/ccn_keystore_key_digest_length(keystore), /*timestamp*/NULL, /*type*/CCN_CONTENT_GONE, /*freshness*/ 42, /*finalblockid*/NULL, /*keylocator*/NULL); if (res < 0) { printf("Failed to create signed_info!\n"); } res = ccn_skeleton_decode(&dd, signed_info->buf, signed_info->length); if (!(res == signed_info->length && dd.state == 0)) { printf("Failed to decode signed_info! Result %d State %d\n", (int)res, dd.state); result = 1; } memset(&dd, 0, sizeof(dd)); printf("Done with signed_info\n"); result = encode_sample_test(ccn_keystore_key(keystore), ccn_keystore_public_key(keystore), ccn_keystore_digest_algorithm(keystore), paths, contents, signed_info, outname); if (! result) { result = encode_sample_test(ccn_keystore_key(aes_keystore), ccn_keystore_key(aes_keystore), ccn_keystore_digest_algorithm(aes_keystore), paths, contents, signed_info, outname); } /* Now exercise as unit tests */ for (i = 0; paths[i] != NULL && contents[i] != NULL; i++) { printf("Unit test case %d\n", i); cur_path = path_create(paths[i]); buffer = ccn_charbuf_create(); if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_key(keystore), ccn_keystore_digest_algorithm(keystore))) { printf("Failed encode\n"); result = 1; } else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_public_key(keystore))) { printf("Failed decode\n"); result = 1; } ccn_charbuf_destroy(&buffer); buffer = ccn_charbuf_create(); if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_key(aes_keystore), ccn_keystore_digest_algorithm(aes_keystore))) { printf("Failed encode\n"); result = 1; } else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_key(aes_keystore))) { printf("Failed decode\n"); result = 1; } path_destroy(&cur_path); ccn_charbuf_destroy(&buffer); } /* Test the uri encode / decode routines */ init_all_chars_percent_encoded(); init_all_chars_mixed_encoded(); const char *uri_tests[] = { "_+4", "ccnx:/this/is/a/test", "", "ccnx:/this/is/a/test", ".+4", "../test2?x=2", "?x=2", "ccnx:/this/is/a/test2", "_-X", "../should/error", "", "", "_+2", "/missing/scheme", "", "ccnx:/missing/scheme", ".+0", "../../../../../././#/", "#/", "ccnx:/", ".+1", all_chars_percent_encoded, "", all_chars_percent_encoded_canon, "_+1", all_chars_percent_encoded_canon, "", all_chars_percent_encoded_canon, ".+4", "ccnx:/.../.%2e./...././.....///?...", "?...", "ccnx:/.../.../..../.....", "_-X", "/%3G?bad-pecent-encode", "", "", "_-X", "/%3?bad-percent-encode", "", "", "_-X", "/%#bad-percent-encode", "", "", "_+3", "ccnx://[email protected]:42/ignore/host/part of uri", "", "ccnx:/ignore/host/part%20of%20uri", NULL, NULL, NULL, NULL }; const char **u; struct ccn_charbuf *uri_out = ccn_charbuf_create(); buffer = ccn_charbuf_create(); for (u = uri_tests; *u != NULL; u += 4, i++) { printf("Unit test case %d\n", i); if (u[0][0] != '.') buffer->length = 0; res = ccn_name_from_uri(buffer, u[1]); if (!expected_res(res, u[0][1])) { printf("Failed: ccn_name_from_uri wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (res > strlen(u[1])) { printf("Failed: ccn_name_from_uri long res %d\n", (int)res); result = 1; } else if (0 != strcmp(u[1] + res, u[2])) { printf("Failed: ccn_name_from_uri expecting leftover '%s', got '%s'\n", u[2], u[1] + res); result = 1; } uri_out->length = 0; res = ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_PERCENTESCAPE | CCN_URI_INCLUDESCHEME); if (!expected_res(res, u[0][2])) { printf("Failed: ccn_uri_append wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (uri_out->length != strlen(u[3])) { printf("Failed: ccn_uri_append produced wrong number of characters\n"); result = 1; } ccn_charbuf_reserve(uri_out, 1)[0] = 0; if (0 != strcmp((const char *)uri_out->buf, u[3])) { printf("Failed: ccn_uri_append produced wrong output\n"); printf("Expected: %s\n", u[3]); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } } } } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); printf("Name marker tests\n"); do { const char *expected_uri = "ccnx:/example.com/.../%01/%FE/%01%02%03%04%05%06%07%08/%FD%10%10%10%10%1F%FF/%00%81"; const char *expected_chopped_uri = "ccnx:/example.com/.../%01/%FE"; const char *expected_bumped_uri = "ccnx:/example.com/.../%01/%FF"; const char *expected_bumped2_uri = "ccnx:/example.com/.../%01/%00%00"; printf("Unit test case %d\n", i++); buffer = ccn_charbuf_create(); uri_out = ccn_charbuf_create(); res = ccn_name_init(buffer); res |= ccn_name_append_str(buffer, "example.com"); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1); res |= ccn_name_append_numeric(buffer, 0xFE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129); res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_PERCENTESCAPE | CCN_URI_INCLUDESCHEME); if (res < 0) { printf("Failed: name marker tests had negative res\n"); result = 1; } if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri)) { printf("Failed: name marker tests produced wrong output\n"); printf("Expected: %s\n", expected_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_chop(buffer, NULL, 100); if (res != -1) { printf("Failed: ccn_name_chop did not produce error \n"); result = 1; } res = ccn_name_chop(buffer, NULL, 4); if (res != 4) { printf("Failed: ccn_name_chop got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_INCLUDESCHEME); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_chopped_uri)) { printf("Failed: ccn_name_chop botch\n"); printf("Expected: %s\n", expected_chopped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_next_sibling(buffer); if (res != 4) { printf("Failed: ccn_name_next_sibling got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_INCLUDESCHEME); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_name_next_sibling(buffer); uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_PERCENTESCAPE | CCN_URI_INCLUDESCHEME); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped2_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped2_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); } while (0); do { const char *expected_uri_mixed = "ccnx:/example.com/.../%01/%FE/=0102030405060708/=FD101010101FFF/=0081"; printf("Unit test case %d\n", i++); buffer = ccn_charbuf_create(); uri_out = ccn_charbuf_create(); res = ccn_name_init(buffer); res |= ccn_name_append_str(buffer, "example.com"); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1); res |= ccn_name_append_numeric(buffer, 0xFE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129); res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_MIXEDESCAPE | CCN_URI_INCLUDESCHEME); if (res < 0) { printf("Failed: name marker tests had negative res\n"); result = 1; } if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri_mixed)) { printf("Failed: name marker tests produced wrong output\n"); printf("Expected: %s\n", expected_uri_mixed); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); } while (0); printf("Empty component encoding test\n"); do { struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_charbuf *expected_encoding = ccn_charbuf_create(); /* manually create an encoding of <Name><Component/></Name> to ensure * that the regular encoders do not create a 0-length blob as part of * the empty component. */ ccnb_element_begin(expected_encoding, CCN_DTAG_Name); ccnb_element_begin(expected_encoding, CCN_DTAG_Component); ccnb_element_end(expected_encoding); ccnb_element_end(expected_encoding); ccn_name_from_uri(name, "ccnx:/..."); if (expected_encoding->length != name->length) { printf("Failed: encoding length %u but expected %u\n", (unsigned) name->length, (unsigned)expected_encoding->length); result = 1; } for (i = 0; i < expected_encoding->length; i++) { if (expected_encoding->buf[i] != name->buf[i]) { printf("Failed: encoding mismatch at %d, got %d but expected %d\n", i, name->buf[i], expected_encoding->buf[i]); result = 1; } } } while (0); printf("Timestamp tests\n"); do { intmax_t sec; int nsec; int r; int f; struct ccn_charbuf *a[2]; int t0 = 1363899678; printf("Unit test case %d\n", i++); /* Run many increasing inputs and make sure the output is in order. */ a[0] = ccn_charbuf_create(); a[1] = ccn_charbuf_create(); ccnb_append_timestamp_blob(a[1], CCN_MARKER_NONE, t0 - 1, 0); for (f = 0, nsec = 0, sec = t0; sec < t0 + 20; nsec += 122099) { while (nsec >= 1000000000) { sec++; nsec -= 1000000000; } ccn_charbuf_reset(a[f]); r = ccnb_append_timestamp_blob(a[f], CCN_MARKER_NONE, sec, nsec); if (r != 0 || a[f]->length != 7 || memcmp(a[1-f]->buf, a[f]->buf, 6) > 0) { printf("Failed ccnb_append_timestamp_blob(...,%jd,%d)\n", sec, nsec); result = 1; } f = 1 - f; } ccn_charbuf_destroy(&a[0]); ccn_charbuf_destroy(&a[1]); } while (0); printf("Message digest tests\n"); do { printf("Unit test case %d\n", i++); struct ccn_digest *dg = ccn_digest_create(CCN_DIGEST_SHA256); if (dg == NULL) { printf("Failed: ccn_digest_create returned NULL\n"); result = 1; break; } printf("Unit test case %d\n", i++); const unsigned char expected_digest[] = { 0xb3, 0x82, 0xcd, 0xb0, 0xe9, 0x5d, 0xf7, 0x3b, 0xe7, 0xdc, 0x19, 0x81, 0x3a, 0xfd, 0xdf, 0x89, 0xfb, 0xd4, 0xd4, 0xa0, 0xdb, 0x11, 0xa6, 0xba, 0x24, 0x16, 0x5b, 0xad, 0x9d, 0x90, 0x72, 0xb0 }; unsigned char actual_digest[sizeof(expected_digest)] = {0}; const char *data = "Content-centric"; if (ccn_digest_size(dg) != sizeof(expected_digest)) { printf("Failed: wrong digest size\n"); result = 1; break; } printf("Unit test case %d\n", i++); ccn_digest_init(dg); res = ccn_digest_update(dg, data, strlen(data)); if (res != 0) printf("Warning: check res %d\n", (int)res); printf("Unit test case %d\n", i++); res = ccn_digest_final(dg, actual_digest, sizeof(expected_digest)); if (res != 0) printf("Warning: check res %d\n", (int)res); if (0 != memcmp(actual_digest, expected_digest, sizeof(expected_digest))) { printf("Failed: wrong digest\n"); result = 1; break; } } while (0); printf("Really basic PRNG test\n"); do { unsigned char r1[42]; unsigned char r2[42]; printf("Unit test case %d\n", i++); ccn_add_entropy(&i, sizeof(i), 0); /* Not much entropy, really. */ ccn_random_bytes(r1, sizeof(r1)); memcpy(r2, r1, sizeof(r2)); ccn_random_bytes(r2, sizeof(r2)); if (0 == memcmp(r1, r2, sizeof(r2))) { printf("Failed: badly broken PRNG\n"); result = 1; break; } } while (0); printf("Bloom filter tests\n"); do { unsigned char seed1[4] = "1492"; const char *a[13] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen" }; struct ccn_bloom *b1 = NULL; struct ccn_bloom *b2 = NULL; int j, k, t1, t2; unsigned short us; printf("Unit test case %d\n", i++); b1 = ccn_bloom_create(13, seed1); for (j = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" matched empty Bloom filter\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0; j < 13; j++) ccn_bloom_insert(b1, a[j], strlen(a[j])); for (j = 0; j < 13; j++) if (!ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" not found when it should have been\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0, k = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j]+1, strlen(a[j]+1))) k++; if (k > 0) { printf("Mmm, found %d false positives\n", k); if (k > 2) { result = 1; break; } } unsigned char seed2[5] = "aqfb\0"; for (; seed2[3] <= 'f'; seed2[3]++) { printf("Unit test case %d (%4s) ", i++, seed2); b2 = ccn_bloom_create(13, seed2); for (j = 0; j < 13; j++) ccn_bloom_insert(b2, a[j], strlen(a[j])); for (j = 0, k = 0, us = ~0; us > 0; us--) { t1 = ccn_bloom_match(b1, &us, sizeof(us)); t2 = ccn_bloom_match(b2, &us, sizeof(us)); j += (t1 | t2); k += (t1 & t2); } printf("either=%d both=%d wiresize=%d\n", j, k, ccn_bloom_wiresize(b1)); if (k > 12) { printf("Failed: Bloom seeding may not be effective\n"); result = 1; } ccn_bloom_destroy(&b2); } ccn_bloom_destroy(&b1); } while (0); printf("ccn_sign_content() tests\n"); do { struct ccn *h = ccn_create(); int res; res = unit_tests_for_signing(h, &i, 0); if (res == 1) result = 1; printf("Unit test case %d\n", i++); ccn_destroy(&h); } while (0); do { struct ccn *h = ccn_create(); int res; res = ccn_load_default_key(h, aes_keystore_name, keystore_password); if (res < 0) { result = 1; printf("Failed: res == %d\n", (int)res); } else res = unit_tests_for_signing(h, &i, 1); if (res == 1) result = 1; printf("Unit test case %d\n", i++); ccn_destroy(&h); } while (0); printf("link tests\n"); printf("link tests\n"); do { struct ccn_charbuf *l = ccn_charbuf_create(); struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_parsed_Link pl = {0}; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; struct ccn_indexbuf *comps = ccn_indexbuf_create(); printf("Unit test case %d\n", i++); ccn_name_from_uri(name, "ccnx:/test/link/name"); ccnb_append_Link(l, name, "label", NULL); d = ccn_buf_decoder_start(&decoder, l->buf, l->length); res = ccn_parse_Link(d, &pl, comps); if (res != 3 /* components in name */) { printf("Failed: ccn_parse_Link res == %d\n", (int)res); result = 1; } } while (0); exit(result); }
int main (int argc, char *argv[]) { struct ccn_charbuf *buffer = ccn_charbuf_create(); struct ccn_charbuf *signed_info = ccn_charbuf_create(); struct ccn_skeleton_decoder dd = {0}; ssize_t res; char *outname = NULL; int fd; int result = 0; char * contents[] = {"INVITE sip:[email protected] SIP/2.0\nVia: SIP/2.0/UDP 127.0.0.1:5060;rport;branch=z9hG4bK519044721\nFrom: <sip:[email protected]>;tag=2105643453\nTo: Test User <sip:[email protected]>\nCall-ID: [email protected]\nCSeq: 20 INVITE\nContact: <sip:[email protected]:5060>\nMax-Forwards: 70\nUser-Agent: Linphone-1.7.1/eXosip\nSubject: Phone call\nExpires: 120\nAllow: INVITE, ACK, CANCEL, BYE, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE\nContent-Type: application/sdp\nContent-Length: 448\n\nv=0\no=jthornto 123456 654321 IN IP4 127.0.0.1\ns=A conversation\nc=IN IP4 127.0.0.1\nt=0 0\nm=audio 7078 RTP/AVP 111 110 0 3 8 101\na=rtpmap:111 speex/16000/1\na=rtpmap:110 speex/8000/1\na=rtpmap:0 PCMU/8000/1\na=rtpmap:3 GSM/8000/1\na=rtpmap:8 PCMA/8000/1\na=rtpmap:101 telephone-event/8000\na=fmtp:101 0-11\nm=video 9078 RTP/AVP 97 98 99\na=rtpmap:97 theora/90000\na=rtpmap:98 H263-1998/90000\na=fmtp:98 CIF=1;QCIF=1\na=rtpmap:99 MP4V-ES/90000\n", "Quaer #%2d zjduer badone", "", NULL}; char * paths[] = { "/sip/protocol/parc.com/domain/foo/principal/invite/verb/[email protected]/id", "/d/e/f", "/zero/length/content", NULL}; struct path * cur_path = NULL; struct ccn_keystore *keystore = ccn_keystore_create(); char *home = getenv("HOME"); char *keystore_suffix = "/.ccnx/.ccnx_keystore"; char *keystore_name = NULL; int i; if (argc == 3 && strcmp(argv[1], "-o") == 0) { outname = argv[2]; } else { printf("Usage: %s -o <outfilename>\n", argv[0]); exit(1); } if (home == NULL) { printf("Unable to determine home directory for keystore\n"); exit(1); } keystore_name = calloc(1, strlen(home) + strlen(keystore_suffix) + 1); strcat(keystore_name, home); strcat(keystore_name, keystore_suffix); if (0 != ccn_keystore_init(keystore, keystore_name, "Th1s1sn0t8g00dp8ssw0rd.")) { printf("Failed to initialize keystore\n"); exit(1); } printf("Creating signed_info\n"); res = ccn_signed_info_create(signed_info, /*pubkeyid*/ccn_keystore_public_key_digest(keystore), /*publisher_key_id_size*/ccn_keystore_public_key_digest_length(keystore), /*datetime*/NULL, /*type*/CCN_CONTENT_GONE, /*freshness*/ 42, /*finalblockid*/NULL, /*keylocator*/NULL); if (res < 0) { printf("Failed to create signed_info!\n"); } res = ccn_skeleton_decode(&dd, signed_info->buf, signed_info->length); if (!(res == signed_info->length && dd.state == 0)) { printf("Failed to decode signed_info! Result %d State %d\n", (int)res, dd.state); result = 1; } memset(&dd, 0, sizeof(dd)); printf("Done with signed_info\n"); printf("Encoding sample message data length %d\n", (int)strlen(contents[0])); cur_path = path_create(paths[0]); if (encode_message(buffer, cur_path, contents[0], strlen(contents[0]), signed_info, ccn_keystore_private_key(keystore))) { printf("Failed to encode message!\n"); } else { printf("Encoded sample message length is %d\n", (int)buffer->length); res = ccn_skeleton_decode(&dd, buffer->buf, buffer->length); if (!(res == buffer->length && dd.state == 0)) { printf("Failed to decode! Result %d State %d\n", (int)res, dd.state); result = 1; } if (outname != NULL) { fd = open(outname, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU); if (fd == -1) perror(outname); res = write(fd, buffer->buf, buffer->length); close(fd); } if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) != 0) { result = 1; } printf("Expect signature verification failure: "); if (buffer->length >= 20) buffer->buf[buffer->length - 20] += 1; if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) == 0) { result = 1; } } path_destroy(&cur_path); ccn_charbuf_destroy(&buffer); printf("Done with sample message\n"); /* Now exercise as unit tests */ for (i = 0; paths[i] != NULL && contents[i] != NULL; i++) { printf("Unit test case %d\n", i); cur_path = path_create(paths[i]); buffer = ccn_charbuf_create(); if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_private_key(keystore))) { printf("Failed encode\n"); result = 1; } else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_public_key(keystore))) { printf("Failed decode\n"); result = 1; } path_destroy(&cur_path); ccn_charbuf_destroy(&buffer); } /* Test the uri encode / decode routines */ init_all_chars_percent_encoded(); const char *uri_tests[] = { "_+4", "ccnx:/this/is/a/test", "", "ccnx:/this/is/a/test", ".+4", "../test2?x=2", "?x=2", "ccnx:/this/is/a/test2", "_-X", "../should/error", "", "", "_+2", "/missing/scheme", "", "ccnx:/missing/scheme", ".+0", "../../../../../././#/", "#/", "ccnx:/", ".+1", all_chars_percent_encoded, "", all_chars_percent_encoded_canon, "_+1", all_chars_percent_encoded_canon, "", all_chars_percent_encoded_canon, ".+4", "ccnx:/.../.%2e./...././.....///?...", "?...", "ccnx:/.../.../..../.....", "_-X", "/%3G?bad-pecent-encode", "", "", "_-X", "/%3?bad-percent-encode", "", "", "_-X", "/%#bad-percent-encode", "", "", "_+3", "ccnx://[email protected]:42/ignore/host/part of uri", "", "ccnx:/ignore/host/part%20of%20uri", NULL, NULL, NULL, NULL }; const char **u; struct ccn_charbuf *uri_out = ccn_charbuf_create(); buffer = ccn_charbuf_create(); for (u = uri_tests; *u != NULL; u += 4, i++) { printf("Unit test case %d\n", i); if (u[0][0] != '.') buffer->length = 0; res = ccn_name_from_uri(buffer, u[1]); if (!expected_res(res, u[0][1])) { printf("Failed: ccn_name_from_uri wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (res > strlen(u[1])) { printf("Failed: ccn_name_from_uri long res %d\n", (int)res); result = 1; } else if (0 != strcmp(u[1] + res, u[2])) { printf("Failed: ccn_name_from_uri expecting leftover '%s', got '%s'\n", u[2], u[1] + res); result = 1; } uri_out->length = 0; res = ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (!expected_res(res, u[0][2])) { printf("Failed: ccn_uri_append wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (uri_out->length != strlen(u[3])) { printf("Failed: ccn_uri_append produced wrong number of characters\n"); result = 1; } ccn_charbuf_reserve(uri_out, 1)[0] = 0; if (0 != strcmp((const char *)uri_out->buf, u[3])) { printf("Failed: ccn_uri_append produced wrong output\n"); printf("Expected: %s\n", u[3]); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } } } } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); printf("Name marker tests\n"); do { const char *expected_uri = "ccnx:/example.com/.../%01/%FE/%01%02%03%04%05%06%07%08/%FD%10%10%10%10%1F%FF/%00%81"; const char *expected_chopped_uri = "ccnx:/example.com/.../%01/%FE"; const char *expected_bumped_uri = "ccnx:/example.com/.../%01/%FF"; const char *expected_bumped2_uri = "ccnx:/example.com/.../%01/%00%00"; printf("Unit test case %d\n", i++); buffer = ccn_charbuf_create(); uri_out = ccn_charbuf_create(); res = ccn_name_init(buffer); res |= ccn_name_append_str(buffer, "example.com"); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1); res |= ccn_name_append_numeric(buffer, 0xFE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129); res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (res < 0) { printf("Failed: name marker tests had negative res\n"); result = 1; } if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri)) { printf("Failed: name marker tests produced wrong output\n"); printf("Expected: %s\n", expected_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_chop(buffer, NULL, 100); if (res != -1) { printf("Failed: ccn_name_chop did not produce error \n"); result = 1; } res = ccn_name_chop(buffer, NULL, 4); if (res != 4) { printf("Failed: ccn_name_chop got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_chopped_uri)) { printf("Failed: ccn_name_chop botch\n"); printf("Expected: %s\n", expected_chopped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_next_sibling(buffer); if (res != 4) { printf("Failed: ccn_name_next_sibling got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_name_next_sibling(buffer); uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped2_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped2_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); } while (0); printf("Message digest tests\n"); do { printf("Unit test case %d\n", i++); struct ccn_digest *dg = ccn_digest_create(CCN_DIGEST_SHA256); if (dg == NULL) { printf("Failed: ccn_digest_create returned NULL\n"); result = 1; break; } printf("Unit test case %d\n", i++); const unsigned char expected_digest[] = { 0xb3, 0x82, 0xcd, 0xb0, 0xe9, 0x5d, 0xf7, 0x3b, 0xe7, 0xdc, 0x19, 0x81, 0x3a, 0xfd, 0xdf, 0x89, 0xfb, 0xd4, 0xd4, 0xa0, 0xdb, 0x11, 0xa6, 0xba, 0x24, 0x16, 0x5b, 0xad, 0x9d, 0x90, 0x72, 0xb0 }; unsigned char actual_digest[sizeof(expected_digest)] = {0}; const char *data = "Content-centric"; if (ccn_digest_size(dg) != sizeof(expected_digest)) { printf("Failed: wrong digest size\n"); result = 1; break; } printf("Unit test case %d\n", i++); ccn_digest_init(dg); res = ccn_digest_update(dg, data, strlen(data)); if (res != 0) printf("Warning: check res %d\n", (int)res); printf("Unit test case %d\n", i++); res = ccn_digest_final(dg, actual_digest, sizeof(expected_digest)); if (res != 0) printf("Warning: check res %d\n", (int)res); if (0 != memcmp(actual_digest, expected_digest, sizeof(expected_digest))) { printf("Failed: wrong digest\n"); result = 1; break; } } while (0); printf("Really basic PRNG test\n"); do { unsigned char r1[42]; unsigned char r2[42]; printf("Unit test case %d\n", i++); ccn_add_entropy(&i, sizeof(i), 0); /* Not much entropy, really. */ ccn_random_bytes(r1, sizeof(r1)); memcpy(r2, r1, sizeof(r2)); ccn_random_bytes(r2, sizeof(r2)); if (0 == memcmp(r1, r2, sizeof(r2))) { printf("Failed: badly broken PRNG\n"); result = 1; break; } } while (0); printf("Bloom filter tests\n"); do { unsigned char seed1[4] = "1492"; const char *a[13] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen" }; struct ccn_bloom *b1 = NULL; struct ccn_bloom *b2 = NULL; int j, k, t1, t2; unsigned short us; printf("Unit test case %d\n", i++); b1 = ccn_bloom_create(13, seed1); for (j = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" matched empty Bloom filter\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0; j < 13; j++) ccn_bloom_insert(b1, a[j], strlen(a[j])); for (j = 0; j < 13; j++) if (!ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" not found when it should have been\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0, k = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j]+1, strlen(a[j]+1))) k++; if (k > 0) { printf("Mmm, found %d false positives\n", k); if (k > 2) { result = 1; break; } } unsigned char seed2[5] = "aqfb\0"; for (; seed2[3] <= 'f'; seed2[3]++) { printf("Unit test case %d (%4s) ", i++, seed2); b2 = ccn_bloom_create(13, seed2); for (j = 0; j < 13; j++) ccn_bloom_insert(b2, a[j], strlen(a[j])); for (j = 0, k = 0, us = ~0; us > 0; us--) { t1 = ccn_bloom_match(b1, &us, sizeof(us)); t2 = ccn_bloom_match(b2, &us, sizeof(us)); j += (t1 | t2); k += (t1 & t2); } printf("either=%d both=%d wiresize=%d\n", j, k, ccn_bloom_wiresize(b1)); if (k > 12) { printf("Failed: Bloom seeding may not be effective\n"); result = 1; } ccn_bloom_destroy(&b2); } ccn_bloom_destroy(&b1); } while (0); printf("ccn_sign_content() tests\n"); do { struct ccn *h = ccn_create(); struct ccn_charbuf *co = ccn_charbuf_create(); struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT; struct ccn_parsed_ContentObject pco = {0}; struct ccn_charbuf *name = ccn_charbuf_create(); printf("Unit test case %d\n", i++); ccn_name_from_uri(name, "ccnx:/test/data/%00%42"); res = ccn_sign_content(h, co, name, NULL, "DATA", 4); if (res != 0) { printf("Failed: res == %d\n", (int)res); result = 1; } sparm.template_ccnb = ccn_charbuf_create(); res = ccn_parse_ContentObject(co->buf, co->length, &pco, NULL); if (res != 0) { printf("Failed: ccn_parse_ContentObject res == %d\n", (int)res); result = 1; break; } ccn_charbuf_append(sparm.template_ccnb, co->buf + pco.offset[CCN_PCO_B_SignedInfo], pco.offset[CCN_PCO_E_SignedInfo] - pco.offset[CCN_PCO_B_SignedInfo]); sparm.sp_flags = CCN_SP_TEMPL_TIMESTAMP; printf("Unit test case %d\n", i++); res = ccn_sign_content(h, co, name, &sparm, "DATA", 4); if (res != 0) { printf("Failed: res == %d\n", (int)res); result = 1; } printf("Unit test case %d\n", i++); sparm.sp_flags = -1; res = ccn_sign_content(h, co, name, &sparm, "DATA", 4); if (res != -1) { printf("Failed: res == %d\n", (int)res); result = 1; } ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&sparm.template_ccnb); ccn_charbuf_destroy(&co); ccn_destroy(&h); } while (0); printf("link tests\n"); do { struct ccn_charbuf *l = ccn_charbuf_create(); struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_parsed_Link pl = {0}; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; struct ccn_indexbuf *comps = ccn_indexbuf_create(); printf("Unit test case %d\n", i++); ccn_name_from_uri(name, "ccnx:/test/link/name"); ccnb_append_Link(l, name, "label", NULL); d = ccn_buf_decoder_start(&decoder, l->buf, l->length); res = ccn_parse_Link(d, &pl, comps); if (res != 3 /* components in name */) { printf("Failed: ccn_parse_Link res == %d\n", (int)res); result = 1; } } while (0); exit(result); }
static PyObject * ExclusionFilter_obj_from_ccn(PyObject *py_exclusion_filter) { PyObject *py_obj_ExclusionFilter, *py_components = NULL; PyObject *py_o; struct ccn_charbuf *exclusion_filter; int r; struct ccn_buf_decoder decoder, *d; size_t start, stop; assert(g_type_ExclusionFilter); debug("ExclusionFilter_from_ccn start\n"); exclusion_filter = CCNObject_Get(EXCLUSION_FILTER, py_exclusion_filter); // 1) Create python object py_obj_ExclusionFilter = PyObject_CallObject(g_type_ExclusionFilter, NULL); JUMP_IF_NULL(py_obj_ExclusionFilter, error); // 2) Set ccn_data to a cobject pointing to the c struct // and ensure proper destructor is set up for the c object. r = PyObject_SetAttrString(py_obj_ExclusionFilter, "ccn_data", py_exclusion_filter); JUMP_IF_NEG(r, error); // 3) Parse c structure and fill python attributes // using PyObject_SetAttrString // // self.components = None // # pyccn // self.ccn_data_dirty = False // self.ccn_data = None # backing charbuf py_components = PyList_New(0); JUMP_IF_NULL(py_components, error); r = PyObject_SetAttrString(py_obj_ExclusionFilter, "components", py_components); JUMP_IF_NEG(r, error); /* begin the actual parsing */ d = ccn_buf_decoder_start(&decoder, exclusion_filter->buf, exclusion_filter->length); r = ccn_buf_match_dtag(d, CCN_DTAG_Exclude); JUMP_IF_NEG(r, parse_error); ccn_buf_advance(d); r = ccn_buf_match_dtag(d, CCN_DTAG_Any); JUMP_IF_NEG(r, error); if (r) { ccn_buf_advance(d); ccn_buf_check_close(d); debug("got any: %d\n", r); py_o = Exclusion_Any_Obj(); JUMP_IF_NULL(py_o, error); r = PyList_Append(py_components, py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { start = d->decoder.token_index; r = ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Component, 0, -1); JUMP_IF_NEG(r, error); stop = d->decoder.token_index; debug("got name\n"); py_o = Exclusion_Name_Obj(exclusion_filter->buf, start, stop); r = PyList_Append(py_components, py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); r = ccn_buf_match_dtag(d, CCN_DTAG_Any); if (r) { ccn_buf_advance(d); ccn_buf_check_close(d); debug("got *any*: %d\n", r); py_o = Exclusion_Any_Obj(); JUMP_IF_NULL(py_o, error); r = PyList_Append(py_components, py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } } ccn_buf_check_close(d); JUMP_IF_NEG(d->decoder.state, parse_error); // 4) Return the created object debug("ExclusionFilter_from_ccn ends\n"); return py_obj_ExclusionFilter; parse_error: PyErr_SetString(g_PyExc_CCNExclusionFilterError, "error parsing the data"); error: Py_XDECREF(py_components); Py_XDECREF(py_obj_ExclusionFilter); return NULL; }
enum ccn_upcall_res andana_client_encap_interest( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { int res; enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR; struct andana_client *client = selfp->data; struct ccn_proxy *proxy = client->proxy; size_t orig_name_ncomps; struct ccn_charbuf *orig_name = NULL; struct ccn_indexbuf *orig_name_comps = NULL; struct ccn_charbuf *new_name = NULL; struct ccn_indexbuf *new_name_comps = NULL; struct hashtb_enumerator ee; struct hashtb_enumerator *e = ⅇ switch (kind) { case CCN_UPCALL_INTEREST: DEBUG_PRINT("Received Interest\n"); break; case CCN_UPCALL_FINAL: DEBUG_PRINT("Encap: callback final\n"); return(CCN_UPCALL_RESULT_OK); default: return(CCN_UPCALL_RESULT_ERR); } /* Extract Name from Interest */ orig_name_ncomps = ccn_util_extract_name(info->interest_ccnb, info->interest_comps, &orig_name, &orig_name_comps); /* * Need to check this Interest doesn't match what we send out. * Otherwise, we'll just keep encapsulating the same thing over and over. */ int num_matching_comps = ccn_util_name_match(client->proxy->prefix, client->proxy->prefix_comps, orig_name, orig_name_comps); if (num_matching_comps == client->proxy->prefix_ncomps) { DEBUG_PRINT("Interest matches %d of %d components, ignoring interest\n", num_matching_comps, (int)client->proxy->prefix_ncomps); #ifdef PROXYDEBUG ccn_util_println_pc_fmt(orig_name->buf, orig_name->length); DEBUG_PRINT("Name has %lu comps\n", orig_name_comps->n-1); ccn_util_println_pc_fmt(client->proxy->prefix->buf, client->proxy->prefix->length); DEBUG_PRINT("Name has %lu comps\n", client->proxy->prefix_comps->n-1); #endif goto MatchBail; } else { DEBUG_PRINT("Interest matches %d of %d components\n", num_matching_comps, (int)client->proxy->prefix_ncomps); } /* Create a new name encapsulated & encrypted name */ // new_name_comps = ccn_indexbuf_create(); ccn_name_append(orig_name, info->interest_ccnb, info->pi->offset[CCN_PI_E]); ccn_indexbuf_destroy(&orig_name_comps); struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = &decoder; ccn_buf_decoder_start(d, orig_name->buf, orig_name->length); orig_name_comps = ccn_indexbuf_create(); res = ccn_parse_Name(d, orig_name_comps); if (res <= 0) { DEBUG_PRINT("%d %s error parsing encapsulated name\n", __LINE__, __func__); goto MatchBail; } res = andana_path_encrypt_encap(client->path, orig_name, orig_name_comps, &new_name, &new_name_comps); if (res <= 0) { DEBUG_PRINT("%d %s error encapsulating and encrypting name\n", __LINE__, __func__); goto EncryptBail; } /* Remember the new name so we know how to decrypt & decapsulate it later */ hashtb_start(client->name_to_path, e); res = hashtb_seek(e, new_name->buf, new_name->length, 0); if (res == HT_NEW_ENTRY) { } else if (res == HT_OLD_ENTRY) { DEBUG_PRINT("Interest recording found old entry\n"); upcall_res = CCN_UPCALL_RESULT_OK; goto LookupBail; } else { DEBUG_PRINT("Error in Interest insertion\n"); goto LookupBail; } /* Send out new Interest */ #ifdef PROXYDEBUG struct ccn_charbuf *c = ccn_charbuf_create(); ccn_uri_append(c, new_name->buf, new_name->length, 1); DEBUG_PRINT("name = %s\n", ccn_charbuf_as_string(c)); ccn_charbuf_destroy(&c); #endif res = ccn_express_interest(proxy->handle, new_name, proxy->content_handler, NULL); if(res != 0) { DEBUG_PRINT("express interest res = %d\n",res); } else { struct andana_path **path_ptr = e->data; *path_ptr = andana_path_copy(client->path); upcall_res = CCN_UPCALL_RESULT_INTEREST_CONSUMED; } LookupBail: hashtb_end(e); EncryptBail: ccn_charbuf_destroy(&new_name); ccn_indexbuf_destroy(&new_name_comps); MatchBail: ccn_charbuf_destroy(&orig_name); ccn_indexbuf_destroy(&orig_name_comps); return(upcall_res); }
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) || ccn_buf_match_dtag(d, CCN_DTAG_PersistentInterest)) { 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); } /*In case of persistent interest*/ if(ccn_buf_match_dtag(d, CCN_DTAG_PersistentInterest)) { interest->persistent = 1; } 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 != 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 ccn_strategy_selection * ccn_strategy_selection_parse(const unsigned char *p, size_t size) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); struct ccn_strategy_selection *result; struct ccn_charbuf *store = NULL; const unsigned char *val = NULL; size_t sz; size_t start; size_t end; int action_off = -1; int ccnd_id_off = -1; int strategyid_off = -1; int parameters_off = -1; result = calloc(1, sizeof(*result)); if (result == NULL) return(NULL); result->name_prefix = ccn_charbuf_create(); result->store = store = ccn_charbuf_create(); if (result->name_prefix == NULL || result->store == NULL) { ccn_strategy_selection_destroy(&result); return(NULL); } if (ccn_buf_match_dtag(d, CCN_DTAG_StrategySelection)) { ccn_buf_advance(d); action_off = ccn_parse_tagged_string(d, CCN_DTAG_Action, store); if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) { start = d->decoder.token_index; ccn_parse_Name(d, NULL); end = d->decoder.token_index; ccn_charbuf_append(result->name_prefix, p + start, end - start); } else ccn_charbuf_destroy(&result->name_prefix); if (ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &val, &sz)) { ccn_buf_advance(d); if (sz != 32) d->decoder.state = -__LINE__; } ccn_buf_check_close(d); if (d->decoder.state >= 0) { ccnd_id_off = store->length; ccn_charbuf_append(store, val, sz); result->ccnd_id_size = sz; } } strategyid_off = ccn_parse_tagged_string(d, CCN_DTAG_StrategyID, store); parameters_off = ccn_parse_tagged_string(d, CCN_DTAG_StrategyParameters, store); result->lifetime = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds); ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) ccn_strategy_selection_destroy(&result); else { const char *b = (const char *)result->store->buf; result->action = (action_off == -1) ? NULL : b + action_off; result->ccnd_id = (ccnd_id_off == -1) ? NULL : result->store->buf + ccnd_id_off; result->strategyid = (strategyid_off == -1) ? NULL : b + strategyid_off; result->parameters = (parameters_off == -1) ? NULL : b + parameters_off; } return(result); }
static int dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *name_tree; proto_tree *exclude_tree; proto_item *titem; struct ccn_parsed_interest interest; struct ccn_parsed_interest *pi = &interest; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; const unsigned char *bloom; size_t bloom_size = 0; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; const unsigned char *blob; size_t blob_size; ssize_t l; unsigned int i; double lifetime; int res; comps = ccn_indexbuf_create(); res = ccn_parse_interest(ccnb, ccnb_size, pi, comps); if (res < 0) return (res); /* Name */ l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pi->offset[CCN_PI_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* MinSuffixComponents */ l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents]; if (l > 0) { i = pi->min_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i); } /* MaxSuffixComponents */ l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents]; if (l > 0) { i = pi->max_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i); } /* PublisherPublicKeyDigest */ /* Exclude */ l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]; if (l > 0) { c = ccn_charbuf_create(); d = ccn_buf_decoder_start(&decoder, ccnb + pi->offset[CCN_PI_B_Exclude], l); if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) { ccn_charbuf_destroy(&c); return(-1); } ccn_charbuf_append_string(c, "Exclude: "); ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_charbuf_append_string(c, "* "); ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_charbuf_append_string(c, "? "); ccn_buf_check_close(d); } while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); comp_size = 0; if (ccn_buf_match_blob(d, &comp, &comp_size)) ccn_buf_advance(d); ccn_uri_append_percentescaped(c, comp, comp_size); ccn_charbuf_append_string(c, " "); ccn_buf_check_close(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_charbuf_append_string(c, "* "); ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_charbuf_append_string(c, "? "); ccn_buf_check_close(d); } } titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l, "%s", ccn_charbuf_as_string(c)); exclude_tree = proto_item_add_subtree(titem, ett_exclude); ccn_charbuf_destroy(&c); } /* ChildSelector */ l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector]; if (l > 0) { i = pi->orderpref; titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i); proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), "")); } /* AnswerOriginKind */ l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind]; if (l > 0) { i = pi->answerfrom; titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i); } /* Scope */ l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope]; if (l > 0) { i = pi->scope; titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i); } /* InterestLifetime */ l = pi->offset[CCN_PI_E_InterestLifetime] - pi->offset[CCN_PI_B_InterestLifetime]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, ccnb, pi->offset[CCN_PI_B_InterestLifetime], pi->offset[CCN_PI_E_InterestLifetime], &blob, &blob_size); lifetime = 0.0; for (i = 0; i < blob_size; i++) lifetime = lifetime * 256.0 + (double)blob[i]; lifetime /= 4096.0; titem = proto_tree_add_double(tree, hf_ccn_interestlifetime, tvb, blob - ccnb, blob_size, lifetime); } /* Nonce */ l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb, pi->offset[CCN_PI_B_Nonce], pi->offset[CCN_PI_E_Nonce], &blob, &blob_size); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, ", <"); for (i = 0; i < blob_size; i++) col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]); col_append_str(pinfo->cinfo, COL_INFO, ">"); } titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb, blob - ccnb, blob_size, FALSE); } return (1); }
/** * Load a link to the repo policy from the repoPolicy file and load the link * target to extract the actual policy. * If a policy file does not exist a new one is created, with a link to a policy * based either on the environment variable CCNR_GLOBAL_PREFIX or the system * default value of ccnx:/parc.com/csl/ccn/Repos, plus the system defaults for * other fields. * This routine must be called after the btree code is initialized and capable * of returning content objects. * Sets the parsed_policy field of the handle to be the new policy. */ static int load_policy(struct ccnr_handle *ccnr) { int fd; ssize_t res; struct content_entry *content = NULL; const unsigned char *content_msg = NULL; struct ccn_parsed_ContentObject pco = {0}; struct ccn_parsed_Link pl = {0}; struct ccn_indexbuf *nc = NULL; struct ccn_charbuf *basename = NULL; struct ccn_charbuf *policy = NULL; struct ccn_charbuf *policy_cob = NULL; struct ccn_charbuf *policyFileName; const char *global_prefix; const unsigned char *buf = NULL; size_t length = 0; int segment = 0; int final = 0; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; policyFileName = ccn_charbuf_create(); ccn_charbuf_putf(policyFileName, "%s/repoPolicy", ccnr->directory); ccnr->parsed_policy = ccnr_parsed_policy_create(); fd = open(ccn_charbuf_as_string(policyFileName), O_RDONLY); if (fd >= 0) { ccnr->policy_link_cob = ccn_charbuf_create(); ccn_charbuf_reserve(ccnr->policy_link_cob, 4096); // limits the size of the policy link ccnr->policy_link_cob->length = 0; // clear the buffer res = read(fd, ccnr->policy_link_cob->buf, ccnr->policy_link_cob->limit - ccnr->policy_link_cob->length); close(fd); if (res == -1) { r_init_fail(ccnr, __LINE__, "Error reading repoPolicy file.", errno); ccn_charbuf_destroy(&ccnr->policy_link_cob); ccn_charbuf_destroy(&policyFileName); return(-1); } ccnr->policy_link_cob->length = res; nc = ccn_indexbuf_create(); res = ccn_parse_ContentObject(ccnr->policy_link_cob->buf, ccnr->policy_link_cob->length, &pco, nc); res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnr->policy_link_cob->buf, pco.offset[CCN_PCO_B_Content], pco.offset[CCN_PCO_E_Content], &buf, &length); d = ccn_buf_decoder_start(&decoder, buf, length); res = ccn_parse_Link(d, &pl, NULL); if (res <= 0) { ccnr_msg(ccnr, "Policy link is malformed."); goto CreateNewPolicy; } basename = ccn_charbuf_create(); ccn_charbuf_append(basename, buf + pl.offset[CCN_PL_B_Name], pl.offset[CCN_PL_E_Name] - pl.offset[CCN_PL_B_Name]); ccnr->policy_name = ccn_charbuf_create(); // to detect writes to this name ccn_charbuf_append_charbuf(ccnr->policy_name, basename); // has version ccn_name_chop(ccnr->policy_name, NULL, -1); // get rid of version policy = ccn_charbuf_create(); // if we fail to retrieve the link target, report and then create a new one do { ccn_name_append_numeric(basename, CCN_MARKER_SEQNUM, segment++); content = r_store_lookup_ccnb(ccnr, basename->buf, basename->length); if (content == NULL) { ccnr_debug_ccnb(ccnr, __LINE__, "policy lookup failed for", NULL, basename->buf, basename->length); break; } ccn_name_chop(basename, NULL, -1); content_msg = r_store_content_base(ccnr, content); if (content_msg == NULL) { ccnr_debug_ccnb(ccnr, __LINE__, "Unable to read policy object", NULL, basename->buf, basename->length); break; } res = ccn_parse_ContentObject(content_msg, r_store_content_size(ccnr, content), &pco, nc); res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, content_msg, pco.offset[CCN_PCO_B_Content], pco.offset[CCN_PCO_E_Content], &buf, &length); ccn_charbuf_append(policy, buf, length); final = ccn_is_final_pco(content_msg, &pco, nc); } while (!final && segment < 100);
PyObject * Signature_obj_from_ccn(PyObject *py_signature) { struct ccn_charbuf *signature; PyObject *py_obj_signature, *py_o; struct ccn_buf_decoder decoder, *d; size_t start, stop, size; const unsigned char *ptr; int r; assert(CCNObject_IsValid(SIGNATURE, py_signature)); signature = CCNObject_Get(SIGNATURE, py_signature); debug("Signature_from_ccn start, len=%zd\n", signature->length); // 1) Create python object py_obj_signature = PyObject_CallObject(g_type_Signature, NULL); if (!py_obj_signature) return NULL; // 2) Set ccn_data to a cobject pointing to the c struct // and ensure proper destructor is set up for the c object. r = PyObject_SetAttrString(py_obj_signature, "ccn_data", py_signature); JUMP_IF_NEG(r, error); // 3) Parse c structure and fill python attributes // Neither DigestAlgorithm nor Witness are included in the packet // from ccnput, so they are apparently both optional d = ccn_buf_decoder_start(&decoder, signature->buf, signature->length); if (!ccn_buf_match_dtag(d, CCN_DTAG_Signature)) { PyErr_Format(g_PyExc_CCNSignatureError, "Error finding" " CCN_DTAG_Signature (decoder state: %d)", d->decoder.state); goto error; } debug("Is a signature\n"); ccn_buf_advance(d); /* CCN_DTAG_DigestAlgorithm */ start = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_DigestAlgorithm, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, d->buf, start, stop, &ptr, &size); if (r == 0) { debug("PyObject_SetAttrString digestAlgorithm\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_signature, "digestAlgorithm", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } /* CCN_DTAG_Witness */ start = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Witness, 1, -1); stop = d->decoder.token_index; debug("witness start %zd stop %zd\n", start, stop); r = ccn_ref_tagged_BLOB(CCN_DTAG_Witness, d->buf, start, stop, &ptr, &size); if (r == 0) { // The Witness is represented as a DER-encoded PKCS#1 DigestInfo, // which contains an AlgorithmIdentifier (an OID, together with any necessary parameters) // and a byte array (OCTET STRING) containing the digest information to be interpreted according to that OID. // http://www.ccnx.org/releases/latest/doc/technical/SignatureGeneration.html debug("PyObject_SetAttrString witness\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_signature, "witness", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } /* CCN_DTAG_SignatureBits */ start = d->decoder.token_index; ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SignatureBits, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, d->buf, start, stop, &ptr, &size); if (r < 0) { PyErr_Format(g_PyExc_CCNSignatureError, "Error parsing" " CCN_DTAG_SignatureBits (decoder state %d)", d->decoder.state); goto error; } assert(r == 0); debug("PyObject_SetAttrString signatureBits\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_signature, "signatureBits", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); ccn_buf_check_close(d); if (d->decoder.state < 0) { PyErr_Format(g_PyExc_CCNSignatureError, "Signature decoding error" " (decoder state: %d, numval: %zd)", d->decoder.state, d->decoder.numval); goto error; } // 4) Return the created object debug("Signature_from_ccn ends\n"); return py_obj_signature; error: Py_DECREF(py_obj_signature); return NULL; }
/** * Parse a ccnb-ecoded FaceInstance into an internal representation * * The space used for the various strings is held by the charbuf. * A client may replace the strings with other pointers, but then * assumes responsibilty for managing those pointers. * @returns pointer to newly allocated structure describing the face, or * NULL if there is an error. */ struct ccn_face_instance * ccn_face_instance_parse(const unsigned char *p, size_t size) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); struct ccn_charbuf *store = ccn_charbuf_create(); struct ccn_face_instance *result; const unsigned char *val; size_t sz; int action_off = -1; int ccnd_id_off = -1; int host_off = -1; int port_off = -1; int mcast_off = -1; if (store == NULL) return(NULL); result = calloc(1, sizeof(*result)); if (result == NULL) { ccn_charbuf_destroy(&store); return(NULL); } result->store = store; if (ccn_buf_match_dtag(d, CCN_DTAG_FaceInstance)) { ccn_buf_advance(d); action_off = ccn_parse_tagged_string(d, CCN_DTAG_Action, store); if (ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &val, &sz)) { ccn_buf_advance(d); if (sz != 32) d->decoder.state = -__LINE__; } ccn_buf_check_close(d); if (d->decoder.state >= 0) { ccnd_id_off = store->length; ccn_charbuf_append(store, val, sz); result->ccnd_id_size = sz; } } result->faceid = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FaceID); result->descr.ipproto = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_IPProto); host_off = ccn_parse_tagged_string(d, CCN_DTAG_Host, store); port_off = ccn_parse_tagged_string(d, CCN_DTAG_Port, store); mcast_off = ccn_parse_tagged_string(d, CCN_DTAG_MulticastInterface, store); result->descr.mcast_ttl = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_MulticastTTL); result->lifetime = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds); ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) ccn_face_instance_destroy(&result); else { char *b = (char *)store->buf; result->action = (action_off == -1) ? NULL : b + action_off; result->ccnd_id = (ccnd_id_off == -1) ? NULL : store->buf + ccnd_id_off; result->descr.address = (host_off == -1) ? NULL : b + host_off; result->descr.port = (port_off == -1) ? NULL : b + port_off; result->descr.source_address = (mcast_off == -1) ? NULL : b + mcast_off; } return(result); }
PyObject * SignedInfo_obj_from_ccn(PyObject *py_signed_info) { struct ccn_charbuf *signed_info; PyObject *py_obj_SignedInfo, *py_o; struct ccn_buf_decoder decoder, *d; size_t start, stop, size; const unsigned char *ptr; int r; signed_info = CCNObject_Get(SIGNED_INFO, py_signed_info); debug("SignedInfo_from_ccn start, size=%zd\n", signed_info->length); // 1) Create python object py_obj_SignedInfo = PyObject_CallObject(g_type_SignedInfo, NULL); if (!py_obj_SignedInfo) return NULL; // 2) Set ccn_data to a cobject pointing to the c struct // and ensure proper destructor is set up for the c object. r = PyObject_SetAttrString(py_obj_SignedInfo, "ccn_data", py_signed_info); JUMP_IF_NEG(r, error); // 3) Parse c structure and fill python attributes // using PyObject_SetAttrString // based on chk_signing_params // from ccn_client.c // //outputs: // Note, it is ok that non-filled optional elements // are initialized to None (through the .py file __init__) // d = ccn_buf_decoder_start(&decoder, signed_info->buf, signed_info->length); if (!ccn_buf_match_dtag(d, CCN_DTAG_SignedInfo)) { PyErr_Format(g_PyExc_CCNSignedInfoError, "Error finding" " CCN_DTAG_SignedInfo (decoder state: %d)", d->decoder.state); goto error; } ccn_buf_advance(d); /* PublisherPublic Key */ //XXX: should we check for case when PublishePublicKeyDigest is not present? -dk start = d->decoder.token_index; ccn_parse_required_tagged_BLOB(d, CCN_DTAG_PublisherPublicKeyDigest, 16, 64); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, d->buf, start, stop, &ptr, &size); if (r < 0) { PyErr_Format(g_PyExc_CCNSignedInfoError, "Error parsing" " CCN_DTAG_PublisherPublicKey (decoder state %d)", d->decoder.state); goto error; } // self.publisherPublicKeyDigest = None # SHA256 hash debug("PyObject_SetAttrString publisherPublicKeyDigest\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "publisherPublicKeyDigest", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); /* Timestamp */ start = d->decoder.token_index; ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Timestamp, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, d->buf, start, stop, &ptr, &size); if (r < 0) { PyErr_Format(g_PyExc_CCNSignedInfoError, "Error parsing" " CCN_DTAG_Timestamp (decoder state %d)", d->decoder.state); goto error; } // self.timeStamp = None # CCNx timestamp debug("PyObject_SetAttrString timeStamp\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "timeStamp", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); /* Type */ assert(d->decoder.state >= 0); r = ccn_parse_optional_tagged_binary_number(d, CCN_DTAG_Type, 3, 3, CCN_CONTENT_DATA); if (d->decoder.state < 0) { PyErr_SetString(g_PyExc_CCNSignedInfoError, "Unable to parse type"); goto error; } py_o = _pyccn_Int_FromLong(r); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "type", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); /* start = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Type, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_Type, d->buf, start, stop, &ptr, &size); if (r == 0) { // type = None # CCNx type // TODO: Provide a string representation with the Base64 mnemonic? debug("PyObject_SetAttrString type\n"); py_o = PyByteArray_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "type", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } */ /* FreshnessSeconds */ r = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds); if (r >= 0) { // self.freshnessSeconds = None debug("PyObject_SetAttrString freshnessSeconds\n"); py_o = _pyccn_Int_FromLong(r); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "freshnessSeconds", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } /* FinalBlockID */ #if 0 /* old code (left in case mine is wrong - dk) */ if (ccn_buf_match_dtag(d, CCN_DTAG_FinalBlockID)) { ccn_buf_advance(d); start = d->decoder.token_index; if (ccn_buf_match_some_blob(d)) ccn_buf_advance(d); stop = d->decoder.token_index; ccn_buf_check_close(d); if (d->decoder.state >= 0 && stop > start) { // self.finalBlockID = None fprintf(stderr, "PyObject_SetAttrString finalBlockID, len=%zd\n", stop - start); py_o = PyByteArray_FromStringAndSize((const char*) (d->buf + start), stop - start); PyObject_SetAttrString(py_obj_SignedInfo, "finalBlockID", py_o); Py_INCREF(py_o); } } #endif start = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_FinalBlockID, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, d->buf, start, stop, &ptr, &size); if (r == 0) { // self.finalBlockID = None debug("PyObject_SetAttrString finalBlockID, len=%zd\n", size); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "finalBlockID", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } /* KeyLocator */ #if 0 /* Old code in case mine is wrong - dk */ start = d->decoder.token_index; if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator)) ccn_buf_advance_past_element(d); stop = d->decoder.token_index; if (d->decoder.state >= 0 && stop > start) { fprintf(stderr, "PyObject_SetAttrString keyLocator, len=%zd\n", stop - start); struct ccn_charbuf* keyLocator = ccn_charbuf_create(); ccn_charbuf_append(keyLocator, d->buf + start, stop - start); // self.keyLocator = None py_o = KeyLocator_obj_from_ccn(keyLocator); // it will free PyObject_SetAttrString(py_obj_SignedInfo, "keyLocator", py_o); Py_INCREF(py_o); } #endif /* * KeyLocator is not a BLOB, but an another structure, this requires * us to parse it differently */ start = d->decoder.token_index; if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator)) { struct ccn_charbuf *key_locator; PyObject *py_key_locator; r = ccn_buf_advance_past_element(d); if (r < 0) { PyErr_Format(g_PyExc_CCNSignedInfoError, "Error locating" " CCN_DTAG_KeyLocator (decoder state: %d, r: %d)", d->decoder.state, r); goto error; } stop = d->decoder.token_index; /* debug("element_index = %zd size = %zd nest = %d numval = %zd state = %d" " token_index %zd\n", d->decoder.element_index, d->decoder.index, d->decoder.nest, d->decoder.numval, d->decoder.state, d->decoder.token_index); assert(d->decoder.state >= 0); */ ptr = d->buf + start; size = stop - start; assert(size > 0); debug("PyObject_SetAttrString keyLocator, len=%zd\n", size); py_key_locator = CCNObject_New_charbuf(KEY_LOCATOR, &key_locator); JUMP_IF_NULL(py_key_locator, error); r = ccn_charbuf_append(key_locator, ptr, size); if (r < 0) { Py_DECREF(py_key_locator); PyErr_NoMemory(); goto error; } // self.keyLocator = None py_o = KeyLocator_obj_from_ccn(py_key_locator); Py_DECREF(py_key_locator); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_SignedInfo, "keyLocator", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } ccn_buf_check_close(d); if (d->decoder.state < 0) { PyErr_Format(g_PyExc_CCNSignedInfoError, "SignedInfo decoding error" " (decoder state: %d, numval: %zd)", d->decoder.state, d->decoder.numval); goto error; } // 4) Return the created object debug("SignedInfo_from_ccn ends\n"); return py_obj_SignedInfo; error: Py_DECREF(py_obj_SignedInfo); return NULL; }
struct ccn_forwarding_entry * ccn_forwarding_entry_parse(const unsigned char *p, size_t size) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); struct ccn_charbuf *store = ccn_charbuf_create(); struct ccn_forwarding_entry *result; const unsigned char *val; size_t sz; size_t start; size_t end; int action_off = -1; int ccnd_id_off = -1; if (store == NULL) return(NULL); result = calloc(1, sizeof(*result)); if (result == NULL) { ccn_charbuf_destroy(&store); return(NULL); } if (ccn_buf_match_dtag(d, CCN_DTAG_ForwardingEntry)) { ccn_buf_advance(d); action_off = ccn_parse_tagged_string(d, CCN_DTAG_Action, store); if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) { result->name_prefix = ccn_charbuf_create(); start = d->decoder.token_index; ccn_parse_Name(d, NULL); end = d->decoder.token_index; ccn_charbuf_append(result->name_prefix, p + start, end - start); } else result->name_prefix = NULL; if (ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &val, &sz)) { ccn_buf_advance(d); if (sz != 32) d->decoder.state = -__LINE__; } ccn_buf_check_close(d); if (d->decoder.state >= 0) { ccnd_id_off = store->length; ccn_charbuf_append(store, val, sz); result->ccnd_id_size = sz; } } result->faceid = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FaceID); result->flags = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_ForwardingFlags); result->lifetime = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds); ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state) || store->length > sizeof(result->store)) ccn_forwarding_entry_destroy(&result); else { char *b = (char *)result->store; memcpy(b, store->buf, store->length); result->action = (action_off == -1) ? NULL : b + action_off; result->ccnd_id = (ccnd_id_off == -1) ? NULL : result->store + ccnd_id_off; } ccn_charbuf_destroy(&store); return(result); }