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); }
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); }
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; }
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); }
/** * 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); }
// 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); }