/** * Destroy the ccnr instance, releasing all associated resources. */ PUBLIC void r_init_destroy(struct ccnr_handle **pccnr) { struct ccnr_handle *h = *pccnr; int stable; if (h == NULL) return; stable = h->active_in_fd == -1 ? 1 : 0; r_io_shutdown_all(h); ccnr_direct_client_stop(h); ccn_schedule_destroy(&h->sched); hashtb_destroy(&h->propagating_tab); hashtb_destroy(&h->nameprefix_tab); hashtb_destroy(&h->enum_state_tab); hashtb_destroy(&h->content_by_accession_tab); // SyncActions sync_stop method should be shutting down heartbeat if (h->sync_plumbing) { h->sync_plumbing->sync_methods->sync_stop(h->sync_plumbing, NULL); free(h->sync_plumbing); h->sync_plumbing = NULL; h->sync_base = NULL; // freed by sync_stop ? } r_store_final(h, stable); if (h->fds != NULL) { free(h->fds); h->fds = NULL; h->nfds = 0; } if (h->fdholder_by_fd != NULL) { free(h->fdholder_by_fd); h->fdholder_by_fd = NULL; h->face_limit = h->face_gen = 0; } if (h->content_by_cookie != NULL) { free(h->content_by_cookie); h->content_by_cookie = NULL; h->cookie_limit = 1; } ccn_charbuf_destroy(&h->scratch_charbuf); ccn_indexbuf_destroy(&h->skiplinks); ccn_indexbuf_destroy(&h->scratch_indexbuf); ccn_indexbuf_destroy(&h->unsol); if (h->parsed_policy != NULL) { ccn_indexbuf_destroy(&h->parsed_policy->namespaces); ccn_charbuf_destroy(&h->parsed_policy->store); free(h->parsed_policy); h->parsed_policy = NULL; } ccn_charbuf_destroy(&h->policy_name); ccn_charbuf_destroy(&h->policy_link_cob); ccn_charbuf_destroy(&h->ccnr_keyid); free(h); *pccnr = NULL; }
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; }
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; }
extern void SyncFreeBase(struct SyncBaseStruct **bp) { if (bp != NULL) { struct SyncBaseStruct *base = *bp; *bp = NULL; if (base != NULL) { struct SyncPrivate *priv = base->priv; // free the errList SyncClearErr(base); // free the roots while (priv->rootHead != NULL) { if (SyncRemRoot(priv->rootHead) != NULL) break; } // free the name accums if (priv->topoAccum != NULL) SyncFreeNameAccumAndNames(priv->topoAccum); if (priv->prefixAccum != NULL) SyncFreeNameAccumAndNames(priv->prefixAccum); if (priv->comps != NULL) ccn_indexbuf_destroy(&priv->comps); ccn_charbuf_destroy(&priv->sliceCmdPrefix); free(priv); free(base); } } }
int main(void) { int res; struct ccn_charbuf *name = NULL; struct ccn_indexbuf *comps = NULL; const unsigned char *comp0 = NULL; size_t comp0size; gen_test(&name, &comps); res = ccn_name_comp_get(name->buf, comps, 0, &comp0, &comp0size); if (res < 0) { printf("Unable to get comp\n"); return(-__LINE__); } intmax_t rec_secs = 0; int rec_nsecs = 0; reclaim_ts(comp0, comp0size, &rec_secs, &rec_nsecs); // printf("seconds = %lu %s\n", rec_secs, (secs == rec_secs)?("YES"):("NO")); // printf("nano seconds = %d %s\n", rec_nsecs, (nsecs == rec_nsecs)?("YES"):("NO")); ccn_charbuf_destroy(&name); ccn_indexbuf_destroy(&comps); return(0); }
/* * deliver_content is used to deliver a previously-buffered * ContentObject to the client. */ static enum ccn_upcall_res deliver_content(struct ccn *h, struct bulkdata *b) { struct ccn_upcall_info info = {0}; struct ccn_parsed_ContentObject obj = {0}; struct pending *p = b->first; int res; enum ccn_upcall_res ans; assert(p != NULL && p->x == b->next_expected && p->content_ccnb != NULL); info.pco = &obj; info.content_comps = ccn_indexbuf_create(); res = ccn_parse_ContentObject(p->content_ccnb, p->content_size, &obj, info.content_comps); assert(res >= 0); info.content_ccnb = p->content_ccnb; info.matched_comps = info.content_comps->n - 2; /* XXX - we have no matched interest to present */ ans = (*b->client->p)(b->client, CCN_UPCALL_CONTENT, &info); // XXX - check for refusal info.content_ccnb = NULL; free(p->content_ccnb); p->content_ccnb = NULL; p->content_size = 0; ccn_indexbuf_destroy(&info.content_comps); if (ans == CCN_UPCALL_RESULT_OK) { struct ccn_closure *old = &p->closure; if ((--(old->refcount)) == 0) { info.pco = NULL; (old->p)(old, CCN_UPCALL_FINAL, &info); } } return(ans); }
static int parse_ContentObject(PyObject *py_content_object) { struct content_object_data *context; struct ccn_charbuf *content_object; int r; assert(CCNObject_IsValid(CONTENT_OBJECT, py_content_object)); context = PyCapsule_GetContext(py_content_object); assert(context); if (context->pco) free(context->pco); ccn_indexbuf_destroy(&context->comps); /* * no error happens between deallocation and following line, so I'm not * setting context->pco to NULL */ context->pco = calloc(1, sizeof(struct ccn_parsed_ContentObject)); JUMP_IF_NULL_MEM(context->pco, error); context->comps = ccn_indexbuf_create(); JUMP_IF_NULL_MEM(context->comps, error); content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object); r = ccn_parse_ContentObject(content_object->buf, content_object->length, context->pco, context->comps); if (r < 0) { PyErr_SetString(g_PyExc_CCNContentObjectError, "Unable to parse the" " ContentObject"); goto error; } return 0; error: if (context->pco) { free(context->pco); context->pco = NULL; } ccn_indexbuf_destroy(&context->comps); return -1; }
void ccnr_internal_client_stop(struct ccnr_handle *ccnr) { ccnr->notice = NULL; /* ccn_destroy will free */ if (ccnr->notice_push != NULL) ccn_schedule_cancel(ccnr->sched, ccnr->notice_push); ccn_indexbuf_destroy(&ccnr->chface); ccn_destroy(&ccnr->internal_client); ccn_charbuf_destroy(&ccnr->service_ccnb); ccn_charbuf_destroy(&ccnr->neighbor_ccnb); if (ccnr->internal_client_refresh != NULL) ccn_schedule_cancel(ccnr->sched, ccnr->internal_client_refresh); }
PUBLIC void ccnr_parsed_policy_destroy(struct ccnr_parsed_policy **ppp) { struct ccnr_parsed_policy *pp; if (*ppp == NULL) return; pp = *ppp; ccn_charbuf_destroy(&pp->store); ccn_indexbuf_destroy(&pp->namespaces); free(pp); *ppp = NULL; }
int decode_message(struct ccn_charbuf *message, struct path * name_path, char *data, size_t len, const void *verkey) { struct ccn_parsed_ContentObject content; struct ccn_indexbuf *comps = ccn_indexbuf_create(); const unsigned char * content_value; size_t content_length; int res = 0; int i; memset(&content, 0x33, sizeof(content)); if (ccn_parse_ContentObject(message->buf, message->length, &content, comps) != 0) { printf("Decode failed to parse object\n"); res = -1; } if (comps->n-1 != name_path->count) { printf("Decode got wrong number of path components: %d vs. %d\n", (int)(comps->n-1), name_path->count); res = -1; } for (i=0; i<name_path->count; i++) { if (ccn_name_comp_strcmp(message->buf, comps, i, name_path->comps[i]) != 0) { printf("Decode mismatch on path component %d\n", i); res = -1; } } if (ccn_content_get_value(message->buf, message->length, &content, &content_value, &content_length) != 0) { printf("Cannot retrieve content value\n"); res = -1; } else if (content_length != len) { printf("Decode mismatch on content length %d vs. %d\n", (int)content_length, (int)len); res = -1; } else if (memcmp(content_value, data, len) != 0) { printf("Decode mismatch of content\n"); res = -1; } if (ccn_verify_signature(message->buf, message->length, &content, verkey) != 1) { printf("Signature did not verify\n"); res = -1; } ccn_indexbuf_destroy(&comps); return res; }
PUBLIC void r_sendq_content_queue_destroy(struct ccnr_handle *h, struct content_queue **pq) { struct content_queue *q; if (*pq != NULL) { q = *pq; ccn_indexbuf_destroy(&q->send_queue); if (q->sender != NULL) { ccn_schedule_cancel(h->sched, q->sender); q->sender = NULL; } free(q); *pq = NULL; } }
/** * Find and consume interests that match given content. * * Schedules the sending of the 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. * For new content, from_face is the source; for old content, from_face is NULL. * @returns number of matches, or -1 if the new content should be dropped. */ PUBLIC int r_match_match_interests(struct ccnr_handle *h, struct content_entry *content, struct ccn_parsed_ContentObject *pc, struct fdholder *fdholder, struct fdholder *from_face) { int n_matched = 0; int new_matches; struct nameprefix_entry *npe = NULL; int ci = 0; int cm = 0; struct ccn_charbuf *name = NULL; struct ccn_indexbuf *namecomps = NULL; unsigned c0 = 0; name = ccn_charbuf_create(); ccn_name_init(name); r_store_name_append_components(name, h, content, 0, -1); namecomps = ccn_indexbuf_create(); ccn_name_split(name, namecomps); c0 = namecomps->buf[0]; for (ci = namecomps->n - 1; ci >= 0; ci--) { int size = namecomps->buf[ci] - c0; npe = hashtb_lookup(h->nameprefix_tab, name->buf + c0, size); if (npe != NULL) break; } ccn_charbuf_destroy(&name); ccn_indexbuf_destroy(&namecomps); for (; npe != NULL; npe = npe->parent, ci--) { // if (npe->fgen != h->forward_to_gen) // r_fwd_update_forward_to(h, npe); if (from_face != NULL && (npe->flags & CCN_FORW_LOCAL) != 0 && (from_face->flags & CCNR_FACE_GG) == 0) return(-1); new_matches = r_match_consume_matching_interests(h, npe, content, pc, fdholder); // if (from_face != NULL && (new_matches != 0 || ci + 1 == cm)) // note_content_from(h, npe, from_face->filedesc, ci); if (new_matches != 0) { cm = ci; /* update stats for this prefix and one shorter */ n_matched += new_matches; } } return(n_matched); }
PUBLIC void r_match_consume_interest(struct ccnr_handle *h, struct propagating_entry *pe) { struct fdholder *fdholder = NULL; ccn_indexbuf_destroy(&pe->outbound); if (pe->interest_msg != NULL) { free(pe->interest_msg); pe->interest_msg = NULL; fdholder = r_io_fdholder_from_fd(h, pe->filedesc); if (fdholder != NULL) fdholder->pending_interests -= 1; } if (pe->next != NULL) { pe->next->prev = pe->prev; pe->prev->next = pe->next; pe->next = pe->prev = NULL; } pe->usec = 0; }
int ccn_parse_Link(struct ccn_buf_decoder *d, struct ccn_parsed_Link *link, struct ccn_indexbuf *components) { int ncomp = 0; int res; if (ccn_buf_match_dtag(d, CCN_DTAG_Link)) { if (components == NULL) { /* We need to have the component offsets. */ components = ccn_indexbuf_create(); if (components == NULL) return(-1); res = ccn_parse_Link(d, link, components); ccn_indexbuf_destroy(&components); return(res); } ccn_buf_advance(d); link->offset[CCN_PL_B_Name] = d->decoder.element_index; link->offset[CCN_PL_B_Component0] = d->decoder.index; ncomp = ccn_parse_Name(d, components); if (d->decoder.state < 0) { memset(link->offset, 0, sizeof(link->offset)); return(d->decoder.state); } link->offset[CCN_PL_E_ComponentLast] = d->decoder.token_index - 1; link->offset[CCN_PL_E_Name] = d->decoder.token_index; link->name_ncomps = ncomp; /* parse optional Label string */ link->offset[CCN_PL_B_Label] = d->decoder.token_index; res = ccn_parse_optional_tagged_UDATA(d, CCN_DTAG_Label); link->offset[CCN_PL_E_Label] = d->decoder.token_index; /* parse optional LinkAuthenticator LinkAuthenticatorType */ if (ccn_buf_match_dtag(d, CCN_DTAG_LinkAuthenticator)) res = ccn_parse_LinkAuthenticator(d, link); ccn_buf_check_close(d); } else return (d->decoder.state = -__LINE__); if (d->decoder.state < 0) return (d->decoder.state); return(ncomp); }
int ccn_proxy_destroy(struct ccn_proxy **proxy) { struct ccn_proxy *p = *proxy; DEBUG_PRINT("IN %d %s\n", __LINE__, __func__); ccn_destroy(&(p->handle)); ccn_charbuf_destroy(&(p->handle_name)); ccn_indexbuf_destroy(&(p->prefix_comps)); ccn_charbuf_destroy(&(p->prefix)); ccn_charbuf_destroy(&(p->filter)); free(p); DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__); return(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); }
PUBLIC void ccnr_uri_listen(struct ccnr_handle *ccnr, struct ccn *ccn, const char *uri, ccn_handler p, intptr_t intdata) { struct ccn_charbuf *name; struct ccn_charbuf *uri_modified = NULL; struct ccn_closure *closure; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; size_t offset; name = ccn_charbuf_create(); ccn_name_from_uri(name, uri); comps = ccn_indexbuf_create(); if (ccn_name_split(name, comps) < 0) abort(); if (ccn_name_comp_get(name->buf, comps, 1, &comp, &comp_size) >= 0) { if (comp_size == 32 && 0 == memcmp(comp, CCNR_ID_TEMPL, 32)) { /* Replace placeholder with our ccnr_id */ offset = comp - name->buf; memcpy(name->buf + offset, ccnr->ccnr_id, 32); uri_modified = ccn_charbuf_create(); ccn_uri_append(uri_modified, name->buf, name->length, 1); uri = (char *)uri_modified->buf; } } closure = calloc(1, sizeof(*closure)); closure->p = p; closure->data = ccnr; closure->intdata = intdata; ccn_set_interest_filter(ccn, name, closure); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&uri_modified); ccn_indexbuf_destroy(&comps); }
ParsedContentObject::~ParsedContentObject() { ccn_indexbuf_destroy(&m_comps); m_comps = NULL; }
int ccn_parse_interest(const unsigned char *msg, size_t size, struct ccn_parsed_interest *interest, struct ccn_indexbuf *components) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size); int magic = 0; int ncomp = 0; int res; if (ccn_buf_match_dtag(d, CCN_DTAG_Interest) || ccn_buf_match_dtag(d, CCN_DTAG_PersistentInterest)) { if (components == NULL) { /* We need to have the component offsets. */ components = ccn_indexbuf_create(); if (components == NULL) return(-1); res = ccn_parse_interest(msg, size, interest, components); ccn_indexbuf_destroy(&components); return(res); } /*In case of persistent interest*/ if(ccn_buf_match_dtag(d, CCN_DTAG_PersistentInterest)) { interest->persistent = 1; } ccn_buf_advance(d); interest->offset[CCN_PI_B_Name] = d->decoder.element_index; interest->offset[CCN_PI_B_Component0] = d->decoder.index; ncomp = ccn_parse_Name(d, components); if (d->decoder.state < 0) { memset(interest->offset, 0, sizeof(interest->offset)); return(d->decoder.state); } interest->offset[CCN_PI_E_ComponentLast] = d->decoder.token_index - 1; interest->offset[CCN_PI_E_Name] = d->decoder.token_index; interest->prefix_comps = ncomp; interest->offset[CCN_PI_B_LastPrefixComponent] = components->buf[(ncomp > 0) ? (ncomp - 1) : 0]; interest->offset[CCN_PI_E_LastPrefixComponent] = components->buf[ncomp]; /* optional MinSuffixComponents, MaxSuffixComponents */ interest->min_suffix_comps = 0; interest->max_suffix_comps = 32767; interest->offset[CCN_PI_B_MinSuffixComponents] = d->decoder.token_index; res = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_MinSuffixComponents); interest->offset[CCN_PI_E_MinSuffixComponents] = d->decoder.token_index; if (res >= 0) interest->min_suffix_comps = res; interest->offset[CCN_PI_B_MaxSuffixComponents] = d->decoder.token_index; res = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_MaxSuffixComponents); interest->offset[CCN_PI_E_MaxSuffixComponents] = d->decoder.token_index; if (res >= 0) interest->max_suffix_comps = res; if (interest->max_suffix_comps < interest->min_suffix_comps) return (d->decoder.state = -__LINE__); /* optional PublisherID */ res = ccn_parse_PublisherID(d, interest); /* optional Exclude element */ interest->offset[CCN_PI_B_Exclude] = d->decoder.token_index; res = ccn_parse_Exclude(d); interest->offset[CCN_PI_E_Exclude] = d->decoder.token_index; /* optional ChildSelector */ interest->offset[CCN_PI_B_ChildSelector] = d->decoder.token_index; res = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_ChildSelector); if (res < 0) res = 0; interest->orderpref = res; interest->offset[CCN_PI_E_ChildSelector] = d->decoder.token_index; if (interest->orderpref > 5) return (d->decoder.state = -__LINE__); /* optional AnswerOriginKind */ interest->offset[CCN_PI_B_AnswerOriginKind] = d->decoder.token_index; interest->answerfrom = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_AnswerOriginKind); interest->offset[CCN_PI_E_AnswerOriginKind] = d->decoder.token_index; if (interest->answerfrom == -1) interest->answerfrom = CCN_AOK_DEFAULT; else if ((interest->answerfrom & CCN_AOK_NEW) != 0 && (interest->answerfrom & CCN_AOK_CS) == 0) return (d->decoder.state = -__LINE__); /* optional Scope */ interest->offset[CCN_PI_B_Scope] = d->decoder.token_index; interest->scope = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_Scope); interest->offset[CCN_PI_E_Scope] = d->decoder.token_index; if (interest->scope > 9) return (d->decoder.state = -__LINE__); if ((interest->answerfrom & CCN_AOK_EXPIRE) != 0 && interest->scope != 0) return (d->decoder.state = -__LINE__); /* optional InterestLifetime */ interest->offset[CCN_PI_B_InterestLifetime] = d->decoder.token_index; res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_InterestLifetime, 1, 8); if (res >= 0) magic |= 20100401; interest->offset[CCN_PI_E_InterestLifetime] = d->decoder.token_index; /* optional Nonce */ interest->offset[CCN_PI_B_Nonce] = d->decoder.token_index; res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Nonce, 4, 64); interest->offset[CCN_PI_E_Nonce] = d->decoder.token_index; /* Allow for no experimental stuff */ interest->offset[CCN_PI_B_OTHER] = d->decoder.token_index; interest->offset[CCN_PI_E_OTHER] = d->decoder.token_index; ccn_buf_check_close(d); interest->offset[CCN_PI_E] = d->decoder.index; } else return (d->decoder.state = -__LINE__); if (d->decoder.state < 0) return (d->decoder.state); if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) return (CCN_DSTATE_ERR_CODING); if (magic == 0) magic = 20090701; if (!(magic == 20090701 || magic == 20100401)) return (d->decoder.state = -__LINE__); interest->magic = magic; return (ncomp); }
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 = ⅇ 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, ×tamp); struct timeval window = {.tv_sec = 1, .tv_usec = 600000}; if (ccn_util_timestamp_window(×tamp, &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 = ⅇ 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); }
int check_key_name_hierarchy(const unsigned char *ccnb, struct ccn_parsed_ContentObject *pco, int key_type, int content_type){ printf("check_key_name_hierarchy called\n"); if (key_type == UNKNOWN_KEY ){ return 1; } int res; struct ccn_charbuf *key_name=get_key_name(ccnb, pco); struct ccn_charbuf *key_uri = ccn_charbuf_create(); ccn_uri_append(key_uri, key_name->buf, key_name->length, 0); printf("Key Name: %s\n",ccn_charbuf_as_string(key_uri)); ccn_charbuf_destroy(&key_uri); struct ccn_charbuf *content_name=ccn_charbuf_create(); res=ccn_charbuf_append(content_name, ccnb + pco->offset[CCN_PCO_B_Name], pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name]); struct ccn_charbuf *content_uri = ccn_charbuf_create(); ccn_uri_append(content_uri, content_name->buf, content_name->length, 0); printf("Content Name: %s\n",ccn_charbuf_as_string(content_uri)); ccn_charbuf_destroy(&content_uri); if ( key_type == NLSR_KEY){ char *orig_router_key_name=get_orig_router_from_key_name(key_name,0,0); char *orig_router_content_name; if ( content_type == 1 ){ orig_router_content_name=get_orig_router_from_lsa_name(content_name); } else if ( content_type == 0 ){ orig_router_content_name=get_orig_router_from_info_content_name(content_name); } printf("Orig Router (Key Name):%s\n",orig_router_key_name); printf("Orig Router (Content Name):%s\n",orig_router_content_name); if (strcmp(orig_router_key_name,orig_router_content_name) == 0 ){ free(orig_router_key_name); free(orig_router_content_name); ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 1; } } if ( key_type == ROUTING_KEY){ char *orig_router_key_name=get_orig_router_from_key_name(key_name,1,0); char *orig_router_content_name=get_orig_router_from_key_name(content_name,1,1); printf("Orig Router (Key Name):%s\n",orig_router_key_name); printf("Orig Router (Content Name):%s\n",orig_router_content_name); if (strcmp(orig_router_key_name,orig_router_content_name) == 0 ){ free(orig_router_key_name); free(orig_router_content_name); ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 1; } } if ( key_type == OPERATOR_KEY){ struct ccn_indexbuf *key_name_comps; key_name_comps = ccn_indexbuf_create(); res = ccn_name_split(key_name, key_name_comps); int last_indx=check_for_tag_component_in_name(key_name,key_name_comps,"O.N.Start"); char *site_key_prefix_key=get_name_segments_from_name(key_name,0,last_indx); printf("Site key prefix(key Name):%s\n",site_key_prefix_key); ccn_indexbuf_destroy(&key_name_comps); struct ccn_indexbuf *content_name_comps; content_name_comps = ccn_indexbuf_create(); res = ccn_name_split(content_name, content_name_comps); int last_indx_rtr=check_for_tag_component_in_name(content_name,content_name_comps,"R.N.Start"); char *site_key_prefix_content=get_name_segments_from_name(key_name,0,last_indx_rtr); printf("Site key prefix(Content Name):%s\n",site_key_prefix_content); ccn_indexbuf_destroy(&content_name_comps); if( strcmp(site_key_prefix_key,site_key_prefix_content) == 0 ){ free(site_key_prefix_key); free(site_key_prefix_content); ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 1; } } if ( key_type == SITE_KEY){ struct ccn_indexbuf *key_name_comps; key_name_comps = ccn_indexbuf_create(); res = ccn_name_split(key_name, key_name_comps); int last_indx=check_for_tag_component_in_name(key_name,key_name_comps,"M.K"); char *site_key_prefix_key=get_name_segments_from_name(key_name,0,last_indx); printf("Site key prefix(key Name):%s\n",site_key_prefix_key); ccn_indexbuf_destroy(&key_name_comps); struct ccn_indexbuf *content_name_comps; content_name_comps = ccn_indexbuf_create(); res = ccn_name_split(content_name, content_name_comps); int last_indx_rtr=check_for_tag_component_in_name(content_name,content_name_comps,"O.N.Start"); char *site_key_prefix_content=get_name_segments_from_name(key_name,0,last_indx_rtr); printf("Site key prefix(Content Name):%s\n",site_key_prefix_content); ccn_indexbuf_destroy(&content_name_comps); if( strcmp(site_key_prefix_key,site_key_prefix_content) == 0 ){ free(site_key_prefix_key); free(site_key_prefix_content); ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 1; } } if ( key_type == ROOT_KEY){ ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 1; } ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 0; }
enum ccn_upcall_res andana_client_encap_interest( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { int res; enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR; struct andana_client *client = selfp->data; struct ccn_proxy *proxy = client->proxy; size_t orig_name_ncomps; struct ccn_charbuf *orig_name = NULL; struct ccn_indexbuf *orig_name_comps = NULL; struct ccn_charbuf *new_name = NULL; struct ccn_indexbuf *new_name_comps = NULL; struct hashtb_enumerator ee; struct hashtb_enumerator *e = ⅇ switch (kind) { case CCN_UPCALL_INTEREST: DEBUG_PRINT("Received Interest\n"); break; case CCN_UPCALL_FINAL: DEBUG_PRINT("Encap: callback final\n"); return(CCN_UPCALL_RESULT_OK); default: return(CCN_UPCALL_RESULT_ERR); } /* Extract Name from Interest */ orig_name_ncomps = ccn_util_extract_name(info->interest_ccnb, info->interest_comps, &orig_name, &orig_name_comps); /* * Need to check this Interest doesn't match what we send out. * Otherwise, we'll just keep encapsulating the same thing over and over. */ int num_matching_comps = ccn_util_name_match(client->proxy->prefix, client->proxy->prefix_comps, orig_name, orig_name_comps); if (num_matching_comps == client->proxy->prefix_ncomps) { DEBUG_PRINT("Interest matches %d of %d components, ignoring interest\n", num_matching_comps, (int)client->proxy->prefix_ncomps); #ifdef PROXYDEBUG ccn_util_println_pc_fmt(orig_name->buf, orig_name->length); DEBUG_PRINT("Name has %lu comps\n", orig_name_comps->n-1); ccn_util_println_pc_fmt(client->proxy->prefix->buf, client->proxy->prefix->length); DEBUG_PRINT("Name has %lu comps\n", client->proxy->prefix_comps->n-1); #endif goto MatchBail; } else { DEBUG_PRINT("Interest matches %d of %d components\n", num_matching_comps, (int)client->proxy->prefix_ncomps); } /* Create a new name encapsulated & encrypted name */ // new_name_comps = ccn_indexbuf_create(); ccn_name_append(orig_name, info->interest_ccnb, info->pi->offset[CCN_PI_E]); ccn_indexbuf_destroy(&orig_name_comps); struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = &decoder; ccn_buf_decoder_start(d, orig_name->buf, orig_name->length); orig_name_comps = ccn_indexbuf_create(); res = ccn_parse_Name(d, orig_name_comps); if (res <= 0) { DEBUG_PRINT("%d %s error parsing encapsulated name\n", __LINE__, __func__); goto MatchBail; } res = andana_path_encrypt_encap(client->path, orig_name, orig_name_comps, &new_name, &new_name_comps); if (res <= 0) { DEBUG_PRINT("%d %s error encapsulating and encrypting name\n", __LINE__, __func__); goto EncryptBail; } /* Remember the new name so we know how to decrypt & decapsulate it later */ hashtb_start(client->name_to_path, e); res = hashtb_seek(e, new_name->buf, new_name->length, 0); if (res == HT_NEW_ENTRY) { } else if (res == HT_OLD_ENTRY) { DEBUG_PRINT("Interest recording found old entry\n"); upcall_res = CCN_UPCALL_RESULT_OK; goto LookupBail; } else { DEBUG_PRINT("Error in Interest insertion\n"); goto LookupBail; } /* Send out new Interest */ #ifdef PROXYDEBUG struct ccn_charbuf *c = ccn_charbuf_create(); ccn_uri_append(c, new_name->buf, new_name->length, 1); DEBUG_PRINT("name = %s\n", ccn_charbuf_as_string(c)); ccn_charbuf_destroy(&c); #endif res = ccn_express_interest(proxy->handle, new_name, proxy->content_handler, NULL); if(res != 0) { DEBUG_PRINT("express interest res = %d\n",res); } else { struct andana_path **path_ptr = e->data; *path_ptr = andana_path_copy(client->path); upcall_res = CCN_UPCALL_RESULT_INTEREST_CONSUMED; } LookupBail: hashtb_end(e); EncryptBail: ccn_charbuf_destroy(&new_name); ccn_indexbuf_destroy(&new_name_comps); MatchBail: ccn_charbuf_destroy(&orig_name); ccn_indexbuf_destroy(&orig_name_comps); return(upcall_res); }
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); }
/** * Extend a Name with a new version stamp * @param h is the the ccn handle. * May be NULL. This procedure does not use the connection. * @param name is a ccnb-encoded Name prefix. By default it gets extended * in-place with one additional Component that conforms to the * versioning profile and is based on the supplied time, unless a * version component is already present. * @param versioning_flags modifies the default behavior: * CCN_V_REPLACE causes the last component to be replaced if it * appears to be a version stamp. If CCN_V_HIGH is set as well, an * attempt will be made to generate a new version stamp that is * later than the existing one, or to return an error. * CCN_V_NOW bases the version on the current time rather than the * supplied time. * CCN_V_NESTOK will allow the new version component to be appended * even if there is one there (this makes no difference if CCN_V_REPLACE * is also set). * @param secs is the desired time, in seconds since epoch * (ignored if CCN_V_NOW is set). * @param nsecs is the number of nanoseconds. * @returns -1 for error, 0 for success. */ int ccn_create_version(struct ccn *h, struct ccn_charbuf *name, int versioning_flags, intmax_t secs, int nsecs) { size_t i; size_t j; size_t lc = 0; size_t oc = 0; int n; struct ccn_indexbuf *nix = NULL; int myres = -1; int already_versioned = 0; int ok_flags = (CCN_V_REPLACE | CCN_V_HIGH | CCN_V_NOW | CCN_V_NESTOK); // XXX - right now we ignore h, but in the future we may use it to try to avoid non-monotonicies in the versions. nix = ccn_indexbuf_create(); n = ccn_name_split(name, nix); if (n < 0) goto Finish; if ((versioning_flags & ~ok_flags) != 0) goto Finish; /* Check for existing version component */ if (n >= 1) { oc = nix->buf[n-1]; lc = nix->buf[n] - oc; if (lc <= 11 && lc >= 6 && name->buf[oc + 2] == CCN_MARKER_VERSION) already_versioned = 1; } myres = 0; if (already_versioned && (versioning_flags & (CCN_V_REPLACE | CCN_V_NESTOK)) == 0) goto Finish; name->length -= 1; /* Strip name closer */ i = name->length; myres |= ccn_charbuf_append_tt(name, CCN_DTAG_Component, CCN_DTAG); if ((versioning_flags & CCN_V_NOW) != 0) myres |= ccnb_append_now_blob(name, CCN_MARKER_VERSION); else { myres |= ccnb_append_timestamp_blob(name, CCN_MARKER_VERSION, secs, nsecs); } myres |= ccn_charbuf_append_closer(name); /* </Component> */ if (myres < 0) { name->length = i; goto CloseName; } j = name->length; if (already_versioned && (versioning_flags & CCN_V_REPLACE) != 0) { oc = nix->buf[n-1]; lc = nix->buf[n] - oc; if ((versioning_flags & CCN_V_HIGH) != 0 && memcmp(name->buf + oc, name->buf + i, j - i) > 0) { /* Supplied version is in the future. */ name->length = i; // XXX - we could try harder to make this work, for now just error out myres = -1; goto CloseName; } memmove(name->buf + oc, name->buf + i, j - i); name->length -= lc; } CloseName: myres |= ccn_charbuf_append_closer(name); /* </Name> */ Finish: myres = (myres < 0) ? -1 : 0; ccn_indexbuf_destroy(&nix); return(myres); }
/** * Resolve the version, based on existing ccn content. * @param h is the the ccn handle; it may be NULL, but it is preferable to * use the handle that the client probably already has. * @param name is a ccnb-encoded Name prefix. It gets extended in-place with * one additional Component such that it names highest extant * version that can be found, subject to the supplied timeout. * @param versioning_flags presently must be CCN_V_HIGH or CCN_V_HIGHEST, * possibly combined with CCN_V_NESTOK. If CCN_V_NESTOK is not present * and the ending component appears to be a version, the routine * returns 0 immediately, on the assumption that an explicit * version has already been provided. * @param timeout_ms is a time value in milliseconds. This is applied per * fetch attempt, so the total time may be longer by a factor that * depends on the number of (ccn) hops to the source(s). * @returns -1 for error, 0 if name could not be extended, 1 if was. */ int ccn_resolve_version(struct ccn *h, struct ccn_charbuf *name, int versioning_flags, int timeout_ms) { int res; int myres = -1; struct ccn_parsed_ContentObject pco_space = { 0 }; struct ccn_charbuf *templ = NULL; struct ccn_charbuf *prefix = ccn_charbuf_create(); struct ccn_charbuf *cobj = ccn_charbuf_create(); struct ccn_parsed_ContentObject *pco = &pco_space; struct ccn_indexbuf *ndx = ccn_indexbuf_create(); const unsigned char *vers = NULL; size_t vers_size = 0; int n; struct ccn_indexbuf *nix = ccn_indexbuf_create(); unsigned char lowtime[7] = {CCN_MARKER_VERSION, 0, FF, FF, FF, FF, FF}; if ((versioning_flags & ~CCN_V_NESTOK & ~CCN_V_EST) != CCN_V_HIGH) { ccn_seterror(h, EINVAL); ccn_perror(h, "ccn_resolve_version is only implemented for versioning_flags = CCN_V_HIGH(EST)"); goto Finish; } n = ccn_name_split(name, nix); if (n < 0) goto Finish; if ((versioning_flags & CCN_V_NESTOK) == 0) { res = ccn_name_comp_get(name->buf, nix, n - 1, &vers, &vers_size); if (res >= 0 && vers_size == 7 && vers[0] == CCN_MARKER_VERSION) { myres = 0; goto Finish; } } templ = resolve_templ(templ, lowtime, sizeof(lowtime)); ccn_charbuf_append(prefix, name->buf, name->length); /* our copy */ cobj->length = 0; res = ccn_get(h, prefix, templ, timeout_ms, cobj, pco, ndx, 0); while (cobj->length != 0) { if (pco->type == CCN_CONTENT_NACK) // XXX - also check for number of components break; res = ccn_name_comp_get(cobj->buf, ndx, n, &vers, &vers_size); if (res < 0) break; if (vers_size == 7 && vers[0] == CCN_MARKER_VERSION) { /* Looks like we have versions. */ name->length = 0; ccn_charbuf_append(name, prefix->buf, prefix->length); ccn_name_append(name, vers, vers_size); myres = 0; if ((versioning_flags & CCN_V_EST) == 0) break; templ = resolve_templ(templ, vers, vers_size); if (templ == NULL) break; cobj->length = 0; res = ccn_get(h, prefix, templ, timeout_ms, cobj, pco, ndx, CCN_GET_NOKEYWAIT); } else break; } Finish: ccn_charbuf_destroy(&prefix); ccn_charbuf_destroy(&cobj); ccn_indexbuf_destroy(&ndx); ccn_indexbuf_destroy(&nix); ccn_charbuf_destroy(&templ); return(myres); }
static int r_store_index_cleaner(struct ccn_schedule *sched, void *clienth, struct ccn_scheduled_event *ev, int flags) { struct ccnr_handle *h = clienth; struct hashtb_enumerator ee; struct hashtb_enumerator *e = ⅇ struct ccn_btree_node *node = NULL; int k; int res; int overquota; (void)(sched); (void)(ev); if ((flags & CCN_SCHEDULE_CANCEL) != 0 || h->btree == NULL || h->btree->io == NULL) { h->index_cleaner = NULL; ccn_indexbuf_destroy(&h->toclean); return(0); } /* First, work on cleaning the things we already know need cleaning */ if (h->toclean != NULL) { for (k = 0; k < CCN_BT_CLEAN_BATCH && h->toclean->n > 0; k++) { node = ccn_btree_rnode(h->btree, h->toclean->buf[--h->toclean->n]); if (node != NULL && node->iodata != NULL) { res = ccn_btree_chknode(node); /* paranoia */ if (res < 0 || CCNSHOULDLOG(h, sdfsdffd, CCNL_FINER)) ccnr_msg(h, "write index node %u (err %d)", (unsigned)node->nodeid, node->corrupt); if (res >= 0) { if (node->clean != node->buf->length) res = h->btree->io->btwrite(h->btree->io, node); if (res < 0) ccnr_msg(h, "failed to write index node %u", (unsigned)node->nodeid); else node->clean = node->buf->length; } if (res >= 0 && node->iodata != NULL && node->activity == 0) { if (CCNSHOULDLOG(h, sdfsdffd, CCNL_FINER)) ccnr_msg(h, "close index node %u", (unsigned)node->nodeid); res = ccn_btree_close_node(h->btree, node); } } } if (h->toclean->n > 0) return(nrand48(h->seed) % (2U * CCN_BT_CLEAN_TICK_MICROS) + 500); } /* Sweep though and find the nodes that still need cleaning */ overquota = 0; if (h->btree->nodepool >= 16) overquota = hashtb_n(h->btree->resident) - h->btree->nodepool; hashtb_start(h->btree->resident, e); for (node = e->data; node != NULL; node = e->data) { if (overquota > 0 && node->activity == 0 && node->iodata == NULL && node->clean == node->buf->length) { overquota -= 1; if (CCNSHOULDLOG(h, sdfsdffd, CCNL_FINEST)) ccnr_msg(h, "prune index node %u", (unsigned)node->nodeid); hashtb_delete(e); continue; } node->activity /= 2; /* Age the node's activity */ if (node->clean != node->buf->length || (node->iodata != NULL && node->activity == 0)) { if (h->toclean == NULL) { h->toclean = ccn_indexbuf_create(); if (h->toclean == NULL) break; } ccn_indexbuf_append_element(h->toclean, node->nodeid); } hashtb_next(e); } hashtb_end(e); /* If nothing to do, shut down cleaner */ if ((h->toclean == NULL || h->toclean->n == 0) && overquota <= 0 && h->btree->io->openfds <= CCN_BT_OPEN_NODES_IDLE) { h->btree->cleanreq = 0; h->index_cleaner = NULL; ccn_indexbuf_destroy(&h->toclean); if (CCNSHOULDLOG(h, sdfsdffd, CCNL_FINE)) ccnr_msg(h, "index btree nodes all clean"); return(0); } return(nrand48(h->seed) % (2U * CCN_BT_CLEAN_TICK_MICROS) + 500); }
static void pyccn_Capsule_Destructor(PyObject *capsule) { const char *name; void *pointer; enum _pyccn_capsules type; assert(PyCapsule_CheckExact(capsule)); name = PyCapsule_GetName(capsule); type = name2type(name); pointer = PyCapsule_GetPointer(capsule, name); assert(pointer); switch (type) { case CLOSURE: { PyObject *py_obj_closure; struct ccn_closure *p = pointer; py_obj_closure = PyCapsule_GetContext(capsule); assert(py_obj_closure); Py_DECREF(py_obj_closure); /* No longer referencing Closure object */ /* If we store something else, than ourselves, it probably is a bug */ assert(capsule == p->data); free(p); } break; case CONTENT_OBJECT: { struct content_object_data *context; struct ccn_charbuf *p = pointer; context = PyCapsule_GetContext(capsule); if (context) { if (context->pco) free(context->pco); ccn_indexbuf_destroy(&context->comps); free(context); } ccn_charbuf_destroy(&p); } break; case HANDLE: { struct ccn *p = pointer; ccn_disconnect(p); ccn_destroy(&p); } break; case INTEREST: { struct interest_data *context; struct ccn_charbuf *p = pointer; context = PyCapsule_GetContext(capsule); if (context) { if (context->pi) free(context->pi); free(context); } ccn_charbuf_destroy(&p); } break; case PKEY_PRIV: case PKEY_PUB: { struct ccn_pkey *p = pointer; ccn_pubkey_free(p); } break; case EXCLUSION_FILTER: case KEY_LOCATOR: case NAME: case SIGNATURE: case SIGNED_INFO: { struct ccn_charbuf *p = pointer; ccn_charbuf_destroy(&p); } break; case SIGNING_PARAMS: { struct ccn_signing_params *p = pointer; if (p->template_ccnb) ccn_charbuf_destroy(&p->template_ccnb); free(p); } break; default: debug("Got capsule: %s\n", PyCapsule_GetName(capsule)); panic("Unable to destroy the object: got an unknown capsule"); } }
enum ccn_upcall_res andana_server_session_listener( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { int res; struct andana_server *server = selfp->data; const unsigned char * const_encrypted = NULL; unsigned char *encrypted = NULL; size_t enc_size; /* * Extract the client's randomness (aka the symmetric key it sent us. * Should be the last component of the incoming Interest. */ struct ccn_charbuf *request_name = NULL; struct ccn_indexbuf *request_comps = NULL; DEBUG_PRINT("IN %d %s\n", __LINE__, __func__); switch (kind) { case CCN_UPCALL_INTEREST: DEBUG_PRINT("%d %s received session request\n", __LINE__, __func__); break; case CCN_UPCALL_INTEREST_TIMED_OUT: DEBUG_PRINT("%d %s received session request time out\n", __LINE__, __func__); /* Fall through */ default: DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__); return(CCN_UPCALL_RESULT_OK); } printf("here now mk?\n"); res = ccn_util_extract_name(info->interest_ccnb, info->interest_comps, &request_name, &request_comps); if (res < 0) { DEBUG_PRINT("%d %s Failed to extract session request name\n", __LINE__, __func__); ccn_charbuf_destroy(&request_name); ccn_indexbuf_destroy(&request_comps); return(CCN_UPCALL_RESULT_ERR); } printf("passed util extract name\n"); res = ccn_name_comp_get(request_name->buf, request_comps, (unsigned int)request_comps->n - 2, &const_encrypted, &enc_size); if (res < 0) { DEBUG_PRINT("%d %s Failed to extract session creation data\n", __LINE__, __func__); ccn_charbuf_destroy(&request_name); ccn_indexbuf_destroy(&request_comps); return(CCN_UPCALL_RESULT_ERR); } encrypted = calloc(enc_size, sizeof(unsigned char)); printf("encryption size = %d\n", enc_size); if (encrypted == NULL) printf("invalid pointer return from calloc\n"); memcpy(encrypted, const_encrypted, enc_size); struct ccn_pkey *symkey = NULL; struct ccn_charbuf *decrypted = NULL; struct ccn_indexbuf *decrypted_comps = ccn_indexbuf_create(); printf("trying asymmetric decryption\n"); ccn_crypto_name_asym_decrypt(server->privkey, encrypted, &symkey, &decrypted, &decrypted_comps); // ccn_crypto_name_sym_decrypt(server->node_key, encrypted, encrypted_size, &decrypted, &decrypted_comps); /* cn_crypto_name_sym_decrypt(server->node_key, encrypted, encrypted_size, &symkey, &decrypted, &decrypted_comps); */ printf("good - now creating a session\n"); unsigned char *session_id = NULL; unsigned char *session_key = NULL; unsigned char *server_rand = NULL; /* * Create a new session id and session key using the client's randomness. * The server is also responsible for contributing randomness of its own for security. */ createSession(&session_id, &session_key, &server_rand, ccn_crypto_symkey_key(symkey), (unsigned int)ccn_crypto_symkey_bytes(symkey), ccn_crypto_symkey_key(server->node_key)); printf("Session made!\n"); /* Construct the response message using a ccn name (for convenience). */ struct ccn_charbuf *session_info = ccn_charbuf_create(); ccn_name_init(session_info); ccn_name_append(session_info, session_id, SESSIONID_LENGTH); ccn_name_append(session_info, session_key, SESSION_KEYLEN); ccn_name_append(session_info, server_rand, SESSIONRAND_LENGTH); /** * Encrypt the response message using the symmetric key * provided by the client and send it out. */ unsigned char *enc_info = NULL; ccn_crypto_content_encrypt(symkey, session_info->buf, session_info->length, &enc_info, &enc_size); struct ccn_charbuf *signed_enc_info = ccn_charbuf_create(); struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT; sp.type = CCN_CONTENT_DATA; res = ccn_sign_content(server->proxy->handle, signed_enc_info, request_name, &sp, enc_info, enc_size); if (res < 0) { DEBUG_PRINT("%d %s Failed to signed session creation response\n", __LINE__, __func__); } else { res = ccn_put(server->proxy->handle, signed_enc_info->buf, signed_enc_info->length); } ccn_charbuf_destroy(&decrypted); ccn_indexbuf_destroy(&decrypted_comps); ccn_crypto_symkey_destroy(&symkey); free(session_id); free(session_key); free(server_rand); free(enc_info); ccn_charbuf_destroy(&signed_enc_info); if (res < 0) { DEBUG_PRINT("%d %s Error writing session creation response\n", __LINE__, __func__); return(CCN_UPCALL_RESULT_ERR); } DEBUG_PRINT("OUT %d %s Created new session. Response sent\n", __LINE__, __func__); return(CCN_UPCALL_RESULT_INTEREST_CONSUMED); }