示例#1
0
char * 
get_orig_router_from_info_content_name(struct ccn_charbuf * content_name)
{
	int start,end;

	start=0;

	struct ccn_indexbuf *comps=ccn_indexbuf_create();
	ccn_name_split (content_name, comps);

	end=check_for_name_component_in_name(content_name,comps,"nlsr");


	struct ccn_charbuf *temp=ccn_charbuf_create();
	ccn_name_init(temp);	
	ccn_name_append_components( temp,	content_name->buf,
								comps->buf[start], 
								comps->buf[end]);

	struct ccn_charbuf *temp1=ccn_charbuf_create();
	ccn_uri_append(temp1, temp->buf, temp->length, 0);

	char *orig_router=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1,
																sizeof(char));
	memcpy(orig_router,ccn_charbuf_as_string(temp1),
										strlen(ccn_charbuf_as_string(temp1)));
	orig_router[strlen(orig_router)]='\0';
	
	ccn_charbuf_destroy(&temp);
	ccn_charbuf_destroy(&temp1);
	ccn_indexbuf_destroy(&comps);
	return orig_router;
	

}
示例#2
0
static PyObject *
Exclusion_Name_Obj(unsigned char *buf, size_t start, size_t stop)
{
	struct ccn_charbuf *name;
	PyObject *py_name, *res;
	int r;

	py_name = CCNObject_New_charbuf(NAME, &name);
	JUMP_IF_NULL(py_name, error);

	r = ccn_name_init(name);
	JUMP_IF_NEG_MEM(r, error);

	r = ccn_name_append_components(name, buf, start, stop);
	JUMP_IF_NEG_MEM(r, error);

	res = Name_obj_from_ccn(py_name);
	Py_DECREF(py_name);

	return res;

error:
	Py_XDECREF(py_name);
	return NULL;
}
示例#3
0
static void
collect_forwarding_html(struct ccnd_handle *h, struct ccn_charbuf *b)
{
    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = ⅇ
    struct ccn_forwarding *f;
    int res;
    struct ccn_charbuf *name = ccn_charbuf_create();
    
    ccn_charbuf_putf(b, "<h4>Forwarding</h4>" NL);
    ccn_charbuf_putf(b, "<ul>");
    hashtb_start(h->nameprefix_tab, e);
    for (; e->data != NULL; hashtb_next(e)) {
        struct nameprefix_entry *ipe = e->data;
        ccn_name_init(name);
        res = ccn_name_append_components(name, e->key, 0, e->keysize);
        if (res < 0)
            abort();
        if (0) {
            ccn_charbuf_putf(b, " <li>");
            ccn_uri_append(b, name->buf, name->length, 1);
            ccn_charbuf_putf(b, "</li>" NL);
        }
        for (f = ipe->forwarding; f != NULL; f = f->next) {
            if ((f->flags & (CCN_FORW_ACTIVE | CCN_FORW_PFXO)) != 0) {
                ccn_name_init(name);
                ccn_name_append_components(name, e->key, 0, e->keysize);
                ccn_charbuf_putf(b, " <li>");
                ccn_uri_append(b, name->buf, name->length, 1);
                ccn_charbuf_putf(b,
                                 " <b>face:</b> %u"
                                 " <b>flags:</b> 0x%x"
                                 " <b>expires:</b> %d",
                                 f->faceid,
                                 f->flags & CCN_FORW_PUBMASK,
                                 f->expires);
                ccn_charbuf_putf(b, "</li>" NL);
            }
        }
    }
    hashtb_end(e);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_putf(b, "</ul>");
}
示例#4
0
char * 
get_orig_router_from_lsa_name(struct ccn_charbuf * content_name)
{
	int start=0;

	size_t comp_size;
	const unsigned char *second_last_comp;
	char *second_comp_type;
	char *sep=".";
	char *rem;

	struct ccn_indexbuf *components=ccn_indexbuf_create();
	struct ccn_charbuf *name=ccn_charbuf_create();
	ccn_name_from_uri(name,nlsr->slice_prefix);
	ccn_name_split (name, components);
	start=components->n-2;
	ccn_charbuf_destroy(&name);
	ccn_indexbuf_destroy(&components);

	struct ccn_indexbuf *comps=ccn_indexbuf_create();
	ccn_name_split (content_name, comps);
	ccn_name_comp_get( content_name->buf, comps, 
					  comps->n-1-2, &second_last_comp, &comp_size);

	second_comp_type=strtok_r((char *)second_last_comp, sep, &rem);
	if ( strcmp( second_comp_type, "lsId" ) == 0 ){
		ccn_name_chop(content_name,comps,-3);
	}
	else{
		ccn_name_chop(content_name,comps,-2);
	}
	

	struct ccn_charbuf *temp=ccn_charbuf_create();
	ccn_name_init(temp);	
	ccn_name_append_components( temp,	content_name->buf,
								comps->buf[start+1], 
								comps->buf[comps->n - 1]);

	struct ccn_charbuf *temp1=ccn_charbuf_create();
	ccn_uri_append(temp1, temp->buf, temp->length, 0);

	char *orig_router=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1,
																sizeof(char));
	memcpy(orig_router,ccn_charbuf_as_string(temp1),
										strlen(ccn_charbuf_as_string(temp1)));
	orig_router[strlen(orig_router)]='\0';
	
	ccn_charbuf_destroy(&temp);
	ccn_charbuf_destroy(&temp1);
	ccn_indexbuf_destroy(&comps);
	return orig_router;
	

}
/**
 * Verify a signed interest
 *
 * params are as returned in upcall info structure
 * key is what should be used to verify
 *
 * returns:
 * -1 for parsing error
 *  0 for incorrect signature / unverified
 *  1 for proper verification
 *
 */
