bool CcnH_regPrefix(CcnPrefixOp operation, struct ccn* ccnh, CCNDID ccndid, int faceid, struct ccn_charbuf* prefix) { struct ccn_forwarding_entry* fe = CcnH_buildForwardingEntry(operation, ccndid, faceid, prefix); struct ccn_charbuf* reqname = CcnH_signForwardingEntry(ccnh, ccndid, fe); int res = ccn_get(ccnh, reqname, CcnH_localScopeTempl(), 5000, NULL, NULL, NULL, 0); ccn_charbuf_destroy(&reqname); free(fe); return res == 0; }
/** * * 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; }
/** * Request the current segment number from the ccnx data producer * * This is a request for meta data for the media stream the user has named with their URI. * We assume that they want to join the media broadcast from what is currently being published * and \em not want to start from the beginning...although there is good reason for that too. * * Getting this data is done by expressing interests in the meta data. The producer of the * media stream will catch this through one of its ccnx filters and produce this meta data * back through the network to us. * * \param h ccnx context handle * \param name the content name for which we desire the meta data * \param timeout how long to wait around * \return the segment number to ask for first, 0 on timeout */ static uintmax_t * get_segment (struct ccn *h, struct ccn_charbuf *name, int timeout) { struct ccn_charbuf *hn; uintmax_t *result = NULL; int res = 0; GST_INFO ("get_segment step 1"); hn = ccn_charbuf_create (); // ccn_name_append_components(hn, name->buf, 0, name->length ); ccn_charbuf_append_charbuf (hn, name); ccn_name_from_uri (hn, "_meta_/.segment"); // ccn_name_append_str(hn, "_meta_"); // ccn_name_append_str(hn, ".segment"); GST_INFO ("get_segment step 2"); // res = ccn_resolve_version(h, hn, CCN_V_HIGHEST, timeout); GST_INFO ("get_segment step 3, res: %d", res); if (res == 0) { struct ccn_charbuf *ho = ccn_charbuf_create (); struct ccn_parsed_ContentObject pcobuf = { 0 }; const unsigned char *hc; size_t hcs; // hDump(DUMP_ADDR(hn->buf), DUMP_SIZE(hn->length)); GST_INFO ("get_segment step 10"); res = ccn_get (h, hn, NULL, timeout, ho, &pcobuf, NULL, 0); GST_INFO ("get_segment step 11, res: %d", res); if (res >= 0) { hc = ho->buf; hcs = ho->length; // hDump( DUMP_ADDR(hc), DUMP_SIZE(hcs)); ccn_content_get_value (hc, hcs, &pcobuf, &hc, &hcs); // hDump( DUMP_ADDR(hc), DUMP_SIZE(hcs)); result = calloc (1, sizeof (uintmax_t)); memcpy (result, hc, sizeof (uintmax_t)); } ccn_charbuf_destroy (&ho); } GST_INFO ("get_segment step 9"); ccn_charbuf_destroy (&hn); return (result); }
void CcnCC_fetchCcndid(CcnCC self) { int res; struct ccn_charbuf* name = ccn_charbuf_create(); struct ccn_charbuf* resultbuf = ccn_charbuf_create(); struct ccn_parsed_ContentObject pcobuf = {0}; const uint8_t* ccndid_result; static size_t ccndid_result_size; ccn_name_from_uri(name, "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY"); res = ccn_get(self->ccnh, name, CcnH_localScopeTempl(), 4500, resultbuf, &pcobuf, NULL, 0); if (res >= 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, resultbuf->buf, pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest], pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest], &ccndid_result, &ccndid_result_size); } if (res >= 0 && ccndid_result_size == CCNDID_length) { memcpy((void*)self->ccndid, ccndid_result, CCNDID_length); } else { self->error = true; } ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&resultbuf); }
/** * Read a slice (from a repository) given the name. * @param h is the ccn_handle on which to read. * @param name is the charbuf containing the name of the sync slice to be read. * @param slice is a pointer to a ccns_slice object which will be filled in * on successful return. * @returns 0 on success, -1 otherwise. */ int ccns_read_slice(struct ccn *h, struct ccn_charbuf *name, struct ccns_slice *slice) { struct ccn_parsed_ContentObject pco_space = { 0 }; struct ccn_parsed_ContentObject *pco = &pco_space; struct ccn_charbuf *nc = ccn_charbuf_create_n(name->length); struct ccn_charbuf *cob = ccn_charbuf_create(); const unsigned char *content; size_t content_length; int res = -1; if (nc == NULL || cob == NULL) goto Cleanup; ccn_charbuf_append_charbuf(nc, name); res = ccn_resolve_version(h, nc, CCN_V_HIGHEST, 100); // XXX: timeout if (res < 0) goto Cleanup; if (res == 0) { // TODO: check if the last component is a segment number, chop it off, try again. } res = ccn_get(h, nc, NULL, 100, cob, pco, NULL, 0); if (res < 0) goto Cleanup; if (pco->type != CCN_CONTENT_DATA) { res = -1; goto Cleanup; } res = ccn_content_get_value(cob->buf, cob->length, pco, &content, &content_length); if (res < 0) goto Cleanup; res = slice_parse(slice, content, content_length); Cleanup: ccn_charbuf_destroy(&nc); ccn_charbuf_destroy(&cob); return (res); }
/** * * Get ccnd id * */ static int get_ccndid(struct ccn *h, struct ccn_charbuf *local_scope_template, unsigned char *ccndid) { 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; static size_t ccndid_result_size; int res; name = ccn_charbuf_create(); resultbuf = ccn_charbuf_create(); res = ccn_name_from_uri(name, ccndid_uri); ON_ERROR_EXIT(res, "Unable to parse service locator URI for ccnd key\n"); /* get Data */ res = ccn_get(h, name, local_scope_template, 4500, resultbuf, &pcobuf, NULL, 0); ON_ERROR_EXIT(res, "Unable to get key from ccnd\n"); /* extract from Data */ res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, resultbuf->buf, pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest], pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest], &ccndid_result, &ccndid_result_size); ON_ERROR_EXIT(res, "Unable to parse ccnd response for ccnd id\n"); memcpy((void *)ccndid, ccndid_result, ccndid_result_size); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&resultbuf); return (ccndid_result_size); }
static int write_slice(struct ccn *h, struct ccns_slice *slice, struct ccn_charbuf *name) { struct ccn_charbuf *content = NULL; unsigned char *cbuf = NULL; size_t clength = 0; struct ccn_charbuf *sw = NULL; struct ccn_charbuf *templ = NULL; struct ccn_charbuf *cob = NULL; struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT; struct ccn_closure *wc = NULL; int res; sw = ccn_charbuf_create_n(32 + name->length); if (sw == NULL) { res = -1; goto Cleanup; } ccn_charbuf_append_charbuf(sw, name); ccn_name_chop(sw, NULL, -1); // remove segment number ccn_name_from_uri(sw, "%C1.R.sw"); ccn_name_append_nonce(sw); // create and sign the content object cob = ccn_charbuf_create(); if (cob == NULL) { res = -1; goto Cleanup; } if (slice != NULL) { content = ccn_charbuf_create(); if (content == NULL) { res = -1; goto Cleanup; } res = append_slice(content, slice); if (res < 0) goto Cleanup; cbuf = content->buf; clength = content->length; } else { sparm.type = CCN_CONTENT_GONE; } sparm.sp_flags = CCN_SP_FINAL_BLOCK; res = ccn_sign_content(h, cob, name, &sparm, cbuf, clength); if (res < 0) goto Cleanup; // establish handler for interest in the slice content object wc = calloc(1, sizeof(*wc)); if (wc == NULL) { res = -1; goto Cleanup; } wc->p = &write_interest_handler; wc->data = cob; res = ccn_set_interest_filter(h, name, wc); if (res < 0) goto Cleanup; templ = make_scope1_template(); if (templ == NULL) { res = -1; goto Cleanup; } res = ccn_get(h, sw, templ, 1000, NULL, NULL, NULL, 0); if (res < 0) goto Cleanup; ccn_run(h, 1000); // give the repository a chance to fetch the data if (wc->intdata != 1) { res = -1; goto Cleanup; } res = 0; Cleanup: ccn_set_interest_filter(h, name, NULL); if (wc != NULL) free(wc); ccn_charbuf_destroy(&cob); ccn_charbuf_destroy(&content); ccn_charbuf_destroy(&sw); ccn_charbuf_destroy(&templ); return (res); }
// 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); }
/** * * 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; }
int main(int argc, char **argv) { const char *progname = argv[0]; struct ccn *ccn = NULL; struct ccn_charbuf *name = NULL; struct ccn_seqwriter *w = NULL; int blocksize = 1024; int torepo = 0; int scope = 1; int i; int status = 0; int res; ssize_t read_res; size_t blockread; unsigned char *buf = NULL; struct ccn_charbuf *templ; while ((res = getopt(argc, argv, "hrb:s:")) != -1) { switch (res) { case 'b': blocksize = atoi(optarg); if (blocksize <= 0 || blocksize > 4096) usage(progname); break; case 'r': torepo = 1; break; case 's': scope = atoi(optarg); if (scope < 1 || scope > 3) usage(progname); break; default: case 'h': usage(progname); break; } } argc -= optind; argv += optind; if (argc != 1) usage(progname); name = ccn_charbuf_create(); res = ccn_name_from_uri(name, argv[0]); if (res < 0) { fprintf(stderr, "%s: bad CCN URI: %s\n", progname, argv[0]); exit(1); } ccn = ccn_create(); if (ccn_connect(ccn, NULL) == -1) { perror("Could not connect to ccnd"); exit(1); } buf = calloc(1, blocksize); w = ccn_seqw_create(ccn, name); if (w == NULL) { fprintf(stderr, "ccn_seqw_create failed\n"); exit(1); } ccn_seqw_set_block_limits(w, blocksize, blocksize); if (torepo) { struct ccn_charbuf *name_v = ccn_charbuf_create(); ccn_seqw_get_name(w, name_v); ccn_name_from_uri(name_v, "%C1.R.sw"); ccn_name_append_nonce(name_v); templ = make_template(scope); res = ccn_get(ccn, name_v, templ, 60000, NULL, NULL, NULL, 0); ccn_charbuf_destroy(&templ); ccn_charbuf_destroy(&name_v); if (res < 0) { fprintf(stderr, "No response from repository\n"); exit(1); } } blockread = 0; for (i = 0;; i++) { while (blockread < blocksize) { ccn_run(ccn, 1); read_res = read(0, buf + blockread, blocksize - blockread); if (read_res == 0) goto cleanup; if (read_res < 0) { perror("read"); status = 1; goto cleanup; } blockread += read_res; } res = ccn_seqw_write(w, buf, blockread); while (res == -1) { ccn_run(ccn, 100); res = ccn_seqw_write(w, buf, blockread); } if (res != blockread) abort(); /* hmm, ccn_seqw_write did a short write or something */ blockread = 0; } cleanup: // flush out any remaining data and close if (blockread > 0) { res = ccn_seqw_write(w, buf, blockread); while (res == -1) { ccn_run(ccn, 100); res = ccn_seqw_write(w, buf, blockread); } } ccn_seqw_close(w); ccn_run(ccn, 1); free(buf); buf = NULL; ccn_charbuf_destroy(&name); ccn_destroy(&ccn); exit(status); }
int main (int argc, char **argv) { int res; //check if user supplied uri to trace if(argv[1] == NULL) { printf("Usage: trace URI\n"); exit(1); } //get the length of user provided URI int argv_length = strlen(argv[1]); //check first six chars for ccnx:/, if present, skip them int skip = 0; res = strncmp("ccnx:/", argv[1], 6); if(res == 0) { skip = 5; } //if URI does not begins with /, exit if (argv[1][skip] != '/') { printf("URI must begin with /\n"); exit(1); } //check if uri ends with slash, append if missing char *slash = ""; if (argv[1][argv_length-1] != '/') { slash = "/"; } //allocate memory for trace URI = /trace/user_input/random_number char *URI = (char *) malloc(sizeof(char)* argv_length+1); //find size of rand if(URI == NULL) { fprintf(stderr, "Can not allocate memory for URI\n"); exit(1); } //put together the trace URI, add a random number to end of URI srand ((unsigned int)time (NULL)*getpid()); sprintf(URI, "%s%s", argv[1]+skip, slash); //allocate memory for interest struct ccn_charbuf *ccnb = ccn_charbuf_create(); if(ccnb == NULL) { fprintf(stderr, "Can not allocate memory for interest\n"); exit(1); } //adding name to interest res = ccn_name_from_uri(ccnb, URI); if(res == -1) { fprintf(stderr, "Failed to assign name to interest"); exit(1); } //create the ccn handle struct ccn *ccn = ccn_create(); if(ccn == NULL) { fprintf(stderr, "Can not create ccn handle\n"); exit(1); } //connect to ccnd res = ccn_connect(ccn, NULL); if (res == -1) { fprintf(stderr, "Could not connect to ccnd... exiting\n"); exit(1); } #ifdef DEBUG printf("Connected to CCND, return code: %d\n", res); #endif //allocate buffer for response struct ccn_charbuf *resultbuf = ccn_charbuf_create(); if(resultbuf == NULL) { fprintf(stderr, "Can not allocate memory for URI\n"); exit(1); } //setting the parameters for ccn_get struct ccn_parsed_ContentObject pcobuf = { 0 }; int timeout_ms = 6000; //express interest //res = ccn_get(ccn, ccnb, NULL, timeout_ms, resultbuf, &pcobuf, NULL, 0); //if cached answer is not allowed, set the template //make sure AnswerOriginKind is 0x0 if(!ALLOW_CACHE) { struct ccn_charbuf *templ = ccn_charbuf_create(); ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG); ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG); ccn_charbuf_append_closer(templ); /* </Name> */ ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG); ccnb_append_number(templ,0x0); ccn_charbuf_append_closer(templ); /* </AnswerOriginKind> */ ccn_charbuf_append_closer(templ); //send out the interest res = ccn_get(ccn, ccnb, templ, timeout_ms, resultbuf, &pcobuf, NULL, 0); } //cached answer is allowed, don't set template else { res = ccn_get(ccn, ccnb, NULL, timeout_ms, resultbuf, &pcobuf, NULL, 0); } if (res == -1) { fprintf(stderr, "Did not receive answer for trace to %s\n", argv[1]); #ifdef DEBUG fprintf(stderr, "Did not receive answer for trace to URI: %s\n", URI); #endif exit(1); } //extract data from the response const unsigned char *ptr; size_t length; ptr = resultbuf->buf; length = resultbuf->length; ccn_content_get_value(ptr, length, &pcobuf, &ptr, &length); //check if received some data if(length == 0) { fprintf(stderr, "Received empty answer for trace to %s\n", argv[1]); #ifdef DEBUG fprintf(stderr, "Received empty answer for trace to URI: %s\n", URI); #endif exit(1); } //print the data printf("Reply: %s\n", ptr); printf("Length of data: %Zu\n", length); exit(0); }
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); }
/** * Resolve the version, based on existing ccn content. * @param h is the the ccn handle; it may be NULL, but it is preferable to * use the handle that the client probably already has. * @param name is a ccnb-encoded Name prefix. It gets extended in-place with * one additional Component such that it names highest extant * version that can be found, subject to the supplied timeout. * @param versioning_flags presently must be CCN_V_HIGH or CCN_V_HIGHEST, * possibly combined with CCN_V_NESTOK. If CCN_V_NESTOK is not present * and the ending component appears to be a version, the routine * returns 0 immediately, on the assumption that an explicit * version has already been provided. * @param timeout_ms is a time value in milliseconds. This is applied per * fetch attempt, so the total time may be longer by a factor that * depends on the number of (ccn) hops to the source(s). * @returns -1 for error, 0 if name could not be extended, 1 if was. */ int ccn_resolve_version(struct ccn *h, struct ccn_charbuf *name, int versioning_flags, int timeout_ms) { int res; int myres = -1; struct ccn_parsed_ContentObject pco_space = { 0 }; struct ccn_charbuf *templ = NULL; struct ccn_charbuf *prefix = ccn_charbuf_create(); struct ccn_charbuf *cobj = ccn_charbuf_create(); struct ccn_parsed_ContentObject *pco = &pco_space; struct ccn_indexbuf *ndx = ccn_indexbuf_create(); const unsigned char *vers = NULL; size_t vers_size = 0; int n; struct ccn_indexbuf *nix = ccn_indexbuf_create(); unsigned char lowtime[7] = {CCN_MARKER_VERSION, 0, FF, FF, FF, FF, FF}; if ((versioning_flags & ~CCN_V_NESTOK & ~CCN_V_EST) != CCN_V_HIGH) { ccn_seterror(h, EINVAL); ccn_perror(h, "ccn_resolve_version is only implemented for versioning_flags = CCN_V_HIGH(EST)"); goto Finish; } n = ccn_name_split(name, nix); if (n < 0) goto Finish; if ((versioning_flags & CCN_V_NESTOK) == 0) { res = ccn_name_comp_get(name->buf, nix, n - 1, &vers, &vers_size); if (res >= 0 && vers_size == 7 && vers[0] == CCN_MARKER_VERSION) { myres = 0; goto Finish; } } templ = resolve_templ(templ, lowtime, sizeof(lowtime)); ccn_charbuf_append(prefix, name->buf, name->length); /* our copy */ cobj->length = 0; res = ccn_get(h, prefix, templ, timeout_ms, cobj, pco, ndx, 0); while (cobj->length != 0) { if (pco->type == CCN_CONTENT_NACK) // XXX - also check for number of components break; res = ccn_name_comp_get(cobj->buf, ndx, n, &vers, &vers_size); if (res < 0) break; if (vers_size == 7 && vers[0] == CCN_MARKER_VERSION) { /* Looks like we have versions. */ name->length = 0; ccn_charbuf_append(name, prefix->buf, prefix->length); ccn_name_append(name, vers, vers_size); myres = 0; if ((versioning_flags & CCN_V_EST) == 0) break; templ = resolve_templ(templ, vers, vers_size); if (templ == NULL) break; cobj->length = 0; res = ccn_get(h, prefix, templ, timeout_ms, cobj, pco, ndx, CCN_GET_NOKEYWAIT); } else break; } Finish: ccn_charbuf_destroy(&prefix); ccn_charbuf_destroy(&cobj); ccn_indexbuf_destroy(&ndx); ccn_indexbuf_destroy(&nix); ccn_charbuf_destroy(&templ); return(myres); }
int main(int argc, char **argv) { const char *progname = argv[0]; struct ccn *ccn = NULL; struct ccn_charbuf *name = NULL; struct ccn_seqwriter *w = NULL; int blocksize = CCN_MAX_CONTENT_PAYLOAD / 2; int freshness = -1; int torepo = 0; int scope = 1; int i; int status = 0; int res; ssize_t read_res; size_t blockread; unsigned char *buf = NULL; struct ccn_charbuf *templ; char *symmetric_suffix = NULL; const char *password = NULL; char *dir = NULL; while ((res = getopt(argc, argv, "hrb:s:x:d:p:o:")) != -1) { switch (res) { case 'b': blocksize = atoi(optarg); if (blocksize <= 0 || blocksize > CCN_MAX_CONTENT_PAYLOAD) usage(progname); break; case 'r': torepo = 1; break; case 's': scope = atoi(optarg); if (scope < 1 || scope > 3) usage(progname); break; case 'x': freshness = atoi(optarg); if (freshness < 0) usage(progname); break; case 'd': symmetric_suffix = optarg; break; case 'p': password = optarg; break; case 'o': dir = optarg; break; case 'h': usage(progname); break; } } argc -= optind; argv += optind; if (argc != 1) usage(progname); name = ccn_charbuf_create(); res = ccn_name_from_uri(name, argv[0]); if (res < 0) { fprintf(stderr, "%s: bad CCN URI: %s\n", progname, argv[0]); exit(1); } ccn = ccn_create(); if (ccn_connect(ccn, NULL) == -1) { perror("Could not connect to ccnd"); exit(1); } buf = calloc(1, blocksize); w = ccn_seqw_create(ccn, name); if (w == NULL) { fprintf(stderr, "ccn_seqw_create failed\n"); exit(1); } if (symmetric_suffix != NULL) { struct ccn_charbuf *key_digest = ccn_charbuf_create(); if (ccn_get_key_digest_from_suffix(ccn, dir, symmetric_suffix, password, key_digest)) { perror("Can't access keystore"); exit(1); } ccn_seqw_set_key_digest(w, key_digest->buf, key_digest->length); ccn_charbuf_destroy(&key_digest); } ccn_seqw_set_block_limits(w, blocksize, blocksize); if (freshness > -1) ccn_seqw_set_freshness(w, freshness); if (torepo) { struct ccn_charbuf *name_v = ccn_charbuf_create(); ccn_seqw_get_name(w, name_v); ccn_name_from_uri(name_v, "%C1.R.sw"); ccn_name_append_nonce(name_v); templ = make_template(scope); res = ccn_get(ccn, name_v, templ, 60000, NULL, NULL, NULL, 0); ccn_charbuf_destroy(&templ); ccn_charbuf_destroy(&name_v); if (res < 0) { fprintf(stderr, "No response from repository\n"); exit(1); } } blockread = 0; for (i = 0;; i++) { while (blockread < blocksize) { if (ccn_run(ccn, 1) < 0) { fprintf(stderr, "Lost connection to ccnd: %s\n", strerror(ccn_geterror(ccn))); exit(1); } read_res = read(0, buf + blockread, blocksize - blockread); if (read_res == 0) goto cleanup; if (read_res < 0) { perror("read"); status = 1; goto cleanup; } blockread += read_res; } res = ccn_seqw_write(w, buf, blockread); while (res == -1) { if (ccn_run(ccn, 100) < 0) { fprintf(stderr, "Lost connection to ccnd: %s\n", strerror(ccn_geterror(ccn))); exit(1); } res = ccn_seqw_write(w, buf, blockread); } if (res != blockread) abort(); /* hmm, ccn_seqw_write did a short write or something */ blockread = 0; } cleanup: // flush out any remaining data and close if (blockread > 0) { res = ccn_seqw_write(w, buf, blockread); while (res == -1) { if (ccn_run(ccn, 100) < 0) { fprintf(stderr, "Lost connection to ccnd: %s\n", strerror(ccn_geterror(ccn))); exit(1); } res = ccn_seqw_write(w, buf, blockread); } } ccn_seqw_close(w); ccn_run(ccn, 1); free(buf); buf = NULL; ccn_charbuf_destroy(&name); ccn_destroy(&ccn); exit(status); }
int verify_key(const unsigned char *ccnb, struct ccn_parsed_ContentObject *pco, int content_type){ if ( nlsr->debugging ) printf("verify key called\n"); int ret=-1; //int res; if ( contain_key_name(ccnb, pco) == 1){ struct ccn_charbuf *key_name=get_key_name(ccnb, pco); struct ccn_charbuf *key_uri = ccn_charbuf_create(); ccn_uri_append(key_uri, key_name->buf, key_name->length, 0); if ( nlsr->debugging ) printf("Key Name from Incoming Content: %s\n",ccn_charbuf_as_string(key_uri)); int key_type=get_key_type_from_key_name(key_name); if ( nlsr->debugging ) printf("Key Type: %d \n",key_type); struct ccn_charbuf *result = ccn_charbuf_create(); struct ccn_parsed_ContentObject temp_pco = {0}; int get_flags = 0; get_flags |= CCN_GET_NOKEYWAIT; int counter = 0; while(ccn_get(nlsr->ccn, key_name, NULL, 500, result, &temp_pco, NULL, get_flags) < 0 && counter < 3) counter++; int chk_verify=ccn_verify_content(nlsr->ccn,ccnb,pco); if ( chk_verify == 0 ){ if ( nlsr->debugging ) printf("Content verification Successful :)\n"); if ( counter == 3){ if ( nlsr->debugging ) printf("Could not retrieve key by name !!!\n"); } else{ if ( key_type == ROOT_KEY ){ ret=0; } else{ if ( nlsr->isStrictHierchicalKeyCheck ){ int key_name_test=check_key_name_hierarchy(ccnb, pco, key_type, content_type); if ( key_name_test == 1){ ret=verify_key(result->buf,&temp_pco,content_type); } } else{ ret=verify_key(result->buf,&temp_pco,content_type); } } } } ccn_charbuf_destroy(&result); ccn_charbuf_destroy(&key_uri); ccn_charbuf_destroy(&key_name); return ret; } return ret; }
int main(int argc, char **argv) { const char *progname = argv[0]; struct ccn *ccn = NULL; struct ccn_charbuf *name = NULL; struct ccn_seqwriter *w = NULL; long blocksize = 1024; int torepo = 0; int i; int status = 0; int res; ssize_t read_res; unsigned char *buf = NULL; while ((res = getopt(argc, argv, "hrb:")) != -1) { switch (res) { case 'b': blocksize = atol(optarg); if (blocksize <= 0 || blocksize > 4096) usage(progname); break; case 'r': torepo = 1; break; default: case 'h': usage(progname); break; } } argc -= optind; argv += optind; if (argv[0] == NULL) usage(progname); name = ccn_charbuf_create(); res = ccn_name_from_uri(name, argv[0]); if (res < 0) { fprintf(stderr, "%s: bad ccnx URI: %s\n", progname, argv[0]); exit(1); } if (argv[1] != NULL) fprintf(stderr, "%s warning: extra arguments ignored\n", progname); ccn = ccn_create(); if (ccn_connect(ccn, NULL) == -1) { perror("Could not connect to ccnd"); exit(1); } buf = calloc(1, blocksize); w = ccn_seqw_create(ccn, name); if (w == NULL) { fprintf(stderr, "ccn_seqw_create failed\n"); exit(1); } if (torepo) { struct ccn_charbuf *name_v = ccn_charbuf_create(); ccn_seqw_get_name(w, name_v); ccn_name_from_uri(name_v, "%C1.R.sw"); ccn_name_append_nonce(name_v); ccn_get(ccn, name_v, NULL, 2000, NULL, NULL, NULL, 0); ccn_charbuf_destroy(&name_v); } for (i = 0;; i++) { ccn_run(ccn, 1); read_res = read(0, buf, blocksize); if (read_res < 0) { perror("read"); read_res = 0; status = 1; } if (read_res == 0) { ccn_seqw_close(w); w = NULL; status = 0; break; } res = ccn_seqw_write(w, buf, read_res); while (res == -1) { ccn_run(ccn, 100); res = ccn_seqw_write(w, buf, read_res); } if (res != read_res) abort(); /* hmm, ccn_seqw_write did a short write or something */ } ccn_run(ccn, 1); free(buf); buf = NULL; ccn_charbuf_destroy(&name); ccn_destroy(&ccn); exit(status); }