示例#1
0
/**
 * Insert a ContentObject into a btree node
 *
 * The caller has presumably already done a lookup and found that the
 * object is not there.
 *
 * The caller is responsible for provinding a valid content parse (pc).
 *
 * The flatname buffer should hold the correct full name, including the
 * digest.
 *
 * @returns the new entry count or, -1 for error.
 */
int
ccn_btree_insert_content(struct ccn_btree_node *node, int ndx,
                         uint_least64_t cobid,
                         const unsigned char *content_object,
                         struct ccn_parsed_ContentObject *pc,
                         struct ccn_charbuf *flatname)
{
    struct ccn_btree_content_payload payload;
    struct ccn_btree_content_payload *e = &payload;
    int ncomp;
    int res;
    unsigned size;
    unsigned flags = 0;
    const unsigned char *blob = NULL;
    size_t blob_size = 0;
    
    size = pc->offset[CCN_PCO_E];
    ncomp = ccn_flatname_ncomps(flatname->buf, flatname->length);
    if (ncomp != pc->name_ncomps + 1)
        return(-1);
    memset(e, 'U', sizeof(*e));
    MYSTORE(e, magic, CCN_BT_CONTENT_MAGIC);
    MYSTORE(e, ctype, pc->type);
    MYSTORE(e, cobsz, size);
    MYSTORE(e, ncomp, ncomp);
    MYSTORE(e, flags, flags); // XXX - need to set CCN_RCFLAG_LASTBLOCK
    MYSTORE(e, ttpad, 0);
    MYSTORE(e, timex, 0);
    res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, content_object,
                              pc->offset[CCN_PCO_B_Timestamp],
                              pc->offset[CCN_PCO_E_Timestamp],
                              &blob, &blob_size);
    if (res < 0 || blob_size > sizeof(e->timex))
        return(-1);
    memcpy(e->timex + sizeof(e->timex) - blob_size, blob, blob_size);
    // XXX - need to set accession time. Should we pass it in?
    MYSTORE64(e, cobid, cobid);
    res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, content_object,
                              pc->offset[CCN_PCO_B_PublisherPublicKeyDigest],
                              pc->offset[CCN_PCO_E_PublisherPublicKeyDigest],
                              &blob, &blob_size);
    if (res < 0 || blob_size != sizeof(e->ppkdg))
        return(-1);
    memcpy(e->ppkdg, blob, sizeof(e->ppkdg));
    /* Now actually do the insert */
    res = ccn_btree_insert_entry(node, ndx,
                                 flatname->buf, flatname->length,
                                 e, sizeof(*e));
    return(res);
}
示例#2
0
文件: pco.cpp 项目: bruinfish/ndn.cxx
HashPtr
ParsedContentObject::publisherPublicKeyDigest() const
{
  const unsigned char *buf = NULL;
  size_t size = 0;
  ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, head(m_bytes), m_pco.offset[CCN_PCO_B_PublisherPublicKeyDigest], m_pco.offset[CCN_PCO_E_PublisherPublicKeyDigest], &buf, &size);

  return boost::make_shared<Hash>(buf, size);
}
示例#3
0
int
ccn_content_get_value(const unsigned char *data, size_t data_size,
                      const struct ccn_parsed_ContentObject *content,
                      const unsigned char **value, size_t *value_size)
{
    int res;
    res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, data,
          content->offset[CCN_PCO_B_Content],
          content->offset[CCN_PCO_E_Content],
          value, value_size);
    return(res);
}
示例#4
0
void NdnMediaProcess::initPipe(struct ccn_closure *selfp, struct ccn_upcall_info *info, UserDataBuf *userBuf) {
	fprintf(stderr, "initializing pipe\n");
	// get seq
	const unsigned char *ccnb = info->content_ccnb;
	size_t ccnb_size = info->pco->offset[CCN_PCO_E];
	struct ccn_indexbuf *comps = info->content_comps;

	long seq;
	const unsigned char *seqptr = NULL;
	char *endptr = NULL;
	size_t seq_size = 0;
	int k = comps->n - 2;

	if (userBuf->seq < 0) {
		seq = ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb,
				comps->buf[k], comps->buf[k + 1],
				&seqptr, &seq_size);
		if (seq >= 0) {
			seq = strtol((const char *)seqptr, &endptr, 10);
			if (endptr != ((const char *)seqptr) + seq_size)
				seq = -1;
		}
		if (seq >= 0) {
			userBuf->seq = seq;
		}
		else {
			return;
		}
	}	
	
	fprintf(stderr, "fetched content with seq %d\n", seq);
	// send hint-ahead interests
	for (int i = 0; i < hint_ahead; i ++) {
		userBuf->seq++;
		struct ccn_charbuf *pathbuf = ccn_charbuf_create();
		ccn_name_init(pathbuf);
		ccn_name_append_components(pathbuf, ccnb, comps->buf[0], comps->buf[k]);
		struct ccn_charbuf *temp = ccn_charbuf_create();
		ccn_charbuf_putf(temp, "%ld", userBuf->seq);
		ccn_name_append(pathbuf, temp->buf, temp->length);
		
		// no need to trylock as we already have the lock
		// this should use  pipe callback, selfp is normal callback
		int res = ccn_express_interest(info->h, pathbuf, userBuf->data_buf.pipe_callback, NULL);
		if (res < 0) {
			fprintf(stderr, "Sending interest failed at normal processor\n");
			std::exit(1);
		}
		ccn_charbuf_destroy(&pathbuf);
		ccn_charbuf_destroy(&temp);
	}
}
示例#5
0
文件: CcnClient.c 项目: ltr120/NDNFD
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);
}
示例#6
0
文件: ccnd_msg.c 项目: wjz/ccnx
/**
 *  Produce a ccnd debug trace entry.
 *  Output is produced by calling ccnd_msg.
 *  @param      h  the ccnd handle
 *  @param      lineno  caller's source line number (usually __LINE__)
 *  @param      msg  a short text tag to identify the entry
 *  @param      face    handle of associated face; may be NULL
 *  @param      ccnb    points to ccnb-encoded Interest or ContentObject
 *  @param      ccnb_size   is in bytes
 */
void
ccnd_debug_ccnb(struct ccnd_handle *h,
                int lineno,
                const char *msg,
                struct face *face,
                const unsigned char *ccnb,
                size_t ccnb_size)
{
    struct ccn_charbuf *c;
    struct ccn_parsed_interest pi;
    const unsigned char *nonce = NULL;
    size_t nonce_size = 0;
    size_t i;
    
    
    if (h != NULL && h->debug == 0)
        return;
    c = ccn_charbuf_create();
    ccn_charbuf_putf(c, "debug.%d %s ", lineno, msg);
    if (face != NULL)
        ccn_charbuf_putf(c, "%u ", face->faceid);
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    ccn_charbuf_putf(c, " (%u bytes)", (unsigned)ccnb_size);
    if (ccn_parse_interest(ccnb, ccnb_size, &pi, NULL) >= 0) {
        const char *p = "";
        ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb,
                  pi.offset[CCN_PI_B_Nonce],
                  pi.offset[CCN_PI_E_Nonce],
                  &nonce,
                  &nonce_size);
        if (nonce_size > 0) {
            ccn_charbuf_putf(c, " ");
            if (nonce_size == 12)
                p = "CCC-P-F-T-NN";
            for (i = 0; i < nonce_size; i++)
                ccn_charbuf_putf(c, "%s%02X", (*p) && (*p++)=='-' ? "-" : "", nonce[i]);
        }
    }
    ccnd_msg(h, "%s", ccn_charbuf_as_string(c));
    ccn_charbuf_destroy(&c);
}
示例#7
0
文件: ccnr_store.c 项目: Emat12/ccnx
PUBLIC int
r_store_content_field_access(struct ccnr_handle *h,
                             struct content_entry *content,
                             enum ccn_dtag dtag,
                             const unsigned char **bufp, size_t *sizep)
{
    int res = -1;
    const unsigned char *content_msg;
    struct ccn_parsed_ContentObject pco = {0};
    
    content_msg = r_store_content_base(h, content);
    if (content_msg == NULL)
        return(-1);
    res = ccn_parse_ContentObject(content_msg, content->size, &pco, NULL);
    if (res < 0)
        return(-1);
    if (dtag == CCN_DTAG_Content)
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, content_msg,
                                  pco.offset[CCN_PCO_B_Content],
                                  pco.offset[CCN_PCO_E_Content],
                                  bufp, sizep);
    return(res);
}
示例#8
0
static seg_t
GetNumberFromInfo(const unsigned char *ccnb,
				  enum ccn_dtag tt, size_t start, size_t stop) {
	// gets the binary number for the info
	// based on the tag and the start and stop indexes
	// returns -1 if the number does not appear to exist
	// must be called from inside of CallMe
	if (start < stop) {
		size_t len = 0;
		const unsigned char *data = NULL;
		ccn_ref_tagged_BLOB(tt, ccnb, start, stop, &data, &len);
		if (len > 0 && data != NULL) {
			// parse big-endian encoded number
			seg_t n = 0;
			size_t i;
            for (i = 0; i < len; i++) {
				n = n * 256 + data[i];
			}
			return n;
		}
	}
	return -1;
}
示例#9
0
/**
 *
 * 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);
}
示例#10
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);
}
示例#11
0
/**
 * Handle the incoming content messages. Extracts the data, and
 * requests the next block in sequence if the received block was
 * not the final one.
 */
enum ccn_upcall_res
incoming_content(struct ccn_closure *selfp,
                 enum ccn_upcall_kind kind,
                 struct ccn_upcall_info *info)
{
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *templ = NULL;
    const unsigned char *ccnb = NULL;
    size_t ccnb_size = 0;
    const unsigned char *data = NULL;
    size_t data_size = 0;
    size_t written;
    const unsigned char *ib = NULL; /* info->interest_ccnb */
    struct ccn_indexbuf *ic = NULL;
    int res;
    struct mydata *md = selfp->data;
    
