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); }
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 = 0; struct ccn* ccn_pub; struct ccn* ccn_rec; // Will hold the public/private key used for signing struct ccn_pkey* public_key = NULL; struct ccn_pkey* private_key = NULL; int complete=0; int outstanding_interests=0; // We need two ccn handles because the same handle cannot be used // to answer interests it issues. // ccn_pub = ccn_create(); if (ccn_connect(ccn_pub, NULL) == -1) { fprintf(stderr, "Could not connect to ccnd"); return(1); } ccn_rec = ccn_create(); if (ccn_connect(ccn_rec, NULL) == -1) { fprintf(stderr, "Could not connect to ccnd"); return(1); } // Closure to handle upcalls struct ccn_closure *cl = NULL; cl = (struct ccn_closure*) calloc(1, sizeof(struct ccn_closure)); cl->p = &packet_handler; handler_data h_data = { &complete, &outstanding_interests, &public_key, &ccn_pub, &ccn_rec}; cl->data = &h_data; // Setup our one test name without signature // The nonce here is just a random string, to avoid content store caching struct ccn_charbuf* name; name = ccn_charbuf_create(); ccn_name_from_uri(name, TEST_URI); ccn_name_append_nonce(name); fprintf(stderr, "Our name: %s/<nonce>\n", TEST_URI); // Set up a filter for interests in that name res = ccn_set_interest_filter(ccn_pub, name, cl); if (res < 0) { fprintf(stderr, "Failed to register interest (res == %d)\n", res); return(1); } // Get our default keys -- Why do we have to do all this work?? // Borrowed from ccn_client.c struct ccn_signing_params name_sp = CCN_SIGNING_PARAMS_INIT; struct ccn_signing_params p = CCN_SIGNING_PARAMS_INIT; struct ccn_keystore *keystore = NULL; struct ccn_charbuf *timestamp = NULL; struct ccn_charbuf *finalblockid = NULL; struct ccn_charbuf *keylocator = NULL; unsigned char* public_key_digest = NULL; size_t public_key_digest_length = 0; res = ccn_chk_signing_params(ccn_pub, &name_sp, &p, ×tamp, &finalblockid, &keylocator); if (res < 0) return(res); // For this test, use our default signing keys get_default_keys(ccn_pub, &p, &keystore, &public_key, &public_key_digest, &public_key_digest_length, &private_key); // We'll need a KeyLocator for our ContentObject // So continue borrowed code /* Construct a key locator containing the key itself */ build_keylocator_from_key(&keylocator, public_key); // And a SignedInfo too struct ccn_charbuf *signed_info = ccn_charbuf_create(); res = ccn_signed_info_create(signed_info, public_key_digest, public_key_digest_length, timestamp, p.type, p.freshness, 0, /* FinalBlockID is optional */ keylocator); // * Test using interests for a name that has one more component than our registered prefix // This is more representative of real apps... // 20-May-2011 ccn_name_append_str(name, "some stuff in a name component"); ccn_name_append_nonce(name); ccn_name_append_nonce(name); // Sign the interest struct ccn_charbuf *name_signed = ccn_charbuf_create(); sign_interest(name_signed, name, signed_info, NULL /* default digest alg */, private_key); // Express the signed interest from a different ccn handle so we get the packet res = ccn_express_interest(ccn_rec, name_signed, cl, NULL); // TODO: AnswerOriginKind could limit to signed interest? outstanding_interests++; // Express an interest with an incorrect namespace struct ccn_charbuf *name_signed_copy = ccn_charbuf_create(); ccn_charbuf_append_charbuf(name_signed_copy, name_signed); size_t k = name->length + 10; // Seek into the namespace part of the buffer name_signed_copy->buf[k] = name_signed_copy->buf[k] + 1; res = ccn_express_interest(ccn_rec, name_signed_copy, cl, NULL); // TODO: AnswerOriginKind could limit to signed interest? outstanding_interests++; // Express an interest with bogus signature name_signed_copy = ccn_charbuf_create(); ccn_charbuf_append_charbuf(name_signed_copy, name_signed); k = name->length + 30; // Seek into the signature part of the buffer name_signed_copy->buf[k] = name_signed_copy->buf[k] + 1; res = ccn_express_interest(ccn_rec, name_signed_copy, cl, NULL); // TODO: AnswerOriginKind could limit to signed interest? outstanding_interests++; if (res < 0) { fprintf(stderr, "Error expressing interest (res == %d)\n", res); } cl = NULL; // freed by ccn? while(!complete && outstanding_interests>0) { // Not sure how to handle two ccn_runs? ccn_run(ccn_rec, 100); /* stop if we run dry for .1 sec */ ccn_run(ccn_pub, 100); /* stop if we run dry for .1 sec */ fflush(stdout); } ccn_charbuf_destroy(×tamp); ccn_charbuf_destroy(&keylocator); ccn_charbuf_destroy(&finalblockid); ccn_charbuf_destroy(&signed_info); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&name_signed); ccn_charbuf_destroy(&name_signed_copy); ccn_destroy(&ccn_pub); ccn_destroy(&ccn_rec); fflush(stderr); return(0); }
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 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); }