Exemple #1
0
static enum ccn_upcall_res
seqw_incoming_interest(
                       struct ccn_closure *selfp,
                       enum ccn_upcall_kind kind,
                       struct ccn_upcall_info *info)
{
    int res;
    struct ccn_charbuf *cob = NULL;
    struct ccn_seqwriter *w = selfp->data;
    
    if (w == NULL || selfp != &(w->cl))
        abort();
    switch (kind) {
        case CCN_UPCALL_FINAL:
            ccn_charbuf_destroy(&w->nb);
            ccn_charbuf_destroy(&w->nv);
            ccn_charbuf_destroy(&w->buffer);
            ccn_charbuf_destroy(&w->cob0);
            free(w);
            break;
        case CCN_UPCALL_INTEREST:
            if (w->closed || w->buffer->length > 0) {
                cob = seqw_next_cob(w);
                if (cob == NULL)
                    return(CCN_UPCALL_RESULT_OK);
                if (ccn_content_matches_interest(cob->buf, cob->length,
                                                 1, NULL,
                                                 info->interest_ccnb,
                                                 info->pi->offset[CCN_PI_E],
                                                 info->pi)) {
                    w->interests_possibly_pending = 0;
                    res = ccn_put(info->h, cob->buf, cob->length);
                    if (res >= 0) {
                        w->buffer->length = 0;
                        w->seqnum++;
                        return(CCN_UPCALL_RESULT_INTEREST_CONSUMED);
                    }
                }
                ccn_charbuf_destroy(&cob);
            }
            if (w->cob0 != NULL) {
                cob = w->cob0;
                if (ccn_content_matches_interest(cob->buf, cob->length,
                                                 1, NULL,
                                                 info->interest_ccnb,
                                                 info->pi->offset[CCN_PI_E],
                                                 info->pi)) {
                    w->interests_possibly_pending = 0;
                    ccn_put(info->h, cob->buf, cob->length);
                    return(CCN_UPCALL_RESULT_INTEREST_CONSUMED);
                }
            }
            w->interests_possibly_pending = 1;
            break;
        default:
            break;
    }
    return(CCN_UPCALL_RESULT_OK);
}
Exemple #2
0
enum ccn_upcall_res
incoming_interest(
    struct ccn_closure *selfp,
    enum ccn_upcall_kind kind,
    struct ccn_upcall_info *info)
{
    struct ccn_charbuf *cob = selfp->data;
    int res;
    
    switch (kind) {
        case CCN_UPCALL_FINAL:
            break;
        case CCN_UPCALL_INTEREST:
            if (ccn_content_matches_interest(cob->buf, cob->length,
                    1, NULL,
                    info->interest_ccnb, info->pi->offset[CCN_PI_E],
                    info->pi)) {
                res = ccn_put(info->h, cob->buf, cob->length);
                if (res >= 0) {
                    selfp->intdata = 1;
                    ccn_set_run_timeout(info->h, 0);
                    return(CCN_UPCALL_RESULT_INTEREST_CONSUMED);
                }
            }
            break;
        default:
            break;
    }
    return(CCN_UPCALL_RESULT_OK);
}
Exemple #3
0
PyObject *
_pyccn_cmd_content_matches_interest(PyObject *UNUSED(self), PyObject *args)
{
    PyObject *py_content_object, *py_interest;
    struct ccn_charbuf *content_object, *interest;
    struct ccn_parsed_ContentObject *pco;
    struct ccn_parsed_interest *pi;
    int r;
    PyObject *res;

    if (!PyArg_ParseTuple(args, "OO", &py_content_object, &py_interest))
        return NULL;

    if (!CCNObject_IsValid(CONTENT_OBJECT, py_content_object)) {
        PyErr_SetString(PyExc_TypeError, "Expected CCN ContentObject");
        return NULL;
    }

    if (!CCNObject_IsValid(INTEREST, py_interest)) {
        PyErr_SetString(PyExc_TypeError, "Expected CCN Interest");
        return NULL;
    }

    content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object);
    interest = CCNObject_Get(INTEREST, py_interest);

    pco = _pyccn_content_object_get_pco(py_content_object);
    if (!pco)
        return NULL;

    pi = _pyccn_interest_get_pi(py_interest);
    if (!pi)
        return NULL;

    r = ccn_content_matches_interest(content_object->buf,
                                     content_object->length, 1, pco, interest->buf, interest->length,
                                     pi);

    res = r ? Py_True : Py_False;

    return Py_INCREF(res), res;
}
Exemple #4
0
static enum ccn_upcall_res
write_interest_handler (struct ccn_closure *selfp,
                        enum ccn_upcall_kind kind,
                        struct ccn_upcall_info *info) {
    struct ccn_charbuf *cob = selfp->data;
    struct ccn *h = info->h;

    if (kind != CCN_UPCALL_INTEREST)
        return(CCN_UPCALL_RESULT_OK);
    if (ccn_content_matches_interest(cob->buf, cob->length, 1, NULL,
                                     info->interest_ccnb,
                                     info->pi->offset[CCN_PI_E],
                                     info->pi)) {
        ccn_put(info->h, cob->buf, cob->length);
        selfp->intdata = 1;
        ccn_set_run_timeout(h, 0);
        return(CCN_UPCALL_RESULT_INTEREST_CONSUMED);
    }
    return(CCN_UPCALL_RESULT_OK);
}
Exemple #5
0
/**
 * Consume matching interests
 * given a nameprefix_entry and a piece of content.
 *
 * If fdholder is not NULL, pay attention only to interests from that fdholder.
 * It is allowed to pass NULL for pc, but if you have a (valid) one it
 * will avoid a re-parse.
 * @returns number of matches found.
 */