    if (kind == CCN_UPCALL_FINAL) {
        if (md != NULL) {
            selfp->data = NULL;
            free(md);
            md = NULL;
        }
        return(CCN_UPCALL_RESULT_OK);
    }
    if (kind == CCN_UPCALL_INTEREST_TIMED_OUT)
        return(CCN_UPCALL_RESULT_REEXPRESS);
    if (kind == CCN_UPCALL_CONTENT_UNVERIFIED)
        return(CCN_UPCALL_RESULT_VERIFY);
    if (kind != CCN_UPCALL_CONTENT)
        return(CCN_UPCALL_RESULT_ERR);
    if (md == NULL)
        selfp->data = md = calloc(1, sizeof(*md));
    ccnb = info->content_ccnb;
    ccnb_size = info->pco->offset[CCN_PCO_E];
    ib = info->interest_ccnb;
    ic = info->interest_comps;
    res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &data, &data_size);
    if (res < 0) abort();
    if (info->pco->type != CCN_CONTENT_DATA) {
        /* For us this is spam. For now, give up. */
        fprintf(stderr, "*** spammed at block %d\n", (int)selfp->intdata);
        exit(1);
    }
    
    /* OK, we will accept this block. */
    if (data_size == 0)
        *(md->done) = 1;
    else {
        written = fwrite(data, data_size, 1, stdout);
        if (written != 1)
            exit(1);
    }
    // XXX The test below should get refactored into the library
    if (info->pco->offset[CCN_PCO_B_FinalBlockID] !=
        info->pco->offset[CCN_PCO_E_FinalBlockID]) {
        const unsigned char *finalid = NULL;
        size_t finalid_size = 0;
        const unsigned char *nameid = NULL;
        size_t nameid_size = 0;
        struct ccn_indexbuf *cc = info->content_comps;
        ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb,
                            info->pco->offset[CCN_PCO_B_FinalBlockID],
                            info->pco->offset[CCN_PCO_E_FinalBlockID],
                            &finalid,
                            &finalid_size);
        if (cc->n < 2) abort();
        ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb,
                            cc->buf[cc->n - 2],
                            cc->buf[cc->n - 1],
                            &nameid,
                            &nameid_size);
        if (finalid_size == nameid_size &&
              0 == memcmp(finalid, nameid, nameid_size))
            *(md->done) = 1;
    }
    
    if (*(md->done)) {
        ccn_set_run_timeout(info->h, 0);
        return(CCN_UPCALL_RESULT_OK);
    }
    
    /* Ask for the next fragment */
    name = ccn_charbuf_create();
    ccn_name_init(name);
    if (ic->n < 2) abort();
    res = ccn_name_append_components(name, ib, ic->buf[0], ic->buf[ic->n - 2]);
    if (res < 0) abort();
    ccn_name_append_numeric(name, CCN_MARKER_SEQNUM, ++(selfp->intdata));
    templ = make_template(md, info);
    
    res = ccn_express_interest(info->h, name, selfp, templ);
    if (res < 0) abort();
    
    ccn_charbuf_destroy(&templ);
    ccn_charbuf_destroy(&name);
    
    return(CCN_UPCALL_RESULT_OK);
}
示例#12
0
文件: packet-ccn.c 项目: futtre/ccnx
static int
dissect_ccn_contentobject(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *signature_tree;
    proto_tree *name_tree;
    proto_tree *signedinfo_tree;
    proto_tree *content_tree;
    proto_item *titem;
    struct ccn_parsed_ContentObject co;
    struct ccn_parsed_ContentObject *pco = &co;
    struct ccn_charbuf *c;
    struct ccn_indexbuf *comps;
    const unsigned char *comp;
    size_t comp_size;
    size_t blob_size;
    const unsigned char *blob;
    int l;
    unsigned int i;
    double dt;
    nstime_t timestamp;
    int res;

    comps = ccn_indexbuf_create();
    res = ccn_parse_ContentObject(ccnb, ccnb_size, pco, comps);
    if (res < 0) return (-1);

    /* Signature */
    l = pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature];
    titem = proto_tree_add_item(tree, hf_ccn_signature, tvb, pco->offset[CCN_PCO_B_Signature], l, FALSE);
    signature_tree = proto_item_add_subtree(titem, ett_signature);

    /* DigestAlgorithm */
    l = pco->offset[CCN_PCO_E_DigestAlgorithm] - pco->offset[CCN_PCO_B_DigestAlgorithm];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, ccnb,
                                  pco->offset[CCN_PCO_B_DigestAlgorithm],
                                  pco->offset[CCN_PCO_E_DigestAlgorithm],
                                  &blob, &blob_size);
        titem = proto_tree_add_item(signature_tree, hf_ccn_signaturedigestalg, tvb,
                                    blob - ccnb, blob_size, FALSE);
    }
    /* Witness */
    l = pco->offset[CCN_PCO_E_Witness] - pco->offset[CCN_PCO_B_Witness];
    if (l > 0) {
        /* add the witness item to the signature tree */
    }

    /* Signature bits */
    l = pco->offset[CCN_PCO_E_SignatureBits] - pco->offset[CCN_PCO_B_SignatureBits];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, ccnb,
                                  pco->offset[CCN_PCO_B_SignatureBits],
                                  pco->offset[CCN_PCO_E_SignatureBits],
                                  &blob, &blob_size);
        titem = proto_tree_add_bytes(signature_tree, hf_ccn_signaturebits, tvb,
                                     blob - ccnb, blob_size, blob);
    }

    /* /Signature */

    /* Name */
    l = pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name];
    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    titem = proto_tree_add_string(tree, hf_ccn_name, tvb,
                                      pco->offset[CCN_PCO_B_Name], l,
                                      ccn_charbuf_as_string(c));
    name_tree = proto_item_add_subtree(titem, ett_name);
    ccn_charbuf_destroy(&c);

    /* Name Components */
    for (i = 0; i < comps->n - 1; i++) {
        res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size);
        titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE);
    }

    /* /Name */

    /* SignedInfo */
    l = pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo];
    titem = proto_tree_add_text(tree, tvb,
                                         pco->offset[CCN_PCO_B_SignedInfo], l,
                                         "SignedInfo");
    signedinfo_tree = proto_item_add_subtree(titem, ett_signedinfo);

    /* PublisherPublicKeyDigest */
    l = pco->offset[CCN_PCO_E_PublisherPublicKeyDigest] - pco->offset[CCN_PCO_B_PublisherPublicKeyDigest];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, ccnb,
                                  pco->offset[CCN_PCO_B_PublisherPublicKeyDigest],
                                  pco->offset[CCN_PCO_E_PublisherPublicKeyDigest],
                                  &blob, &blob_size);
        titem = proto_tree_add_bytes(signedinfo_tree, hf_ccn_publisherpublickeydigest, tvb, blob - ccnb, blob_size, blob);
    }

    /* Timestamp */
    l = pco->offset[CCN_PCO_E_Timestamp] - pco->offset[CCN_PCO_B_Timestamp];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, ccnb,
                                  pco->offset[CCN_PCO_B_Timestamp],
                                  pco->offset[CCN_PCO_E_Timestamp],
                                  &blob, &blob_size);
        dt = 0.0;
        for (i = 0; i < blob_size; i++)
            dt = dt * 256.0 + (double)blob[i];
        dt /= 4096.0;
        timestamp.secs = dt; /* truncates */
        timestamp.nsecs = (dt - (double) timestamp.secs) *  1000000000.0;
        titem = proto_tree_add_time(signedinfo_tree, hf_ccn_timestamp, tvb, blob - ccnb, blob_size, &timestamp);
    }

    /* Type */
    l = pco->offset[CCN_PCO_E_Type] - pco->offset[CCN_PCO_B_Type];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Type, ccnb,
                                  pco->offset[CCN_PCO_B_Type],
                                  pco->offset[CCN_PCO_E_Type],
                                  &blob, &blob_size);
        titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, tvb, blob - ccnb, blob_size, pco->type);
    } else {
        titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, NULL, 0, 0, pco->type);
    }

    /* FreshnessSeconds */
    l = pco->offset[CCN_PCO_E_FreshnessSeconds] - pco->offset[CCN_PCO_B_FreshnessSeconds];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_FreshnessSeconds, ccnb,
                                  pco->offset[CCN_PCO_B_FreshnessSeconds],
                                  pco->offset[CCN_PCO_E_FreshnessSeconds],
                                  &blob, &blob_size);
        i = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_FreshnessSeconds, ccnb,
                                                  pco->offset[CCN_PCO_B_FreshnessSeconds],
                                                  pco->offset[CCN_PCO_E_FreshnessSeconds]);

        titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_freshnessseconds, tvb, blob - ccnb, blob_size, i);
    }

    /* FinalBlockID */
    l = pco->offset[CCN_PCO_E_FinalBlockID] - pco->offset[CCN_PCO_B_FinalBlockID];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb,
                                  pco->offset[CCN_PCO_B_FinalBlockID],
                                  pco->offset[CCN_PCO_E_FinalBlockID],
                                  &blob, &blob_size);

        titem = proto_tree_add_item(signedinfo_tree, hf_ccn_finalblockid, tvb, blob - ccnb, blob_size, FALSE);
    }
    /* TODO: KeyLocator */
    /* /SignedInfo */

    /* Content */
    l = pco->offset[CCN_PCO_E_Content] - pco->offset[CCN_PCO_B_Content];
    res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnb,
                                  pco->offset[CCN_PCO_B_Content],
                                  pco->offset[CCN_PCO_E_Content],
                                  &blob, &blob_size);
    titem = proto_tree_add_text(tree, tvb,
                                         pco->offset[CCN_PCO_B_Content], l,
                                         "Content: %d bytes", blob_size);
    if (blob_size > 0) {
        content_tree = proto_item_add_subtree(titem, ett_content);
        titem = proto_tree_add_item(content_tree, hf_ccn_contentdata, tvb, blob - ccnb, blob_size, FALSE);
    }

    return (ccnb_size);
}
示例#13
0
/* does that mean the last component is the implicit digest ? */
enum ccn_upcall_res
packet_handler(struct ccn_closure *selfp,
                 enum ccn_upcall_kind upcall_kind,
                 struct ccn_upcall_info *info)
{
	handler_data* h_data = (handler_data*) selfp->data; // Client data returned