int verify_signed_interest(const unsigned char *ccnb, const struct ccn_indexbuf *comps,
							  size_t num_comps, size_t start, size_t stop,
							  struct ccn_pkey* key) {

    fprintf(stderr,"verifying signed interest...\n");
    
    // What is info->interest_comps->n ?
    //fprintf(stderr, "Interest components %d\n", (int) info->interest_comps->n);

    unsigned char* comp;
    size_t size;
    int res;

    // Create a charbuf with the matched interest name incl nonce
	struct ccn_charbuf* name = ccn_charbuf_create();
    ccn_name_init(name);
    res = ccn_name_append_components(name, ccnb, start, stop);

    // Last component, should be the signature
    res = ccn_name_comp_get(ccnb, comps,
    						num_comps,
                            (const unsigned char**)&comp, &size);
	if (memcmp(NS_SIGNATURE, comp, NS_SIGNATURE_LEN) != 0) {
		fprintf(stderr, "debug: Last component not tagged as a signature.\n");
		return(-1);
	}
    
	// Parse our nameless, dataless content object that follows the namespace
	// and replace the name with the implicit name from the interest, so that
	// we can use the standard signature verification calls.  Could be made
	// more efficient with different library calls.
	struct ccn_charbuf* co_with_name = ccn_charbuf_create();
    unsigned char* co = &comp[NS_SIGNATURE_LEN];
    replace_name(co_with_name, co, size-NS_SIGNATURE_LEN, name);
	//fprintf(stderr, "replace_name == %d (%s)\n", res, (res==0)?"ok":"fail");

	// For now, use standard routines to verify signature
	struct ccn_parsed_ContentObject pco = {0};

    fprintf(stderr,"verifying signed interest...2\n");
    
	res = ccn_parse_ContentObject(co_with_name->buf, co_with_name->length, &pco, NULL);
	if (!res) {
		// Verify the signature against the authorized public key given to us, passed through to the handler
		res = ccn_verify_signature(co_with_name->buf, pco.offset[CCN_PCO_E], &pco, key );
	} else {
		fprintf(stderr, "debug: Constructed content object parse failed (res==%d)\n", res);
	}
    fprintf(stderr,"verifying signed interest...3\n");
	ccn_charbuf_destroy(&co_with_name);
	ccn_charbuf_destroy(&name);
	return (res);

}
示例#6
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);
	}
}
示例#7
0
static void
collect_forwarding_xml(struct ccnd_handle *h, struct ccn_charbuf *b)
{
    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;
    struct ccn_forwarding *f;
    int res;
    struct ccn_charbuf *name = ccn_charbuf_create();
    
    ccn_charbuf_putf(b, "<forwarding>");
    hashtb_start(h->nameprefix_tab, e);
    for (; e->data != NULL; hashtb_next(e)) {
        struct nameprefix_entry *ipe = e->data;
        for (f = ipe->forwarding, res = 0; f != NULL && !res; f = f->next) {
            if ((f->flags & (CCN_FORW_ACTIVE | CCN_FORW_PFXO)) != 0)
                res = 1;
        }
        if (res) {
            ccn_name_init(name);
            ccn_name_append_components(name, e->key, 0, e->keysize);
            ccn_charbuf_putf(b, "<fentry>");
            ccn_charbuf_putf(b, "<prefix>");
            ccn_uri_append(b, name->buf, name->length, 1);
            ccn_charbuf_putf(b, "</prefix>");
            for (f = ipe->forwarding; f != NULL; f = f->next) {
                if ((f->flags & (CCN_FORW_ACTIVE | CCN_FORW_PFXO)) != 0) {
                    ccn_charbuf_putf(b,
                                     "<dest>"
                                     "<faceid>%u</faceid>"
                                     "<flags>%x</flags>"
                                     "<expires>%d</expires>"
                                     "</dest>",
                                     f->faceid,
                                     f->flags & CCN_FORW_PUBMASK,
                                     f->expires);
                }
            }
            ccn_charbuf_putf(b, "</fentry>");
        }
    }
    hashtb_end(e);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_putf(b, "</forwarding>");
}
示例#8
0
void
get_name_part(struct name_prefix *name_part,struct ccn_charbuf * interest_ccnb, 
		struct ccn_indexbuf *interest_comps, int offset)
{
	int lsa_position=0;
	
	struct ccn_indexbuf *components=ccn_indexbuf_create();
	struct ccn_charbuf *name=ccn_charbuf_create();
	ccn_name_from_uri(name,nlsr->slice_prefix);
	ccn_name_split (name, components);
	lsa_position=components->n-2;
	ccn_charbuf_destroy(&name);

	struct ccn_charbuf *temp=ccn_charbuf_create();
	ccn_name_init(temp);	
	ccn_name_append_components( temp,	interest_ccnb->buf,
								interest_comps->buf[lsa_position+1], 
								interest_comps->buf[interest_comps->n - 1]);

	struct ccn_charbuf *temp1=ccn_charbuf_create();
	ccn_uri_append(temp1, temp->buf, temp->length, 0);