PUBLIC int
r_match_consume_matching_interests(struct ccnr_handle *h,
                           struct nameprefix_entry *npe,
                           struct content_entry *content,
                           struct ccn_parsed_ContentObject *pc,
                           struct fdholder *fdholder)
{
    int matches = 0;
    struct propagating_entry *head;
    struct propagating_entry *next;
    struct propagating_entry *p;
    const unsigned char *content_msg;
    size_t content_size;
    struct fdholder *f;
    
    head = &npe->pe_head;
    // XXX - i do not think this is called in practice
    content_msg = r_store_content_base(h, content);
    content_size = r_store_content_size(h, content);
    f = fdholder;
    for (p = head->next; p != head; p = next) {
        next = p->next;
        if (p->interest_msg != NULL &&
            ((fdholder == NULL && (f = r_io_fdholder_from_fd(h, p->filedesc)) != NULL) ||
             (fdholder != NULL && p->filedesc == fdholder->filedesc))) {
            if (ccn_content_matches_interest(content_msg, content_size, 1, pc,
                                             p->interest_msg, p->size, NULL)) {
                r_sendq_face_send_queue_insert(h, f, content);
                if (CCNSHOULDLOG(h, (32 | 8), CCNL_FINE))
                    ccnr_debug_ccnb(h, __LINE__, "consume", f,
                                    p->interest_msg, p->size);
                matches += 1;
                r_match_consume_interest(h, p);
            }
        }
    }
    return(matches);
}
Exemple #6
0
// handling incoming interest when it is incoming / received
static enum ccn_upcall_res incoming_interest (
		struct ccn_closure *selfp,
		enum ccn_upcall_kind kind,
		struct ccn_upcall_info *info)
{
	struct ccn_charbuf *cob = selfp -> data;
	int res;

	switch (kind) {
	case CCN_UPCALL_FINAL:              // handler is about to be deregistered
		printf("deregistering handler...\n");
		return CCN_UPCALL_RESULT_OK;

	case CCN_UPCALL_INTEREST:           // incoming interest; cob is content, info is incoming interest
		if (ccn_content_matches_interest(cob -> buf, cob -> length, 1, NULL, info -> interest_ccnb, info -> pi -> offset[CCN_PI_E], info -> pi)) {
			res = ccn_put(info->h, cob->buf, cob->length);
			if (res >= 0) {
				selfp -> intdata = 1;
				ccn_set_run_timeout(info->h, 0);
				return (CCN_UPCALL_RESULT_INTEREST_CONSUMED);
			}
		}
		break;

	//case CCN_UPCALL_CONSUMED_INTEREST:  // incoming interest, someone has answered
	//case CCN_UPCALL_CONTENT:            // incoming verified content
	//case CCN_UPCALL_INTEREST_TIMED_OUT:  // interest timed out
	//case CCN_UPCALL_CONTENT_UNVERIFIED:  // content that has not been verified
	//case CCN_UPCALL_CONTENT_BAD:         // verification failed

	default:
		printf("Unexpected response.\n");
		return CCN_UPCALL_RESULT_ERR;
	}
	return (CCN_UPCALL_RESULT_OK);
}
/**
 * Common interest handler
 */
PUBLIC enum ccn_upcall_res
ccnr_answer_req(struct ccn_closure *selfp,
                 enum ccn_upcall_kind kind,
                 struct ccn_upcall_info *info)
{
    struct ccn_charbuf *msg = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *keylocator = NULL;
    struct ccn_charbuf *signed_info = NULL;
    struct ccn_charbuf *reply_body = NULL;
    struct ccnr_handle *ccnr = NULL;
    int res = 0;
    int morecomps = 0;
    const unsigned char *final_comp = NULL;
    size_t final_size = 0;
    