	fprintf(stderr, "\nUpcall from %s handle\n", (info->h==(*h_data->ccn_rec))? "receiver":"publisher");
	ccn_set_run_timeout(info->h, 0); // Return to client faster

    switch(upcall_kind) {
    case CCN_UPCALL_FINAL:
        fprintf(stderr, "CCN_UPCALL_FINAL\n");
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_INTEREST_TIMED_OUT:
        fprintf(stderr, "CCN_UPCALL_INTEREST_TIMED_OUT\n");
        (*h_data->complete) = 1; 	      // End the main loop, some sort of problem
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_CONTENT:
        fprintf(stderr, "CCN_UPCALL_CONTENT\n");
        const unsigned char* content = NULL;
        size_t content_bytes = 0;
        ccn_ref_tagged_BLOB(CCN_DTAG_Content, info->content_ccnb,
							  info->pco->offset[CCN_PCO_B_Content],
							  info->pco->offset[CCN_PCO_E_Content],
							  &content, &content_bytes);
        fprintf(stderr, "\tContent: %s\n", content);
        (*h_data->outstanding_interests)--;
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_CONTENT_UNVERIFIED:
        fprintf(stderr, "CCN_UPCALL_CONTENT_UNVERIFIED\n");
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_CONTENT_BAD:
        fprintf(stderr, "CCN_UPCALL_CONTENT_BAD\n");
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_CONSUMED_INTEREST:
        fprintf(stderr, "CCN_UPCALL_CONSUMED_INTEREST\n");
        return (CCN_UPCALL_RESULT_OK);
    case CCN_UPCALL_INTEREST:
    	fprintf(stderr, "CCN_UPCALL_INTEREST, (matched comp  == %d)\n", info->matched_comps);
    	fprintf(stderr, "                     (interest comps == %zu)\n", info->interest_comps->n);
    	int res = 0;

    	// Corrected 20-May-2011 to support interests with additional components after prefix
    	//
    	if (info->interest_comps->n < 3) {	// Name + signature + implicit digest, minimum
    		fprintf(stderr, "\tnot enough components, %zu<3\n", info->interest_comps->n);
    	} else {
    	// Verify the interest
			res = verify_signed_interest(info->interest_ccnb, info->interest_comps,
										 info->interest_comps->n-2, info->interest_comps->buf[0], info->interest_comps->buf[info->interest_comps->n-2],
										   (*h_data->public_key));
			fprintf(stderr, "\tverify_signed_interest == %d (%s)\n", res, (res==1)?"verified":"unverified");
    	}
		// Based on the results,
		// create and send a reply using default key & algorithm for the receiving handle
		// to sign the content object.
		//
		char* reply_data = (res==1) ? "OK" : "AUTH_FAIL";	// A modest content.
		struct ccn_charbuf* reply = ccn_charbuf_create();
		struct ccn_charbuf* name = ccn_charbuf_create();
		struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
	    ccn_name_init(name); // Don't need to create a new name, could just index into the buffer.
	    res = ccn_name_append_components(name, info->interest_ccnb,
	    					info->interest_comps->buf[0], info->interest_comps->buf[info->interest_comps->n - 1]);
		ccn_sign_content(info->h, reply, name, &sp, (void*)reply_data, strlen(reply_data)+1);
		res = ccn_put(info->h, reply->buf, reply->length);
		ccn_charbuf_destroy(&reply);
		ccn_charbuf_destroy(&name);
		if (res >= 0) {
			fprintf (stderr, "\tReturned Content: %s\n", reply_data);
			return (CCN_UPCALL_RESULT_INTEREST_CONSUMED);
		}
        return (CCN_UPCALL_RESULT_OK);
    }
    return (CCN_UPCALL_RESULT_ERR);
}
示例#14
0
enum ccn_upcall_res
ccn_text_handler(struct ccn_closure *selfp,
		    enum ccn_upcall_kind kind,
		    struct ccn_upcall_info *info)
{
    UserDataBuf *userBuf  = (UserDataBuf *)selfp->data;
    if (userBuf == NULL || userBuf->iNeedDestroy) {
        //if (userBuf != NULL) delete userBuf;
        //selfp->data = NULL;
        return CCN_UPCALL_RESULT_OK;
    }

	switch (kind) {
	case CCN_UPCALL_INTEREST_TIMED_OUT: {
		// if it's short Interest without seq, reexpress
		// TODO: check whether the user is still in the conference
		//	     don't re-express if it is not
		return (CCN_UPCALL_RESULT_REEXPRESS);
	}
	case CCN_UPCALL_CONTENT_UNVERIFIED:
		fprintf(stderr, "unverified content received\n");
		return CCN_UPCALL_RESULT_OK;
	case CCN_UPCALL_FINAL:
        return CCN_UPCALL_RESULT_OK;
	case CCN_UPCALL_CONTENT:
		break;
	default:
		return CCN_UPCALL_RESULT_OK;

	}

    struct data_buffer *buffer = &userBuf->data_buf;
    const unsigned char *content_value;
	size_t len;
    NDNState *state = buffer->state;

	const unsigned char *ccnb = info->content_ccnb;
	size_t ccnb_size = info->pco->offset[CCN_PCO_E];
	struct ccn_indexbuf *comps = info->content_comps;

	ccn_content_get_value(ccnb, ccnb_size, info->pco,
			&content_value, &len);

	unsigned char *msg = (unsigned char *)calloc((len + 1), sizeof(char));
	memcpy(msg, content_value, len);
	msg[len] = '\0';
	QString textMsg = (const char *)msg;
	state->emitTextMsgArrival(userBuf->user_name, textMsg);
	free(msg);

	long seq;
	const unsigned char *seqptr = NULL;
	char *endptr = NULL;
	size_t seq_size = 0;
	int k = comps->n - 2;

	seq = ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb,
			comps->buf[k], comps->buf[k + 1],
			&seqptr, &seq_size);
	if (seq >= 0) {
		seq = strtol((const char *)seqptr, &endptr, 10);
		if (endptr != ((const char *)seqptr) + seq_size)
			seq = -1;
	}
	if (seq < 0) {
		return CCN_UPCALL_RESULT_OK;
	}

	seq++;

	struct ccn_charbuf *path = ccn_charbuf_create();
	ccn_name_init(path);
	ccn_name_append_components(path, ccnb, comps->buf[0], comps->buf[k]);
	struct ccn_charbuf *temp = ccn_charbuf_create();
	ccn_charbuf_putf(temp, "%ld", seq);
	ccn_name_append(path, temp->buf, temp->length);
	int res = ccn_express_interest(info->h, path, selfp, NULL);
	if (res < 0) {
		fprintf(stderr, "sending the first interest failed\n");
		exit(1);
	}
	ccn_charbuf_destroy(&path);
	ccn_charbuf_destroy(&temp);

    return CCN_UPCALL_RESULT_OK;
}
示例#15
0
/**
 * Main working loop for stuff coming in from the CCNx network
 *
 * The only kind of content we work with are data messages. They are in response to the
 * interest messages we send out. The work involves 2 pieces: packing the data from ccn message
 * sizes into buffer sizes we use internally, and detecting when the stream of data is done.
 * 
 * The first is fairly simple. Each internal buffer we 'fill' is placed onto the fifo queue
 * so the main thread can take it off and reply to the pipeline request for more data.
 *
 * Determining the end of stream at the moment is a bit of a hack and could use some work.
 * \todo volunteers?  8-)
 *
 * \param	selfp		-> a context structure we created when registering this call-back
 * \param	kind		specifies the type of call-back being processed, see the \b switch statement
 * \param	info		context information about the call-back itself; interests, data, etc.
 * \return a response as to how successful we were in processing the call-back
 * \retval CCN_UPCALL_RESULT_OK		things went well
 * \retval CCN_UPCALL_RESULT_VERIFY	need to verify the contents of what we received
 * \retval CCN_UPCALL_RESULT_REEXPRESS an interest timedout waiting for data, so we try again
 * \retval CCN_UPCALL_RESULT_ERR	some error was encountered
 */
static enum ccn_upcall_res
incoming_content (struct ccn_closure *selfp,
    enum ccn_upcall_kind kind, struct ccn_upcall_info *info)
{
  Gstccnxsrc *me = GST_CCNXSRC (selfp->data);

  const unsigned char *ccnb = NULL;
  size_t ccnb_size = 0;
  const unsigned char *ib = NULL;       /* info->interest_ccnb */
  struct ccn_indexbuf *ic = NULL;
  unsigned int i;
  uintmax_t segment;
  CcnxInterestState *istate = NULL;
  gint res;
  const unsigned char *cp;
  size_t sz;
  const unsigned char *data = NULL;
  size_t data_size = 0;
  gboolean b_last = FALSE;

  GST_INFO ("content has arrived!");

  /* Do some basic sanity and type checks to see if we want to process this data */

  if (CCN_UPCALL_FINAL == kind) {
    GST_LOG_OBJECT (me, "CCN upcall final %p", selfp);
    if (me->i_bufoffset > 0) {
      GST_BUFFER_SIZE (me->buf) = me->i_bufoffset;
      fifo_put (me, me->buf);
      me->buf = gst_buffer_new_and_alloc (CCN_FIFO_BLOCK_SIZE);
      me->i_bufoffset = 0;
    }
/*
 * Should emit an eos here instead of the empty buffer
 */
    GST_BUFFER_SIZE (me->buf) = 0;
    fifo_put (me, me->buf);
    me->i_bufoffset = 0;
    return (CCN_UPCALL_RESULT_OK);
  }