	name_part->name=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1,
																sizeof(char));
	memcpy(name_part->name,ccn_charbuf_as_string(temp1),
										strlen(ccn_charbuf_as_string(temp1)));
	name_part->name[strlen(ccn_charbuf_as_string(temp1))]='\0';
	name_part->length=strlen(ccn_charbuf_as_string(temp1))+1;

	ccn_charbuf_destroy(&temp1);
	ccn_charbuf_destroy(&temp);
	ccn_indexbuf_destroy(&components);

	if ( nlsr->debugging )
		printf("Name Part: %s \n",name_part->name);
	
}
示例#9
0
void GroupManager::incomingInterest(ccn_upcall_info *info) {
    int res;

    const char *data = NULL;
    const unsigned char *requester = NULL;
    const unsigned char *refresher = NULL;
    const unsigned char *filter = NULL;
    size_t filter_len = 0;

    ccn_charbuf *signed_info = NULL;
    ccn_charbuf *name = NULL;
    ccn_charbuf *content = NULL;

    RemoteUser *refreshUser = NULL;

    // requesterPrefix starts from index 4 to (info->interest_comps->n - 2)
    int nameEnd = 0;
	nameEnd = (info->interest_comps)->n - 2;

	/* construct reply data
	 * name format:
	 *   /ndn/broadcast/conference/conference-name/speaker-list/username
	 */
	signed_info = ccn_charbuf_create();
	struct ccn_charbuf *keylocator = ccn_charbuf_create();
	ccn_create_keylocator(keylocator, ccn_keystore_public_key(cached_keystore));
	res = ccn_signed_info_create(signed_info,
			/*pubkeyid*/ get_my_publisher_key_id(),
			/*publisher_key_id_size*/ get_my_publisher_key_id_length(),
			/*datetime*/ NULL,
			/*type*/ CCN_CONTENT_DATA,
			///*freshness*/ -1,
			/*freshness*/ FRESHNESS,
			/*finalblockid*/ NULL,
			/*keylocator*/ keylocator);
	if (res < 0) {
		DPRINT("FAILED TO CREATE signed_info (res == %d)", res);
	}

	name = ccn_charbuf_create();
	content = ccn_charbuf_create();
	ccn_name_init(name);
	ccn_name_append_components(name, info->interest_ccnb,
			info->interest_comps->buf[0], info->interest_comps->buf[nameEnd + 1]);
	// append own  username
	ccn_name_append_str(name, userName.toLocal8Bit().constData());
	// get user list, the caller need to free the data buffer allocated 
	int dlen = userListtoXml(&data);
	ccn_encode_ContentObject(content, name, signed_info,
			data, dlen, 
			NULL, get_my_private_key());
	// already have the lock, no need to trylock
	ccn_put(info->h, content->buf, content->length);
	ccn_charbuf_destroy(&signed_info);
	ccn_charbuf_destroy(&name);
	ccn_charbuf_destroy(&content);
	if (data != NULL) {
		free((void *)data);
		data = NULL;
	}
}
示例#10
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);
}
示例#11
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;
}
示例#12
0
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;
    struct ccn_charbuf *temp = 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 && kind != CCN_UPCALL_CONTENT_UNVERIFIED)
        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;
    /* XXX - must verify sig, and make sure it is LEAF content */
    res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &data, &data_size);
    if (res < 0) abort();
    if (data_size > CHUNK_SIZE) {
        /* For us this is spam. Give up now. */
        fprintf(stderr, "*** Segment %d found with a data size of %d."
                        " This program only works with segments of 1024 bytes."
                        " Try ccncatchunks2 instead.\n",
                        (int)selfp->intdata, (int)data_size);
        exit(1);
    }
    
    /* OK, we will accept this block. */
    
    written = fwrite(data, data_size, 1, stdout);
    if (written != 1)
        exit(1);
    
    /* A short block signals EOF for us. */
    if (data_size < CHUNK_SIZE)
        exit(0);
    
    /* Ask for the next one */
    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();
    temp = ccn_charbuf_create();
    ccn_charbuf_putf(temp, "%d", ++(selfp->intdata));
    ccn_name_append(name, temp->buf, temp->length);
    ccn_charbuf_destroy(&temp);
    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);
}
示例#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
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;
    struct ccn_charbuf *temp = NULL;
    const unsigned char *ccnb = NULL;
    size_t ccnb_size = 0;
    const unsigned char *data = NULL;
    size_t data_size = 0;
    // TANG: no need to write data to stdout
    //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 && kind != CCN_UPCALL_CONTENT_UNVERIFIED)
        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;
    /* XXX - must verify sig, and make sure it is LEAF content */
    res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &data, &data_size);
    if (res < 0) abort();
    if (data_size > CHUNK_SIZE) {
        /* For us this is spam. Give up now. */
        fprintf(stderr, "*** Segment %d found with a data size of %d."
                        " This program only works with segments of 1024 bytes."
                        " Try ccncatchunks2 instead.\n",
                        (int)selfp->intdata, (int)data_size);
        exit(1);
    }
    
    /* OK, we will accept this block. */
    //sleep(1);
    // TANG: No need to write data to stdout, skip 3 lines
    //written = fwrite(data, data_size, 1, stdout);
    //if (written != 1)
    //    exit(1);
    
    /* A short block signals EOF for us. */
    // TANG: to support data_size smaller than 1024, skip 2 lines
    //if (data_size < CHUNK_SIZE)
    //    exit(0);
    
    /* Ask for the next one */
    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();
    temp = ccn_charbuf_create();
	//printf("intdata = %d \n ", selfp->intdata);
    ccn_charbuf_putf(temp, "%d", ++(selfp->intdata));
    ccn_name_append(name, temp->buf, temp->length);
    ccn_charbuf_destroy(&temp);
	
	if(DEBUG){
		//Print out the interest's name
		printf("Interest name = ");
		
		int myres = 0;
		struct ccn_indexbuf* ndx = ccn_indexbuf_create();
		unsigned char* mycomp = NULL;
		size_t mysize = 0;
		
		ndx->n = 0;
		myres = ccn_name_split(name, ndx);
		if(myres < 0){
			fprintf(stderr, "ccn_name_split @ ccntraffic. failed");
		}
		
		int it = 0;
		for(it = 0; it < ndx->n-1; it++){
			mysize = 0;
			myres = ccn_name_comp_get(name->buf, ndx, it, &mycomp, &mysize);
			printf("%s/", mycomp);
			mycomp = NULL;
		}
		
		printf("\n");
	}
	
    templ = make_template(md);

    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);
}
示例#15
0
int
sync_cb(struct ccns_name_closure *nc,
		struct ccn_charbuf *lhash,
		struct ccn_charbuf *rhash,
		struct ccn_charbuf *name)
{
	nlsr_lock();
	int res;
	struct ccn_charbuf *content_name; 
	struct ccn_indexbuf *content_comps;
	struct ccn_indexbuf *name_comps;
	
	content_comps = ccn_indexbuf_create();
	res = ccn_name_split(name, content_comps);
	if ( res < 0 )
		return 0;
	
	if (content_comps->n < 2)
		return 0;

	content_name = ccn_charbuf_create();
	ccn_name_init(content_name);
	
	res = ccn_name_append_components( content_name,	name->buf,
			content_comps->buf[0], content_comps->buf[content_comps->n - 1]);

	if ( res < 0)
		return 0;

	// for debugging
	struct ccn_charbuf *temp=ccn_charbuf_create();
	ccn_uri_append(temp, content_name->buf, content_name->length, 0);
	if ( nlsr->debugging )
		printf("Name before chopping: %s \n",ccn_charbuf_as_string(temp));
	ccn_charbuf_destroy(&temp);

	name_comps = ccn_indexbuf_create();
	res=ccn_name_split (content_name, name_comps);
	if (res < 0)
		return 0;		

	if ( nlsr->debugging )
	{
		printf("Number of components in name = %d \n",res);
		printf("Number of components in name as indexbuf->n = %d \n",
				(int)name_comps->n);
	}

	ccn_name_chop(content_name, name_comps, -3);
	if ( nlsr->debugging )
		printf("Number of components in name as indexbuf->n after chopping= %d \n"
				, (int)name_comps->n);	

	//for debugging 
	struct ccn_charbuf *temp1=ccn_charbuf_create();
	ccn_uri_append(temp1, content_name->buf, content_name->length, 0);
	if ( nlsr->debugging )
		printf("Name after chopping: %s \n",ccn_charbuf_as_string(temp1));
	ccn_charbuf_destroy(&temp1);

	//main method that processes contents from the sync
	process_content_from_sync(content_name, name_comps);
	
