int encode_message(struct ccn_charbuf *message, struct path * name_path, char *data, size_t len, struct ccn_charbuf *signed_info, const void *pkey, const char *digest_algorithm) { struct ccn_charbuf *path = ccn_charbuf_create(); int i; int res; if (path == NULL || ccn_name_init(path) == -1) { fprintf(stderr, "Failed to allocate or initialize content path\n"); return -1; } for (i = 0; i < name_path->count; i++) { ccn_name_append_str(path, name_path->comps[i]); } res = ccn_encode_ContentObject(message, path, signed_info, data, len, digest_algorithm, pkey); if (res != 0) { fprintf(stderr, "Failed to encode ContentObject\n"); } ccn_charbuf_destroy(&path); return(res); }
static PyObject * Exclusion_Name_Obj(unsigned char *buf, size_t start, size_t stop) { struct ccn_charbuf *name; PyObject *py_name, *res; int r; py_name = CCNObject_New_charbuf(NAME, &name); JUMP_IF_NULL(py_name, error); r = ccn_name_init(name); JUMP_IF_NEG_MEM(r, error); r = ccn_name_append_components(name, buf, start, stop); JUMP_IF_NEG_MEM(r, error); res = Name_obj_from_ccn(py_name); Py_DECREF(py_name); return res; error: Py_XDECREF(py_name); return NULL; }
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); }
struct ccndc_data * ccndc_initialize_data(void) { struct ccndc_data *self; const char *msg = "Unable to initialize ccndc"; int res; self = calloc(1, sizeof(*self)); if (self == NULL) { ON_ERROR_EXIT (-1, msg); } self->ccn_handle = ccn_create(); ON_ERROR_EXIT(ccn_connect(self->ccn_handle, NULL), "Unable to connect to local ccnd"); ON_ERROR_EXIT(ccndc_get_ccnd_id(self), "Unable to obtain ID of local ccnd"); /* Set up an Interest template to indicate scope 1 (Local) */ self->local_scope_template = ccn_charbuf_create(); res = ccnb_element_begin(self->local_scope_template, CCN_DTAG_Interest); res |= ccnb_element_begin(self->local_scope_template, CCN_DTAG_Name); res |= ccnb_element_end(self->local_scope_template); /* </Name> */ res |= ccnb_tagged_putf(self->local_scope_template, CCN_DTAG_Scope, "1"); res |= ccnb_element_end(self->local_scope_template); /* </Interest> */ ON_ERROR_EXIT(res, msg); /* Create a null name */ self->no_name = ccn_charbuf_create(); ON_ERROR_EXIT(ccn_name_init(self->no_name), msg); self->lifetime = (~0U) >> 1; return self; }
char * get_orig_router_from_info_content_name(struct ccn_charbuf * content_name) { int start,end; start=0; struct ccn_indexbuf *comps=ccn_indexbuf_create(); ccn_name_split (content_name, comps); end=check_for_name_component_in_name(content_name,comps,"nlsr"); struct ccn_charbuf *temp=ccn_charbuf_create(); ccn_name_init(temp); ccn_name_append_components( temp, content_name->buf, comps->buf[start], comps->buf[end]); struct ccn_charbuf *temp1=ccn_charbuf_create(); ccn_uri_append(temp1, temp->buf, temp->length, 0); char *orig_router=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1, sizeof(char)); memcpy(orig_router,ccn_charbuf_as_string(temp1), strlen(ccn_charbuf_as_string(temp1))); orig_router[strlen(orig_router)]='\0'; ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&temp1); ccn_indexbuf_destroy(&comps); return orig_router; }
/** * * Create new face by sending out a request Interest * The actual new face instance is returned * */ static struct ccn_face_instance *create_face(struct ccn *h, struct ccn_charbuf *local_scope_template, struct ccn_charbuf *no_name, struct ccn_face_instance *face_instance) { struct ccn_charbuf *newface = NULL; struct ccn_charbuf *signed_info = NULL; struct ccn_charbuf *temp = NULL; struct ccn_charbuf *name = NULL; struct ccn_charbuf *resultbuf = NULL; struct ccn_parsed_ContentObject pcobuf = {0}; struct ccn_face_instance *new_face_instance = NULL; const unsigned char *ptr = NULL; size_t length = 0; int res = 0; /* Encode the given face instance */ newface = ccn_charbuf_create(); ccnb_append_face_instance(newface, face_instance); temp = ccn_charbuf_create(); res = ccn_sign_content(h, temp, no_name, NULL, newface->buf, newface->length); resultbuf = ccn_charbuf_create(); /* Construct the Interest name that will create the face */ name = ccn_charbuf_create(); ccn_name_init(name); ccn_name_append_str(name, "ccnx"); ccn_name_append(name, face_instance->ccnd_id, face_instance->ccnd_id_size); ccn_name_append_str(name, face_instance->action); ccn_name_append(name, temp->buf, temp->length); /* send Interest to retrieve Data that contains the newly created face */ res = ccn_get(h, name, local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0); ON_ERROR_CLEANUP(res); /* decode Data to get the actual face instance */ res = ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length); ON_ERROR_CLEANUP(res); new_face_instance = ccn_face_instance_parse(ptr, length); ccn_charbuf_destroy(&newface); ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&resultbuf); ccn_charbuf_destroy(&name); return new_face_instance; cleanup: ccn_charbuf_destroy(&newface); ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&resultbuf); ccn_charbuf_destroy(&name); return NULL; }
static void collect_forwarding_html(struct ccnd_handle *h, struct ccn_charbuf *b) { struct hashtb_enumerator ee; struct hashtb_enumerator *e = ⅇ struct ccn_forwarding *f; int res; struct ccn_charbuf *name = ccn_charbuf_create(); ccn_charbuf_putf(b, "<h4>Forwarding</h4>" NL); ccn_charbuf_putf(b, "<ul>"); hashtb_start(h->nameprefix_tab, e); for (; e->data != NULL; hashtb_next(e)) { struct nameprefix_entry *ipe = e->data; ccn_name_init(name); res = ccn_name_append_components(name, e->key, 0, e->keysize); if (res < 0) abort(); if (0) { ccn_charbuf_putf(b, " <li>"); ccn_uri_append(b, name->buf, name->length, 1); ccn_charbuf_putf(b, "</li>" NL); } for (f = ipe->forwarding; f != NULL; f = f->next) { if ((f->flags & (CCN_FORW_ACTIVE | CCN_FORW_PFXO)) != 0) { ccn_name_init(name); ccn_name_append_components(name, e->key, 0, e->keysize); ccn_charbuf_putf(b, " <li>"); ccn_uri_append(b, name->buf, name->length, 1); ccn_charbuf_putf(b, " <b>face:</b> %u" " <b>flags:</b> 0x%x" " <b>expires:</b> %d", f->faceid, f->flags & CCN_FORW_PUBMASK, f->expires); ccn_charbuf_putf(b, "</li>" NL); } } } hashtb_end(e); ccn_charbuf_destroy(&name); ccn_charbuf_putf(b, "</ul>"); }
/* * Utility routines to allocate/deallocate ccns_slice structures */ struct ccns_slice * ccns_slice_create() { struct ccns_slice *s = calloc(1, sizeof(*s)); if (s == NULL) return(NULL); s->version = SLICE_VERSION; s->topo = ccn_charbuf_create_n(8); // name encoding requires minimum 2 s->prefix = ccn_charbuf_create_n(8); if (s->topo == NULL || s->prefix == NULL) { ccn_charbuf_destroy(&s->topo); ccn_charbuf_destroy(&s->prefix); free(s); s = NULL; } else { ccn_name_init(s->topo); ccn_name_init(s->prefix); } return(s); }
char * get_orig_router_from_lsa_name(struct ccn_charbuf * content_name) { int start=0; size_t comp_size; const unsigned char *second_last_comp; char *second_comp_type; char *sep="."; char *rem; struct ccn_indexbuf *components=ccn_indexbuf_create(); struct ccn_charbuf *name=ccn_charbuf_create(); ccn_name_from_uri(name,nlsr->slice_prefix); ccn_name_split (name, components); start=components->n-2; ccn_charbuf_destroy(&name); ccn_indexbuf_destroy(&components); struct ccn_indexbuf *comps=ccn_indexbuf_create(); ccn_name_split (content_name, comps); ccn_name_comp_get( content_name->buf, comps, comps->n-1-2, &second_last_comp, &comp_size); second_comp_type=strtok_r((char *)second_last_comp, sep, &rem); if ( strcmp( second_comp_type, "lsId" ) == 0 ){ ccn_name_chop(content_name,comps,-3); } else{ ccn_name_chop(content_name,comps,-2); } struct ccn_charbuf *temp=ccn_charbuf_create(); ccn_name_init(temp); ccn_name_append_components( temp, content_name->buf, comps->buf[start+1], comps->buf[comps->n - 1]); struct ccn_charbuf *temp1=ccn_charbuf_create(); ccn_uri_append(temp1, temp->buf, temp->length, 0); char *orig_router=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1, sizeof(char)); memcpy(orig_router,ccn_charbuf_as_string(temp1), strlen(ccn_charbuf_as_string(temp1))); orig_router[strlen(orig_router)]='\0'; ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&temp1); ccn_indexbuf_destroy(&comps); return orig_router; }
/** * Verify a signed interest * * params are as returned in upcall info structure * key is what should be used to verify * * returns: * -1 for parsing error * 0 for incorrect signature / unverified * 1 for proper verification * */ int verify_signed_interest(const unsigned char *ccnb, const struct ccn_indexbuf *comps, size_t num_comps, size_t start, size_t stop, struct ccn_pkey* key) { fprintf(stderr,"verifying signed interest...\n"); // What is info->interest_comps->n ? //fprintf(stderr, "Interest components %d\n", (int) info->interest_comps->n); unsigned char* comp; size_t size; int res; // Create a charbuf with the matched interest name incl nonce struct ccn_charbuf* name = ccn_charbuf_create(); ccn_name_init(name); res = ccn_name_append_components(name, ccnb, start, stop); // Last component, should be the signature res = ccn_name_comp_get(ccnb, comps, num_comps, (const unsigned char**)&comp, &size); if (memcmp(NS_SIGNATURE, comp, NS_SIGNATURE_LEN) != 0) { fprintf(stderr, "debug: Last component not tagged as a signature.\n"); return(-1); } // Parse our nameless, dataless content object that follows the namespace // and replace the name with the implicit name from the interest, so that // we can use the standard signature verification calls. Could be made // more efficient with different library calls. struct ccn_charbuf* co_with_name = ccn_charbuf_create(); unsigned char* co = &comp[NS_SIGNATURE_LEN]; replace_name(co_with_name, co, size-NS_SIGNATURE_LEN, name); //fprintf(stderr, "replace_name == %d (%s)\n", res, (res==0)?"ok":"fail"); // For now, use standard routines to verify signature struct ccn_parsed_ContentObject pco = {0}; fprintf(stderr,"verifying signed interest...2\n"); res = ccn_parse_ContentObject(co_with_name->buf, co_with_name->length, &pco, NULL); if (!res) { // Verify the signature against the authorized public key given to us, passed through to the handler res = ccn_verify_signature(co_with_name->buf, pco.offset[CCN_PCO_E], &pco, key ); } else { fprintf(stderr, "debug: Constructed content object parse failed (res==%d)\n", res); } fprintf(stderr,"verifying signed interest...3\n"); ccn_charbuf_destroy(&co_with_name); ccn_charbuf_destroy(&name); return (res); }
/* * initialize local data */ void init_data(struct ccn_charbuf *local_scope_template, struct ccn_charbuf *no_name) { ccn_charbuf_append_tt(local_scope_template, CCN_DTAG_Interest, CCN_DTAG); ccn_charbuf_append_tt(local_scope_template, CCN_DTAG_Name, CCN_DTAG); ccn_charbuf_append_closer(local_scope_template); /* </Name> */ ccnb_tagged_putf(local_scope_template, CCN_DTAG_Scope, "1"); ccn_charbuf_append_closer(local_scope_template); /* </Interest> */ ccn_name_init(no_name); }
void NdnMediaProcess::initPipe(struct ccn_closure *selfp, struct ccn_upcall_info *info, UserDataBuf *userBuf) { fprintf(stderr, "initializing pipe\n"); // get seq const unsigned char *ccnb = info->content_ccnb; size_t ccnb_size = info->pco->offset[CCN_PCO_E]; struct ccn_indexbuf *comps = info->content_comps; long seq; const unsigned char *seqptr = NULL; char *endptr = NULL; size_t seq_size = 0; int k = comps->n - 2; if (userBuf->seq < 0) { seq = ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb, comps->buf[k], comps->buf[k + 1], &seqptr, &seq_size); if (seq >= 0) { seq = strtol((const char *)seqptr, &endptr, 10); if (endptr != ((const char *)seqptr) + seq_size) seq = -1; } if (seq >= 0) { userBuf->seq = seq; } else { return; } } fprintf(stderr, "fetched content with seq %d\n", seq); // send hint-ahead interests for (int i = 0; i < hint_ahead; i ++) { userBuf->seq++; struct ccn_charbuf *pathbuf = ccn_charbuf_create(); ccn_name_init(pathbuf); ccn_name_append_components(pathbuf, ccnb, comps->buf[0], comps->buf[k]); struct ccn_charbuf *temp = ccn_charbuf_create(); ccn_charbuf_putf(temp, "%ld", userBuf->seq); ccn_name_append(pathbuf, temp->buf, temp->length); // no need to trylock as we already have the lock // this should use pipe callback, selfp is normal callback int res = ccn_express_interest(info->h, pathbuf, userBuf->data_buf.pipe_callback, NULL); if (res < 0) { fprintf(stderr, "Sending interest failed at normal processor\n"); std::exit(1); } ccn_charbuf_destroy(&pathbuf); ccn_charbuf_destroy(&temp); } }
/** * Find and consume interests that match given content. * * Schedules the sending of the content. * If fdholder is not NULL, pay attention only to interests from that fdholder. * It is allowed to pass NULL for pc, but if you have a (valid) one it * will avoid a re-parse. * For new content, from_face is the source; for old content, from_face is NULL. * @returns number of matches, or -1 if the new content should be dropped. */ PUBLIC int r_match_match_interests(struct ccnr_handle *h, struct content_entry *content, struct ccn_parsed_ContentObject *pc, struct fdholder *fdholder, struct fdholder *from_face) { int n_matched = 0; int new_matches; struct nameprefix_entry *npe = NULL; int ci = 0; int cm = 0; struct ccn_charbuf *name = NULL; struct ccn_indexbuf *namecomps = NULL; unsigned c0 = 0; name = ccn_charbuf_create(); ccn_name_init(name); r_store_name_append_components(name, h, content, 0, -1); namecomps = ccn_indexbuf_create(); ccn_name_split(name, namecomps); c0 = namecomps->buf[0]; for (ci = namecomps->n - 1; ci >= 0; ci--) { int size = namecomps->buf[ci] - c0; npe = hashtb_lookup(h->nameprefix_tab, name->buf + c0, size); if (npe != NULL) break; } ccn_charbuf_destroy(&name); ccn_indexbuf_destroy(&namecomps); for (; npe != NULL; npe = npe->parent, ci--) { // if (npe->fgen != h->forward_to_gen) // r_fwd_update_forward_to(h, npe); if (from_face != NULL && (npe->flags & CCN_FORW_LOCAL) != 0 && (from_face->flags & CCNR_FACE_GG) == 0) return(-1); new_matches = r_match_consume_matching_interests(h, npe, content, pc, fdholder); // if (from_face != NULL && (new_matches != 0 || ci + 1 == cm)) // note_content_from(h, npe, from_face->filedesc, ci); if (new_matches != 0) { cm = ci; /* update stats for this prefix and one shorter */ n_matched += new_matches; } } return(n_matched); }
int sign_interest(struct ccn_charbuf* name_signed, struct ccn_charbuf* name, struct ccn_charbuf* signed_info, const char* digest_algorithm, struct ccn_pkey* key) { int res = 0; // Now assemble a signed Content object // Use ccn_encode_ContentObject so we can specify the key of our choice struct ccn_charbuf *tempContentObj = ccn_charbuf_create(); res = ccn_encode_ContentObject(tempContentObj, name, signed_info, NULL /* no data */, 0, digest_algorithm, key); if (res < 0) { fprintf(stderr, "Error building content object (res == %d)\n", res); return(res); } // Call replace_name to knock out the name; // it would be more efficient to assemble this with no name a modified ccn_encode_ContentObject() call // but that requires modification to the library function struct ccn_charbuf *empty_name = ccn_charbuf_create(); struct ccn_charbuf *sigContentObj = ccn_charbuf_create(); ccn_name_init(empty_name); // First prepend the namespace; (should this be done as a "name component"?) ccn_charbuf_append(sigContentObj, NS_SIGNATURE, NS_SIGNATURE_LEN); replace_name(sigContentObj, tempContentObj->buf, tempContentObj->length, empty_name); //fprintf(stderr, "replace_name == %d (%s)\n", res, (res==0)?"ok":"fail"); /* // Check that we didn't break things struct ccn_parsed_ContentObject pco = {0}; res = ccn_parse_ContentObject(&sigContentObj->buf[NS_SIGNATURE_LEN], sigContentObj->length - NS_SIGNATURE_LEN, &pco, NULL); if (res < 0) { fprintf(stderr, "Error parsing built content object (res == %d)\n", res); return(1); } */ ccn_charbuf_destroy(&empty_name); ccn_charbuf_destroy(&tempContentObj); // Build the final name for the interest <prefix>/<namespace><contentObj> ccn_charbuf_append_charbuf(name_signed, name); // Copy the name ccn_name_append(name_signed, sigContentObj->buf, sigContentObj->length); // Concatenate the new component // Dump the signature // print_hex(stderr,&(sigContentObj->buf)[NS_SIGNATURE_LEN],sigContentObj->length - NS_SIGNATURE_LEN,12); // fprintf(stderr,"\n"); // ccn_charbuf_destroy(&sigContentObj); return (res); }
static void collect_forwarding_xml(struct ccnd_handle *h, struct ccn_charbuf *b) { struct hashtb_enumerator ee; struct hashtb_enumerator *e = ⅇ struct ccn_forwarding *f; int res; struct ccn_charbuf *name = ccn_charbuf_create(); ccn_charbuf_putf(b, "<forwarding>"); hashtb_start(h->nameprefix_tab, e); for (; e->data != NULL; hashtb_next(e)) { struct nameprefix_entry *ipe = e->data; for (f = ipe->forwarding, res = 0; f != NULL && !res; f = f->next) { if ((f->flags & (CCN_FORW_ACTIVE | CCN_FORW_PFXO)) != 0) res = 1; } if (res) { ccn_name_init(name); ccn_name_append_components(name, e->key, 0, e->keysize); ccn_charbuf_putf(b, "<fentry>"); ccn_charbuf_putf(b, "<prefix>"); ccn_uri_append(b, name->buf, name->length, 1); ccn_charbuf_putf(b, "</prefix>"); for (f = ipe->forwarding; f != NULL; f = f->next) { if ((f->flags & (CCN_FORW_ACTIVE | CCN_FORW_PFXO)) != 0) { ccn_charbuf_putf(b, "<dest>" "<faceid>%u</faceid>" "<flags>%x</flags>" "<expires>%d</expires>" "</dest>", f->faceid, f->flags & CCN_FORW_PUBMASK, f->expires); } } ccn_charbuf_putf(b, "</fentry>"); } } hashtb_end(e); ccn_charbuf_destroy(&name); ccn_charbuf_putf(b, "</forwarding>"); }
struct ccn_charbuf* CcnH_signForwardingEntry(struct ccn* ccnh, CCNDID ccndid, struct ccn_forwarding_entry* fe) { struct ccn_charbuf* request = ccn_charbuf_create(); ccnb_append_forwarding_entry(request, fe); struct ccn_charbuf* emptyname = ccn_charbuf_create(); ccn_name_init(emptyname); struct ccn_charbuf* signed_request = ccn_charbuf_create(); ccn_sign_content(ccnh, signed_request, emptyname, NULL, request->buf, request->length); struct ccn_charbuf* reqname = ccn_charbuf_create(); ccn_name_from_uri(reqname, "ccnx:/ccnx"); ccn_name_append(reqname, ccndid, CCNDID_length); ccn_name_append_str(reqname, fe->action); ccn_name_append(reqname, signed_request->buf, signed_request->length); ccn_charbuf_destroy(&request); ccn_charbuf_destroy(&emptyname); ccn_charbuf_destroy(&signed_request); return reqname; }
PUBLIC struct content_entry * r_store_next_child_at_level(struct ccnr_handle *h, struct content_entry *content, int level) { struct content_entry *next = NULL; struct ccn_charbuf *name; struct ccn_charbuf *flatname = NULL; int res; if (content == NULL) return(NULL); name = ccn_charbuf_create(); ccn_name_init(name); res = ccn_name_append_flatname(name, content->flatname->buf, content->flatname->length, 0, level + 1); if (res < level) goto Bail; if (res == level) res = ccn_name_append(name, NULL, 0); else if (res == level + 1) res = ccn_name_next_sibling(name); // XXX - would be nice to have a flatname version of this if (res < 0) goto Bail; if (CCNSHOULDLOG(h, LM_8, CCNL_FINER)) ccnr_debug_ccnb(h, __LINE__, "child_successor", NULL, name->buf, name->length); flatname = ccn_charbuf_create(); ccn_flatname_from_ccnb(flatname, name->buf, name->length); next = r_store_look(h, flatname->buf, flatname->length); if (next == content) { // XXX - I think this case should not occur, but just in case, avoid a loop. ccnr_debug_content(h, __LINE__, "urp", NULL, next); next = NULL; } Bail: ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&flatname); return(next); }
/** * Like ccn_uri_append(), but accepts a flatname instead of ccnb */ int ccn_uri_append_flatname(struct ccn_charbuf *uri, const unsigned char *flatname, size_t size, int includescheme) { struct ccn_charbuf *ccnb = NULL; int res; ccnb = ccn_charbuf_create(); if (ccnb == NULL) return(-1); res = ccn_name_init(ccnb); if (res < 0) goto Bail; res = ccn_name_append_flatname(ccnb, flatname, size, 0, -1); if (res < 0) goto Bail; res = ccn_uri_append(uri, ccnb->buf, ccnb->length, includescheme); Bail: ccn_charbuf_destroy(&ccnb); return(res); }
void get_name_part(struct name_prefix *name_part,struct ccn_charbuf * interest_ccnb, struct ccn_indexbuf *interest_comps, int offset) { int lsa_position=0; struct ccn_indexbuf *components=ccn_indexbuf_create(); struct ccn_charbuf *name=ccn_charbuf_create(); ccn_name_from_uri(name,nlsr->slice_prefix); ccn_name_split (name, components); lsa_position=components->n-2; ccn_charbuf_destroy(&name); struct ccn_charbuf *temp=ccn_charbuf_create(); ccn_name_init(temp); ccn_name_append_components( temp, interest_ccnb->buf, interest_comps->buf[lsa_position+1], interest_comps->buf[interest_comps->n - 1]); struct ccn_charbuf *temp1=ccn_charbuf_create(); ccn_uri_append(temp1, temp->buf, temp->length, 0); name_part->name=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1, sizeof(char)); memcpy(name_part->name,ccn_charbuf_as_string(temp1), strlen(ccn_charbuf_as_string(temp1))); name_part->name[strlen(ccn_charbuf_as_string(temp1))]='\0'; name_part->length=strlen(ccn_charbuf_as_string(temp1))+1; ccn_charbuf_destroy(&temp1); ccn_charbuf_destroy(&temp); ccn_indexbuf_destroy(&components); if ( nlsr->debugging ) printf("Name Part: %s \n",name_part->name); }
int main(int argc, char **argv) { struct ccn_keystore *keystore = NULL; int res = 0; struct ccn_charbuf *signed_info = ccn_charbuf_create(); int i; int sec, usec; char msgbuf[PAYLOAD_SIZE]; struct timeval start, end; struct ccn_charbuf *message = ccn_charbuf_create(); struct ccn_charbuf *path = ccn_charbuf_create(); struct ccn_charbuf *seq = ccn_charbuf_create(); struct ccn_charbuf *temp = ccn_charbuf_create(); keystore = ccn_keystore_create(); ccn_charbuf_putf(temp, "%s/.ccnx/.ccnx_keystore", getenv("HOME")); res = ccn_keystore_init(keystore, ccn_charbuf_as_string(temp), "Th1s1sn0t8g00dp8ssw0rd."); if (res != 0) { printf("Failed to initialize keystore %s\n", ccn_charbuf_as_string(temp)); exit(1); } ccn_charbuf_destroy(&temp); 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_DATA, /* freshness */ FRESHNESS, /*finalblockid*/ NULL, /* keylocator */ NULL); srandom(time(NULL)); for (i=0; i<PAYLOAD_SIZE; i++) { msgbuf[i] = random(); } printf("Generating %d signed ContentObjects (one . per 100)\n", COUNT); gettimeofday(&start, NULL); for (i=0; i<COUNT; i++) { if (i>0 && (i%100) == 0) { printf("."); fflush(stdout); } ccn_name_init(path); ccn_name_append_str(path, "rtp"); ccn_name_append_str(path, "protocol"); ccn_name_append_str(path, "13.2.117.34"); ccn_name_append_str(path, "domain"); ccn_name_append_str(path, "smetters"); ccn_name_append_str(path, "principal"); ccn_name_append_str(path, "2021915340"); ccn_name_append_str(path, "id"); ccn_charbuf_putf(seq, "%u", i); ccn_name_append(path, seq->buf, seq->length); ccn_name_append_str(path, "seq"); res = ccn_encode_ContentObject(/* out */ message, path, signed_info, msgbuf, PAYLOAD_SIZE, /* digest_algorithm */ NULL, ccn_keystore_private_key(keystore)); ccn_charbuf_reset(message); ccn_charbuf_reset(path); ccn_charbuf_reset(seq); } gettimeofday(&end, NULL); sec = end.tv_sec - start.tv_sec; usec = (int)end.tv_usec - (int)start.tv_usec; while (usec < 0) { sec--; usec += 1000000; } printf("\nComplete in %d.%06d secs\n", sec, usec); return(0); }
// creates a full structure without action, if proto == "face" only the // faceid (from cmd_host parameter) and lifetime will be filled in. struct ccn_face_instance * parse_ccn_face_instance(struct ccndc_data *self, const char *cmd_proto, const char *cmd_host, const char *cmd_port, const char *cmd_mcastttl, const char *cmd_mcastif, int freshness) { struct ccn_face_instance *entry; struct addrinfo hints = {.ai_family = AF_UNSPEC, .ai_flags = (AI_ADDRCONFIG)}; struct addrinfo mcasthints = {.ai_family = AF_UNSPEC, .ai_flags = (AI_ADDRCONFIG | AI_NUMERICHOST)}; struct addrinfo *raddrinfo = NULL; struct addrinfo *mcastifaddrinfo = NULL; char rhostnamebuf [NI_MAXHOST]; char rhostportbuf [NI_MAXSERV]; int off_address = -1, off_port = -1, off_source_address = -1; int res; int socktype; entry = calloc(1, sizeof(*entry)); if (entry == NULL) { ccndc_warn(__LINE__, "Fatal error: memory allocation failed"); goto ExitOnError; } // allocate storage for Face data entry->store = ccn_charbuf_create(); if (entry->store == NULL) { ccndc_warn(__LINE__, "Fatal error: memory allocation failed"); goto ExitOnError; } // copy static info entry->ccnd_id = (const unsigned char *)self->ccnd_id; entry->ccnd_id_size = self->ccnd_id_size; if (cmd_proto == NULL) { ccndc_warn(__LINE__, "command error, missing address type\n"); goto ExitOnError; } if (strcasecmp(cmd_proto, "udp") == 0) { entry->descr.ipproto = IPPROTO_UDP; socktype = SOCK_DGRAM; } else if (strcasecmp(cmd_proto, "tcp") == 0) { entry->descr.ipproto = IPPROTO_TCP; socktype = SOCK_STREAM; } else if (strcasecmp(cmd_proto, "face") == 0) { errno = 0; unsigned long faceid = strtoul(cmd_host, (char **)NULL, 10); if (errno == ERANGE || errno == EINVAL || faceid > UINT_MAX || faceid == 0) { ccndc_warn(__LINE__, "command error, face number invalid or out of range '%s'\n", cmd_host); goto ExitOnError; } entry->faceid = (unsigned) faceid; entry->lifetime = freshness; return (entry); } else { ccndc_warn(__LINE__, "command error, unrecognized address type '%s'\n", cmd_proto); goto ExitOnError; } if (cmd_host == NULL) { ccndc_warn(__LINE__, "command error, missing hostname\n"); goto ExitOnError; } if (cmd_port == NULL || cmd_port[0] == 0) cmd_port = CCN_DEFAULT_UNICAST_PORT; hints.ai_socktype = socktype; res = getaddrinfo(cmd_host, cmd_port, &hints, &raddrinfo); if (res != 0 || raddrinfo == NULL) { ccndc_warn(__LINE__, "command error, getaddrinfo for host [%s] port [%s]: %s\n", cmd_host, cmd_port, gai_strerror(res)); goto ExitOnError; } res = getnameinfo(raddrinfo->ai_addr, raddrinfo->ai_addrlen, rhostnamebuf, sizeof(rhostnamebuf), rhostportbuf, sizeof(rhostportbuf), NI_NUMERICHOST | NI_NUMERICSERV); freeaddrinfo(raddrinfo); if (res != 0) { ccndc_warn(__LINE__, "command error, getnameinfo: %s\n", gai_strerror(res)); goto ExitOnError; } off_address = entry->store->length; res = ccn_charbuf_append(entry->store, rhostnamebuf, strlen(rhostnamebuf)+1); if (res != 0) { ccndc_warn(__LINE__, "Cannot append to charbuf"); goto ExitOnError; } off_port = entry->store->length; res = ccn_charbuf_append(entry->store, rhostportbuf, strlen(rhostportbuf)+1); if (res != 0) { ccndc_warn(__LINE__, "Cannot append to charbuf"); goto ExitOnError; } entry->descr.mcast_ttl = -1; if (cmd_mcastttl != NULL) { char *endptr; entry->descr.mcast_ttl = strtol(cmd_mcastttl, &endptr, 10); if ((endptr != &cmd_mcastttl[strlen(cmd_mcastttl)]) || entry->descr.mcast_ttl < 0 || entry->descr.mcast_ttl > 255) { ccndc_warn(__LINE__, "command error, invalid multicast ttl: %s\n", cmd_mcastttl); goto ExitOnError; } } if (cmd_mcastif != NULL) { res = getaddrinfo(cmd_mcastif, NULL, &mcasthints, &mcastifaddrinfo); if (res != 0) { ccndc_warn(__LINE__, "command error, incorrect multicat interface [%s]: " "mcastifaddr getaddrinfo: %s\n", cmd_mcastif, gai_strerror(res)); goto ExitOnError; } res = getnameinfo(mcastifaddrinfo->ai_addr, mcastifaddrinfo->ai_addrlen, rhostnamebuf, sizeof(rhostnamebuf), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); freeaddrinfo(mcastifaddrinfo); if (res != 0) { ccndc_warn(__LINE__, "command error, getnameinfo: %s\n", gai_strerror(res)); goto ExitOnError; } off_source_address = entry->store->length; res = ccn_charbuf_append(entry->store, rhostnamebuf, strlen(rhostnamebuf)+1); if (res != 0) { ccndc_warn(__LINE__, "Cannot append to charbuf"); goto ExitOnError; } } entry->descr.address = (const char *)(entry->store->buf + off_address); entry->descr.port = (const char *)(entry->store->buf + off_port); if (off_source_address >= 0) { entry->descr.source_address = (const char *)(entry->store->buf + off_source_address); } entry->lifetime = freshness; return entry; ExitOnError: ccn_face_instance_destroy(&entry); return (NULL); } struct ccn_face_instance * parse_ccn_face_instance_from_face(struct ccndc_data *self, const char *cmd_faceid) { struct ccn_face_instance *entry = calloc(1, sizeof(*entry)); // allocate storage for Face data entry->store = ccn_charbuf_create(); // copy static info entry->ccnd_id = (const unsigned char *)self->ccnd_id; entry->ccnd_id_size = self->ccnd_id_size; /* destroy a face - the URI field will hold the face number */ if (cmd_faceid == NULL) { ccndc_warn(__LINE__, "command error, missing face number for destroyface\n"); goto ExitOnError; } char *endptr; int facenumber = strtol(cmd_faceid, &endptr, 10); if ((endptr != &cmd_faceid[strlen(cmd_faceid)]) || facenumber < 0) { ccndc_warn(__LINE__, "command error invalid face number for destroyface: %d\n", facenumber); goto ExitOnError; } entry->faceid = facenumber; return entry; ExitOnError: ccn_face_instance_destroy(&entry); return (NULL); } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // "private section /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// int ccndc_get_ccnd_id(struct ccndc_data *self) { struct ccn_charbuf *name = NULL; struct ccn_charbuf *resultbuf = NULL; struct ccn_parsed_ContentObject pcobuf = {0}; char ccndid_uri[] = "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY"; const unsigned char *ccndid_result; int res = 0; name = ccn_charbuf_create(); if (name == NULL) { ccndc_warn(__LINE__, "Unable to allocate storage for service locator name charbuf\n"); return -1; } resultbuf = ccn_charbuf_create(); if (resultbuf == NULL) { ccndc_warn(__LINE__, "Unable to allocate storage for result charbuf"); res = -1; goto Cleanup; } res = ccn_name_from_uri(name, ccndid_uri); if (res < 0) { ccndc_warn(__LINE__, "Unable to parse service locator URI for ccnd key"); goto Cleanup; } res = ccn_get(self->ccn_handle, name, self->local_scope_template, 4500, resultbuf, &pcobuf, NULL, 0); if (res < 0) { ccndc_warn(__LINE__, "Unable to get key from ccnd"); goto Cleanup; } res = ccn_ref_tagged_BLOB (CCN_DTAG_PublisherPublicKeyDigest, resultbuf->buf, pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest], pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest], &ccndid_result, &self->ccnd_id_size); if (res < 0) { ccndc_warn(__LINE__, "Unable to parse ccnd response for ccnd id"); goto Cleanup; } if (self->ccnd_id_size > sizeof (self->ccnd_id)) { ccndc_warn(__LINE__, "Incorrect size for ccnd id in response"); goto Cleanup; } memcpy(self->ccnd_id, ccndid_result, self->ccnd_id_size); Cleanup: ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&resultbuf); return (res); } struct ccn_face_instance * ccndc_do_face_action(struct ccndc_data *self, const char *action, struct ccn_face_instance *face_instance) { struct ccn_charbuf *newface = NULL; struct ccn_charbuf *signed_info = NULL; struct ccn_charbuf *temp = NULL; struct ccn_charbuf *name = NULL; struct ccn_charbuf *resultbuf = NULL; struct ccn_parsed_ContentObject pcobuf = {0}; struct ccn_face_instance *new_face_instance = NULL; const unsigned char *ptr = NULL; size_t length = 0; int res = 0; face_instance->action = action; /* Encode the given face instance */ newface = ccn_charbuf_create(); ON_NULL_CLEANUP(newface); ON_ERROR_CLEANUP(ccnb_append_face_instance(newface, face_instance)); temp = ccn_charbuf_create(); ON_NULL_CLEANUP(temp); res = ccn_sign_content(self->ccn_handle, temp, self->no_name, NULL, newface->buf, newface->length); ON_ERROR_CLEANUP(res); resultbuf = ccn_charbuf_create(); ON_NULL_CLEANUP(resultbuf); /* Construct the Interest name that will create the face */ name = ccn_charbuf_create(); ON_NULL_CLEANUP(name); ON_ERROR_CLEANUP(ccn_name_init(name)); ON_ERROR_CLEANUP(ccn_name_append_str(name, "ccnx")); ON_ERROR_CLEANUP(ccn_name_append(name, face_instance->ccnd_id, face_instance->ccnd_id_size)); ON_ERROR_CLEANUP(ccn_name_append_str(name, face_instance->action)); ON_ERROR_CLEANUP(ccn_name_append(name, temp->buf, temp->length)); res = ccn_get(self->ccn_handle, name, self->local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0); ON_ERROR_CLEANUP(res); ON_ERROR_CLEANUP(ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length)); new_face_instance = ccn_face_instance_parse(ptr, length); ON_NULL_CLEANUP(new_face_instance); ccn_charbuf_destroy(&newface); ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&resultbuf); ccn_charbuf_destroy(&name); return (new_face_instance); Cleanup: ccn_charbuf_destroy(&newface); ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&resultbuf); ccn_charbuf_destroy(&name); ccn_face_instance_destroy(&new_face_instance); return (NULL); } int ccndc_do_prefix_action(struct ccndc_data *self, const char *action, struct ccn_forwarding_entry *forwarding_entry) { struct ccn_charbuf *temp = NULL; struct ccn_charbuf *resultbuf = NULL; struct ccn_charbuf *signed_info = NULL; struct ccn_charbuf *name = NULL; struct ccn_charbuf *prefixreg = NULL; struct ccn_parsed_ContentObject pcobuf = {0}; struct ccn_forwarding_entry *new_forwarding_entry = NULL; const unsigned char *ptr = NULL; size_t length = 0; int res; forwarding_entry->action = action; prefixreg = ccn_charbuf_create(); ON_NULL_CLEANUP(prefixreg); ON_ERROR_CLEANUP(ccnb_append_forwarding_entry(prefixreg, forwarding_entry)); temp = ccn_charbuf_create(); ON_NULL_CLEANUP(temp); res = ccn_sign_content(self->ccn_handle, temp, self->no_name, NULL, prefixreg->buf, prefixreg->length); ON_ERROR_CLEANUP(res); resultbuf = ccn_charbuf_create(); ON_NULL_CLEANUP(resultbuf); name = ccn_charbuf_create(); ON_ERROR_CLEANUP(ccn_name_init(name)); ON_ERROR_CLEANUP(ccn_name_append_str(name, "ccnx")); ON_ERROR_CLEANUP(ccn_name_append(name, forwarding_entry->ccnd_id, forwarding_entry->ccnd_id_size)); ON_ERROR_CLEANUP(ccn_name_append_str(name, forwarding_entry->action)); ON_ERROR_CLEANUP(ccn_name_append(name, temp->buf, temp->length)); res = ccn_get(self->ccn_handle, name, self->local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0); ON_ERROR_CLEANUP(res); ON_ERROR_CLEANUP(ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length)); new_forwarding_entry = ccn_forwarding_entry_parse(ptr, length); ON_NULL_CLEANUP(new_forwarding_entry); res = new_forwarding_entry->faceid; ccn_forwarding_entry_destroy(&new_forwarding_entry); ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&resultbuf); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&prefixreg); return (res); /* This is where ON_ERROR_CLEANUP sends us in case of an error * and we must free any storage we allocated before returning. */ Cleanup: ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&resultbuf); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&prefixreg); return (-1); }
void GroupManager::expressEnumInterest(struct ccn_charbuf *interest, QList<QString> &toExclude) { if (toExclude.size() == 0) { mutex_trylock(); int res = ccn_express_interest(ccn, interest, join_closure, NULL); mutex_unlock(); if (res < 0) { critical("express interest failed!"); } ccn_charbuf_destroy(&interest); return; } struct ccn_charbuf **excl = NULL; if (toExclude.size() > 0) { excl = new ccn_charbuf *[toExclude.size()]; for (int i = 0; i < toExclude.size(); i ++) { QString compName = toExclude.at(i); struct ccn_charbuf *comp = ccn_charbuf_create(); ccn_name_init(comp); ccn_name_append_str(comp, compName.toStdString().c_str()); excl[i] = comp; comp = NULL; } qsort(excl, toExclude.size(), sizeof(excl[0]), &namecompare); } int begin = 0; bool excludeLow = false; bool excludeHigh = true; while (begin < toExclude.size()) { if (begin != 0) { excludeLow = true; } struct ccn_charbuf *templ = ccn_charbuf_create(); ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG); // <Interest> ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG); // <Name> ccn_charbuf_append_closer(templ); // </Name> ccn_charbuf_append_tt(templ, CCN_DTAG_Exclude, CCN_DTAG); // <Exclude> if (excludeLow) { append_bf_all(templ); } for (; begin < toExclude.size(); begin++) { struct ccn_charbuf *comp = excl[begin]; if (comp->length < 4) abort(); // we are being conservative here if (interest->length + templ->length + comp->length > 1350) { break; } ccn_charbuf_append(templ, comp->buf + 1, comp->length - 2); } if (begin == toExclude.size()) { excludeHigh = false; } if (excludeHigh) { append_bf_all(templ); } ccn_charbuf_append_closer(templ); // </Exclude> ccn_charbuf_append_closer(templ); // </Interest> mutex_trylock(); int res = ccn_express_interest(ccn, interest, join_closure, templ); mutex_unlock(); if (res < 0) { critical("express interest failed!"); } ccn_charbuf_destroy(&templ); } ccn_charbuf_destroy(&interest); for (int i = 0; i < toExclude.size(); i++) { ccn_charbuf_destroy(&excl[i]); } if (excl != NULL) { delete []excl; } }
/** * * Bind a prefix to a face * */ static int register_unregister_prefix(struct ccn *h, struct ccn_charbuf *local_scope_template, struct ccn_charbuf *no_name, struct ccn_charbuf *name_prefix, struct ccn_face_instance *face_instance, int operation) { struct ccn_charbuf *temp = NULL; struct ccn_charbuf *resultbuf = NULL; struct ccn_charbuf *signed_info = NULL; struct ccn_charbuf *name = NULL; struct ccn_charbuf *prefixreg = NULL; struct ccn_parsed_ContentObject pcobuf = {0}; struct ccn_forwarding_entry forwarding_entry_storage = {0}; struct ccn_forwarding_entry *forwarding_entry = &forwarding_entry_storage; struct ccn_forwarding_entry *new_forwarding_entry; const unsigned char *ptr = NULL; size_t length = 0; int res; /* Register or unregister the prefix */ forwarding_entry->action = (operation == OP_REG) ? "prefixreg" : "unreg"; forwarding_entry->name_prefix = name_prefix; forwarding_entry->ccnd_id = face_instance->ccnd_id; forwarding_entry->ccnd_id_size = face_instance->ccnd_id_size; forwarding_entry->faceid = face_instance->faceid; forwarding_entry->flags = -1; forwarding_entry->lifetime = 2100; prefixreg = ccn_charbuf_create(); ccnb_append_forwarding_entry(prefixreg, forwarding_entry); temp = ccn_charbuf_create(); res = ccn_sign_content(h, temp, no_name, NULL, prefixreg->buf, prefixreg->length); resultbuf = ccn_charbuf_create(); /* construct Interest containing prefixreg request */ name = ccn_charbuf_create(); ccn_name_init(name); ccn_name_append_str(name, "ccnx"); ccn_name_append(name, face_instance->ccnd_id, face_instance->ccnd_id_size); ccn_name_append_str(name, (operation == OP_REG) ? "prefixreg" : "unreg"); ccn_name_append(name, temp->buf, temp->length); /* send Interest, get Data */ res = ccn_get(h, name, local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0); ON_ERROR_CLEANUP(res); res = ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length); ON_ERROR_CLEANUP(res); /* extract new forwarding entry from Data */ new_forwarding_entry = ccn_forwarding_entry_parse(ptr, length); ON_NULL_CLEANUP(new_forwarding_entry); res = new_forwarding_entry->faceid; ccn_forwarding_entry_destroy(&new_forwarding_entry); ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&resultbuf); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&prefixreg); return res; cleanup: ccn_forwarding_entry_destroy(&new_forwarding_entry); ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&resultbuf); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&prefixreg); return -1; }
enum ccn_upcall_res incoming_content( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { struct ccn_charbuf *name = NULL; struct ccn_charbuf *templ = NULL; struct ccn_charbuf *temp = NULL; const unsigned char *ccnb = NULL; size_t ccnb_size = 0; const unsigned char *data = NULL; size_t data_size = 0; size_t written; const unsigned char *ib = NULL; /* info->interest_ccnb */ struct ccn_indexbuf *ic = NULL; int res; struct mydata *md = selfp->data; if (kind == CCN_UPCALL_FINAL) { if (md != NULL) { selfp->data = NULL; free(md); md = NULL; } return(CCN_UPCALL_RESULT_OK); } if (kind == CCN_UPCALL_INTEREST_TIMED_OUT) return(CCN_UPCALL_RESULT_REEXPRESS); if (kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED) return(CCN_UPCALL_RESULT_ERR); if (md == NULL) selfp->data = md = calloc(1, sizeof(*md)); ccnb = info->content_ccnb; ccnb_size = info->pco->offset[CCN_PCO_E]; ib = info->interest_ccnb; ic = info->interest_comps; /* XXX - must verify sig, and make sure it is LEAF content */ res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &data, &data_size); if (res < 0) abort(); if (data_size > CHUNK_SIZE) { /* For us this is spam. Give up now. */ fprintf(stderr, "*** Segment %d found with a data size of %d." " This program only works with segments of 1024 bytes." " Try ccncatchunks2 instead.\n", (int)selfp->intdata, (int)data_size); exit(1); } /* OK, we will accept this block. */ written = fwrite(data, data_size, 1, stdout); if (written != 1) exit(1); /* A short block signals EOF for us. */ if (data_size < CHUNK_SIZE) exit(0); /* Ask for the next one */ name = ccn_charbuf_create(); ccn_name_init(name); if (ic->n < 2) abort(); res = ccn_name_append_components(name, ib, ic->buf[0], ic->buf[ic->n - 2]); if (res < 0) abort(); temp = ccn_charbuf_create(); ccn_charbuf_putf(temp, "%d", ++(selfp->intdata)); ccn_name_append(name, temp->buf, temp->length); ccn_charbuf_destroy(&temp); templ = make_template(md, info); res = ccn_express_interest(info->h, name, selfp, templ); if (res < 0) abort(); ccn_charbuf_destroy(&templ); ccn_charbuf_destroy(&name); return(CCN_UPCALL_RESULT_OK); }
/* * This upcall gets called for each piece of incoming content that * matches one of our interests. We need to issue a new interest that * excludes another component at the current level, and perhaps also * and interest to start exploring the next level. Thus if the matched * interest is * /a/b/c exclude {d,e,f,i,j,k} * and we get * /a/b/c/g/h * we would issue a new interest * /a/b/c exclude {d,e,f,g,i,j,k} * to continue exploring the current level, plus a simple interest * /a/b/c/g * to start exploring the next level as well. * * This does end up fetching each piece of content multiple times, once for * each level in the name. The repeated requests will be answered from the local * content store, though, and so should not generate extra network traffic. * There is a lot of unanswerable interest generated, though. * * To prevent the interests from becoming too huge, we may need to split them. * Thus if the first new interest above were deemed too large, we could instead * issue the two interests * /a/b/c exclude {d,e,f,g,*} * /a/b/c exclude {*,g,i,j,k} * where * stands for a Bloom filter that excludes anything. Note the * repetition of g to ensure that these two interests cover disjoint portions * of the hierarchy. We need to keep track of the endpoint conditions * as well as the excluded set in our upcall data. * When a split happens, we need a new closure to track it, as we do when * we start exploring a new level. */ static enum ccn_upcall_res incoming_content( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { struct ccn_charbuf *c = NULL; struct ccn_charbuf *comp = NULL; struct ccn_charbuf *uri = NULL; const unsigned char *ccnb = NULL; size_t ccnb_size = 0; struct ccn_indexbuf *comps = NULL; int matched_comps = 0; int res; int i; struct ccn_traversal *data = get_my_data(selfp); if (kind == CCN_UPCALL_FINAL) { for (i = 0; i < data->n_excl; i++) ccn_charbuf_destroy(&(data->excl[i])); if (data->excl != NULL) free(data->excl); free(data); free(selfp); return(0); } if (kind == CCN_UPCALL_INTEREST_TIMED_OUT) return(0); if (kind == CCN_UPCALL_CONTENT_BAD) return(0); if (kind == CCN_UPCALL_CONTENT_UNVERIFIED) { if ((data->flags & MUST_VERIFY) != 0) return(CCN_UPCALL_RESULT_VERIFY); } if (kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED) abort(); ccnb = info->content_ccnb; ccnb_size = info->pco->offset[CCN_PCO_E]; comps = info->content_comps; matched_comps = info->pi->prefix_comps; c = ccn_charbuf_create(); uri = ccn_charbuf_create(); if (matched_comps + 1 > comps->n) { ccn_uri_append(c, ccnb, ccnb_size, 1); fprintf(stderr, "How did this happen? %s\n", ccn_charbuf_as_string(uri)); exit(1); } data->counter[0]++; /* Tell main that something new came in */ /* Recover the same prefix as before */ ccn_name_init(c); ccn_name_append_components(c, ccnb, comps->buf[0], comps->buf[matched_comps]); comp = ccn_charbuf_create(); ccn_name_init(comp); if (matched_comps + 1 == comps->n) { /* Reconstruct the implicit content digest component */ ccn_digest_ContentObject(ccnb, info->pco); ccn_name_append(comp, info->pco->digest, info->pco->digest_bytes); } else { ccn_name_append_components(comp, ccnb, comps->buf[matched_comps], comps->buf[matched_comps + 1]); } data->excl = realloc(data->excl, (data->n_excl + 1) * sizeof(data->excl[0])); data->excl[data->n_excl++] = comp; comp = NULL; qsort(data->excl, data->n_excl, sizeof(data->excl[0]), &namecompare); res = express_my_interest(info->h, selfp, c); if (res == -1) { struct ccn_closure *high = split_my_excludes(selfp); if (high == NULL) abort(); express_my_interest(info->h, selfp, c); express_my_interest(info->h, high, c); } /* Explore the next level, if there is one. */ if (matched_comps + 2 < comps->n) { struct ccn_traversal *newdat = NULL; struct ccn_closure *cl; newdat = calloc(1, sizeof(*newdat)); newdat->magic = 68955871; newdat->warn = 1492; newdat->counter = data->counter; newdat->flags = data->flags & ~(EXCLUDE_LOW | EXCLUDE_HIGH); newdat->n_excl = 0; newdat->excl = NULL; cl = calloc(1, sizeof(*cl)); cl->p = &incoming_content; cl->data = newdat; ccn_name_init(c); ccn_name_append_components(c, ccnb, comps->buf[0], comps->buf[matched_comps + 1]); express_my_interest(info->h, cl, c); } else { res = ccn_uri_append(uri, info->content_ccnb, info->pco->offset[CCN_PCO_E], 1); if (res < 0) fprintf(stderr, "*** Error: ccn_traverse line %d res=%d\n", __LINE__, res); else printf("%s\n", ccn_charbuf_as_string(uri)); } ccn_charbuf_destroy(&c); ccn_charbuf_destroy(&uri); return(0); }
/** * Call-back from the CCN network that something has arrived * * We get notified that a client has interests in things we are producing. * This function will do some basic checking to see what exactly the client has * an interest in, and will produce what is appropriate. * Currently the things we produce are: * \li last block - we resend the last block we have published for a given name * \li last segment - we produce a data message that only contains the latest segment number we used * * \param selfp -> a context structure we created when registering this call-back * \param kind specifies the type of call-back being processed, see the \b switch statement * \param info context information about the call-back itself; interests, data, etc. * \return a response as to how successful we were in processing the call-back * \retval CCN_UPCALL_RESULT_OK things went well * \retval CCN_UPCALL_RESULT_VERIFY need to verify the contents of what we received * \retval CCN_UPCALL_RESULT_REEXPRESS an interest timedout waiting for data, so we try again * \retval CCN_UPCALL_RESULT_ERR some error was encountered */ static enum ccn_upcall_res new_interests (struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { Gstccnxsink *me = GST_CCNXSINK (selfp->data); struct ccn_charbuf *cb; struct ccn_charbuf *sname = NULL; const unsigned char *cp1, *cp2; size_t sz1; size_t sz2; long lastSeq; struct ccn_signing_params myparams; unsigned int i; int rc; GST_DEBUG ("something has arrived!"); GST_DEBUG ("matched is: %d", info->matched_comps); // number of filter components that were matched by the interest cb = interestAsUri (info); GST_DEBUG ("as URI: %s", ccn_charbuf_as_string (cb)); ccn_charbuf_destroy (&cb); myparams = me->sp; /* Some debugging stuff */ for (i = 0; i < 10; ++i) { const unsigned char *cp; size_t sz; GST_DEBUG ("%3d: ", i); if (0 > ccn_name_comp_get (info->interest_ccnb, info->interest_comps, i, &cp, &sz)) { // fprintf(stderr, "could not get comp\n"); break; } else { // hDump( DUMP_ADDR( cp ), DUMP_SIZE( sz ) ); } } switch (kind) { case CCN_UPCALL_FINAL: GST_LOG_OBJECT (me, "CCN upcall final %p", selfp); return (0); case CCN_UPCALL_INTEREST_TIMED_OUT: if (selfp != me->ccn_closure) { GST_LOG_OBJECT (me, "CCN Interest timed out on dead closure %p", selfp); return (0); } GST_LOG_OBJECT (me, "CCN upcall reexpress -- timed out"); if (me->timeouts > 5) { GST_LOG_OBJECT (me, "CCN upcall reexpress -- too many reexpressions"); return (0); } me->timeouts++; return (CCN_UPCALL_RESULT_REEXPRESS); case CCN_UPCALL_CONTENT_UNVERIFIED: if (selfp != me->ccn_closure) { GST_LOG_OBJECT (me, "CCN unverified content on dead closure %p", selfp); return (0); } return (CCN_UPCALL_RESULT_VERIFY); case CCN_UPCALL_CONTENT: if (selfp != me->ccn_closure) { GST_LOG_OBJECT (me, "CCN content on dead closure %p", selfp); return (0); } break; case CCN_UPCALL_CONTENT_BAD: GST_LOG_OBJECT (me, "Content signature verification failed! Discarding.\n"); return (CCN_UPCALL_RESULT_ERR); case CCN_UPCALL_CONSUMED_INTEREST: GST_LOG_OBJECT (me, "Upcall consumed interest\n"); return (CCN_UPCALL_RESULT_ERR); /* no data */ /* Here is the most interesting case...when an interest arrives */ case CCN_UPCALL_INTEREST: GST_INFO ("We got an interest\n"); myparams.freshness = 1; /* meta data is old very quickly */ /* See if any meta information is sought */ for (i = 0;; ++i) { if (0 > ccn_name_comp_get (info->interest_ccnb, info->interest_comps, i, &cp1, &sz1)) { cp1 = NULL; break; } else { if (!strncmp ((const char *) cp1, "_meta_", 6)) { // OK, found meta, now which one is needed? if (0 > ccn_name_comp_get (info->interest_ccnb, info->interest_comps, i + 1, &cp2, &sz2)) { GST_LOG_OBJECT (me, "CCN interest received with invalid meta request"); cp1 = NULL; } break; } // Component not meta, keep looking } } // At this point, i is left pointing at '_meta_' or at the end of component list if (cp1) { // hDump( DUMP_ADDR(cp1), DUMP_SIZE(sz1) ); // hDump( DUMP_ADDR(cp2), DUMP_SIZE(sz2) ); if (strncmp ((const char *) cp2, ".segment", 8)) goto Exit_Interest; /* not a match */ /* publish what segment we are up to in reply to the meta request */ lastSeq = me->segment - 1; GST_INFO ("sending meta data....segment: %d", lastSeq); sname = ccn_charbuf_create (); ccn_name_init (sname); rc = ccn_name_append_components (sname, info->interest_ccnb, info->interest_comps->buf[0], info->interest_comps->buf[i + 2]); if (rc < 0) goto Error_Interest; // rc = ccn_create_version(me->ccn, sname, CCN_V_REPLACE | CCN_V_NOW | CCN_V_HIGH, 0, 0); // if (rc < 0) goto Error_Interest; me->temp->length = 0; rc = ccn_sign_content (me->ccn, me->temp, sname, &myparams, &lastSeq, sizeof (lastSeq)); // hDump(DUMP_ADDR(sname->buf), DUMP_SIZE(sname->length)); if (rc != 0) { GST_LOG_OBJECT (me, "Failed to encode ContentObject (rc == %d)\n", rc); goto Error_Interest; } GST_INFO ("sending meta data..."); // hDump(DUMP_ADDR(me->temp->buf), DUMP_SIZE(me->temp->length)); rc = ccn_put (me->ccn, me->temp->buf, me->temp->length); me->temp->length = 0; if (rc < 0) { GST_LOG_OBJECT (me, "ccn_put failed (res == %d)\n", rc); goto Error_Interest; } GST_INFO ("meta data sent"); } else goto Exit_Interest; /* do not have _meta_ */ Exit_Interest: ccn_charbuf_destroy (&sname); break; Error_Interest: ccn_charbuf_destroy (&sname); return CCN_UPCALL_RESULT_ERR; default: GST_LOG_OBJECT (me, "CCN upcall result error"); return (CCN_UPCALL_RESULT_ERR); } me->timeouts = 0; return (CCN_UPCALL_RESULT_OK); }
int main(int argc, char **argv) { struct ccn *h = NULL; struct ccn_charbuf *name = NULL; struct ccn_charbuf *null_name = NULL; struct ccn_charbuf *name_prefix = NULL; struct ccn_charbuf *newface = NULL; struct ccn_charbuf *prefixreg = NULL; struct ccn_charbuf *resultbuf = NULL; struct ccn_charbuf *temp = NULL; struct ccn_charbuf *templ = NULL; const unsigned char *ptr = NULL; size_t length = 0; const char *arg = NULL; const char *progname = NULL; struct ccn_parsed_ContentObject pcobuf = {0}; struct ccn_face_instance face_instance_storage = {0}; struct ccn_face_instance *face_instance = &face_instance_storage; struct ccn_forwarding_entry forwarding_entry_storage = {0}; struct ccn_forwarding_entry *forwarding_entry = &forwarding_entry_storage; struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT; struct ccn_charbuf *keylocator_templ = NULL; struct ccn_keystore *keystore = NULL; long expire = -1; int ipproto; unsigned char ccndid_storage[32] = {0}; const unsigned char *ccndid = NULL; size_t ccndid_size = 0; int res; int opt; progname = argv[0]; while ((opt = getopt(argc, argv, "h")) != -1) { switch (opt) { case 'h': default: usage(progname); } } /* Sanity check the URI and argument count */ arg = argv[optind]; if (arg == NULL) usage(progname); name = ccn_charbuf_create(); res = ccn_name_from_uri(name, arg); if (res < 0) { fprintf(stderr, "%s: bad ccn URI: %s\n", progname, arg); exit(1); } if (argc - optind < 3 || argc - optind > 4) usage(progname); h = ccn_create(); res = ccn_connect(h, NULL); if (res < 0) { ccn_perror(h, "ccn_connect"); exit(1); } newface = ccn_charbuf_create(); temp = ccn_charbuf_create(); templ = ccn_charbuf_create(); keylocator_templ = ccn_charbuf_create(); resultbuf = ccn_charbuf_create(); name_prefix = ccn_charbuf_create(); null_name = ccn_charbuf_create(); CHKRES(ccn_name_init(null_name)); keystore = ccn_keystore_create(); /* We need to figure out our local ccnd's CCIDID */ /* Set up our Interest template to indicate scope 1 */ ccn_charbuf_reset(templ); ccnb_element_begin(templ, CCN_DTAG_Interest); ccnb_element_begin(templ, CCN_DTAG_Name); ccnb_element_end(templ); /* </Name> */ ccnb_tagged_putf(templ, CCN_DTAG_Scope, "1"); ccnb_element_end(templ); /* </Interest> */ ccn_charbuf_reset(name); CHKRES(res = ccn_name_from_uri(name, "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY")); CHKRES(res = ccn_get(h, name, templ, 200, resultbuf, &pcobuf, NULL, 0)); res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, resultbuf->buf, pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest], pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest], &ccndid, &ccndid_size); CHKRES(res); if (ccndid_size > sizeof(ccndid_storage)) CHKRES(-1); memcpy(ccndid_storage, ccndid, ccndid_size); ccndid = ccndid_storage; face_instance->action = "newface"; face_instance->ccnd_id = ccndid; face_instance->ccnd_id_size = ccndid_size; if (strcmp(argv[optind + 1], "tcp") == 0) ipproto = 6; else if (strcmp(argv[optind + 1], "udp") == 0) ipproto = 17; else ipproto = atoi(argv[optind + 1]); face_instance->descr.ipproto = ipproto; // XXX - 6 = tcp or 17 = udp face_instance->descr.address = argv[optind + 2]; face_instance->descr.port = argv[optind + 3]; if (face_instance->descr.port == NULL) face_instance->descr.port = CCN_DEFAULT_UNICAST_PORT; face_instance->descr.mcast_ttl = -1; face_instance->lifetime = (~0U) >> 1; CHKRES(res = ccnb_append_face_instance(newface, face_instance)); temp->length = 0; CHKRES(ccn_charbuf_putf(temp, "%s/.ccnx/.ccnx_keystore", getenv("HOME"))); res = ccn_keystore_init(keystore, ccn_charbuf_as_string(temp), "Th1s1sn0t8g00dp8ssw0rd."); CHKRES(res); ccnb_element_begin(keylocator_templ, CCN_DTAG_SignedInfo); ccnb_element_begin(keylocator_templ, CCN_DTAG_KeyLocator); ccnb_element_begin(keylocator_templ, CCN_DTAG_Key); CHKRES(ccn_append_pubkey_blob(keylocator_templ, ccn_keystore_public_key(keystore))); ccnb_element_end(keylocator_templ); /* </Key> */ ccnb_element_end(keylocator_templ); /* </KeyLocator> */ ccnb_element_end(keylocator_templ); /* </SignedInfo> */ sp.template_ccnb = keylocator_templ; sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR; sp.freshness = expire; ccn_charbuf_reset(temp); res = ccn_sign_content(h, temp, null_name, &sp, newface->buf, newface->length); CHKRES(res); /* Create the new face */ CHKRES(ccn_name_init(name)); CHKRES(ccn_name_append_str(name, "ccnx")); CHKRES(ccn_name_append(name, ccndid, ccndid_size)); CHKRES(ccn_name_append(name, "newface", 7)); CHKRES(ccn_name_append(name, temp->buf, temp->length)); res = ccn_get(h, name, templ, 1000, resultbuf, &pcobuf, NULL, 0); if (res < 0) { fprintf(stderr, "no response from face creation request\n"); exit(1); } ptr = resultbuf->buf; length = resultbuf->length; res = ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length); CHKRES(res); face_instance = ccn_face_instance_parse(ptr, length); if (face_instance == NULL) CHKRES(res = -1); CHKRES(face_instance->faceid); /* Finally, register the prefix */ ccn_charbuf_reset(name_prefix); CHKRES(ccn_name_from_uri(name_prefix, arg)); forwarding_entry->action = "prefixreg"; forwarding_entry->name_prefix = name_prefix; forwarding_entry->ccnd_id = ccndid; forwarding_entry->ccnd_id_size = ccndid_size; forwarding_entry->faceid = face_instance->faceid; forwarding_entry->flags = -1; /* let ccnd decide */ forwarding_entry->lifetime = (~0U) >> 1; prefixreg = ccn_charbuf_create(); CHKRES(res = ccnb_append_forwarding_entry(prefixreg, forwarding_entry)); ccn_charbuf_reset(temp); res = ccn_sign_content(h, temp, null_name, &sp, prefixreg->buf, prefixreg->length); CHKRES(res); CHKRES(ccn_name_init(name)); CHKRES(ccn_name_append_str(name, "ccnx")); CHKRES(ccn_name_append(name, ccndid, ccndid_size)); CHKRES(ccn_name_append_str(name, "prefixreg")); CHKRES(ccn_name_append(name, temp->buf, temp->length)); res = ccn_get(h, name, templ, 1000, resultbuf, &pcobuf, NULL, 0); if (res < 0) { fprintf(stderr, "no response from prefix registration request\n"); exit(1); } fprintf(stderr, "Prefix %s will be forwarded to face %d\n", arg, face_instance->faceid); /* We're about to exit, so don't bother to free everything. */ ccn_destroy(&h); exit(res < 0); }
enum ccn_upcall_res incoming_content( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { struct ccn_charbuf *name = NULL; struct ccn_charbuf *templ = NULL; struct ccn_charbuf *temp = NULL; const unsigned char *ccnb = NULL; size_t ccnb_size = 0; const unsigned char *data = NULL; size_t data_size = 0; // TANG: no need to write data to stdout //size_t written; const unsigned char *ib = NULL; /* info->interest_ccnb */ struct ccn_indexbuf *ic = NULL; int res; struct mydata *md = selfp->data; if (kind == CCN_UPCALL_FINAL) { if (md != NULL) { selfp->data = NULL; free(md); md = NULL; } return(CCN_UPCALL_RESULT_OK); } if (kind == CCN_UPCALL_INTEREST_TIMED_OUT) return(CCN_UPCALL_RESULT_REEXPRESS); if (kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED) return(CCN_UPCALL_RESULT_ERR); if (md == NULL) selfp->data = md = calloc(1, sizeof(*md)); ccnb = info->content_ccnb; ccnb_size = info->pco->offset[CCN_PCO_E]; ib = info->interest_ccnb; ic = info->interest_comps; /* XXX - must verify sig, and make sure it is LEAF content */ res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &data, &data_size); if (res < 0) abort(); if (data_size > CHUNK_SIZE) { /* For us this is spam. Give up now. */ fprintf(stderr, "*** Segment %d found with a data size of %d." " This program only works with segments of 1024 bytes." " Try ccncatchunks2 instead.\n", (int)selfp->intdata, (int)data_size); exit(1); } /* OK, we will accept this block. */ //sleep(1); // TANG: No need to write data to stdout, skip 3 lines //written = fwrite(data, data_size, 1, stdout); //if (written != 1) // exit(1); /* A short block signals EOF for us. */ // TANG: to support data_size smaller than 1024, skip 2 lines //if (data_size < CHUNK_SIZE) // exit(0); /* Ask for the next one */ name = ccn_charbuf_create(); ccn_name_init(name); if (ic->n < 2) abort(); res = ccn_name_append_components(name, ib, ic->buf[0], ic->buf[ic->n - 2]); if (res < 0) abort(); temp = ccn_charbuf_create(); //printf("intdata = %d \n ", selfp->intdata); ccn_charbuf_putf(temp, "%d", ++(selfp->intdata)); ccn_name_append(name, temp->buf, temp->length); ccn_charbuf_destroy(&temp); if(DEBUG){ //Print out the interest's name printf("Interest name = "); int myres = 0; struct ccn_indexbuf* ndx = ccn_indexbuf_create(); unsigned char* mycomp = NULL; size_t mysize = 0; ndx->n = 0; myres = ccn_name_split(name, ndx); if(myres < 0){ fprintf(stderr, "ccn_name_split @ ccntraffic. failed"); } int it = 0; for(it = 0; it < ndx->n-1; it++){ mysize = 0; myres = ccn_name_comp_get(name->buf, ndx, it, &mycomp, &mysize); printf("%s/", mycomp); mycomp = NULL; } printf("\n"); } templ = make_template(md); res = ccn_express_interest(info->h, name, selfp, templ); if (res < 0) abort(); ccn_charbuf_destroy(&templ); ccn_charbuf_destroy(&name); return(CCN_UPCALL_RESULT_OK); }
void GroupManager::incomingInterest(ccn_upcall_info *info) { int res; const char *data = NULL; const unsigned char *requester = NULL; const unsigned char *refresher = NULL; const unsigned char *filter = NULL; size_t filter_len = 0; ccn_charbuf *signed_info = NULL; ccn_charbuf *name = NULL; ccn_charbuf *content = NULL; RemoteUser *refreshUser = NULL; // requesterPrefix starts from index 4 to (info->interest_comps->n - 2) int nameEnd = 0; nameEnd = (info->interest_comps)->n - 2; /* construct reply data * name format: * /ndn/broadcast/conference/conference-name/speaker-list/username */ signed_info = ccn_charbuf_create(); struct ccn_charbuf *keylocator = ccn_charbuf_create(); ccn_create_keylocator(keylocator, ccn_keystore_public_key(cached_keystore)); res = ccn_signed_info_create(signed_info, /*pubkeyid*/ get_my_publisher_key_id(), /*publisher_key_id_size*/ get_my_publisher_key_id_length(), /*datetime*/ NULL, /*type*/ CCN_CONTENT_DATA, ///*freshness*/ -1, /*freshness*/ FRESHNESS, /*finalblockid*/ NULL, /*keylocator*/ keylocator); if (res < 0) { DPRINT("FAILED TO CREATE signed_info (res == %d)", res); } name = ccn_charbuf_create(); content = ccn_charbuf_create(); ccn_name_init(name); ccn_name_append_components(name, info->interest_ccnb, info->interest_comps->buf[0], info->interest_comps->buf[nameEnd + 1]); // append own username ccn_name_append_str(name, userName.toLocal8Bit().constData()); // get user list, the caller need to free the data buffer allocated int dlen = userListtoXml(&data); ccn_encode_ContentObject(content, name, signed_info, data, dlen, NULL, get_my_private_key()); // already have the lock, no need to trylock ccn_put(info->h, content->buf, content->length); ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&content); if (data != NULL) { free((void *)data); data = NULL; } }
/** * Convert a ccnx-scheme URI to a ccnb-encoded Name. * The converted result is placed in c. * On input, c may contain a base name, in which case relative URIs are allowed. * Otherwise c should start out empty, and the URI must be absolute. * @returns -1 if an error is found, otherwise returns the number of characters * that were processed. */ int ccn_name_from_uri(struct ccn_charbuf *c, const char *uri) { int res = 0; struct ccn_charbuf *compbuf = NULL; const char *stop = uri + strlen(uri); const char *s = uri; size_t cont = 0; compbuf = ccn_charbuf_create(); if (compbuf == NULL) return(-1); if (s[0] != '/') { res = ccn_append_uri_component(compbuf, s, stop - s, &cont); if (res < -2) goto Done; ccn_charbuf_reserve(compbuf, 1)[0] = 0; if ((0 == strcasecmp((const char *)(compbuf->buf), "ccnx:") || 0 == strcasecmp((const char *)(compbuf->buf), "ccn:")) && s[cont-1] == ':') { s += cont; cont = 0; } /// @bug XXX - need to error out on other uri schemes } if (s[0] == '/') { ccn_name_init(c); if (s[1] == '/') { /* Skip over hostname part - not used in ccnx scheme */ s += 2; compbuf->length = 0; res = ccn_append_uri_component(compbuf, s, stop - s, &cont); if (res < 0 && res != -2) goto Done; s += cont; cont = 0; } } while (s[0] != 0 && s[0] != '?' && s[0] != '#') { if (s[0] == '/') s++; compbuf->length = 0; res = ccn_append_uri_component(compbuf, s, stop - s, &cont); s += cont; cont = 0; if (res < -2) goto Done; if (res == -2) { res = 0; /* process . or equiv in URI */ continue; } if (res == -1) { /* process .. in URI - discard last name component */ res = ccn_name_last_component_offset(c->buf, c->length); if (res < 0) goto Done; c->length = res; ccn_charbuf_append_closer(c); continue; } res = ccn_name_append(c, compbuf->buf, compbuf->length); if (res < 0) goto Done; } Done: ccn_charbuf_destroy(&compbuf); if (res < 0) return(-1); if (c->length < 2 || c->buf[c->length-1] != CCN_CLOSE) return(-1); return(s - uri); }