  if (!info)
    return CCN_UPCALL_RESULT_ERR;       // Now why would this happen?

  // show_comps( info->content_ccnb, info->content_comps);

  if (CCN_UPCALL_INTEREST_TIMED_OUT == kind) {
    if (selfp != me->ccn_closure) {
      GST_LOG_OBJECT (me, "CCN Interest timed out on dead closure %p", selfp);
      return (CCN_UPCALL_RESULT_OK);
    }
    segment =
        ccn_ccnb_fetch_segment (info->interest_ccnb, info->interest_comps);
    GST_INFO ("...looks to be for segment: %d", segment);
    GST_LOG_OBJECT (me, "CCN upcall reexpress -- timed out");
    istate = fetchSegmentInterest (me, segment);
    if (istate) {
      if (istate->timeouts > 5) {
        GST_LOG_OBJECT (me, "CCN upcall reexpress -- too many reexpressions");
        if (segment == me->post_seg)    // We have been waiting for this one...process as an empty block to trigger other activity
          process_or_queue (me, me->post_seg, NULL, 0, FALSE);
        else
          freeInterestState (me, istate);
        post_next_interest (me);        // make sure to ask for new stuff if needed, or else we stall waiting for nothing
        return (CCN_UPCALL_RESULT_OK);
      } else {
        istate->timeouts++;
        return (CCN_UPCALL_RESULT_REEXPRESS);
      }
    } else {
      GST_LOG_OBJECT (me, "segment not found in cache: %d", segment);
      return (CCN_UPCALL_RESULT_OK);
    }

  } else if (CCN_UPCALL_CONTENT_UNVERIFIED == kind) {
    if (selfp != me->ccn_closure) {
      GST_LOG_OBJECT (me, "CCN unverified content on dead closure %p", selfp);
      return (CCN_UPCALL_RESULT_OK);
    }
    return (CCN_UPCALL_RESULT_VERIFY);

  } else if (CCN_UPCALL_CONTENT != kind) {
    GST_LOG_OBJECT (me, "CCN upcall result error");
    return (CCN_UPCALL_RESULT_ERR);
  }

  segment = ccn_ccnb_fetch_segment (info->content_ccnb, info->content_comps);
  GST_INFO ("...looks to be for segment: %d", segment);
  if (selfp != me->ccn_closure) {
    GST_LOG_OBJECT (me, "CCN content on dead closure %p", selfp);
    return (CCN_UPCALL_RESULT_OK);
  }


  /* At this point it seems we have a data message we want to process */

  ccnb = info->content_ccnb;
  ccnb_size = info->pco->offset[CCN_PCO_E];

  /* spit out some debug information */
  for (i = 0; i < 5; ++i) {
    GST_DEBUG ("%3d: ", i);
    if (0 > ccn_name_comp_get (info->content_ccnb, info->content_comps, i, &cp,
            &sz)) {
      // fprintf(stderr, "could not get comp\n");
    } else {
      // hDump( DUMP_ADDR( cp ), DUMP_SIZE( sz ) );
    }
  }

  /* go get the data and process it...note that the data pointer here is only temporary, a copy is needed to keep the data */
  ib = info->interest_ccnb;
  ic = info->interest_comps;
  res = ccn_content_get_value (ccnb, ccnb_size, info->pco, &data, &data_size);
  if (res < 0) {
    GST_LOG_OBJECT (me, "CCN error on get value of size");
    process_or_queue (me, segment, NULL, 0, FALSE);     // process null block to adjust interest array queue
    post_next_interest (me);    // Keep the data flowing
    return (CCN_UPCALL_RESULT_ERR);
  }

  /* was this the last block? [code taken from a ccnx tool */
  /* \todo  the test below should get refactored into the library */
  if (info->pco->offset[CCN_PCO_B_FinalBlockID] !=
      info->pco->offset[CCN_PCO_E_FinalBlockID]) {
    const unsigned char *finalid = NULL;
    size_t finalid_size = 0;
    const unsigned char *nameid = NULL;
    size_t nameid_size = 0;
    struct ccn_indexbuf *cc = info->content_comps;
    ccn_ref_tagged_BLOB (CCN_DTAG_FinalBlockID, ccnb,
        info->pco->offset[CCN_PCO_B_FinalBlockID],
        info->pco->offset[CCN_PCO_E_FinalBlockID], &finalid, &finalid_size);
    if (cc->n < 2)
      abort ();                 // \todo we need to behave better than this
    ccn_ref_tagged_BLOB (CCN_DTAG_Component, ccnb,
        cc->buf[cc->n - 2], cc->buf[cc->n - 1], &nameid, &nameid_size);
    if (finalid_size == nameid_size
        && 0 == memcmp (finalid, nameid, nameid_size)) {
      b_last = TRUE;
    }
  }

  /* a short block can also indicate the end, if the client isn't using FinalBlockID */
  if (data_size < CCN_CHUNK_SIZE)
    b_last = TRUE;

  /* something to process */
  process_or_queue (me, segment, data, data_size, b_last);
  post_next_interest (me);

  if (!b_last)
    return post_next_interest (me);

  return (CCN_UPCALL_RESULT_OK);

}
示例#16
0
/**
 * Load a link to the repo policy from the repoPolicy file and load the link
 * target to extract the actual policy.
 * If a policy file does not exist a new one is created, with a link to a policy
 * based either on the environment variable CCNR_GLOBAL_PREFIX or the system
 * default value of ccnx:/parc.com/csl/ccn/Repos, plus the system defaults for
 * other fields.
 * This routine must be called after the btree code is initialized and capable
 * of returning content objects.
 * Sets the parsed_policy field of the handle to be the new policy.
 */
static int
load_policy(struct ccnr_handle *ccnr)
{
    int fd;
    ssize_t res;
    struct content_entry *content = NULL;
    const unsigned char *content_msg = NULL;
    struct ccn_parsed_ContentObject pco = {0};
    struct ccn_parsed_Link pl = {0};
    struct ccn_indexbuf *nc = NULL;
    struct ccn_charbuf *basename = NULL;
    struct ccn_charbuf *policy = NULL;
    struct ccn_charbuf *policy_cob = NULL;
    struct ccn_charbuf *policyFileName;
    const char *global_prefix;
    const unsigned char *buf = NULL;
    size_t length = 0;
    int segment = 0;
    int final = 0;
    struct ccn_buf_decoder decoder;
    struct ccn_buf_decoder *d;
    
    policyFileName = ccn_charbuf_create();
    ccn_charbuf_putf(policyFileName, "%s/repoPolicy", ccnr->directory);
    ccnr->parsed_policy = ccnr_parsed_policy_create();
    fd = open(ccn_charbuf_as_string(policyFileName), O_RDONLY);
    if (fd >= 0) {
        ccnr->policy_link_cob = ccn_charbuf_create();
        ccn_charbuf_reserve(ccnr->policy_link_cob, 4096);   // limits the size of the policy link
        ccnr->policy_link_cob->length = 0;    // clear the buffer
        res = read(fd, ccnr->policy_link_cob->buf, ccnr->policy_link_cob->limit - ccnr->policy_link_cob->length);
        close(fd);
        if (res == -1) {
            r_init_fail(ccnr, __LINE__, "Error reading repoPolicy file.", errno);
            ccn_charbuf_destroy(&ccnr->policy_link_cob);
            ccn_charbuf_destroy(&policyFileName);
            return(-1);
        }
        ccnr->policy_link_cob->length = res;
        nc = ccn_indexbuf_create();
        res = ccn_parse_ContentObject(ccnr->policy_link_cob->buf,
                                      ccnr->policy_link_cob->length, &pco, nc);
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnr->policy_link_cob->buf,
                                  pco.offset[CCN_PCO_B_Content],
                                  pco.offset[CCN_PCO_E_Content],
                                  &buf, &length);
        d = ccn_buf_decoder_start(&decoder, buf, length);
        res = ccn_parse_Link(d, &pl, NULL);
        if (res <= 0) {
            ccnr_msg(ccnr, "Policy link is malformed.");
            goto CreateNewPolicy;
        }
        basename = ccn_charbuf_create();
        ccn_charbuf_append(basename, buf + pl.offset[CCN_PL_B_Name],
                           pl.offset[CCN_PL_E_Name] - pl.offset[CCN_PL_B_Name]);
        ccnr->policy_name = ccn_charbuf_create(); // to detect writes to this name
        ccn_charbuf_append_charbuf(ccnr->policy_name, basename); // has version
        ccn_name_chop(ccnr->policy_name, NULL, -1); // get rid of version
        policy = ccn_charbuf_create();
        // if we fail to retrieve the link target, report and then create a new one
        do {
            ccn_name_append_numeric(basename, CCN_MARKER_SEQNUM, segment++);
            content = r_store_lookup_ccnb(ccnr, basename->buf, basename->length);
            if (content == NULL) {
                ccnr_debug_ccnb(ccnr, __LINE__, "policy lookup failed for", NULL,
                                basename->buf, basename->length);
                break;
            }
            ccn_name_chop(basename, NULL, -1);
            content_msg = r_store_content_base(ccnr, content);
            if (content_msg == NULL) {
                ccnr_debug_ccnb(ccnr, __LINE__, "Unable to read policy object", NULL,
                                basename->buf, basename->length);
                break;
            }
            res = ccn_parse_ContentObject(content_msg, r_store_content_size(ccnr, content), &pco, nc);
            res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, content_msg,
                                      pco.offset[CCN_PCO_B_Content],
                                      pco.offset[CCN_PCO_E_Content],
                                      &buf, &length);
            ccn_charbuf_append(policy, buf, length);
            final = ccn_is_final_pco(content_msg, &pco, nc);
        } while (!final && segment < 100);