	ccn_charbuf_destroy(&content_name);
	ccn_indexbuf_destroy(&content_comps);
	ccn_indexbuf_destroy(&name_comps);

	nlsr_unlock();
	return(0);
}
示例#16
0
/**
 * Call-back from the CCN network that something has arrived
 *
 * We get notified that a client has interests in things we are producing.
 * This function will do some basic checking to see what exactly the client has
 * an interest in, and will produce what is appropriate.
 * Currently the things we produce are:
 * \li last block - we resend the last block we have published for a given name
 * \li last segment - we produce a data message that only contains the latest segment number we used
 *
 * \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
new_interests (struct ccn_closure *selfp,
    enum ccn_upcall_kind kind, struct ccn_upcall_info *info)
{
  Gstccnxsink *me = GST_CCNXSINK (selfp->data);
  struct ccn_charbuf *cb;
  struct ccn_charbuf *sname = NULL;
  const unsigned char *cp1, *cp2;
  size_t sz1;
  size_t sz2;
  long lastSeq;
  struct ccn_signing_params myparams;
  unsigned int i;
  int rc;


  GST_DEBUG ("something has arrived!");
  GST_DEBUG ("matched is: %d", info->matched_comps);    // number of filter components that were matched by the interest
  cb = interestAsUri (info);
  GST_DEBUG ("as URI: %s", ccn_charbuf_as_string (cb));
  ccn_charbuf_destroy (&cb);

  myparams = me->sp;

  /* Some debugging stuff */
  for (i = 0; i < 10; ++i) {
    const unsigned char *cp;
    size_t sz;
    GST_DEBUG ("%3d: ", i);
    if (0 > ccn_name_comp_get (info->interest_ccnb, info->interest_comps, i,
            &cp, &sz)) {
      // fprintf(stderr, "could not get comp\n");
      break;
    } else {
      // hDump( DUMP_ADDR( cp ), DUMP_SIZE( sz ) );
    }
  }

  switch (kind) {

    case CCN_UPCALL_FINAL:
      GST_LOG_OBJECT (me, "CCN upcall final %p", selfp);
      return (0);

    case CCN_UPCALL_INTEREST_TIMED_OUT:
      if (selfp != me->ccn_closure) {
        GST_LOG_OBJECT (me, "CCN Interest timed out on dead closure %p", selfp);
        return (0);
      }
      GST_LOG_OBJECT (me, "CCN upcall reexpress -- timed out");
      if (me->timeouts > 5) {
        GST_LOG_OBJECT (me, "CCN upcall reexpress -- too many reexpressions");
        return (0);
      }
      me->timeouts++;
      return (CCN_UPCALL_RESULT_REEXPRESS);

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

    case CCN_UPCALL_CONTENT:
      if (selfp != me->ccn_closure) {
        GST_LOG_OBJECT (me, "CCN content on dead closure %p", selfp);
        return (0);
      }
      break;

    case CCN_UPCALL_CONTENT_BAD:
      GST_LOG_OBJECT (me,
          "Content signature verification failed! Discarding.\n");
      return (CCN_UPCALL_RESULT_ERR);

    case CCN_UPCALL_CONSUMED_INTEREST:
      GST_LOG_OBJECT (me, "Upcall consumed interest\n");
      return (CCN_UPCALL_RESULT_ERR);   /* no data */

      /* Here is the most interesting case...when an interest arrives */
    case CCN_UPCALL_INTEREST:
      GST_INFO ("We got an interest\n");
      myparams.freshness = 1;   /* meta data is old very quickly */

      /* See if any meta information is sought */
      for (i = 0;; ++i) {
        if (0 > ccn_name_comp_get (info->interest_ccnb, info->interest_comps, i,
                &cp1, &sz1)) {
          cp1 = NULL;
          break;
        } else {
          if (!strncmp ((const char *) cp1, "_meta_", 6)) {     // OK, found meta, now which one is needed?
            if (0 > ccn_name_comp_get (info->interest_ccnb,
                    info->interest_comps, i + 1, &cp2, &sz2)) {
              GST_LOG_OBJECT (me,
                  "CCN interest received with invalid meta request");
              cp1 = NULL;
            }
            break;
          }                     // Component not meta, keep looking
        }
      }                         // At this point, i is left pointing at '_meta_' or at the end of component list

      if (cp1) {
        // hDump( DUMP_ADDR(cp1), DUMP_SIZE(sz1) );
        // hDump( DUMP_ADDR(cp2), DUMP_SIZE(sz2) );
        if (strncmp ((const char *) cp2, ".segment", 8))
          goto Exit_Interest;   /* not a match */

        /* publish what segment we are up to in reply to the meta request */
        lastSeq = me->segment - 1;
        GST_INFO ("sending meta data....segment: %d", lastSeq);

        sname = ccn_charbuf_create ();
        ccn_name_init (sname);
        rc = ccn_name_append_components (sname, info->interest_ccnb,
            info->interest_comps->buf[0], info->interest_comps->buf[i + 2]);
        if (rc < 0)
          goto Error_Interest;
        // rc = ccn_create_version(me->ccn, sname, CCN_V_REPLACE | CCN_V_NOW | CCN_V_HIGH, 0, 0);
        // if (rc < 0) goto Error_Interest;
        me->temp->length = 0;
        rc = ccn_sign_content (me->ccn, me->temp, sname, &myparams,
            &lastSeq, sizeof (lastSeq));
        // hDump(DUMP_ADDR(sname->buf), DUMP_SIZE(sname->length));
        if (rc != 0) {
          GST_LOG_OBJECT (me, "Failed to encode ContentObject (rc == %d)\n",
              rc);
          goto Error_Interest;
        }

        GST_INFO ("sending meta data...");
        // hDump(DUMP_ADDR(me->temp->buf), DUMP_SIZE(me->temp->length));
        rc = ccn_put (me->ccn, me->temp->buf, me->temp->length);
        me->temp->length = 0;
        if (rc < 0) {
          GST_LOG_OBJECT (me, "ccn_put failed (res == %d)\n", rc);
          goto Error_Interest;
        }
        GST_INFO ("meta data sent");

      } else
        goto Exit_Interest;     /* do not have _meta_ */

    Exit_Interest:
      ccn_charbuf_destroy (&sname);
      break;

    Error_Interest:
      ccn_charbuf_destroy (&sname);
      return CCN_UPCALL_RESULT_ERR;


    default:
      GST_LOG_OBJECT (me, "CCN upcall result error");
      return (CCN_UPCALL_RESULT_ERR);
  }


  me->timeouts = 0;


  return (CCN_UPCALL_RESULT_OK);

}
示例#17
0
文件: ccnls.c 项目: Emat12/ccnx
enum ccn_upcall_res
incoming_content(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    struct ccn_charbuf *c = NULL;
    struct ccn_charbuf *comp = NULL;
    struct ccn_charbuf *uri = NULL;
    struct ccn_charbuf *templ = NULL;
    const unsigned char *ccnb = NULL;
    size_t ccnb_size = 0;
    struct ccn_indexbuf *comps = NULL;
    int matched_comps = 0;
    int res;
    int i;
    struct upcalldata *data = selfp->data;
    
    if (data->magic != 856372) abort();
    if (kind == CCN_UPCALL_FINAL)
        return(CCN_UPCALL_RESULT_OK);
    if (kind == CCN_UPCALL_INTEREST_TIMED_OUT)
        return(CCN_UPCALL_RESULT_REEXPRESS);
    if (kind == CCN_UPCALL_CONTENT_UNVERIFIED) {
        if ((data->option & MUST_VERIFY) != 0)
        return(CCN_UPCALL_RESULT_VERIFY);
        }
    else if (kind != CCN_UPCALL_CONTENT) abort();
    
    ccnb = info->content_ccnb;
    ccnb_size = info->pco->offset[CCN_PCO_E];
    comps = info->content_comps;
    matched_comps = info->pi->prefix_comps;
    c = ccn_charbuf_create();
    uri = ccn_charbuf_create();
    templ = ccn_charbuf_create();
    /* note that comps->n is 1 greater than the number of explicit components */
    if (matched_comps > comps->n) {
        ccn_uri_append(c, ccnb, ccnb_size, 1);
        fprintf(stderr, "How did this happen?  %s\n", ccn_charbuf_as_string(uri));
        exit(1);
    }
    data->counter[0]++;
    /* Recover the same prefix as before */
    ccn_name_init(c);
    res = ccn_name_append_components(c, info->interest_ccnb,
                                     info->interest_comps->buf[0],
                                     info->interest_comps->buf[matched_comps]);
    if (res < 0) abort();
    
    comp = ccn_charbuf_create();
    ccn_name_init(comp);
    if (matched_comps + 1 == comps->n) {
        /* Reconstruct the implicit ContentObject digest component */
        ccn_digest_ContentObject(ccnb, info->pco);
        ccn_name_append(comp, info->pco->digest, info->pco->digest_bytes);
    }
    else if (matched_comps < comps->n) {
        ccn_name_append_components(comp, ccnb,
                                   comps->buf[matched_comps],
                                   comps->buf[matched_comps + 1]);
    }
    res = ccn_uri_append(uri, comp->buf, comp->length, 0);
    if (res < 0 || uri->length < 1)
        fprintf(stderr, "*** Error: ccnls line %d res=%d\n", __LINE__, res);
    else {
        if (uri->length == 1)
            ccn_charbuf_append(uri, ".", 1);
        printf("%s%s\n", ccn_charbuf_as_string(uri) + 1,
               kind == CCN_UPCALL_CONTENT ? " [verified]" : " [unverified]");
    }
    ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
    ccn_charbuf_append(templ, c->buf, c->length); /* Name */
    if (matched_comps == comps->n) {
        /* The interest supplied the digest component */
        ccn_charbuf_destroy(&comp);
        /*
         * We can't rely on the Exclude filter to keep from seeing this, so 
         * say that we need at least one more name component.
         */
        ccn_charbuf_append_tt(templ, CCN_DTAG_MinSuffixComponents, CCN_DTAG);
        ccn_charbuf_append_tt(templ, 1, CCN_UDATA);
        ccn_charbuf_append(templ, "1", 1);
        ccn_charbuf_append_closer(templ); /* </MinSuffixComponents> */
    }
    else {
        data->excl = realloc(data->excl, (data->n_excl + 1) * sizeof(data->excl[0]));
        data->excl[data->n_excl++] = comp;
        comp = NULL;
    }
    qsort(data->excl, data->n_excl, sizeof(data->excl[0]), &namecompare);
    ccn_charbuf_append_tt(templ, CCN_DTAG_Exclude, CCN_DTAG);
    for (i = 0; i < data->n_excl; i++) {
        comp = data->excl[i];
        if (comp->length < 4) abort();
        ccn_charbuf_append(templ, comp->buf + 1, comp->length - 2);
    }
    comp = NULL;
    ccn_charbuf_append_closer(templ); /* </Exclude> */
    ccnb_tagged_putf(templ, CCN_DTAG_AnswerOriginKind, "%d", CCN_AOK_CS);
    if (data->scope > -1)
       ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", data->scope);
    ccn_charbuf_append_closer(templ); /* </Interest> */
    if (templ->length > data->warn) {
        fprintf(stderr, "*** Interest packet is %d bytes\n", (int)templ->length);
        data->warn = data->warn * 8 / 5;
    }
    ccn_express_interest(info->h, c, selfp, templ);
    ccn_charbuf_destroy(&templ);
    ccn_charbuf_destroy(&c);
    ccn_charbuf_destroy(&uri);
    return(CCN_UPCALL_RESULT_OK);
}
示例#18
0
/*
 * This upcall gets called for each piece of incoming content that
 * matches one of our interests.  We need to issue a new interest that
 * excludes another component at the current level, and perhaps also
 * and interest to start exploring the next level.  Thus if the matched
 * interest is
 *   /a/b/c exclude {d,e,f,i,j,k}
 * and we get
 *   /a/b/c/g/h
 * we would issue a new interest
 *   /a/b/c exclude {d,e,f,g,i,j,k}
 * to continue exploring the current level, plus a simple interest
 *   /a/b/c/g
 * to start exploring the next level as well.
 *
 * This does end up fetching each piece of content multiple times, once for
 * each level in the name. The repeated requests will be answered from the local
 * content store, though, and so should not generate extra network traffic.
 * There is a lot of unanswerable interest generated, though.
 *
 * To prevent the interests from becoming too huge, we may need to split them.
 * Thus if the first new interest above were deemed too large, we could instead
 * issue the two interests
 *   /a/b/c exclude {d,e,f,g,*}
 *   /a/b/c exclude {*,g,i,j,k}
 * where * stands for a Bloom filter that excludes anything.  Note the
 * repetition of g to ensure that these two interests cover disjoint portions
 * of the hierarchy. We need to keep track of the endpoint conditions
 * as well as the excluded set in our upcall data.
 * When a split happens, we need a new closure to track it, as we do when
 * we start exploring a new level.
 */
