static int append_signature_bits(struct ccn_charbuf *signature, PyObject *py_obj_Signature) { PyObject *py_signatureBits = NULL; const char *blob; Py_ssize_t blobsize; int r; if (!PyObject_HasAttrString(py_obj_Signature, "signatureBits")) return 0; py_signatureBits = PyObject_GetAttrString(py_obj_Signature, "signatureBits"); JUMP_IF_NULL(py_signatureBits, error); if (py_signatureBits != Py_None) { blob = PyBytes_AsString(py_signatureBits); JUMP_IF_NULL(blob, error); blobsize = PyBytes_GET_SIZE(py_signatureBits); r = ccnb_append_tagged_blob(signature, CCN_DTAG_SignatureBits, blob, blobsize); JUMP_IF_NEG_MEM(r, error); } Py_DECREF(py_signatureBits); return 0; error: Py_XDECREF(py_signatureBits); return -1; }
int ccnb_append_forwarding_entry(struct ccn_charbuf *c, const struct ccn_forwarding_entry *fe) { int res; res = ccnb_element_begin(c, CCN_DTAG_ForwardingEntry); if (fe->action != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Action, "%s", fe->action); if (fe->name_prefix != NULL && fe->name_prefix->length > 0) res |= ccn_charbuf_append(c, fe->name_prefix->buf, fe->name_prefix->length); if (fe->ccnd_id_size != 0) res |= ccnb_append_tagged_blob(c, CCN_DTAG_PublisherPublicKeyDigest, fe->ccnd_id, fe->ccnd_id_size); if (fe->faceid != ~0) res |= ccnb_tagged_putf(c, CCN_DTAG_FaceID, "%u", fe->faceid); if (fe->flags >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_ForwardingFlags, "%d", fe->flags); if (fe->lifetime >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_FreshnessSeconds, "%d", fe->lifetime); res |= ccnb_element_end(c); return(res); }
static int append_digest_algorithm(struct ccn_charbuf *signature, PyObject *py_obj_Signature) { PyObject *py_digestAlgorithm = NULL; PyObject *py_o; char *str; Py_ssize_t str_len; int r; if (!PyObject_HasAttrString(py_obj_Signature, "digestAlgorithm")) return 0; py_digestAlgorithm = PyObject_GetAttrString(py_obj_Signature, "digestAlgorithm"); JUMP_IF_NULL(py_digestAlgorithm, error); if (py_digestAlgorithm != Py_None) { py_o = _pyccn_unicode_to_utf8(py_digestAlgorithm, &str, &str_len); assert((Py_ssize_t) strlen(str) == str_len); JUMP_IF_NULL(py_o, error); r = ccnb_append_tagged_blob(signature, CCN_DTAG_DigestAlgorithm, str, str_len); Py_DECREF(py_o); JUMP_IF_NEG_MEM(r, error); } Py_DECREF(py_digestAlgorithm); return 0; error: Py_XDECREF(py_digestAlgorithm); return -1; }
/* * This appends a tagged, valid, fully-saturated Bloom filter, useful for * excluding everything between two 'fenceposts' in an Exclude construct. */ static void append_bf_all(struct ccn_charbuf *c) { unsigned char bf_all[9] = { 3, 1, 'A', 0, 0, 0, 0, 0, 0xFF }; const struct ccn_bloom_wire *b = ccn_bloom_validate_wire(bf_all, sizeof(bf_all)); if (b == NULL) abort(); ccnb_append_tagged_blob(c, CCN_DTAG_Bloom, bf_all, sizeof(bf_all)); }
static void append_lifetime(ccn_charbuf *templ) { unsigned int nonce = rand() % MAXNONCE; unsigned int lifetime = INTEREST_LIFETIME * 4096 + nonce; unsigned char buf[3] = {0}; for (int i = sizeof(buf) - 1; i >= 0; i--, lifetime >>=8) { buf[i] = lifetime & 0xff; } ccnb_append_tagged_blob(templ, CCN_DTAG_InterestLifetime, buf, sizeof(buf)); }
int get_content_by_content_name(char *content_name, unsigned char **content_data, char *orig_router) { int ret=-1; struct ccn_charbuf *name = NULL; struct ccn_charbuf *templ = NULL; struct ccn_charbuf *resultbuf = NULL; struct ccn_parsed_ContentObject pcobuf = { 0 }; int res; int allow_stale = 1; int content_only = 1; int scope = -1; const unsigned char *ptr,*ptr_in; size_t length,length_in; int resolve_version = CCN_V_HIGHEST; int timeout_ms = 3000; const unsigned lifetime_default = CCN_INTEREST_LIFETIME_SEC << 12; unsigned lifetime_l12 = lifetime_default; int get_flags = 0; name = ccn_charbuf_create(); res = ccn_name_from_uri(name,content_name); if (res < 0) { fprintf(stderr, "Bad ccn URI: %s\n", content_name); ccn_charbuf_destroy(&name); return ret; } if (allow_stale || lifetime_l12 != lifetime_default || scope != -1) { 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> */ if (allow_stale) { ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG); ccnb_append_number(templ, CCN_AOK_DEFAULT | CCN_AOK_STALE); ccn_charbuf_append_closer(templ); /* </AnswerOriginKind> */ } if (scope != -1) { ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope); } if (lifetime_l12 != lifetime_default) { /* * Choose the interest lifetime so there are at least 3 * expressions (in the unsatisfied case). */ unsigned char buf[3] = { 0 }; int i; for (i = sizeof(buf) - 1; i >= 0; i--, lifetime_l12 >>= 8) buf[i] = lifetime_l12 & 0xff; ccnb_append_tagged_blob(templ, CCN_DTAG_InterestLifetime, buf, sizeof(buf)); }
/** * Append a tagged binary number as a blob containing the integer value * * This is a ccnb-encoded element holding a * @param cb is the buffer to append to. * @param dtag is the element's dtab * @param val is the unsigned integer to be appended * @returns 0 for success or -1 for error. */ int ccnb_append_tagged_binary_number(struct ccn_charbuf *cb, enum ccn_dtag dtag, uintmax_t val) { unsigned char buf[sizeof(val)]; int pos; int res = 0; for (pos = sizeof(buf); val != 0 && pos > 0; val >>= 8) buf[--pos] = val & 0xff; res |= ccnb_append_tagged_blob(cb, dtag, buf+pos, sizeof(buf)-pos); return(res); }
// replace_name() // Helper function to replace names in content objects // Could build another version that works on already parsed content objects // But as seen below it would be better to use a modified encoding call that // didn't include the name at all. // int replace_name(struct ccn_charbuf* dest, unsigned char* src, size_t src_size, struct ccn_charbuf* name) { struct ccn_parsed_ContentObject* pco = (struct ccn_parsed_ContentObject*) calloc(sizeof(struct ccn_parsed_ContentObject), 1); int res = 0; res = ccn_parse_ContentObject(src,src_size, pco, NULL); if (res < 0) { free(pco); return (res); } ccn_charbuf_append_tt(dest, CCN_DTAG_ContentObject, CCN_DTAG); ccn_charbuf_append(dest, &src[pco->offset[CCN_PCO_B_Signature]], pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature]); ccn_charbuf_append_charbuf(dest, name); // Already tagged ccn_charbuf_append(dest, &src[pco->offset[CCN_PCO_B_SignedInfo]], pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo]); ccnb_append_tagged_blob(dest, CCN_DTAG_Content, NULL, 0); ccn_charbuf_append_closer(dest); free(pco); return (0); }
int ccnb_append_strategy_selection(struct ccn_charbuf *c, const struct ccn_strategy_selection *ss) { int ch; int i; int len; int res; res = ccnb_element_begin(c, CCN_DTAG_StrategySelection); if (ss->action != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Action, "%s", ss->action); if (ss->name_prefix != NULL && ss->name_prefix->length > 0) res |= ccn_charbuf_append(c, ss->name_prefix->buf, ss->name_prefix->length); if (ss->ccnd_id_size != 0) res |= ccnb_append_tagged_blob(c, CCN_DTAG_PublisherPublicKeyDigest, ss->ccnd_id, ss->ccnd_id_size); if (ss->strategyid != NULL) { len = strlen(ss->strategyid); for (i = 0; i < len; i++) { ch = ss->strategyid[i]; if (!(('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z') || ('0' <= ch && ch <= '9') || (ch == '_'))) res |= -1; } if (len > 0) { res |= ccnb_tagged_putf(c, CCN_DTAG_StrategyID, "%.15s", ss->strategyid); if (len >= STRATEGY_ID_MAX_SIZE) res |= -1; } } if (ss->parameters != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_StrategyParameters, "%s", ss->parameters); if (ss->lifetime >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_FreshnessSeconds, "%d", ss->lifetime); res |= ccnb_element_end(c); return(res); }
/** * Marshal an internal face instance representation into ccnb form */ int ccnb_append_face_instance(struct ccn_charbuf *c, const struct ccn_face_instance *fi) { int res; res = ccnb_element_begin(c, CCN_DTAG_FaceInstance); if (fi->action != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Action, "%s", fi->action); if (fi->ccnd_id_size != 0) res |= ccnb_append_tagged_blob(c, CCN_DTAG_PublisherPublicKeyDigest, fi->ccnd_id, fi->ccnd_id_size); if (fi->faceid != ~0) res |= ccnb_tagged_putf(c, CCN_DTAG_FaceID, "%u", fi->faceid); if (fi->descr.ipproto >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_IPProto, "%d", fi->descr.ipproto); if (fi->descr.address != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Host, "%s", fi->descr.address); if (fi->descr.port != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Port, "%s", fi->descr.port); if (fi->descr.source_address != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_MulticastInterface, "%s", fi->descr.source_address); if (fi->descr.mcast_ttl >= 0 && fi->descr.mcast_ttl != 1) res |= ccnb_tagged_putf(c, CCN_DTAG_MulticastTTL, "%d", fi->descr.mcast_ttl); if (fi->lifetime >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_FreshnessSeconds, "%d", fi->lifetime); res |= ccnb_element_end(c); return(res); }
/** * Encode and sign a ContentObject. * @param buf is the output buffer where encoded object is written. * @param Name is the ccnb-encoded name from ccn_name_init and friends. * @param SignedInfo is the ccnb-encoded info from ccn_signed_info_create. * @param data pintes to the raw data to be encoded. * @param size is the size, in bytes, of the raw data to be encoded. * @param digest_algorithm may be NULL for default. * @param private_key is the private key to use for signing. * @returns 0 for success or -1 for error. */ int ccn_encode_ContentObject(struct ccn_charbuf *buf, const struct ccn_charbuf *Name, const struct ccn_charbuf *SignedInfo, const void *data, size_t size, const char *digest_algorithm, const struct ccn_pkey *private_key ) { int res = 0; struct ccn_sigc *sig_ctx; struct ccn_signature *signature; size_t signature_size; struct ccn_charbuf *content_header; size_t closer_start; content_header = ccn_charbuf_create(); res |= ccn_charbuf_append_tt(content_header, CCN_DTAG_Content, CCN_DTAG); if (size != 0) res |= ccn_charbuf_append_tt(content_header, size, CCN_BLOB); closer_start = content_header->length; res |= ccn_charbuf_append_closer(content_header); if (res < 0) return(-1); sig_ctx = ccn_sigc_create(); if (sig_ctx == NULL) return(-1); if (0 != ccn_sigc_init(sig_ctx, digest_algorithm, private_key)) return(-1); if (0 != ccn_sigc_update(sig_ctx, Name->buf, Name->length)) return(-1); if (0 != ccn_sigc_update(sig_ctx, SignedInfo->buf, SignedInfo->length)) return(-1); if (0 != ccn_sigc_update(sig_ctx, content_header->buf, closer_start)) return(-1); if (0 != ccn_sigc_update(sig_ctx, data, size)) return(-1); if (0 != ccn_sigc_update(sig_ctx, content_header->buf + closer_start, content_header->length - closer_start)) return(-1); signature = calloc(1, ccn_sigc_signature_max_size(sig_ctx, private_key)); if (signature == NULL) return(-1); res = ccn_sigc_final(sig_ctx, signature, &signature_size, private_key); if (0 != res) { free(signature); return(-1); } ccn_sigc_destroy(&sig_ctx); res |= ccn_charbuf_append_tt(buf, CCN_DTAG_ContentObject, CCN_DTAG); res |= ccn_encode_Signature(buf, digest_algorithm, NULL, 0, signature, signature_size); res |= ccn_charbuf_append_charbuf(buf, Name); res |= ccn_charbuf_append_charbuf(buf, SignedInfo); res |= ccnb_append_tagged_blob(buf, CCN_DTAG_Content, data, size); res |= ccn_charbuf_append_closer(buf); free(signature); ccn_charbuf_destroy(&content_header); return(res == 0 ? 0 : -1); }
static PyObject * Interest_obj_to_ccn(PyObject *py_obj_Interest) { struct ccn_charbuf *interest; PyObject *py_interest, *py_o; int r; py_interest = CCNObject_New_charbuf(INTEREST, &interest); if (!py_interest) return NULL; r = ccn_charbuf_append_tt(interest, CCN_DTAG_Interest, CCN_DTAG); JUMP_IF_NEG_MEM(r, error); /* Name */ { struct ccn_charbuf *name; PyObject *py_name; r = is_attr_set(py_obj_Interest, "name", &py_o); JUMP_IF_NEG(r, error); if (r) { py_name = Name_obj_to_ccn(py_o); Py_DECREF(py_o); JUMP_IF_NULL(py_name, error); name = CCNObject_Get(NAME, py_name); r = ccn_charbuf_append_charbuf(interest, name); Py_DECREF(py_name); JUMP_IF_NEG_MEM(r, error); } else { // Even though Name is mandatory we still use this code to generate // templates, so it is ok if name is not given, the code below // creates an empty tag r = ccn_charbuf_append_tt(interest, CCN_DTAG_Name, CCN_DTAG); JUMP_IF_NEG(r, error); r = ccn_charbuf_append_closer(interest); /* </Name> */ JUMP_IF_NEG(r, error); } } r = process_int_attribute(interest, CCN_DTAG_MinSuffixComponents, py_obj_Interest, "minSuffixComponents"); JUMP_IF_NEG(r, error); r = process_int_attribute(interest, CCN_DTAG_MaxSuffixComponents, py_obj_Interest, "maxSuffixComponents"); JUMP_IF_NEG(r, error); r = is_attr_set(py_obj_Interest, "publisherPublicKeyDigest", &py_o); JUMP_IF_NEG(r, error); if (r) { const char *blob; Py_ssize_t blobsize; blob = PyBytes_AsString(py_o); if (!blob) { Py_DECREF(py_o); goto error; } blobsize = PyBytes_GET_SIZE(py_o); r = ccnb_append_tagged_blob(interest, CCN_DTAG_PublisherPublicKeyDigest, blob, blobsize); Py_DECREF(py_o); JUMP_IF_NEG_MEM(r, error); } r = is_attr_set(py_obj_Interest, "exclude", &py_o); JUMP_IF_NEG(r, error); if (r) { PyObject *py_exclusions; struct ccn_charbuf *exclusion_filter; if (!PyObject_IsInstance(py_o, g_type_ExclusionFilter)) { Py_DECREF(py_o); PyErr_SetString(PyExc_TypeError, "Expected ExclusionFilter"); goto error; } r = is_attr_set(py_o, "ccn_data", &py_exclusions); Py_DECREF(py_o); JUMP_IF_NEG(r, error); exclusion_filter = CCNObject_Get(EXCLUSION_FILTER, py_exclusions); r = ccn_charbuf_append_charbuf(interest, exclusion_filter); Py_DECREF(py_exclusions); JUMP_IF_NEG(r, error); } r = process_int_attribute(interest, CCN_DTAG_ChildSelector, py_obj_Interest, "childSelector"); JUMP_IF_NEG(r, error); r = process_int_attribute(interest, CCN_DTAG_AnswerOriginKind, py_obj_Interest, "answerOriginKind"); JUMP_IF_NEG(r, error); r = process_int_attribute(interest, CCN_DTAG_Scope, py_obj_Interest, "scope"); JUMP_IF_NEG(r, error); r = is_attr_set(py_obj_Interest, "interestLifetime", &py_o); if (r) { unsigned char buf[3] = {0}; double lifetime; unsigned long i_lifetime; if (!PyFloat_Check(py_o)) { Py_DECREF(py_o); PyErr_SetString(PyExc_TypeError, "expected float type in interest" " lifetime"); goto error; } lifetime = PyFloat_AS_DOUBLE(py_o); Py_DECREF(py_o); i_lifetime = lifetime * 4096; /* XXX: probably won't work in bigendian */ for (int i = sizeof(buf) - 1; i >= 0; i--, i_lifetime >>= 8) buf[i] = i_lifetime & 0xff; r = ccnb_append_tagged_blob(interest, CCN_DTAG_InterestLifetime, buf, sizeof(buf)); JUMP_IF_NEG_MEM(r, error); } r = is_attr_set(py_obj_Interest, "nonce", &py_o); if (r) { char *s; Py_ssize_t len; r = PyBytes_AsStringAndSize(py_o, &s, &len); if (r < 0) { Py_DECREF(py_o); goto error; } r = ccnb_append_tagged_blob(interest, CCN_DTAG_Nonce, s, len); Py_DECREF(py_o); JUMP_IF_NEG_MEM(r, error); } r = ccn_charbuf_append_closer(interest); /* </Interest> */ JUMP_IF_NEG_MEM(r, error); return py_interest; error: Py_DECREF(py_interest); return NULL; }
int main(int argc, char **argv) { struct ccn *h = NULL; struct ccn_charbuf *name = NULL; struct ccn_charbuf *templ = NULL; struct ccn_charbuf *resultbuf = NULL; const char *arg = NULL; struct ccn_parsed_ContentObject pcobuf = { 0 }; int res; char ch; int allow_stale = 0; int content_only = 0; const unsigned char *ptr; size_t length; int resolve_version = 0; const char *env_timeout = getenv("CCN_LINGER"); int timeout_ms = 3000; while ((ch = getopt(argc, argv, "hacv")) != -1) { switch (ch) { case 'a': allow_stale = 1; break; case 'c': content_only = 1; break; case 'v': if (resolve_version == 0) resolve_version = CCN_V_HIGHEST; else resolve_version = CCN_V_HIGH; break; case 'h': default: usage(argv[0]); } } arg = argv[optind]; if (arg == NULL) usage(argv[0]); name = ccn_charbuf_create(); res = ccn_name_from_uri(name, arg); if (res < 0) { fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], arg); exit(1); } if (argv[optind + 1] != NULL) fprintf(stderr, "%s warning: extra arguments ignored\n", argv[0]); h = ccn_create(); res = ccn_connect(h, NULL); if (res < 0) { ccn_perror(h, "ccn_connect"); exit(1); } if (res < 0) { fprintf(stderr, "%s: bad ccn URI: %s\n", argv[0], arg); exit(1); } if (env_timeout != NULL && (res = atoi(env_timeout)) > 0) { timeout_ms = res * 1000; } if (allow_stale || env_timeout != NULL) { 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> */ if (allow_stale) { ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG); ccnb_append_number(templ, CCN_AOK_DEFAULT | CCN_AOK_STALE); ccn_charbuf_append_closer(templ); /* </AnswerOriginKind> */ } if (env_timeout != NULL) { /* * Choose the interest lifetime so there are at least 3 * expressions (in the unsatisfied case). */ unsigned char buf[3] = { 0 }; unsigned lifetime; int i; if (timeout_ms > 60000) lifetime = 30 << 12; else { lifetime = timeout_ms * 2 / 5 * 4096 / 1000; } for (i = sizeof(buf) - 1; i >= 0; i--, lifetime >>= 8) buf[i] = lifetime & 0xff; ccnb_append_tagged_blob(templ, CCN_DTAG_InterestLifetime, buf, sizeof(buf)); }
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); }