示例#17
0
文件: packet-ccn.c 项目: futtre/ccnx
static int
dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *name_tree;
    proto_tree *exclude_tree;
    proto_item *titem;
    struct ccn_parsed_interest interest;
    struct ccn_parsed_interest *pi = &interest;
    struct ccn_charbuf *c;
    struct ccn_indexbuf *comps;
    const unsigned char *comp;
    size_t comp_size;
    const unsigned char *blob;
    size_t blob_size;
    ssize_t l;
    unsigned int i;
    int res;

    comps = ccn_indexbuf_create();
    res = ccn_parse_interest(ccnb, ccnb_size, pi, comps);

    /* Name */
    l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name];
    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    titem = proto_tree_add_string(tree, hf_ccn_name, tvb,
                                      pi->offset[CCN_PI_B_Name], l,
                                      ccn_charbuf_as_string(c));
    name_tree = proto_item_add_subtree(titem, ett_name);
    ccn_charbuf_destroy(&c);

    for (i = 0; i < comps->n - 1; i++) {
        res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size);
        titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE);
    }

    /* MinSuffixComponents */
    l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents];
    if (l > 0) {
        i = pi->min_suffix_comps;
        titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i);
    }

    /* MaxSuffixComponents */
    l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents];
    if (l > 0) {
        i = pi->max_suffix_comps;
        titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i);
    }

    /* PublisherIDKeyDigest? */
    /* Exclude */
    l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude];
    if (l > 0) {
            titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l,
                                         "Exclude");
            exclude_tree = proto_item_add_subtree(titem, ett_exclude);
    }
    /* ChildSelector */
    l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector];
    if (l > 0) {
        i = pi->orderpref;
        titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i);
        proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), ""));

    }

    /* AnswerOriginKind */
    l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind];
    if (l > 0) {
        i = pi->answerfrom;
        titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i);
    }

    /* Scope */
    l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope];
    if (l > 0) {
        i = pi->scope;
        titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i);
    }

    /* Nonce */
    /* Nonce */
    l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce];
    if (l > 0) {
        i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb,
                                pi->offset[CCN_PI_B_Nonce],
                                pi->offset[CCN_PI_E_Nonce],
                                &blob, &blob_size);
        if (check_col(pinfo->cinfo, COL_INFO)) {
            col_append_str(pinfo->cinfo, COL_INFO, ", <");
            for (i = 0; i < blob_size; i++)
                col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]);
            col_append_str(pinfo->cinfo, COL_INFO, ">");
        }
        titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb,
                                    blob - ccnb, blob_size, FALSE);
    }
    
    return (1);

}
示例#18
0
PyObject *
SignedInfo_obj_from_ccn(PyObject *py_signed_info)
{
	struct ccn_charbuf *signed_info;
	PyObject *py_obj_SignedInfo, *py_o;
	struct ccn_buf_decoder decoder, *d;
	size_t start, stop, size;
	const unsigned char *ptr;
	int r;

	signed_info = CCNObject_Get(SIGNED_INFO, py_signed_info);

	debug("SignedInfo_from_ccn start, size=%zd\n", signed_info->length);

	// 1) Create python object
	py_obj_SignedInfo = PyObject_CallObject(g_type_SignedInfo, NULL);
	if (!py_obj_SignedInfo)
		return NULL;

	// 2) Set ccn_data to a cobject pointing to the c struct
	//    and ensure proper destructor is set up for the c object.
	r = PyObject_SetAttrString(py_obj_SignedInfo, "ccn_data", py_signed_info);
	JUMP_IF_NEG(r, error);

	// 3) Parse c structure and fill python attributes
	//    using PyObject_SetAttrString
	// based on chk_signing_params
	// from ccn_client.c
	//
	//outputs:

	// Note, it is ok that non-filled optional elements
	// are initialized to None (through the .py file __init__)
	//

	d = ccn_buf_decoder_start(&decoder, signed_info->buf, signed_info->length);

	if (!ccn_buf_match_dtag(d, CCN_DTAG_SignedInfo)) {
		PyErr_Format(g_PyExc_CCNSignedInfoError, "Error finding"
				" CCN_DTAG_SignedInfo (decoder state: %d)", d->decoder.state);
		goto error;
	}

	ccn_buf_advance(d);

	/* PublisherPublic Key */
	//XXX: should we check for case when PublishePublicKeyDigest is not present? -dk
	start = d->decoder.token_index;
	ccn_parse_required_tagged_BLOB(d, CCN_DTAG_PublisherPublicKeyDigest,
			16, 64);
	stop = d->decoder.token_index;

	r = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, d->buf, start,
			stop, &ptr, &size);
	if (r < 0) {
		PyErr_Format(g_PyExc_CCNSignedInfoError, "Error parsing"
				" CCN_DTAG_PublisherPublicKey (decoder state %d)",
				d->decoder.state);
		goto error;
	}

	//    self.publisherPublicKeyDigest = None     # SHA256 hash
	debug("PyObject_SetAttrString publisherPublicKeyDigest\n");
	py_o = PyBytes_FromStringAndSize((const char*) ptr, size);
	JUMP_IF_NULL(py_o, error);
	r = PyObject_SetAttrString(py_obj_SignedInfo, "publisherPublicKeyDigest",
			py_o);
	Py_DECREF(py_o);
	JUMP_IF_NEG(r, error);

	/* Timestamp */
	start = d->decoder.token_index;
	ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Timestamp, 1, -1);
	stop = d->decoder.token_index;

	r = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, d->buf, start, stop, &ptr,
			&size);
	if (r < 0) {
		PyErr_Format(g_PyExc_CCNSignedInfoError, "Error parsing"
				" CCN_DTAG_Timestamp (decoder state %d)", d->decoder.state);
		goto error;
	}

	//    self.timeStamp = None   # CCNx timestamp
	debug("PyObject_SetAttrString timeStamp\n");
	py_o = PyBytes_FromStringAndSize((const char*) ptr, size);
	JUMP_IF_NULL(py_o, error);
	r = PyObject_SetAttrString(py_obj_SignedInfo, "timeStamp", py_o);
	Py_DECREF(py_o);
	JUMP_IF_NEG(r, error);

	/* Type */
	assert(d->decoder.state >= 0);
	r = ccn_parse_optional_tagged_binary_number(d, CCN_DTAG_Type, 3, 3,
			CCN_CONTENT_DATA);
	if (d->decoder.state < 0) {
		PyErr_SetString(g_PyExc_CCNSignedInfoError, "Unable to parse type");
		goto error;
	}

	py_o = _pyccn_Int_FromLong(r);
	JUMP_IF_NULL(py_o, error);
	r = PyObject_SetAttrString(py_obj_SignedInfo, "type", py_o);
	Py_DECREF(py_o);
	JUMP_IF_NEG(r, error);

	/*
		start = d->decoder.token_index;
		ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Type, 1, -1);
		stop = d->decoder.token_index;

		r = ccn_ref_tagged_BLOB(CCN_DTAG_Type, d->buf, start, stop, &ptr, &size);
		if (r == 0) {
			//    type = None   # CCNx type
			// TODO: Provide a string representation with the Base64 mnemonic?
			debug("PyObject_SetAttrString type\n");
			py_o = PyByteArray_FromStringAndSize((const char*) ptr, size);
			JUMP_IF_NULL(py_o, error);
			r = PyObject_SetAttrString(py_obj_SignedInfo, "type", py_o);
			Py_DECREF(py_o);
			JUMP_IF_NEG(r, error);
		}
	 */

	/* FreshnessSeconds */
	r = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds);
	if (r >= 0) {
		//    self.freshnessSeconds = None
		debug("PyObject_SetAttrString freshnessSeconds\n");
		py_o = _pyccn_Int_FromLong(r);
		JUMP_IF_NULL(py_o, error);
		r = PyObject_SetAttrString(py_obj_SignedInfo, "freshnessSeconds", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	/* FinalBlockID */
#if 0 /* old code (left in case mine is wrong - dk) */
	if (ccn_buf_match_dtag(d, CCN_DTAG_FinalBlockID)) {
		ccn_buf_advance(d);
		start = d->decoder.token_index;
		if (ccn_buf_match_some_blob(d))
			ccn_buf_advance(d);
		stop = d->decoder.token_index;
		ccn_buf_check_close(d);
		if (d->decoder.state >= 0 && stop > start) {
			//    self.finalBlockID = None
			fprintf(stderr, "PyObject_SetAttrString finalBlockID, len=%zd\n", stop - start);
			py_o = PyByteArray_FromStringAndSize((const char*) (d->buf + start), stop - start);
			PyObject_SetAttrString(py_obj_SignedInfo, "finalBlockID", py_o);
			Py_INCREF(py_o);
		}
	}
#endif
	start = d->decoder.token_index;
	ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_FinalBlockID, 1, -1);
	stop = d->decoder.token_index;

	r = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, d->buf, start, stop, &ptr,
			&size);
	if (r == 0) {
		//    self.finalBlockID = None
		debug("PyObject_SetAttrString finalBlockID, len=%zd\n", size);
		py_o = PyBytes_FromStringAndSize((const char*) ptr, size);
		JUMP_IF_NULL(py_o, error);
		r = PyObject_SetAttrString(py_obj_SignedInfo, "finalBlockID", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	/* KeyLocator */
#if 0 /* Old code in case mine is wrong - dk */
	start = d->decoder.token_index;
	if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator))
		ccn_buf_advance_past_element(d);
	stop = d->decoder.token_index;
	if (d->decoder.state >= 0 && stop > start) {
		fprintf(stderr, "PyObject_SetAttrString keyLocator, len=%zd\n", stop - start);
		struct ccn_charbuf* keyLocator = ccn_charbuf_create();
		ccn_charbuf_append(keyLocator, d->buf + start, stop - start);
		//    self.keyLocator = None
		py_o = KeyLocator_obj_from_ccn(keyLocator); // it will free
		PyObject_SetAttrString(py_obj_SignedInfo, "keyLocator", py_o);
		Py_INCREF(py_o);
	}