static enum ccn_upcall_res
incoming_content(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    struct ccn_charbuf *c = NULL;
    struct ccn_charbuf *comp = NULL;
    struct ccn_charbuf *uri = NULL;
    const unsigned char *ccnb = NULL;
    size_t ccnb_size = 0;
    struct ccn_indexbuf *comps = NULL;
    int matched_comps = 0;
    int res;
    int i;
    struct ccn_traversal *data = get_my_data(selfp);

    if (kind == CCN_UPCALL_FINAL) {
        for (i = 0; i < data->n_excl; i++)
            ccn_charbuf_destroy(&(data->excl[i]));
        if (data->excl != NULL)
            free(data->excl);
        free(data);
        free(selfp);
        return(0);
    }
    if (kind == CCN_UPCALL_INTEREST_TIMED_OUT)
        return(0);
    if (kind == CCN_UPCALL_CONTENT_BAD)
        return(0);
    if (kind == CCN_UPCALL_CONTENT_UNVERIFIED) {
        if ((data->flags & MUST_VERIFY) != 0)
            return(CCN_UPCALL_RESULT_VERIFY);
    }
    if (kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED) abort();

    ccnb = info->content_ccnb;
    ccnb_size = info->pco->offset[CCN_PCO_E];
    comps = info->content_comps;
    matched_comps = info->pi->prefix_comps;
    c = ccn_charbuf_create();
    uri = ccn_charbuf_create();

    if (matched_comps + 1 > comps->n) {
        ccn_uri_append(c, ccnb, ccnb_size, 1);
        fprintf(stderr, "How did this happen?  %s\n", ccn_charbuf_as_string(uri));
        exit(1);
    }

    data->counter[0]++; /* Tell main that something new came in */

    /* Recover the same prefix as before */
    ccn_name_init(c);
    ccn_name_append_components(c, ccnb, comps->buf[0], comps->buf[matched_comps]);

    comp = ccn_charbuf_create();
    ccn_name_init(comp);
    if (matched_comps + 1 == comps->n) {
        /* Reconstruct the implicit content digest component */
        ccn_digest_ContentObject(ccnb, info->pco);
        ccn_name_append(comp, info->pco->digest, info->pco->digest_bytes);
    }
    else {
        ccn_name_append_components(comp, ccnb,
        comps->buf[matched_comps],
        comps->buf[matched_comps + 1]);
    }
    data->excl = realloc(data->excl, (data->n_excl + 1) * sizeof(data->excl[0]));
    data->excl[data->n_excl++] = comp;
    comp = NULL;
    qsort(data->excl, data->n_excl, sizeof(data->excl[0]), &namecompare);
    res = express_my_interest(info->h, selfp, c);
    if (res == -1) {
        struct ccn_closure *high = split_my_excludes(selfp);
        if (high == NULL) abort();
        express_my_interest(info->h, selfp, c);
        express_my_interest(info->h, high, c);
    }
    /* Explore the next level, if there is one. */
    if (matched_comps + 2 < comps->n) {
        struct ccn_traversal *newdat = NULL;
        struct ccn_closure *cl;
        newdat = calloc(1, sizeof(*newdat));
        newdat->magic = 68955871;
        newdat->warn = 1492;
        newdat->counter = data->counter;
        newdat->flags = data->flags & ~(EXCLUDE_LOW | EXCLUDE_HIGH);
        newdat->n_excl = 0;
        newdat->excl = NULL;
        cl = calloc(1, sizeof(*cl));
        cl->p = &incoming_content;
        cl->data = newdat;
        ccn_name_init(c);
        ccn_name_append_components(c, ccnb,
        comps->buf[0],
        comps->buf[matched_comps + 1]);
        express_my_interest(info->h, cl, c);
    }
    else {
        res = ccn_uri_append(uri, info->content_ccnb, info->pco->offset[CCN_PCO_E], 1);
        if (res < 0)
            fprintf(stderr, "*** Error: ccn_traverse line %d res=%d\n", __LINE__, res);
        else
            printf("%s\n", ccn_charbuf_as_string(uri));
    }
    ccn_charbuf_destroy(&c);
    ccn_charbuf_destroy(&uri);
    return(0);
}
示例#19
0
enum ccn_upcall_res
andana_server_decap_interest(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR;
    struct andana_server *server = selfp->data;

    struct ccn_proxy *proxy = server->proxy;

    struct ccn_charbuf *new_interest = NULL;
    struct ccn_charbuf *new_name = NULL;

    struct ccn_charbuf *orig_name = NULL;
    struct ccn_indexbuf *orig_name_indexbuf = NULL;
    int orig_name_ncomps;

    char is_session = 0;

    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;

    int res;


    DEBUG_PRINT("IN %d %s\n", __LINE__, __func__);

    switch (kind) {
    case CCN_UPCALL_INTEREST:
        DEBUG_PRINT("%d %s received interest\n", __LINE__, __func__);
        break;
    case CCN_UPCALL_INTEREST_TIMED_OUT:
        DEBUG_PRINT("%d %s received interest time out\n", __LINE__, __func__);
        /* Fall through */
    default:
        DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__);
        return(CCN_UPCALL_RESULT_OK);
    }


    /* Extract Name from Interest */

    orig_name_ncomps = ccn_util_extract_name(info->interest_ccnb,
                                             info->interest_comps,
                                             &orig_name,
                                             &orig_name_indexbuf);

