/** * Write a ccns_slice object to a repository. * @param h is the ccn_handle on which to write. * @param slice is a pointer to a ccns_slice object to be written. * @param name, if non-NULL, is a pointer to a charbuf which will be filled * in with the name of the slice that was written. * @returns 0 on success, -1 otherwise. */ int ccns_write_slice(struct ccn *h, struct ccns_slice *slice, struct ccn_charbuf *name) { struct ccn_charbuf *n = NULL; int res; // calculate versioned and segmented name for the slice n = ccn_charbuf_create(); if (n == NULL) return(-1); res = ccns_slice_name(n, slice); if (res < 0) goto Cleanup; res |= ccn_create_version(h, n, CCN_V_NOW, 0, 0); if (name != NULL) { ccn_charbuf_reset(name); res |= ccn_charbuf_append_charbuf(name, n); } res |= ccn_name_append_numeric(n, CCN_MARKER_SEQNUM, 0); if (res < 0) goto Cleanup; res = write_slice(h, slice, n); Cleanup: ccn_charbuf_destroy(&n); return (res); }
int gen_test(struct ccn_charbuf **name, struct ccn_indexbuf **comps) { int res; intmax_t secs = 1234567890; int nsecs = 6000000; *name = ccn_charbuf_create(); ccn_name_init(*name); res = ccn_create_version(NULL, *name, 0, secs, nsecs); if (res < 0) { printf("Unable to create version\n"); return(-__LINE__); } *comps = ccn_indexbuf_create(); struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = &decoder; ccn_buf_decoder_start(d, (*name)->buf, (*name)->length); res = ccn_parse_Name(d, *comps); if (res < 0) { printf("Unable to parse name\n"); return(-__LINE__); } return(0); }
extern int SyncCacheEntryStore(struct SyncHashCacheEntry *ce) { // causes the cache entry to be saved to the repo int res = 0; if (ce == NULL) { // not an entry res = -1; } else if (ce->ncL == NULL || ce->ncL->cb == NULL || (ce->state & SyncHashState_stored) || (ce->state & SyncHashState_storing) == 0 ) { // not eligible res = 0; } else { struct SyncRootStruct *root = ce->head->root; struct SyncBaseStruct *base = root->base; struct ccn_charbuf *name = SyncNameForLocalNode(root, ce->hash); struct ccn_charbuf *content = ce->ncL->cb; // TBD: do we want to omit version and segment? res |= ccn_create_version(base->sd->ccn, name, CCN_V_NOW, 0, 0); res |= ccn_name_append_numeric(name, CCN_MARKER_SEQNUM, 0); res = SyncLocalRepoStore(base, name, content, CCN_SP_FINAL_BLOCK); if (res > 0) { // clear the bits ce->state |= SyncHashState_stored; ce->state = ce->state - SyncHashState_storing; } ccn_charbuf_destroy(&name); } return res; }
/** * should probably return a new cob, rather than reusing one. * should publish link as: * CCNRID_POLICY_URI("ccnx:/%C1.M.S.localhost/%C1.M.SRV/repository/POLICY)/%C1.M.K--pubid--/--version--/%00 * should have key locator which is the key name of the repository */ PUBLIC struct ccn_charbuf * ccnr_init_policy_link_cob(struct ccnr_handle *ccnr, struct ccn *h, struct ccn_charbuf *targetname) { struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT; struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_charbuf *pubid = ccn_charbuf_create(); struct ccn_charbuf *pubkey = ccn_charbuf_create(); struct ccn_charbuf *keyid = ccn_charbuf_create(); struct ccn_charbuf *content = ccn_charbuf_create(); struct ccn_charbuf *cob = ccn_charbuf_create(); struct ccn_charbuf *answer = NULL; int res; res = ccn_get_public_key(h, NULL, pubid, pubkey); if (res < 0) goto Bail; if (ccn_name_from_uri(name, CCNRID_POLICY_URI) < 0) goto Bail; res |= ccn_charbuf_append_value(keyid, CCN_MARKER_CONTROL, 1); res |= ccn_charbuf_append_string(keyid, ".M.K"); res |= ccn_charbuf_append_value(keyid, 0, 1); res |= ccn_charbuf_append_charbuf(keyid, pubid); res |= ccn_name_append(name, keyid->buf, keyid->length); res |= ccn_create_version(h, name, CCN_V_NOW, 0, 0); if (ccn_name_from_uri(name, "%00") < 0) goto Bail; sp.sp_flags |= CCN_SP_FINAL_BLOCK; sp.type = CCN_CONTENT_LINK; res |= ccnb_append_Link(content, targetname, "Repository Policy", NULL); if (res != 0) goto Bail; res |= ccn_sign_content(h, cob, name, &sp, content->buf, content->length); if (res != 0) goto Bail; answer = cob; cob = NULL; Bail: ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&pubid); ccn_charbuf_destroy(&pubkey); ccn_charbuf_destroy(&keyid); ccn_charbuf_destroy(&content); ccn_charbuf_destroy(&cob); return (answer); }
/** * Delete a ccns_slice object from a repository. * @param h is the ccn_handle on which to write. * @param name is a pointer to a charbuf naming the slice to be deleted. * @returns 0 on success, -1 otherwise. */ int ccns_delete_slice(struct ccn *h, struct ccn_charbuf *name) { struct ccn_charbuf *n = NULL; int res = 0; // calculate versioned and segmented name for the slice n = ccn_charbuf_create_n(32 + name->length); if (n == NULL) return(-1); res |= ccn_charbuf_append_charbuf(n, name); res |= ccn_create_version(h, n, CCN_V_NOW | CCN_V_REPLACE, 0, 0); res |= ccn_name_append_numeric(n, CCN_MARKER_SEQNUM, 0); if (res >= 0) res = write_slice(h, NULL, n); ccn_charbuf_destroy(&n); return (res); }
static struct ccn_charbuf * ccnr_init_service_ccnb(struct ccnr_handle *ccnr, struct ccn *h, const char *baseuri, int freshness) { struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT; struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_charbuf *pubid = ccn_charbuf_create(); struct ccn_charbuf *pubkey = ccn_charbuf_create(); struct ccn_charbuf *keyid = ccn_charbuf_create(); struct ccn_charbuf *cob = ccn_charbuf_create(); int res; res = ccn_get_public_key(h, NULL, pubid, pubkey); if (res < 0) abort(); ccn_name_from_uri(name, baseuri); ccn_charbuf_append_value(keyid, CCN_MARKER_CONTROL, 1); ccn_charbuf_append_string(keyid, ".M.K"); ccn_charbuf_append_value(keyid, 0, 1); ccn_charbuf_append_charbuf(keyid, pubid); ccn_name_append(name, keyid->buf, keyid->length); ccn_create_version(h, name, 0, ccnr->starttime, ccnr->starttime_usec * 1000); sp.template_ccnb = ccn_charbuf_create(); ccnb_element_begin(sp.template_ccnb, CCN_DTAG_SignedInfo); ccnb_element_begin(sp.template_ccnb, CCN_DTAG_KeyLocator); ccnb_element_begin(sp.template_ccnb, CCN_DTAG_KeyName); ccn_charbuf_append_charbuf(sp.template_ccnb, name); ccnb_element_end(sp.template_ccnb); // ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_PublisherPublicKeyDigest, // CCN_DTAG); // ccn_charbuf_append_charbuf(sp.template_ccnb, pubid); // ccnb_element_end(sp.template_ccnb); ccnb_element_end(sp.template_ccnb); ccnb_element_end(sp.template_ccnb); sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR; ccn_name_from_uri(name, "%00"); sp.sp_flags |= CCN_SP_FINAL_BLOCK; sp.type = CCN_CONTENT_KEY; sp.freshness = freshness; res = ccn_sign_content(h, cob, name, &sp, pubkey->buf, pubkey->length); if (res != 0) abort(); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&pubid); ccn_charbuf_destroy(&pubkey); ccn_charbuf_destroy(&keyid); ccn_charbuf_destroy(&sp.template_ccnb); return(cob); }
/** * Set up a connection with the ccnd router * * During this setup we establish a basic connection with the router service * over an IP connection. * This is also a good time to setup the ccn name for the content we will * produce; that is the prefix name and the timestamp [Tnow], since the * segment portion of the name is added just as the packet is being sent. * * Lastly we also load our security keys and create our signing parameters. * * \param me context sink element for which the socket is for */ static void setup_ccn (Gstccnxsink * me) { struct ccn *ccn; GST_DEBUG ("CCNxSink: setup name..."); if ((me->name = ccn_charbuf_create ()) == NULL) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("name alloc failed")); return; } if (ccn_name_from_uri (me->name, me->uri) < 0) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("name from uri failed")); return; } GST_DEBUG ("CCNxSink: creating ccn object"); if ((ccn = ccn_create ()) == NULL) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("ccn_create failed")); return; } me->ccn = ccn; GST_DEBUG ("CCNxSink: connecting"); if (-1 == ccn_connect (me->ccn, ccndHost ())) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("ccn_connect failed to %s", ccndHost ())); return; } GST_DEBUG ("CCNxSink: setting name version"); if (0 > ccn_create_version (ccn, me->name, CCN_V_REPLACE | CCN_V_NOW | CCN_V_HIGH, 0, 0)) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("ccn_create_version() failed")); return; } GST_DEBUG ("CCNxSink: setting up keystore"); /* me->keystore = fetchStore(); if( me->keystore ) me->keylocator = makeLocator( ccn_keystore_public_key(me->keystore) ); */ loadKey (me->ccn, &me->sp); GST_DEBUG ("CCNxSink: done; have keys!"); }
/** * Create a seqwriter for writing data to a versioned, segmented stream. * * @param name is a ccnb-encoded Name. It will be provided with a version * based on the current time unless it already ends in a version * component. */ struct ccn_seqwriter * ccn_seqw_create(struct ccn *h, struct ccn_charbuf *name) { struct ccn_seqwriter *w = NULL; struct ccn_charbuf *nb = NULL; struct ccn_charbuf *nv = NULL; int res; w = calloc(1, sizeof(*w)); if (w == NULL) return(NULL); nb = ccn_charbuf_create(); ccn_charbuf_append(nb, name->buf, name->length); nv = ccn_charbuf_create(); ccn_charbuf_append(nv, name->buf, name->length); res = ccn_create_version(h, nv, CCN_V_NOW, 0, 0); if (res < 0 || nb == NULL) { ccn_charbuf_destroy(&nv); ccn_charbuf_destroy(&nb); free(w); return(NULL); } w->cl.p = &seqw_incoming_interest; w->cl.data = w; w->nb = nb; w->nv = nv; w->buffer = ccn_charbuf_create(); w->h = h; w->seqnum = 0; w->interests_possibly_pending = 1; res = ccn_set_interest_filter(h, nb, &(w->cl)); if (res < 0) { ccn_charbuf_destroy(&w->nb); ccn_charbuf_destroy(&w->nv); ccn_charbuf_destroy(&w->buffer); free(w); return(NULL); } return(w); }
int main(int argc, char **argv) { const char *progname = argv[0]; struct ccn *ccn = NULL; struct ccn_charbuf *name = NULL; struct ccn_charbuf *pname = NULL; struct ccn_charbuf *temp = NULL; struct ccn_charbuf *extopt = NULL; long expire = -1; int versioned = 0; size_t blocksize = 8*1024; int status = 0; int res; ssize_t read_res; unsigned char *buf = NULL; enum ccn_content_type content_type = CCN_CONTENT_DATA; struct ccn_closure in_interest = {.p=&incoming_interest}; const char *postver = NULL; const char *key_uri = NULL; int force = 0; int verbose = 0; int timeout = -1; int setfinal = 0; int prefixcomps = -1; int fd; struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT; while ((res = getopt(argc, argv, "e:fhk:lvV:p:t:w:x:")) != -1) { switch (res) { case 'e': if (extopt == NULL) extopt = ccn_charbuf_create(); fd = open(optarg, O_RDONLY); if (fd < 0) { perror(optarg); exit(1); } for (;;) { read_res = read(fd, ccn_charbuf_reserve(extopt, 64), 64); if (read_res <= 0) break; extopt->length += read_res; } if (read_res < 0) perror(optarg); close(fd); break; case 'f': force = 1; break; case 'l': setfinal = 1; // set FinalBlockID to last comp of name break; case 'k': key_uri = optarg; break; case 'p': prefixcomps = atoi(optarg); if (prefixcomps < 0) usage(progname); break; case 'x': expire = atol(optarg); if (expire <= 0) usage(progname); break; case 'v': verbose = 1; break; case 'V': versioned = 1; postver = optarg; if (0 == memcmp(postver, "%00", 3)) setfinal = 1; break; case 'w': timeout = atol(optarg); if (timeout <= 0) usage(progname); timeout *= 1000; break; case 't': if (0 == strcasecmp(optarg, "DATA")) { content_type = CCN_CONTENT_DATA; break; } if (0 == strcasecmp(optarg, "ENCR")) { content_type = CCN_CONTENT_ENCR; break; } if (0 == strcasecmp(optarg, "GONE")) { content_type = CCN_CONTENT_GONE; break; } if (0 == strcasecmp(optarg, "KEY")) { content_type = CCN_CONTENT_KEY; break; } if (0 == strcasecmp(optarg, "LINK")) { content_type = CCN_CONTENT_LINK; break; } if (0 == strcasecmp(optarg, "NACK")) { content_type = CCN_CONTENT_NACK; break; } content_type = atoi(optarg); if (content_type > 0 && content_type <= 0xffffff) break; fprintf(stderr, "Unknown content type %s\n", optarg); /* FALLTHRU */ 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 ccn URI: %s\n", progname, argv[0]); exit(1); } if (argv[1] != NULL) fprintf(stderr, "%s warning: extra arguments ignored\n", progname); /* Preserve the original prefix, in case we add versioning, * but trim it down if requested for the interest filter registration */ pname = ccn_charbuf_create(); ccn_charbuf_append(pname, name->buf, name->length); if (prefixcomps >= 0) { res = ccn_name_chop(pname, NULL, prefixcomps); if (res < 0) { fprintf(stderr, "%s: unable to trim name to %d component%s.\n", progname, prefixcomps, prefixcomps == 1 ? "" : "s"); exit(1); } } /* Connect to ccnd */ ccn = ccn_create(); if (ccn_connect(ccn, NULL) == -1) { perror("Could not connect to ccnd"); exit(1); } /* Read the actual user data from standard input */ buf = calloc(1, blocksize); read_res = read_full(0, buf, blocksize); if (read_res < 0) { perror("read"); read_res = 0; status = 1; } /* Tack on the version component if requested */ if (versioned) { res = ccn_create_version(ccn, name, CCN_V_REPLACE | CCN_V_NOW | CCN_V_HIGH, 0, 0); if (res < 0) { fprintf(stderr, "%s: ccn_create_version() failed\n", progname); exit(1); } if (postver != NULL) { res = ccn_name_from_uri(name, postver); if (res < 0) { fprintf(stderr, "-V %s: invalid name suffix\n", postver); exit(0); } } } temp = ccn_charbuf_create(); /* Ask for a FinalBlockID if appropriate. */ if (setfinal) sp.sp_flags |= CCN_SP_FINAL_BLOCK; if (res < 0) { fprintf(stderr, "Failed to create signed_info (res == %d)\n", res); exit(1); } /* Set content type */ sp.type = content_type; /* Set freshness */ if (expire >= 0) { if (sp.template_ccnb == NULL) { sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); } else if (sp.template_ccnb->length > 0) { sp.template_ccnb->length--; } ccnb_tagged_putf(sp.template_ccnb, CCN_DTAG_FreshnessSeconds, "%ld", expire); sp.sp_flags |= CCN_SP_TEMPL_FRESHNESS; ccn_charbuf_append_closer(sp.template_ccnb); } /* Set key locator, if supplied */ if (key_uri != NULL) { struct ccn_charbuf *c = ccn_charbuf_create(); res = ccn_name_from_uri(c, key_uri); if (res < 0) { fprintf(stderr, "%s is not a valid ccnx URI\n", key_uri); exit(1); } if (sp.template_ccnb == NULL) { sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); } else if (sp.template_ccnb->length > 0) { sp.template_ccnb->length--; } ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyLocator, CCN_DTAG); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyName, CCN_DTAG); ccn_charbuf_append(sp.template_ccnb, c->buf, c->length); ccn_charbuf_append_closer(sp.template_ccnb); ccn_charbuf_append_closer(sp.template_ccnb); sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR; ccn_charbuf_append_closer(sp.template_ccnb); ccn_charbuf_destroy(&c); } if (extopt != NULL && extopt->length > 0) { if (sp.template_ccnb == NULL) { sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); } else if (sp.template_ccnb->length > 0) { sp.template_ccnb->length--; } ccnb_append_tagged_blob(sp.template_ccnb, CCN_DTAG_ExtOpt, extopt->buf, extopt->length); sp.sp_flags |= CCN_SP_TEMPL_EXT_OPT; ccn_charbuf_append_closer(sp.template_ccnb); } /* Create the signed content object, ready to go */ temp->length = 0; res = ccn_sign_content(ccn, temp, name, &sp, buf, read_res); if (res != 0) { fprintf(stderr, "Failed to encode ContentObject (res == %d)\n", res); exit(1); } if (read_res == blocksize) { read_res = read_full(0, buf, 1); if (read_res == 1) { fprintf(stderr, "%s: warning - truncated data\n", argv[0]); status = 1; } } free(buf); buf = NULL; if (force) { /* At user request, send without waiting to see an interest */ res = ccn_put(ccn, temp->buf, temp->length); if (res < 0) { fprintf(stderr, "ccn_put failed (res == %d)\n", res); exit(1); } } else { in_interest.data = temp; /* Set up a handler for interests */ res = ccn_set_interest_filter(ccn, pname, &in_interest); if (res < 0) { fprintf(stderr, "Failed to register interest (res == %d)\n", res); exit(1); } res = ccn_run(ccn, timeout); if (in_interest.intdata == 0) { if (verbose) fprintf(stderr, "Nobody's interested\n"); exit(1); } } if (verbose) { struct ccn_charbuf *uri = ccn_charbuf_create(); uri->length = 0; ccn_uri_append(uri, name->buf, name->length, 1); printf("wrote %s\n", ccn_charbuf_as_string(uri)); ccn_charbuf_destroy(&uri); } ccn_destroy(&ccn); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&pname); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&sp.template_ccnb); ccn_charbuf_destroy(&extopt); exit(status); }