#endif

	/*
	 * KeyLocator is not a BLOB, but an another structure, this requires
	 * us to parse it differently
	 */
	start = d->decoder.token_index;
	if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator)) {
		struct ccn_charbuf *key_locator;
		PyObject *py_key_locator;

		r = ccn_buf_advance_past_element(d);
		if (r < 0) {
			PyErr_Format(g_PyExc_CCNSignedInfoError, "Error locating"
					" CCN_DTAG_KeyLocator (decoder state: %d, r: %d)",
					d->decoder.state, r);
			goto error;
		}
		stop = d->decoder.token_index;
		/*
				debug("element_index = %zd size = %zd nest = %d numval = %zd state = %d"
						" token_index %zd\n",
						d->decoder.element_index, d->decoder.index, d->decoder.nest,
						d->decoder.numval, d->decoder.state, d->decoder.token_index);
				assert(d->decoder.state >= 0);
		 */

		ptr = d->buf + start;
		size = stop - start;
		assert(size > 0);

		debug("PyObject_SetAttrString keyLocator, len=%zd\n", size);

		py_key_locator = CCNObject_New_charbuf(KEY_LOCATOR, &key_locator);
		JUMP_IF_NULL(py_key_locator, error);

		r = ccn_charbuf_append(key_locator, ptr, size);
		if (r < 0) {
			Py_DECREF(py_key_locator);
			PyErr_NoMemory();
			goto error;
		}

		//    self.keyLocator = None
		py_o = KeyLocator_obj_from_ccn(py_key_locator);
		Py_DECREF(py_key_locator);
		JUMP_IF_NULL(py_o, error);
		r = PyObject_SetAttrString(py_obj_SignedInfo, "keyLocator", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	ccn_buf_check_close(d);
	if (d->decoder.state < 0) {
		PyErr_Format(g_PyExc_CCNSignedInfoError, "SignedInfo decoding error"
				" (decoder state: %d, numval: %zd)", d->decoder.state,
				d->decoder.numval);
		goto error;
	}

	// 4) Return the created object
	debug("SignedInfo_from_ccn ends\n");
	return py_obj_SignedInfo;

error:
	Py_DECREF(py_obj_SignedInfo);

	return NULL;
}
示例#19
0
int ccn_verify_signature(const unsigned char *msg,
                     size_t size,
                     const struct ccn_parsed_ContentObject *co,
                     const struct ccn_pkey *verification_pubkey)
{
    EVP_MD_CTX verc;
    EVP_MD_CTX *ver_ctx = &verc;
    X509_SIG *digest_info = NULL;
    MP_info *merkle_path_info = NULL;
    unsigned char *root_hash;
    size_t root_hash_size;

    int res;

    const EVP_MD *digest = EVP_md_null();
    const EVP_MD *merkle_path_digest = EVP_md_null();

    const unsigned char *signature_bits = NULL;
    size_t signature_bits_size = 0;
    const unsigned char *witness = NULL;
    size_t witness_size = 0;
    EVP_PKEY *pkey = (EVP_PKEY *)verification_pubkey;
#ifdef DEBUG
    int x, h;
#endif

    res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, msg,
                              co->offset[CCN_PCO_B_SignatureBits],
                              co->offset[CCN_PCO_E_SignatureBits],
                              &signature_bits,
                              &signature_bits_size);
    if (res < 0)
        return (-1);

    if (co->offset[CCN_PCO_B_DigestAlgorithm] == co->offset[CCN_PCO_E_DigestAlgorithm]) {
        digest = EVP_sha256();
    }
    else {
        /* XXX - figure out what algorithm the OID represents */
        fprintf(stderr, "not a DigestAlgorithm I understand right now\n");
        return (-1);
    }

    EVP_MD_CTX_init(ver_ctx);
    res = EVP_VerifyInit_ex(ver_ctx, digest, NULL);
    if (!res)
        return (-1);

    if (co->offset[CCN_PCO_B_Witness] != co->offset[CCN_PCO_E_Witness]) {
        /* The witness is a DigestInfo, where the octet-string therein encapsulates
         * a sequence of [integer (origin 1 node#), sequence of [octet-string]]
         * where the inner octet-string is the concatenated hashes on the merkle-path
         */
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Witness, msg,
                                  co->offset[CCN_PCO_B_Witness],
                                  co->offset[CCN_PCO_E_Witness],
                                  &witness,
                                  &witness_size);
        if (res < 0)
            return (-1);


        digest_info = d2i_X509_SIG(NULL, &witness, witness_size);
        /* digest_info->algor->algorithm->{length, data}
         * digest_info->digest->{length, type, data}
         */
        /* ...2.2 is an MHT w/ SHA256 */
        ASN1_OBJECT *merkle_hash_tree_oid = OBJ_txt2obj("1.2.840.113550.11.1.2.2", 1);
        if (0 != OBJ_cmp(digest_info->algor->algorithm, merkle_hash_tree_oid)) {
            fprintf(stderr, "A witness is present without an MHT OID!\n");
            ASN1_OBJECT_free(merkle_hash_tree_oid);
            return (-1);
        }
        /* we're doing an MHT */
        ASN1_OBJECT_free(merkle_hash_tree_oid);
        merkle_path_digest = EVP_sha256();
        /* DER-encoded in the digest_info's digest ASN.1 octet string is the Merkle path info */
        merkle_path_info = d2i_MP_info(NULL, (const unsigned char **)&(digest_info->digest->data), digest_info->digest->length);
#ifdef DEBUG
        int node = ASN1_INTEGER_get(merkle_path_info->node);
        int hash_count = merkle_path_info->hashes->num;
        ASN1_OCTET_STRING *hash;
        fprintf(stderr, "A witness is present with an MHT OID\n");
        fprintf(stderr, "This is node %d, with %d hashes\n", node, hash_count);
        for (h = 0; h < hash_count; h++) {
            hash = (ASN1_OCTET_STRING *)merkle_path_info->hashes->data[h];
            fprintf(stderr, "     hashes[%d] len = %d data = ", h, hash->length);
            for (x = 0; x < hash->length; x++) {
                fprintf(stderr, "%02x", hash->data[x]);
            }
            fprintf(stderr, "\n");
        }
#endif
        /* In the MHT signature case, we signed/verify the root hash */
        root_hash_size = EVP_MD_size(merkle_path_digest);
        root_hash = calloc(1, root_hash_size);
        res = ccn_merkle_root_hash(msg, size, co, merkle_path_digest, merkle_path_info, root_hash, root_hash_size);
        res = EVP_VerifyUpdate(ver_ctx, root_hash, root_hash_size);
        res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey);
        EVP_MD_CTX_cleanup(ver_ctx);
    } else {
        /*
         * In the simple signature case, we signed/verify from the name through
         * the end of the content.
         */
        size_t signed_size = co->offset[CCN_PCO_E_Content] - co->offset[CCN_PCO_B_Name];
        res = EVP_VerifyUpdate(ver_ctx, msg + co->offset[CCN_PCO_B_Name], signed_size);
        res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey);
        EVP_MD_CTX_cleanup(ver_ctx);
    }

    if (res == 1)
        return (1);
    else
        return (0);
}
示例#20
0
文件: packet-ccn.c 项目: YichiLL/ccnx
static int
dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *name_tree;
    proto_tree *exclude_tree;
    proto_item *titem;
    struct ccn_parsed_interest interest;
    struct ccn_parsed_interest *pi = &interest;
    struct ccn_buf_decoder decoder;
    struct ccn_buf_decoder *d;
    const unsigned char *bloom;
    size_t bloom_size = 0;
    struct ccn_charbuf *c;
    struct ccn_indexbuf *comps;
    const unsigned char *comp;
    size_t comp_size;
    const unsigned char *blob;
    size_t blob_size;
    ssize_t l;
    unsigned int i;
    double lifetime;
    int res;
    
    comps = ccn_indexbuf_create();
    res = ccn_parse_interest(ccnb, ccnb_size, pi, comps);
    if (res < 0)
        return (res);
    
    /* Name */
    l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name];
    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    titem = proto_tree_add_string(tree, hf_ccn_name, tvb,
                                  pi->offset[CCN_PI_B_Name], l,
                                  ccn_charbuf_as_string(c));
    name_tree = proto_item_add_subtree(titem, ett_name);
    ccn_charbuf_destroy(&c);
    
    for (i = 0; i < comps->n - 1; i++) {
        res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size);
        titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE);
    }
    
    /* MinSuffixComponents */
    l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents];
    if (l > 0) {
        i = pi->min_suffix_comps;
        titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i);
    }
    
    /* MaxSuffixComponents */
    l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents];
    if (l > 0) {
        i = pi->max_suffix_comps;
        titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i);
    }
    
    /* PublisherPublicKeyDigest */
    /* Exclude */
    l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude];
    if (l > 0) {
        c = ccn_charbuf_create();
        d = ccn_buf_decoder_start(&decoder, ccnb + pi->offset[CCN_PI_B_Exclude], l);
        if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) {
            ccn_charbuf_destroy(&c);
            return(-1);
        }
        ccn_charbuf_append_string(c, "Exclude: ");
        ccn_buf_advance(d);
        if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
            ccn_buf_advance(d);
            ccn_charbuf_append_string(c, "* ");
            ccn_buf_check_close(d);
        }
        else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) {
            ccn_buf_advance(d);
            if (ccn_buf_match_blob(d, &bloom, &bloom_size))
                ccn_buf_advance(d);
            ccn_charbuf_append_string(c, "? ");
            ccn_buf_check_close(d);
        }
        while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
            ccn_buf_advance(d);
            comp_size = 0;
            if (ccn_buf_match_blob(d, &comp, &comp_size))
                ccn_buf_advance(d);
            ccn_uri_append_percentescaped(c, comp, comp_size);
            ccn_charbuf_append_string(c, " ");
            ccn_buf_check_close(d);
            if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
                ccn_buf_advance(d);
                ccn_charbuf_append_string(c, "* ");
                ccn_buf_check_close(d);
            }
            else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) {
                ccn_buf_advance(d);
                if (ccn_buf_match_blob(d, &bloom, &bloom_size))
                    ccn_buf_advance(d);
                ccn_charbuf_append_string(c, "? ");
                ccn_buf_check_close(d);
            }
        }
        
        titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l,
                                    "%s", ccn_charbuf_as_string(c));
        exclude_tree = proto_item_add_subtree(titem, ett_exclude);
        ccn_charbuf_destroy(&c);

    }
    /* ChildSelector */
    l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector];
    if (l > 0) {
        i = pi->orderpref;
        titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i);
        proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), ""));
        
    }
    
    /* AnswerOriginKind */
    l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind];
    if (l > 0) {
        i = pi->answerfrom;
        titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i);
    }
    
    /* Scope */
    l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope];
    if (l > 0) {
        i = pi->scope;
        titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i);
    }
    
    /* InterestLifetime */
    l = pi->offset[CCN_PI_E_InterestLifetime] - pi->offset[CCN_PI_B_InterestLifetime];
    if (l > 0) {
        i = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, ccnb,
                                pi->offset[CCN_PI_B_InterestLifetime],
                                pi->offset[CCN_PI_E_InterestLifetime],
                                &blob, &blob_size);
        lifetime = 0.0;
        for (i = 0; i < blob_size; i++)
            lifetime = lifetime * 256.0 + (double)blob[i];
        lifetime /= 4096.0;
        titem = proto_tree_add_double(tree, hf_ccn_interestlifetime, tvb, blob - ccnb, blob_size, lifetime);
    }
    
    /* Nonce */
    l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce];
    if (l > 0) {
        i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb,
                                pi->offset[CCN_PI_B_Nonce],
                                pi->offset[CCN_PI_E_Nonce],
                                &blob, &blob_size);
        if (check_col(pinfo->cinfo, COL_INFO)) {
            col_append_str(pinfo->cinfo, COL_INFO, ", <");
            for (i = 0; i < blob_size; i++)
                col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]);
            col_append_str(pinfo->cinfo, COL_INFO, ">");
        }
        titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb,
                                    blob - ccnb, blob_size, FALSE);
    }
    
    return (1);
    
}
示例#21
0
PyObject *
Signature_obj_from_ccn(PyObject *py_signature)
{
	struct ccn_charbuf *signature;
	PyObject *py_obj_signature, *py_o;
	struct ccn_buf_decoder decoder, *d;
	size_t start, stop, size;
	const unsigned char *ptr;
	int r;

	assert(CCNObject_IsValid(SIGNATURE, py_signature));
	signature = CCNObject_Get(SIGNATURE, py_signature);

	debug("Signature_from_ccn start, len=%zd\n", signature->length);

	// 1) Create python object
	py_obj_signature = PyObject_CallObject(g_type_Signature, NULL);
	if (!py_obj_signature)
		return NULL;

	// 2) Set ccn_data to a cobject pointing to the c struct
	//    and ensure proper destructor is set up for the c object.
	r = PyObject_SetAttrString(py_obj_signature, "ccn_data", py_signature);
	JUMP_IF_NEG(r, error);

	// 3) Parse c structure and fill python attributes

	// Neither DigestAlgorithm nor Witness are included in the packet
	// from ccnput, so they are apparently both optional
	d = ccn_buf_decoder_start(&decoder, signature->buf, signature->length);

	if (!ccn_buf_match_dtag(d, CCN_DTAG_Signature)) {
		PyErr_Format(g_PyExc_CCNSignatureError, "Error finding"
				" CCN_DTAG_Signature (decoder state: %d)", d->decoder.state);
		goto error;
	}

	debug("Is a signature\n");
	ccn_buf_advance(d);

	/* CCN_DTAG_DigestAlgorithm */
	start = d->decoder.token_index;
	ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_DigestAlgorithm, 1, -1);
	stop = d->decoder.token_index;

	r = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, d->buf, start, stop,
			&ptr, &size);
	if (r == 0) {
		debug("PyObject_SetAttrString digestAlgorithm\n");
		py_o = PyBytes_FromStringAndSize((const char*) ptr, size);
		JUMP_IF_NULL(py_o, error);
		r = PyObject_SetAttrString(py_obj_signature, "digestAlgorithm", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	/* CCN_DTAG_Witness */
	start = d->decoder.token_index;
	ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Witness, 1, -1);
	stop = d->decoder.token_index;
	debug("witness start %zd stop %zd\n", start, stop);

	r = ccn_ref_tagged_BLOB(CCN_DTAG_Witness, d->buf, start, stop, &ptr, &size);
	if (r == 0) {
		// The Witness is represented as a DER-encoded PKCS#1 DigestInfo,
		// which contains an AlgorithmIdentifier (an OID, together with any necessary parameters)
		// and a byte array (OCTET STRING) containing the digest information to be interpreted according to that OID.
		// http://www.ccnx.org/releases/latest/doc/technical/SignatureGeneration.html
		debug("PyObject_SetAttrString witness\n");
		py_o = PyBytes_FromStringAndSize((const char*) ptr, size);
		JUMP_IF_NULL(py_o, error);
		r = PyObject_SetAttrString(py_obj_signature, "witness", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	/* CCN_DTAG_SignatureBits */
	start = d->decoder.token_index;
	ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SignatureBits, 1, -1);
	stop = d->decoder.token_index;

	r = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, d->buf, start, stop, &ptr,
			&size);
	if (r < 0) {
		PyErr_Format(g_PyExc_CCNSignatureError, "Error parsing"
				" CCN_DTAG_SignatureBits (decoder state %d)", d->decoder.state);
		goto error;
	}

	assert(r == 0);
	debug("PyObject_SetAttrString signatureBits\n");
	py_o = PyBytes_FromStringAndSize((const char*) ptr, size);
	JUMP_IF_NULL(py_o, error);
	r = PyObject_SetAttrString(py_obj_signature, "signatureBits", py_o);
	Py_DECREF(py_o);
	JUMP_IF_NEG(r, error);

	ccn_buf_check_close(d);
	if (d->decoder.state < 0) {
		PyErr_Format(g_PyExc_CCNSignatureError, "Signature decoding error"
				" (decoder state: %d, numval: %zd)", d->decoder.state,
				d->decoder.numval);
		goto error;
	}

	// 4) Return the created object
	debug("Signature_from_ccn ends\n");
	return py_obj_signature;

error:
	Py_DECREF(py_obj_signature);
	return NULL;
}
示例#22
0
PyObject *
Interest_obj_from_ccn(PyObject *py_interest)
{
	struct ccn_charbuf *interest;
	struct ccn_parsed_interest *pi;
	PyObject *py_obj_Interest, *py_o;
	int r;

	debug("Interest_from_ccn_parsed start\n");

	interest = CCNObject_Get(INTEREST, py_interest);

	// 1) Create python object
	py_obj_Interest = PyObject_CallObject(g_type_Interest, NULL);
	if (!py_obj_Interest)
		return NULL;

	pi = _pyccn_interest_get_pi(py_interest);
	JUMP_IF_NULL(pi, error);

	// 2) Set ccn_data to a cobject pointing to the c struct
	//    and ensure proper destructor is set up for the c object.
	r = PyObject_SetAttrString(py_obj_Interest, "ccn_data", py_interest);
	JUMP_IF_NEG(r, error);

	// 3) Parse c structure and fill python attributes
	//    using PyObject_SetAttrString

	ssize_t len;
	const unsigned char *blob;
	size_t blob_size, start, end;
	struct ccn_charbuf * cb;

	// Best decoding examples are in packet-ccn.c for wireshark plugin?

	//        self.name = None  # Start from None to use for templates?
	len = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name];
	if (len > 0) {
		PyObject *py_cname;

		py_cname = CCNObject_New_charbuf(NAME, &cb);
		JUMP_IF_NULL(py_cname, error);

		r = ccn_charbuf_append(cb, interest->buf + pi->offset[CCN_PI_B_Name],
				len);
		JUMP_IF_NEG_MEM(r, error);

		py_o = Name_obj_from_ccn(py_cname);
		Py_DECREF(py_cname);
		JUMP_IF_NULL(py_o, error);

		r = PyObject_SetAttrString(py_obj_Interest, "name", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	} else {
		PyErr_SetString(g_PyExc_CCNInterestError, "Got interest without a"
				" name!");
		goto error;
	}

	//        self.minSuffixComponents = None  # default 0
	len = pi->offset[CCN_PI_E_MinSuffixComponents] -
			pi->offset[CCN_PI_B_MinSuffixComponents];
	if (len > 0) {
		r = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_MinSuffixComponents,
				interest->buf, pi->offset[CCN_PI_B_MinSuffixComponents],
				pi->offset[CCN_PI_E_MinSuffixComponents]);
		if (r < 0) {
			PyErr_SetString(g_PyExc_CCNInterestError, "Invalid"
					" MinSuffixComponents value");
			goto error;
		}

		py_o = _pyccn_Int_FromLong(r);
		JUMP_IF_NULL(py_o, error);

		r = PyObject_SetAttrString(py_obj_Interest, "minSuffixComponents",
				py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	//        self.maxSuffixComponents = None  # default infinity
	len = pi->offset[CCN_PI_E_MaxSuffixComponents] -
			pi->offset[CCN_PI_B_MaxSuffixComponents];
	if (len > 0) {
		r = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_MaxSuffixComponents,
				interest->buf, pi->offset[CCN_PI_B_MaxSuffixComponents],
				pi->offset[CCN_PI_E_MaxSuffixComponents]);
		if (r < 0) {
			PyErr_SetString(g_PyExc_CCNInterestError, "Invalid"
					" MaxSuffixComponents value");
			goto error;
		}

		py_o = _pyccn_Int_FromLong(r);
		JUMP_IF_NULL(py_o, error);

		r = PyObject_SetAttrString(py_obj_Interest, "maxSuffixComponents",
				py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	//        self.publisherPublicKeyDigest = None   # SHA256 hash
	// TODO: what is CN_PI_B_PublisherID? -- looks like it is the data including
	//                                       the tags while PublisherIDKeyDigest
	//                                       is just the raw digest -- dk
	start = pi->offset[CCN_PI_B_PublisherID];
	end = pi->offset[CCN_PI_E_PublisherID];
	len = end - start;
	if (len > 0) {
		r = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest,
				interest->buf, start, end, &blob, &blob_size);
		if (r < 0) {
			PyErr_SetString(g_PyExc_CCNInterestError, "Invalid"
					" PublisherPublicKeyDigest value");
			goto error;
		}

		py_o = PyBytes_FromStringAndSize((const char*) blob, blob_size);
		JUMP_IF_NULL(py_o, error);

		r = PyObject_SetAttrString(py_obj_Interest, "publisherPublicKeyDigest",
				py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	//        self.exclude = None
	len = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude];
	if (len > 0) {
		PyObject *py_exclusion_filter;

		py_exclusion_filter = CCNObject_New_charbuf(EXCLUSION_FILTER, &cb);
		JUMP_IF_NULL(py_exclusion_filter, error);

		r = ccn_charbuf_append(cb, interest->buf + pi->offset[CCN_PI_B_Exclude],
				len);
		JUMP_IF_NEG_MEM(r, error);

		py_o = ExclusionFilter_obj_from_ccn(py_exclusion_filter);
		Py_DECREF(py_exclusion_filter);
		JUMP_IF_NULL(py_o, error);

		r = PyObject_SetAttrString(py_obj_Interest, "exclude", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	//        self.childSelector = None
	len = pi->offset[CCN_PI_E_ChildSelector] -
			pi->offset[CCN_PI_B_ChildSelector];
	if (len > 0) {
		r = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_ChildSelector,
				interest->buf, pi->offset[CCN_PI_B_ChildSelector],
				pi->offset[CCN_PI_E_ChildSelector]);
		if (r < 0) {
			PyErr_SetString(g_PyExc_CCNInterestError, "Invalid"
					" ChildSelector value");
			goto error;
		}

		py_o = _pyccn_Int_FromLong(r);
		JUMP_IF_NULL(py_o, error);

		r = PyObject_SetAttrString(py_obj_Interest, "childSelector", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	//        self.answerOriginKind = None
	len = pi->offset[CCN_PI_E_AnswerOriginKind] -
			pi->offset[CCN_PI_B_AnswerOriginKind];
	if (len > 0) {
		r = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_AnswerOriginKind,
				interest->buf, pi->offset[CCN_PI_B_AnswerOriginKind],
				pi->offset[CCN_PI_E_AnswerOriginKind]);
		if (r < 0) {
			PyErr_SetString(g_PyExc_CCNInterestError, "Invalid"
					" AnswerOriginKind value");
			goto error;
		}

		py_o = _pyccn_Int_FromLong(r);
		JUMP_IF_NULL(py_o, error);

		r = PyObject_SetAttrString(py_obj_Interest, "answerOriginKind", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	//        self.scope  = None
	len = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope];
	if (len > 0) {
		r = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_Scope, interest->buf,
				pi->offset[CCN_PI_B_Scope], pi->offset[CCN_PI_E_Scope]);
		if (r < 0) {
			PyErr_SetString(g_PyExc_CCNInterestError, "Invalid"
					" Scope value");
			goto error;
		}

		py_o = _pyccn_Int_FromLong(r);
		JUMP_IF_NULL(py_o, error);

		r = PyObject_SetAttrString(py_obj_Interest, "scope", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	//        self.interestLifetime = None
	len = pi->offset[CCN_PI_E_InterestLifetime] -
			pi->offset[CCN_PI_B_InterestLifetime];
	if (len > 0) {
		double lifetime;

		// From packet-ccn.c
		r = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, interest->buf,
				pi->offset[CCN_PI_B_InterestLifetime],
				pi->offset[CCN_PI_E_InterestLifetime], &blob, &blob_size);
		if (r < 0) {
			PyErr_SetString(g_PyExc_CCNInterestError, "Invalid"
					" InterestLifetime value");
			goto error;
		}

		/* XXX: probably won't work with bigendian */
		lifetime = 0.0;
		for (size_t i = 0; i < blob_size; i++)
			lifetime = lifetime * 256.0 + (double) blob[i];
		lifetime /= 4096.0;

		py_o = PyFloat_FromDouble(lifetime);
		JUMP_IF_NULL(py_o, error);

		r = PyObject_SetAttrString(py_obj_Interest, "interestLifetime", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	//        self.nonce = None
	len = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce];
	if (len > 0) {
		r = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, interest->buf,
				pi->offset[CCN_PI_B_Nonce], pi->offset[CCN_PI_E_Nonce], &blob,
				&blob_size);
		if (r < 0) {
			PyErr_SetString(g_PyExc_CCNInterestError, "Invalid"
					" Nonce value");
			goto error;
		}

		py_o = PyBytes_FromStringAndSize((const char *) blob, blob_size);
		JUMP_IF_NULL(py_o, error);

		r = PyObject_SetAttrString(py_obj_Interest, "nonce", py_o);
		Py_DECREF(py_o);
		JUMP_IF_NEG(r, error);
	}

	r = PyObject_SetAttrString(py_obj_Interest, "ccn_data_dirty", Py_False);
	JUMP_IF_NEG(r, error);

	// 4) Return the created object
	debug("Interest_from_ccn ends\n");

	return py_obj_Interest;

error:
	Py_DECREF(py_obj_Interest);

	return NULL;
}
示例#23
0
文件: ccndc.c 项目: IthacaDream/ccnx
// 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);
}
示例#24
0
/**
 * Test for a match between the ContentObject described by a btree 
 * index entry and an Interest, assuming that it is already known that
 * there is a prefix match.
 *
 * This does not need access to the actual ContentObject, since the index
 * entry contains everything that we know to know to do the match.
 *
 * @param node                  leaf node
 * @param ndx                   index of entry within leaf node
 * @param interest_msg          ccnb-encoded Interest
 * @param pi                    corresponding parsed interest
 * @param scratch               for scratch use
 *
 * @result 1 for match, 0 for no match, -1 for error.
 */
int
ccn_btree_match_interest(struct ccn_btree_node *node, int ndx,
                         const unsigned char *interest_msg,
                         const struct ccn_parsed_interest *pi,
                         struct ccn_charbuf *scratch)
{
    const unsigned char *blob = NULL;
    const unsigned char *nextcomp = NULL;
    int i;
    int n;
    int ncomps;
    int pubidend;
    int pubidstart;
    int res;
    int rnc;
    size_t blob_size = 0;
    size_t nextcomp_size = 0;
    size_t size;
    struct ccn_btree_content_payload *e = NULL;
    unsigned char *flatname = NULL;
    
    e = ccn_btree_node_getentry(sizeof(*e), node, ndx);
    if (e == NULL || e->magic[0] != CCN_BT_CONTENT_MAGIC)
        return(-1);
    
    ncomps = MYFETCH(e, ncomp);
    if (ncomps < pi->prefix_comps + pi->min_suffix_comps)
        return(0);
    if (ncomps > pi->prefix_comps + pi->max_suffix_comps)
        return(0);
    /* Check that the publisher id matches */
    pubidstart = pi->offset[CCN_PI_B_PublisherID];
    pubidend = pi->offset[CCN_PI_E_PublisherID];
    if (pubidstart < pubidend) {
        blob_size = 0;
        ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest,
                            interest_msg,
                            pubidstart, pubidend,
                            &blob, &blob_size);
        if (blob_size != sizeof(e->ppkdg))
            return(0);
        if (0 != memcmp(blob, e->ppkdg, blob_size))
            return(0);
    }
    /* Do Exclude processing if necessary */
    if (pi->offset[CCN_PI_E_Exclude] > pi->offset[CCN_PI_B_Exclude]) {
        res = ccn_btree_key_fetch(scratch, node, ndx);
        if (res < 0)
            return(-1);
        flatname = scratch->buf;
        size = scratch->length;
        nextcomp = NULL;
        nextcomp_size = 0;
        for (i = 0, n = 0; i < size; i += CCNFLATSKIP(rnc), n++) {
            rnc = ccn_flatname_next_comp(flatname + i, size - i);
            if (rnc <= 0)
                return(-1);
            if (n == pi->prefix_comps) {
                nextcomp = flatname + i + CCNFLATDELIMSZ(rnc);
                nextcomp_size = CCNFLATDATASZ(rnc);
                break;
            }
        }
        if (nextcomp == NULL)
            return(0);
        if (ccn_excluded(interest_msg + pi->offset[CCN_PI_B_Exclude],
                         (pi->offset[CCN_PI_E_Exclude] -
                          pi->offset[CCN_PI_B_Exclude]),
                         nextcomp,
                         nextcomp_size))
            return(0);
    }
    /*
     * At this point the prefix matches and exclude-by-next-component is done.
     */
    // test any other qualifiers here
    return(1);
}