#ifdef PROXYDEBUG
    ccn_util_print_pc_fmt(orig_name->buf, orig_name->length);
    DEBUG_PRINT("\n");

    DEBUG_PRINT("Name has %lu comps\n", orig_name_indexbuf->n-1);
#endif

    /*Decapsulate & decrypt Interest. */


    const unsigned char *const_encrypted = NULL;
    unsigned char *encrypted = NULL;
    size_t encrypted_size;

    if (orig_name_ncomps >= 2) {
        const unsigned char *session_check = NULL;
        size_t session_check_size;

        res = ccn_name_comp_get(orig_name->buf,
				orig_name_indexbuf,
				(unsigned int)server->SESSION_FLAG,
				&session_check,
				&session_check_size);

        if (res < 0) {
            DEBUG_PRINT("%d %s Error extracting session check component %lu\n", __LINE__, __func__, server->SESSION_FLAG);
            goto SessionFail;
        } else {
            DEBUG_PRINT("%d %s Extracted component %lu\n", __LINE__, __func__,server->SESSION_FLAG);
        }

        if (session_check_size == strlen("SESSION") &&
            memcmp(session_check, "SESSION", session_check_size) == 0) {

            DEBUG_PRINT("%d %s Session identified\n", __LINE__, __func__);
            is_session = 1;

        } else {
            DEBUG_PRINT("%d %s Not a session\n", __LINE__, __func__);
        }
    }



    /* Decrypt the name (contains a new name and an Interest template) */

    struct ccn_pkey *symkey = NULL;
    struct ccn_charbuf *decrypted = NULL;
    struct ccn_indexbuf *decrypted_comps = ccn_indexbuf_create();

    if (is_session) {

        res = ccn_name_comp_get(orig_name->buf,
				orig_name_indexbuf,
				(unsigned int)server->SESSION_ENC,
				&const_encrypted,
				&encrypted_size);

        if (res < 0) {
            DEBUG_PRINT("%d %s Error extracting encrypted session component %lu\n", __LINE__, __func__, server->SESSION_ENC);
            goto SessionParseFail;
        } else {
            DEBUG_PRINT("%d %s Extracted encrypted session component  %lu\n", __LINE__, __func__, server->SESSION_ENC);
        }

        encrypted = calloc(encrypted_size, sizeof(unsigned char));
        memcpy(encrypted, const_encrypted, encrypted_size);

        ccn_crypto_name_sym_decrypt(server->node_key,
                                    encrypted,
                                    encrypted_size,
                                    &symkey,
                                    &decrypted,
                                    &decrypted_comps);
    } else {

        ccn_name_comp_get(orig_name->buf, orig_name_indexbuf, (unsigned int)server->ENC, &const_encrypted, &encrypted_size);
        encrypted = calloc(encrypted_size, sizeof(unsigned char));
        memcpy(encrypted, const_encrypted, encrypted_size);

        ccn_crypto_name_asym_decrypt(server->privkey,
                                     encrypted,
                                     &symkey,
                                     &decrypted,
                                     &decrypted_comps);
    }

    size_t ncomps = decrypted_comps->n-1;
    const unsigned char *tmpl = NULL;
    size_t tmpl_size;

    res = ccn_name_comp_get(decrypted->buf, decrypted_comps, (unsigned int)ncomps - 1, &tmpl, &tmpl_size);

    if (res < 0) {
        DEBUG_PRINT("ABORT %d %s unable to retrieve component %d\n",
                    __LINE__, __func__, (int)ncomps);
        goto CompExtractFail;
    }

    /* Pull timestamp component (comp 0) */
    const unsigned char *ts_data = NULL;
    size_t ts_size;
    res = ccn_name_comp_get(decrypted->buf, decrypted_comps, 0, &ts_data, &ts_size);

    if (res < 0) {
        goto CompExtractFail;
    }

    struct timeval timestamp;
    ccn_util_extract_timestamp(ts_data, ts_size, &timestamp);

    struct timeval window = {.tv_sec = 1, .tv_usec = 600000};

    if (ccn_util_timestamp_window(&timestamp, &window) == 0) {
        /* Timestamp too far away, this may be a replay attack */
        DEBUG_PRINT("%d %s Timestamp too distant\n", __LINE__, __func__);
        goto TimestampFail;
    }

    new_name = ccn_charbuf_create();
    ccn_name_init(new_name);


    res = ccn_name_append_components(new_name,
                                     decrypted->buf,
                                     decrypted_comps->buf[1],
                                     decrypted_comps->buf[ncomps-1]);

    if (res < 0) {
        DEBUG_PRINT("ABORT %d %s unable to append components\n",
                    __LINE__, __func__);
        goto AppendCompFail;
    }


    /*Construct new Interest*/

    if (tmpl_size == 0) {
        /* Detected default template */
        DEBUG_PRINT("%d %s Using default Interest template\n", __LINE__, __func__);
        new_interest = NULL;
    } else {
        DEBUG_PRINT("%d %s Copying Interest template\n", __LINE__, __func__);
        new_interest = ccn_charbuf_create();
        ccn_charbuf_append(new_interest, tmpl, tmpl_size);
    }

    /*Map new name to that of the original Interest and the requested symkey */

    hashtb_start(server->cname_to_pair, e);
    res = hashtb_seek(e, new_name->buf, new_name->length, 0);

    if (res == HT_NEW_ENTRY) {
        struct andana_server_pair *p = andana_server_pair_init(orig_name, symkey);
        struct andana_server_pair **loc = e->data;
        *loc = p;
    } else if (res == HT_OLD_ENTRY) {
        DEBUG_PRINT("Interest recording found old entry\n");
        goto LookupFail;
    } else {
        DEBUG_PRINT("Error in Interest insertion\n");
        goto LookupFail;
    }





    DEBUG_PRINT("%d %s starting to write new interest\n", __LINE__, __func__);

    res = ccn_express_interest(proxy->handle, new_name, proxy->content_handler, new_interest);

    DEBUG_PRINT("%d %s done to writing new interest\n", __LINE__, __func__);

    if(res != 0) {
        DEBUG_PRINT("ABORT %d %s express interest res = %d\n", __LINE__, __func__, res);
        goto SendFail;
    }

    upcall_res = CCN_UPCALL_RESULT_OK;