    switch (kind) {
        case CCN_UPCALL_FINAL:
            free(selfp);
            return(CCN_UPCALL_RESULT_OK);
        case CCN_UPCALL_INTEREST:
            break;
        case CCN_UPCALL_CONSUMED_INTEREST:
            return(CCN_UPCALL_RESULT_OK);
        default:
            return(CCN_UPCALL_RESULT_ERR);
    }
    ccnr = (struct ccnr_handle *)selfp->data;
    if (CCNSHOULDLOG(ccnr, LM_128, CCNL_FINE))
        ccnr_debug_ccnb(ccnr, __LINE__, "ccnr_answer_req", NULL,
                        info->interest_ccnb, info->pi->offset[CCN_PI_E]);
    morecomps = selfp->intdata & MORECOMPS_MASK;
    if ((info->pi->answerfrom & CCN_AOK_NEW) == 0 &&
        selfp->intdata != OP_SERVICE)
        return(CCN_UPCALL_RESULT_OK);
    if (info->matched_comps >= info->interest_comps->n)
        goto Bail;
    if ((selfp->intdata & OPER_MASK) != OP_SERVICE &&
        info->pi->prefix_comps != info->matched_comps + morecomps)
        goto Bail;
    if (morecomps == 1) {
        res = ccn_name_comp_get(info->interest_ccnb, info->interest_comps,
                                info->matched_comps,
                                &final_comp, &final_size);
        if (res < 0)
            goto Bail;
    }
    if ((selfp->intdata & MUST_VERIFY) != 0) {
        struct ccn_parsed_ContentObject pco = {0};
        // XXX - probably should check for message origin BEFORE verify
        res = ccn_parse_ContentObject(final_comp, final_size, &pco, NULL);
        if (res < 0) {
            ccnr_debug_ccnb(ccnr, __LINE__, "co_parse_failed", NULL,
                            info->interest_ccnb, info->pi->offset[CCN_PI_E]);
            goto Bail;
        }
        res = ccn_verify_content(info->h, final_comp, &pco);
        if (res != 0) {
            ccnr_debug_ccnb(ccnr, __LINE__, "co_verify_failed", NULL,
                            info->interest_ccnb, info->pi->offset[CCN_PI_E]);
            goto Bail;
        }
    }
    switch (selfp->intdata & OPER_MASK) {
        case OP_SERVICE:
            if (ccnr->service_ccnb == NULL)
                ccnr->service_ccnb = ccnr_init_service_ccnb(ccnr, info->h, CCNRID_LOCAL_URI, 600);
            if (ccn_content_matches_interest(
                    ccnr->service_ccnb->buf,
                    ccnr->service_ccnb->length,
                    1,
                    NULL,
                    info->interest_ccnb,
                    info->pi->offset[CCN_PI_E],
                    info->pi
                )) {
                ccn_put(info->h, ccnr->service_ccnb->buf,
                                 ccnr->service_ccnb->length);
                res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
                goto Finish;
            }
            // XXX this needs refactoring.
            if (ccnr->neighbor_ccnb == NULL)
                ccnr->neighbor_ccnb = ccnr_init_service_ccnb(ccnr, info->h, CCNRID_NEIGHBOR_URI, 5);
            if (ccn_content_matches_interest(
                    ccnr->neighbor_ccnb->buf,
                    ccnr->neighbor_ccnb->length,
                    1,
                    NULL,
                    info->interest_ccnb,
                    info->pi->offset[CCN_PI_E],
                    info->pi
                )) {
                ccn_put(info->h, ccnr->neighbor_ccnb->buf,
                                 ccnr->neighbor_ccnb->length);
                res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
                goto Finish;
            }
            if (ccn_content_matches_interest(
                                             ccnr->policy_link_cob->buf,
                                             ccnr->policy_link_cob->length,
                                             1,
                                             NULL,
                                             info->interest_ccnb,
                                             info->pi->offset[CCN_PI_E],
                                             info->pi
                                             )) {
                ccn_put(info->h, ccnr->policy_link_cob->buf,
                        ccnr->policy_link_cob->length);
                res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
                goto Finish;
            }
            goto Bail;
            break;
        default:
            // No other OP_xxx are supported here
            goto Bail;
    }
Bail:
    res = CCN_UPCALL_RESULT_ERR;
Finish:
    ccn_charbuf_destroy(&msg);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&keylocator);
    ccn_charbuf_destroy(&reply_body);
    ccn_charbuf_destroy(&signed_info);
    return(res);
}