void testHASH() { int rand, key; FILE *fp, *fr; char rand_line[10]; char key_line[10]; struct timeval start, end; struct hashtb *newht; newht=NULL; newht=hashtb_create(); fp=fopen("rand_data.txt","r"); fr=fopen("rand_keys.txt","r"); gettimeofday(&start,NULL); while(fgets(rand_line,10,fp) != NULL && fgets(key_line,10,fr) != NULL ) { sscanf(rand_line, "%d", &rand); sscanf(key_line, "%d", &key); hashtb_add_element(newht,key,rand); } fclose(fp); rewind(fr); while(fgets(key_line,10,fr) != NULL) { sscanf(key_line, "%d", &key); hashtb_lookup(newht,key); } fclose(fr); gettimeofday(&end,NULL); free(newht); printf("Total time: %ld microseconds\n", ((end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec))); printf("Test complete!\n"); }
/** * 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); }
/** * Get a handle on the content object that matches key, or if there is * no match, the one that would come just after it. * * The key is in flatname format. */ static struct content_entry * r_store_look(struct ccnr_handle *h, const unsigned char *key, size_t size) { struct content_entry *content = NULL; struct ccn_btree_node *leaf = NULL; ccnr_accession accession; int ndx; int res; res = ccn_btree_lookup(h->btree, key, size, &leaf); if (res >= 0) { ndx = CCN_BT_SRCH_INDEX(res); if (ndx == ccn_btree_node_nent(leaf)) { res = ccn_btree_next_leaf(h->btree, leaf, &leaf); if (res <= 0) return(NULL); ndx = 0; } accession = ccnr_accession_decode(h, ccn_btree_content_cobid(leaf, ndx)); if (accession != CCNR_NULL_ACCESSION) { struct content_by_accession_entry *entry; entry = hashtb_lookup(h->content_by_accession_tab, &accession, sizeof(accession)); if (entry != NULL) content = entry->content; if (content == NULL) { /* Construct handle without actually reading the cob */ res = ccn_btree_content_cobsz(leaf, ndx); content = calloc(1, sizeof(*content)); if (res > 0 && content != NULL) { content->accession = accession; content->cob = NULL; content->size = res; content->flatname = ccn_charbuf_create(); CHKPTR(content->flatname); res = ccn_btree_key_fetch(content->flatname, leaf, ndx); CHKRES(res); r_store_enroll_content(h, content); } } } } return(content); }
PUBLIC struct content_entry * r_store_content_from_accession(struct ccnr_handle *h, ccnr_accession accession) { struct ccn_parsed_ContentObject obj = {0}; struct content_entry *content = NULL; struct content_by_accession_entry *entry; const unsigned char *content_base = NULL; int res; ccnr_accession acc; if (accession == CCNR_NULL_ACCESSION) return(NULL); entry = hashtb_lookup(h->content_by_accession_tab, &accession, sizeof(accession)); if (entry != NULL) { h->content_from_accession_hits++; return(entry->content); } h->content_from_accession_misses++; content = calloc(1, sizeof(*content)); CHKPTR(content); content->cookie = 0; content->accession = accession; content->cob = NULL; content->size = 0; content_base = r_store_content_base(h, content); if (content_base == NULL || content->size == 0) goto Bail; res = r_store_set_flatname(h, content, &obj); if (res < 0) goto Bail; r_store_enroll_content(h, content); res = r_store_content_btree_insert(h, content, &obj, &acc); if (res < 0) goto Bail; if (res == 1 || CCNSHOULDLOG(h, sdf, CCNL_FINEST)) ccnr_debug_content(h, __LINE__, "content/accession", NULL, content); return(content); Bail: ccnr_msg(h, "r_store_content_from_accession.%d failed 0x%jx", __LINE__, ccnr_accession_encode(h, accession)); r_store_forget_content(h, &content); return(content); }
int does_key_exist(char *keyname){ if (nlsr->debugging) { printf("does_key_exist called\n"); printf("Keyname : %s \n",keyname); } int ret=0; unsigned *v; v = hashtb_lookup(nlsr->keys, keyname, strlen(keyname)); if (v != NULL){ ret = 1; if (nlsr->debugging) printf("Key Found\n"); } return ret; }
int does_face_exist_for_router(char *dest_router, int face_id) { if (nlsr->debugging) { printf("does_face_exist_for_router called\n"); printf("Dest Router: %s and Face id: %d \n",dest_router, face_id); } int ret=0; int res; struct routing_table_entry *rte; struct hashtb_enumerator ee; struct hashtb_enumerator *e = ⅇ hashtb_start(nlsr->routing_table, e); res = hashtb_seek(e, dest_router, strlen(dest_router), 0); if( res == HT_OLD_ENTRY ) { rte=e->data; unsigned *v; v = hashtb_lookup(rte->face_list, &face_id, sizeof(face_id)); if (v != NULL) ret = 1; } else { hashtb_delete(e); } hashtb_end(e); return ret; }
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); }