SendFail:
LookupFail:

    if (upcall_res == CCN_UPCALL_RESULT_ERR) {
        hashtb_delete(e);
    }

    hashtb_end(e);

    if (new_interest != NULL) {
        ccn_charbuf_destroy(&new_interest);
    }

TimestampFail:
AppendCompFail:
    ccn_charbuf_destroy(&new_name);

CompExtractFail:
    ccn_charbuf_destroy(&decrypted);
    free(encrypted);
    ccn_crypto_symkey_destroy(&symkey);

SessionParseFail:
    ccn_indexbuf_destroy(&decrypted_comps);

SessionFail:
    ccn_charbuf_destroy(&orig_name);
    ccn_indexbuf_destroy(&orig_name_indexbuf);

    DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__);

    return(upcall_res);
}

/**
 * Encapsulate and encrypt returning content objects. Encryption
 * uses the ephemeral symmetric key provided by the user in the original
 * interest (stored in a pair).
 *
 * This node will naturally sign the outgoing content object, thus providing
 * verifiability.
 */

enum ccn_upcall_res
andana_server_encap_content(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR;
    struct andana_server *server = selfp->data;
    struct ccn_proxy *proxy = server->proxy;

    struct ccn_charbuf *new_name = NULL;
    struct andana_server_pair **pair_ptr = NULL;
    struct ccn_charbuf *new_content = NULL;
    struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;

    struct hashtb_enumerator ee;
    struct hashtb_enumerator *e = &ee;

    int res;

    DEBUG_PRINT("IN %d %s\n",__LINE__, __func__);

    switch (kind) {
    case CCN_UPCALL_CONTENT:           /**< incoming verified content */
        DEBUG_PRINT("%d %s Incoming verified content\n",__LINE__, __func__);
        break;
    case CCN_UPCALL_CONTENT_UNVERIFIED:/**< content that has not been verified */
        DEBUG_PRINT("%d %s Incoming unverified content\n", __LINE__, __func__);
        break;
    case CCN_UPCALL_CONTENT_BAD:        /**< verification failed */
        DEBUG_PRINT("%d %s Incoming bad content (verification failure)\n", __LINE__, __func__);
        break;

    case CCN_UPCALL_INTEREST_TIMED_OUT:/**< interest timed out */
    {
        DEBUG_PRINT("OUT %d %s Interest timed out\n", __LINE__, __func__);

        const unsigned char *name = info->interest_ccnb + info->pi->offset[CCN_PI_B_Name];
        const size_t length =  info->pi->offset[CCN_PI_E_Name] - info->pi->offset[CCN_PI_B_Name];

        hashtb_start(server->cname_to_pair, e);
        hashtb_seek(e, name, length, 0);
        hashtb_delete(e);
        hashtb_end(e);

        return(CCN_UPCALL_RESULT_OK);
    }
    case CCN_UPCALL_FINAL:/**< handler is about to be deregistered */
        DEBUG_PRINT("OUT %d %s final upcall\n", __LINE__, __func__);
        return(CCN_UPCALL_RESULT_OK);

    case CCN_UPCALL_INTEREST:          /**< incoming interest */
    case CCN_UPCALL_CONSUMED_INTEREST: /**< incoming interest, someone has answered */
    default:
        DEBUG_PRINT("OUT %d %s upcall other kind = %d\n", __LINE__, __func__, kind);
        return(CCN_UPCALL_RESULT_ERR);
    }



    DEBUG_PRINT("%d %s Received content object\n", __LINE__, __func__);

    if (info->content_ccnb == NULL) {
        DEBUG_PRINT("OUT %d %s in content upcall, but no content, check kind: %d\n", __LINE__, __func__, kind);
        return(CCN_UPCALL_RESULT_OK);
    }

    /*Find name in Content Object*/

    new_name = ccn_charbuf_create();
    ccn_name_init(new_name);
    ccn_name_append_components(new_name, info->content_ccnb,
                               info->content_comps->buf[0], info->content_comps->buf[info->matched_comps]);

#ifdef PROXYDEBUG
    DEBUG_PRINT("name matches %d comps\n", info->matched_comps);
    ccn_util_print_pc_fmt(info->content_ccnb + info->pco->offset[CCN_PCO_B_Name],
                          info->pco->offset[CCN_PCO_E_Name] - info->pco->offset[CCN_PCO_B_Name]);
    DEBUG_PRINT("\n");
#endif

    pair_ptr = hashtb_lookup(server->cname_to_pair, new_name->buf, new_name->length);

    if(pair_ptr == NULL) {
        /* No match for name*/
#ifdef PROXYDEBUG
        DEBUG_PRINT("Unsolicited content object with name: ");
        ccn_util_print_pc_fmt(new_name->buf, new_name->length);
        DEBUG_PRINT("\n");
#endif
        goto LookupFail;
    }

    struct ccn_charbuf *orig_name = (*pair_ptr)->name;
    struct ccn_pkey *symkey = (*pair_ptr)->symkey;






    /*Created signed info for new content object*/
    unsigned char *encrypted_content = NULL;
    size_t encrypted_length;

    struct ccn_charbuf *content = ccn_charbuf_create();
    ccn_charbuf_append(content, info->content_ccnb, info->pco->offset[CCN_PCO_E]);

    ccn_crypto_content_encrypt(symkey, content->buf, content->length, &encrypted_content, &encrypted_length);

    new_content = ccn_charbuf_create();
    sp.type = CCN_CONTENT_DATA;

    res = ccn_sign_content(proxy->handle,
                           new_content,
                           orig_name,
                           &sp,
                           encrypted_content,
                           encrypted_length);


    if (ccn_util_validate_content_object(new_content->buf, new_content->length) != 0) {
        DEBUG_PRINT("ABORT %d %s Failed to validated signed content\n", __LINE__, __func__);
        abort();
        goto SignFail;
    } else {
        DEBUG_PRINT("OK %d %s signed content is valid\n", __LINE__, __func__);
    }


    if (res != 0) {
        DEBUG_PRINT("ABORT %d %s Failed to encode ContentObject (res == %d)\n", __LINE__, __func__, res);
        goto SignFail;
    }

    DEBUG_PRINT("%d %s starting content write\n", __LINE__, __func__);

    res = ccn_put(proxy->handle, new_content->buf, new_content->length);

    DEBUG_PRINT("%d %s done content write line\n", __LINE__, __func__);

    if (res < 0) {
        DEBUG_PRINT("ABORT %d %s ccn_put failed (res == %d)\n", __LINE__, __func__, res);
        goto SendFail;
    }

    DEBUG_PRINT("%d %s Reply sent\n", __LINE__, __func__);
    upcall_res = CCN_UPCALL_RESULT_OK;


SendFail:
    hashtb_start(server->cname_to_pair, e);
    hashtb_seek(e, new_name->buf, new_name->length, 0);
    hashtb_delete(e);
    hashtb_end(e);



SignFail:
    ccn_charbuf_destroy(&new_content);
    free(encrypted_content);
    ccn_charbuf_destroy(&content);

LookupFail:
    ccn_charbuf_destroy(&new_name);

    DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__);

    return(upcall_res);
}


/**
 * Clean up and destroy anonymous server object. Expect
 * to be called once at program close.
 *
 * @param pointer to anonymous server to be destroyed
 * @returns 0 (always)
 */

int
andana_server_destroy(struct andana_server **server)
{
    struct andana_server *s = *server;

    free(s->proxy->int_handler);
    free(s->proxy->content_handler);
    ccn_proxy_destroy(&(s->proxy));
    ccn_crypto_pubkey_destroy(&(s->privkey));
    hashtb_destroy(&(s->cname_to_pair));
    free(s);

    return(0);
}