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; }
int gen_test(struct ccn_charbuf **name, struct ccn_indexbuf **comps) { int res; intmax_t secs = 1234567890; int nsecs = 6000000; *name = ccn_charbuf_create(); ccn_name_init(*name); res = ccn_create_version(NULL, *name, 0, secs, nsecs); if (res < 0) { printf("Unable to create version\n"); return(-__LINE__); } *comps = ccn_indexbuf_create(); struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = &decoder; ccn_buf_decoder_start(d, (*name)->buf, (*name)->length); res = ccn_parse_Name(d, *comps); if (res < 0) { printf("Unable to parse name\n"); return(-__LINE__); } 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); }
PUBLIC struct ccnr_parsed_policy * ccnr_parsed_policy_create(void) { struct ccnr_parsed_policy *pp; pp = calloc(1, sizeof(struct ccnr_parsed_policy)); pp->store = ccn_charbuf_create(); pp->namespaces = ccn_indexbuf_create(); return(pp); }
void ParsedContentObject::init(const unsigned char *data, size_t len) { readRaw(m_bytes, data, len); m_comps = ccn_indexbuf_create(); int res = ccn_parse_ContentObject(head (m_bytes), len, &m_pco, m_comps); if (res < 0) { boost::throw_exception(MisformedContentObjectException()); } }
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; }
struct ccn_proxy * ccn_proxy_init(const char *filter_uri, const char *prefix_uri) { struct ccn_proxy *proxy = calloc(1, sizeof(struct ccn_proxy)); struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = &decoder; int res; DEBUG_PRINT("IN %d %s\n", __LINE__, __func__); /* Convert URI to name this proxy is responsible for */ proxy->prefix = ccn_charbuf_create(); res = ccn_name_from_uri(proxy->prefix, prefix_uri); if (res < 0) { DEBUG_PRINT("ABORT %d %s bad ccn URI: %s\n", __LINE__, __func__, prefix_uri); abort(); } d = ccn_buf_decoder_start(d, proxy->prefix->buf, proxy->prefix->length); proxy->prefix_comps = ccn_indexbuf_create(); proxy->prefix_ncomps = ccn_parse_Name(d, proxy->prefix_comps); proxy->filter = ccn_charbuf_create(); res = ccn_name_from_uri(proxy->filter, filter_uri); if (res < 0) { DEBUG_PRINT("ABORT %d %s bad ccn URI: %s\n", __LINE__, __func__, filter_uri); abort(); } /* Initialization should be done by ccn_proxy_connect() */ proxy->handle_name = ccn_charbuf_create(); ccn_charbuf_append_string(proxy->handle_name, "in/outb"); DEBUG_PRINT("OUT %d %s\n", __LINE__, __func__); return(proxy); }
/** * 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); }
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; }
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); }
static struct content_queue * content_queue_create(struct ccnr_handle *h, struct fdholder *fdholder, enum cq_delay_class c) { struct content_queue *q; unsigned usec; q = calloc(1, sizeof(*q)); if (q != NULL) { usec = choose_face_delay(h, fdholder, c); q->burst_nsec = (usec <= 500 ? 500 : 150000); // XXX - needs a knob q->min_usec = usec; q->rand_usec = 2 * usec; q->nrun = 0; q->send_queue = ccn_indexbuf_create(); if (q->send_queue == NULL) { free(q); return(NULL); } q->sender = NULL; } return(q); }
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); }
extern struct SyncBaseStruct * SyncNewBase(struct ccnr_handle *ccnr, struct ccn *ccn, struct ccn_schedule *sched) { sync_time now = SyncCurrentTime(); struct SyncBaseStruct *base = NEW_STRUCT(1, SyncBaseStruct); base->ccnr = ccnr; base->ccn = ccn; base->sched = sched; struct SyncPrivate *priv = NEW_STRUCT(1, SyncPrivate); base->priv = priv; priv->topoAccum = SyncAllocNameAccum(4); priv->prefixAccum = SyncAllocNameAccum(4); priv->sliceCmdPrefix = ccn_charbuf_create(); priv->localHostPrefix = ccn_charbuf_create(); priv->comps = ccn_indexbuf_create(); priv->stableTarget = CCNR_NULL_HWM; priv->stableStored = CCNR_NULL_HWM; priv->lastStable = now; priv->lastCacheClean = now; ccn_name_from_uri(priv->localHostPrefix, "/%C1.M.S.localhost"); ccn_name_from_uri(priv->sliceCmdPrefix, "/%C1.M.S.localhost/%C1.S.cs"); return base; }
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); }
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 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); }
static int dissect_ccn_contentobject(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *signature_tree; proto_tree *name_tree; proto_tree *signedinfo_tree; proto_tree *content_tree; proto_item *titem; struct ccn_parsed_ContentObject co; struct ccn_parsed_ContentObject *pco = &co; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; size_t blob_size; const unsigned char *blob; int l; unsigned int i; double dt; nstime_t timestamp; int res; comps = ccn_indexbuf_create(); res = ccn_parse_ContentObject(ccnb, ccnb_size, pco, comps); if (res < 0) return (-1); /* Signature */ l = pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature]; titem = proto_tree_add_item(tree, hf_ccn_signature, tvb, pco->offset[CCN_PCO_B_Signature], l, FALSE); signature_tree = proto_item_add_subtree(titem, ett_signature); /* DigestAlgorithm */ l = pco->offset[CCN_PCO_E_DigestAlgorithm] - pco->offset[CCN_PCO_B_DigestAlgorithm]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, ccnb, pco->offset[CCN_PCO_B_DigestAlgorithm], pco->offset[CCN_PCO_E_DigestAlgorithm], &blob, &blob_size); titem = proto_tree_add_item(signature_tree, hf_ccn_signaturedigestalg, tvb, blob - ccnb, blob_size, FALSE); } /* Witness */ l = pco->offset[CCN_PCO_E_Witness] - pco->offset[CCN_PCO_B_Witness]; if (l > 0) { /* add the witness item to the signature tree */ } /* Signature bits */ l = pco->offset[CCN_PCO_E_SignatureBits] - pco->offset[CCN_PCO_B_SignatureBits]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, ccnb, pco->offset[CCN_PCO_B_SignatureBits], pco->offset[CCN_PCO_E_SignatureBits], &blob, &blob_size); titem = proto_tree_add_bytes(signature_tree, hf_ccn_signaturebits, tvb, blob - ccnb, blob_size, blob); } /* /Signature */ /* Name */ l = pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pco->offset[CCN_PCO_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); /* Name Components */ for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* /Name */ /* SignedInfo */ l = pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo]; titem = proto_tree_add_text(tree, tvb, pco->offset[CCN_PCO_B_SignedInfo], l, "SignedInfo"); signedinfo_tree = proto_item_add_subtree(titem, ett_signedinfo); /* PublisherPublicKeyDigest */ l = pco->offset[CCN_PCO_E_PublisherPublicKeyDigest] - pco->offset[CCN_PCO_B_PublisherPublicKeyDigest]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, ccnb, pco->offset[CCN_PCO_B_PublisherPublicKeyDigest], pco->offset[CCN_PCO_E_PublisherPublicKeyDigest], &blob, &blob_size); titem = proto_tree_add_bytes(signedinfo_tree, hf_ccn_publisherpublickeydigest, tvb, blob - ccnb, blob_size, blob); } /* Timestamp */ l = pco->offset[CCN_PCO_E_Timestamp] - pco->offset[CCN_PCO_B_Timestamp]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, ccnb, pco->offset[CCN_PCO_B_Timestamp], pco->offset[CCN_PCO_E_Timestamp], &blob, &blob_size); dt = 0.0; for (i = 0; i < blob_size; i++) dt = dt * 256.0 + (double)blob[i]; dt /= 4096.0; timestamp.secs = dt; /* truncates */ timestamp.nsecs = (dt - (double) timestamp.secs) * 1000000000.0; titem = proto_tree_add_time(signedinfo_tree, hf_ccn_timestamp, tvb, blob - ccnb, blob_size, ×tamp); } /* Type */ l = pco->offset[CCN_PCO_E_Type] - pco->offset[CCN_PCO_B_Type]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_Type, ccnb, pco->offset[CCN_PCO_B_Type], pco->offset[CCN_PCO_E_Type], &blob, &blob_size); titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, tvb, blob - ccnb, blob_size, pco->type); } else { titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, NULL, 0, 0, pco->type); } /* FreshnessSeconds */ l = pco->offset[CCN_PCO_E_FreshnessSeconds] - pco->offset[CCN_PCO_B_FreshnessSeconds]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_FreshnessSeconds, ccnb, pco->offset[CCN_PCO_B_FreshnessSeconds], pco->offset[CCN_PCO_E_FreshnessSeconds], &blob, &blob_size); i = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_FreshnessSeconds, ccnb, pco->offset[CCN_PCO_B_FreshnessSeconds], pco->offset[CCN_PCO_E_FreshnessSeconds]); titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_freshnessseconds, tvb, blob - ccnb, blob_size, i); } /* FinalBlockID */ l = pco->offset[CCN_PCO_E_FinalBlockID] - pco->offset[CCN_PCO_B_FinalBlockID]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb, pco->offset[CCN_PCO_B_FinalBlockID], pco->offset[CCN_PCO_E_FinalBlockID], &blob, &blob_size); titem = proto_tree_add_item(signedinfo_tree, hf_ccn_finalblockid, tvb, blob - ccnb, blob_size, FALSE); } /* TODO: KeyLocator */ /* /SignedInfo */ /* Content */ l = pco->offset[CCN_PCO_E_Content] - pco->offset[CCN_PCO_B_Content]; res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnb, pco->offset[CCN_PCO_B_Content], pco->offset[CCN_PCO_E_Content], &blob, &blob_size); titem = proto_tree_add_text(tree, tvb, pco->offset[CCN_PCO_B_Content], l, "Content: %d bytes", blob_size); if (blob_size > 0) { content_tree = proto_item_add_subtree(titem, ett_content); titem = proto_tree_add_item(content_tree, hf_ccn_contentdata, tvb, blob - ccnb, blob_size, FALSE); } return (ccnb_size); }
static int dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *name_tree; proto_tree *exclude_tree; proto_item *titem; struct ccn_parsed_interest interest; struct ccn_parsed_interest *pi = &interest; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; const unsigned char *blob; size_t blob_size; ssize_t l; unsigned int i; int res; comps = ccn_indexbuf_create(); res = ccn_parse_interest(ccnb, ccnb_size, pi, comps); /* Name */ l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pi->offset[CCN_PI_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* MinSuffixComponents */ l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents]; if (l > 0) { i = pi->min_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i); } /* MaxSuffixComponents */ l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents]; if (l > 0) { i = pi->max_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i); } /* PublisherIDKeyDigest? */ /* Exclude */ l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]; if (l > 0) { titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l, "Exclude"); exclude_tree = proto_item_add_subtree(titem, ett_exclude); } /* ChildSelector */ l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector]; if (l > 0) { i = pi->orderpref; titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i); proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), "")); } /* AnswerOriginKind */ l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind]; if (l > 0) { i = pi->answerfrom; titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i); } /* Scope */ l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope]; if (l > 0) { i = pi->scope; titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i); } /* Nonce */ /* Nonce */ l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb, pi->offset[CCN_PI_B_Nonce], pi->offset[CCN_PI_E_Nonce], &blob, &blob_size); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, ", <"); for (i = 0; i < blob_size; i++) col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]); col_append_str(pinfo->cinfo, COL_INFO, ">"); } titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb, blob - ccnb, blob_size, FALSE); } return (1); }
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); }
enum ccn_upcall_res incoming_content( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { struct ccn_charbuf *name = NULL; struct ccn_charbuf *templ = NULL; struct ccn_charbuf *temp = NULL; const unsigned char *ccnb = NULL; size_t ccnb_size = 0; const unsigned char *data = NULL; size_t data_size = 0; // TANG: no need to write data to stdout //size_t written; const unsigned char *ib = NULL; /* info->interest_ccnb */ struct ccn_indexbuf *ic = NULL; int res; struct mydata *md = selfp->data; if (kind == CCN_UPCALL_FINAL) { if (md != NULL) { selfp->data = NULL; free(md); md = NULL; } return(CCN_UPCALL_RESULT_OK); } if (kind == CCN_UPCALL_INTEREST_TIMED_OUT) return(CCN_UPCALL_RESULT_REEXPRESS); if (kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED) return(CCN_UPCALL_RESULT_ERR); if (md == NULL) selfp->data = md = calloc(1, sizeof(*md)); ccnb = info->content_ccnb; ccnb_size = info->pco->offset[CCN_PCO_E]; ib = info->interest_ccnb; ic = info->interest_comps; /* XXX - must verify sig, and make sure it is LEAF content */ res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &data, &data_size); if (res < 0) abort(); if (data_size > CHUNK_SIZE) { /* For us this is spam. Give up now. */ fprintf(stderr, "*** Segment %d found with a data size of %d." " This program only works with segments of 1024 bytes." " Try ccncatchunks2 instead.\n", (int)selfp->intdata, (int)data_size); exit(1); } /* OK, we will accept this block. */ //sleep(1); // TANG: No need to write data to stdout, skip 3 lines //written = fwrite(data, data_size, 1, stdout); //if (written != 1) // exit(1); /* A short block signals EOF for us. */ // TANG: to support data_size smaller than 1024, skip 2 lines //if (data_size < CHUNK_SIZE) // exit(0); /* Ask for the next one */ name = ccn_charbuf_create(); ccn_name_init(name); if (ic->n < 2) abort(); res = ccn_name_append_components(name, ib, ic->buf[0], ic->buf[ic->n - 2]); if (res < 0) abort(); temp = ccn_charbuf_create(); //printf("intdata = %d \n ", selfp->intdata); ccn_charbuf_putf(temp, "%d", ++(selfp->intdata)); ccn_name_append(name, temp->buf, temp->length); ccn_charbuf_destroy(&temp); if(DEBUG){ //Print out the interest's name printf("Interest name = "); int myres = 0; struct ccn_indexbuf* ndx = ccn_indexbuf_create(); unsigned char* mycomp = NULL; size_t mysize = 0; ndx->n = 0; myres = ccn_name_split(name, ndx); if(myres < 0){ fprintf(stderr, "ccn_name_split @ ccntraffic. failed"); } int it = 0; for(it = 0; it < ndx->n-1; it++){ mysize = 0; myres = ccn_name_comp_get(name->buf, ndx, it, &mycomp, &mysize); printf("%s/", mycomp); mycomp = NULL; } printf("\n"); } templ = make_template(md); res = ccn_express_interest(info->h, name, selfp, templ); if (res < 0) abort(); ccn_charbuf_destroy(&templ); ccn_charbuf_destroy(&name); return(CCN_UPCALL_RESULT_OK); }
static void ask_set(struct mydata *md, char ** urlList, int flying){ if(DEBUG) printf("In function askset \n "); struct ccn_charbuf * name = NULL; struct ccn_charbuf * templ = NULL; int i = 0; int res = -1; struct ccn_closure * cl = NULL; /* TODO: Zipf Distribution //Test the Zipf distribution printf("Zipf starts \n"); for(i = 1; i < 100000; i++){ printf("%d \n", zipf(5, 100, i)); } printf("Zipfs ends\n"); */ int r = 0; for(r = 0; r < 1; r++){ for(i = 0; i < flying; i++){ cl = &(md->ooo[i].closure); name = ccn_charbuf_create(); printf("url = %s \n", urlList[i]); printf("===\n"); res = ccn_name_from_uri(name, urlList[i]); if(res < 0){ printf("ccn_name_from_uri failed \n"); abort(); } ccn_name_append(name, "0", 1); templ = make_template(md); if(DEBUG){ //Print out the interest's name printf("Sending Interest : "); int myres = 0; struct ccn_indexbuf* ndx = ccn_indexbuf_create(); unsigned char* mycomp = NULL; size_t mysize = 0; ndx->n = 0; myres = ccn_name_split(name, ndx); if(myres < 0){ fprintf(stderr, "ccn_name_split @ ccntraffic. failed"); } int it = 0; for(it = 0; it < ndx->n-1; it++){ mysize = 0; myres = ccn_name_comp_get(name->buf, ndx, it, &mycomp, &mysize); printf("%s/", mycomp); mycomp = NULL; } printf("\n"); } res = ccn_express_interest(md->h, name, cl, templ); if(res < 0) abort(); ccn_charbuf_destroy(&name); } } printf("Sent!\n"); }
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); }
/** * 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); }
static int dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *name_tree; proto_tree *exclude_tree; proto_item *titem; struct ccn_parsed_interest interest; struct ccn_parsed_interest *pi = &interest; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; const unsigned char *bloom; size_t bloom_size = 0; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; const unsigned char *blob; size_t blob_size; ssize_t l; unsigned int i; double lifetime; int res; comps = ccn_indexbuf_create(); res = ccn_parse_interest(ccnb, ccnb_size, pi, comps); if (res < 0) return (res); /* Name */ l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pi->offset[CCN_PI_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* MinSuffixComponents */ l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents]; if (l > 0) { i = pi->min_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i); } /* MaxSuffixComponents */ l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents]; if (l > 0) { i = pi->max_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i); } /* PublisherPublicKeyDigest */ /* Exclude */ l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]; if (l > 0) { c = ccn_charbuf_create(); d = ccn_buf_decoder_start(&decoder, ccnb + pi->offset[CCN_PI_B_Exclude], l); if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) { ccn_charbuf_destroy(&c); return(-1); } ccn_charbuf_append_string(c, "Exclude: "); ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_charbuf_append_string(c, "* "); ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_charbuf_append_string(c, "? "); ccn_buf_check_close(d); } while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); comp_size = 0; if (ccn_buf_match_blob(d, &comp, &comp_size)) ccn_buf_advance(d); ccn_uri_append_percentescaped(c, comp, comp_size); ccn_charbuf_append_string(c, " "); ccn_buf_check_close(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_charbuf_append_string(c, "* "); ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_charbuf_append_string(c, "? "); ccn_buf_check_close(d); } } titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l, "%s", ccn_charbuf_as_string(c)); exclude_tree = proto_item_add_subtree(titem, ett_exclude); ccn_charbuf_destroy(&c); } /* ChildSelector */ l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector]; if (l > 0) { i = pi->orderpref; titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i); proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), "")); } /* AnswerOriginKind */ l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind]; if (l > 0) { i = pi->answerfrom; titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i); } /* Scope */ l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope]; if (l > 0) { i = pi->scope; titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i); } /* InterestLifetime */ l = pi->offset[CCN_PI_E_InterestLifetime] - pi->offset[CCN_PI_B_InterestLifetime]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, ccnb, pi->offset[CCN_PI_B_InterestLifetime], pi->offset[CCN_PI_E_InterestLifetime], &blob, &blob_size); lifetime = 0.0; for (i = 0; i < blob_size; i++) lifetime = lifetime * 256.0 + (double)blob[i]; lifetime /= 4096.0; titem = proto_tree_add_double(tree, hf_ccn_interestlifetime, tvb, blob - ccnb, blob_size, lifetime); } /* Nonce */ l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb, pi->offset[CCN_PI_B_Nonce], pi->offset[CCN_PI_E_Nonce], &blob, &blob_size); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, ", <"); for (i = 0; i < blob_size; i++) col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]); col_append_str(pinfo->cinfo, COL_INFO, ">"); } titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb, blob - ccnb, blob_size, FALSE); } return (1); }
/** * 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); }
int main (int argc, char *argv[]) { struct ccn_charbuf *buffer = ccn_charbuf_create(); struct ccn_charbuf *signed_info = ccn_charbuf_create(); struct ccn_skeleton_decoder dd = {0}; ssize_t res; char *outname = NULL; int fd; int result = 0; char * contents[] = {"INVITE sip:[email protected] SIP/2.0\nVia: SIP/2.0/UDP 127.0.0.1:5060;rport;branch=z9hG4bK519044721\nFrom: <sip:[email protected]>;tag=2105643453\nTo: Test User <sip:[email protected]>\nCall-ID: [email protected]\nCSeq: 20 INVITE\nContact: <sip:[email protected]:5060>\nMax-Forwards: 70\nUser-Agent: Linphone-1.7.1/eXosip\nSubject: Phone call\nExpires: 120\nAllow: INVITE, ACK, CANCEL, BYE, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE\nContent-Type: application/sdp\nContent-Length: 448\n\nv=0\no=jthornto 123456 654321 IN IP4 127.0.0.1\ns=A conversation\nc=IN IP4 127.0.0.1\nt=0 0\nm=audio 7078 RTP/AVP 111 110 0 3 8 101\na=rtpmap:111 speex/16000/1\na=rtpmap:110 speex/8000/1\na=rtpmap:0 PCMU/8000/1\na=rtpmap:3 GSM/8000/1\na=rtpmap:8 PCMA/8000/1\na=rtpmap:101 telephone-event/8000\na=fmtp:101 0-11\nm=video 9078 RTP/AVP 97 98 99\na=rtpmap:97 theora/90000\na=rtpmap:98 H263-1998/90000\na=fmtp:98 CIF=1;QCIF=1\na=rtpmap:99 MP4V-ES/90000\n", "Quaer #%2d zjduer badone", "", NULL}; char * paths[] = { "/sip/protocol/parc.com/domain/foo/principal/invite/verb/[email protected]/id", "/d/e/f", "/zero/length/content", NULL}; struct path * cur_path = NULL; struct ccn_keystore *keystore = ccn_keystore_create(); char *home = getenv("HOME"); char *keystore_suffix = "/.ccnx/.ccnx_keystore"; char *keystore_name = NULL; int i; if (argc == 3 && strcmp(argv[1], "-o") == 0) { outname = argv[2]; } else { printf("Usage: %s -o <outfilename>\n", argv[0]); exit(1); } if (home == NULL) { printf("Unable to determine home directory for keystore\n"); exit(1); } keystore_name = calloc(1, strlen(home) + strlen(keystore_suffix) + 1); strcat(keystore_name, home); strcat(keystore_name, keystore_suffix); if (0 != ccn_keystore_init(keystore, keystore_name, "Th1s1sn0t8g00dp8ssw0rd.")) { printf("Failed to initialize keystore\n"); exit(1); } printf("Creating signed_info\n"); res = ccn_signed_info_create(signed_info, /*pubkeyid*/ccn_keystore_public_key_digest(keystore), /*publisher_key_id_size*/ccn_keystore_public_key_digest_length(keystore), /*datetime*/NULL, /*type*/CCN_CONTENT_GONE, /*freshness*/ 42, /*finalblockid*/NULL, /*keylocator*/NULL); if (res < 0) { printf("Failed to create signed_info!\n"); } res = ccn_skeleton_decode(&dd, signed_info->buf, signed_info->length); if (!(res == signed_info->length && dd.state == 0)) { printf("Failed to decode signed_info! Result %d State %d\n", (int)res, dd.state); result = 1; } memset(&dd, 0, sizeof(dd)); printf("Done with signed_info\n"); printf("Encoding sample message data length %d\n", (int)strlen(contents[0])); cur_path = path_create(paths[0]); if (encode_message(buffer, cur_path, contents[0], strlen(contents[0]), signed_info, ccn_keystore_private_key(keystore))) { printf("Failed to encode message!\n"); } else { printf("Encoded sample message length is %d\n", (int)buffer->length); res = ccn_skeleton_decode(&dd, buffer->buf, buffer->length); if (!(res == buffer->length && dd.state == 0)) { printf("Failed to decode! Result %d State %d\n", (int)res, dd.state); result = 1; } if (outname != NULL) { fd = open(outname, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU); if (fd == -1) perror(outname); res = write(fd, buffer->buf, buffer->length); close(fd); } if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) != 0) { result = 1; } printf("Expect signature verification failure: "); if (buffer->length >= 20) buffer->buf[buffer->length - 20] += 1; if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) == 0) { result = 1; } } path_destroy(&cur_path); ccn_charbuf_destroy(&buffer); printf("Done with sample message\n"); /* Now exercise as unit tests */ for (i = 0; paths[i] != NULL && contents[i] != NULL; i++) { printf("Unit test case %d\n", i); cur_path = path_create(paths[i]); buffer = ccn_charbuf_create(); if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_private_key(keystore))) { printf("Failed encode\n"); result = 1; } else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_public_key(keystore))) { printf("Failed decode\n"); result = 1; } path_destroy(&cur_path); ccn_charbuf_destroy(&buffer); } /* Test the uri encode / decode routines */ init_all_chars_percent_encoded(); const char *uri_tests[] = { "_+4", "ccnx:/this/is/a/test", "", "ccnx:/this/is/a/test", ".+4", "../test2?x=2", "?x=2", "ccnx:/this/is/a/test2", "_-X", "../should/error", "", "", "_+2", "/missing/scheme", "", "ccnx:/missing/scheme", ".+0", "../../../../../././#/", "#/", "ccnx:/", ".+1", all_chars_percent_encoded, "", all_chars_percent_encoded_canon, "_+1", all_chars_percent_encoded_canon, "", all_chars_percent_encoded_canon, ".+4", "ccnx:/.../.%2e./...././.....///?...", "?...", "ccnx:/.../.../..../.....", "_-X", "/%3G?bad-pecent-encode", "", "", "_-X", "/%3?bad-percent-encode", "", "", "_-X", "/%#bad-percent-encode", "", "", "_+3", "ccnx://[email protected]:42/ignore/host/part of uri", "", "ccnx:/ignore/host/part%20of%20uri", NULL, NULL, NULL, NULL }; const char **u; struct ccn_charbuf *uri_out = ccn_charbuf_create(); buffer = ccn_charbuf_create(); for (u = uri_tests; *u != NULL; u += 4, i++) { printf("Unit test case %d\n", i); if (u[0][0] != '.') buffer->length = 0; res = ccn_name_from_uri(buffer, u[1]); if (!expected_res(res, u[0][1])) { printf("Failed: ccn_name_from_uri wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (res > strlen(u[1])) { printf("Failed: ccn_name_from_uri long res %d\n", (int)res); result = 1; } else if (0 != strcmp(u[1] + res, u[2])) { printf("Failed: ccn_name_from_uri expecting leftover '%s', got '%s'\n", u[2], u[1] + res); result = 1; } uri_out->length = 0; res = ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (!expected_res(res, u[0][2])) { printf("Failed: ccn_uri_append wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (uri_out->length != strlen(u[3])) { printf("Failed: ccn_uri_append produced wrong number of characters\n"); result = 1; } ccn_charbuf_reserve(uri_out, 1)[0] = 0; if (0 != strcmp((const char *)uri_out->buf, u[3])) { printf("Failed: ccn_uri_append produced wrong output\n"); printf("Expected: %s\n", u[3]); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } } } } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); printf("Name marker tests\n"); do { const char *expected_uri = "ccnx:/example.com/.../%01/%FE/%01%02%03%04%05%06%07%08/%FD%10%10%10%10%1F%FF/%00%81"; const char *expected_chopped_uri = "ccnx:/example.com/.../%01/%FE"; const char *expected_bumped_uri = "ccnx:/example.com/.../%01/%FF"; const char *expected_bumped2_uri = "ccnx:/example.com/.../%01/%00%00"; printf("Unit test case %d\n", i++); buffer = ccn_charbuf_create(); uri_out = ccn_charbuf_create(); res = ccn_name_init(buffer); res |= ccn_name_append_str(buffer, "example.com"); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1); res |= ccn_name_append_numeric(buffer, 0xFE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129); res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (res < 0) { printf("Failed: name marker tests had negative res\n"); result = 1; } if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri)) { printf("Failed: name marker tests produced wrong output\n"); printf("Expected: %s\n", expected_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_chop(buffer, NULL, 100); if (res != -1) { printf("Failed: ccn_name_chop did not produce error \n"); result = 1; } res = ccn_name_chop(buffer, NULL, 4); if (res != 4) { printf("Failed: ccn_name_chop got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_chopped_uri)) { printf("Failed: ccn_name_chop botch\n"); printf("Expected: %s\n", expected_chopped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_next_sibling(buffer); if (res != 4) { printf("Failed: ccn_name_next_sibling got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_name_next_sibling(buffer); uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped2_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped2_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); } while (0); printf("Message digest tests\n"); do { printf("Unit test case %d\n", i++); struct ccn_digest *dg = ccn_digest_create(CCN_DIGEST_SHA256); if (dg == NULL) { printf("Failed: ccn_digest_create returned NULL\n"); result = 1; break; } printf("Unit test case %d\n", i++); const unsigned char expected_digest[] = { 0xb3, 0x82, 0xcd, 0xb0, 0xe9, 0x5d, 0xf7, 0x3b, 0xe7, 0xdc, 0x19, 0x81, 0x3a, 0xfd, 0xdf, 0x89, 0xfb, 0xd4, 0xd4, 0xa0, 0xdb, 0x11, 0xa6, 0xba, 0x24, 0x16, 0x5b, 0xad, 0x9d, 0x90, 0x72, 0xb0 }; unsigned char actual_digest[sizeof(expected_digest)] = {0}; const char *data = "Content-centric"; if (ccn_digest_size(dg) != sizeof(expected_digest)) { printf("Failed: wrong digest size\n"); result = 1; break; } printf("Unit test case %d\n", i++); ccn_digest_init(dg); res = ccn_digest_update(dg, data, strlen(data)); if (res != 0) printf("Warning: check res %d\n", (int)res); printf("Unit test case %d\n", i++); res = ccn_digest_final(dg, actual_digest, sizeof(expected_digest)); if (res != 0) printf("Warning: check res %d\n", (int)res); if (0 != memcmp(actual_digest, expected_digest, sizeof(expected_digest))) { printf("Failed: wrong digest\n"); result = 1; break; } } while (0); printf("Really basic PRNG test\n"); do { unsigned char r1[42]; unsigned char r2[42]; printf("Unit test case %d\n", i++); ccn_add_entropy(&i, sizeof(i), 0); /* Not much entropy, really. */ ccn_random_bytes(r1, sizeof(r1)); memcpy(r2, r1, sizeof(r2)); ccn_random_bytes(r2, sizeof(r2)); if (0 == memcmp(r1, r2, sizeof(r2))) { printf("Failed: badly broken PRNG\n"); result = 1; break; } } while (0); printf("Bloom filter tests\n"); do { unsigned char seed1[4] = "1492"; const char *a[13] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen" }; struct ccn_bloom *b1 = NULL; struct ccn_bloom *b2 = NULL; int j, k, t1, t2; unsigned short us; printf("Unit test case %d\n", i++); b1 = ccn_bloom_create(13, seed1); for (j = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" matched empty Bloom filter\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0; j < 13; j++) ccn_bloom_insert(b1, a[j], strlen(a[j])); for (j = 0; j < 13; j++) if (!ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" not found when it should have been\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0, k = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j]+1, strlen(a[j]+1))) k++; if (k > 0) { printf("Mmm, found %d false positives\n", k); if (k > 2) { result = 1; break; } } unsigned char seed2[5] = "aqfb\0"; for (; seed2[3] <= 'f'; seed2[3]++) { printf("Unit test case %d (%4s) ", i++, seed2); b2 = ccn_bloom_create(13, seed2); for (j = 0; j < 13; j++) ccn_bloom_insert(b2, a[j], strlen(a[j])); for (j = 0, k = 0, us = ~0; us > 0; us--) { t1 = ccn_bloom_match(b1, &us, sizeof(us)); t2 = ccn_bloom_match(b2, &us, sizeof(us)); j += (t1 | t2); k += (t1 & t2); } printf("either=%d both=%d wiresize=%d\n", j, k, ccn_bloom_wiresize(b1)); if (k > 12) { printf("Failed: Bloom seeding may not be effective\n"); result = 1; } ccn_bloom_destroy(&b2); } ccn_bloom_destroy(&b1); } while (0); printf("ccn_sign_content() tests\n"); do { struct ccn *h = ccn_create(); struct ccn_charbuf *co = ccn_charbuf_create(); struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT; struct ccn_parsed_ContentObject pco = {0}; struct ccn_charbuf *name = ccn_charbuf_create(); printf("Unit test case %d\n", i++); ccn_name_from_uri(name, "ccnx:/test/data/%00%42"); res = ccn_sign_content(h, co, name, NULL, "DATA", 4); if (res != 0) { printf("Failed: res == %d\n", (int)res); result = 1; } sparm.template_ccnb = ccn_charbuf_create(); res = ccn_parse_ContentObject(co->buf, co->length, &pco, NULL); if (res != 0) { printf("Failed: ccn_parse_ContentObject res == %d\n", (int)res); result = 1; break; } ccn_charbuf_append(sparm.template_ccnb, co->buf + pco.offset[CCN_PCO_B_SignedInfo], pco.offset[CCN_PCO_E_SignedInfo] - pco.offset[CCN_PCO_B_SignedInfo]); sparm.sp_flags = CCN_SP_TEMPL_TIMESTAMP; printf("Unit test case %d\n", i++); res = ccn_sign_content(h, co, name, &sparm, "DATA", 4); if (res != 0) { printf("Failed: res == %d\n", (int)res); result = 1; } printf("Unit test case %d\n", i++); sparm.sp_flags = -1; res = ccn_sign_content(h, co, name, &sparm, "DATA", 4); if (res != -1) { printf("Failed: res == %d\n", (int)res); result = 1; } ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&sparm.template_ccnb); ccn_charbuf_destroy(&co); ccn_destroy(&h); } while (0); printf("link tests\n"); do { struct ccn_charbuf *l = ccn_charbuf_create(); struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_parsed_Link pl = {0}; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; struct ccn_indexbuf *comps = ccn_indexbuf_create(); printf("Unit test case %d\n", i++); ccn_name_from_uri(name, "ccnx:/test/link/name"); ccnb_append_Link(l, name, "label", NULL); d = ccn_buf_decoder_start(&decoder, l->buf, l->length); res = ccn_parse_Link(d, &pl, comps); if (res != 3 /* components in name */) { printf("Failed: ccn_parse_Link res == %d\n", (int)res); result = 1; } } while (0); exit(result); }
int main(int argc, char *argv[]) { struct ccn_charbuf *buffer; struct ccn_charbuf *signed_info = ccn_charbuf_create(); struct ccn_skeleton_decoder dd = {0}; ssize_t res; char *outname = NULL; int result = 0; char * contents[] = {"INVITE sip:[email protected] SIP/2.0\nVia: SIP/2.0/UDP 127.0.0.1:5060;rport;branch=z9hG4bK519044721\nFrom: <sip:[email protected]>;tag=2105643453\nTo: Test User <sip:[email protected]>\nCall-ID: [email protected]\nCSeq: 20 INVITE\nContact: <sip:[email protected]:5060>\nMax-Forwards: 70\nUser-Agent: Linphone-1.7.1/eXosip\nSubject: Phone call\nExpires: 120\nAllow: INVITE, ACK, CANCEL, BYE, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE\nContent-Type: application/sdp\nContent-Length: 448\n\nv=0\no=jthornto 123456 654321 IN IP4 127.0.0.1\ns=A conversation\nc=IN IP4 127.0.0.1\nt=0 0\nm=audio 7078 RTP/AVP 111 110 0 3 8 101\na=rtpmap:111 speex/16000/1\na=rtpmap:110 speex/8000/1\na=rtpmap:0 PCMU/8000/1\na=rtpmap:3 GSM/8000/1\na=rtpmap:8 PCMA/8000/1\na=rtpmap:101 telephone-event/8000\na=fmtp:101 0-11\nm=video 9078 RTP/AVP 97 98 99\na=rtpmap:97 theora/90000\na=rtpmap:98 H263-1998/90000\na=fmtp:98 CIF=1;QCIF=1\na=rtpmap:99 MP4V-ES/90000\n", "Quaer #%2d zjduer badone", "", NULL}; char * paths[] = { "/sip/protocol/parc.com/domain/foo/principal/invite/verb/[email protected]/id", "/d/e/f", "/zero/length/content", NULL}; struct path * cur_path = NULL; struct ccn_keystore *keystore = ccn_keystore_create(); struct ccn_keystore *aes_keystore = ccn_aes_keystore_create(); char *keystore_name = NULL; char *keystore_password = NULL; char *aes_keystore_name = NULL; unsigned char keybuf[32]; int i; while ((i = getopt(argc, argv, "a:k:p:o:")) != -1) { switch (i) { case 'a': aes_keystore_name = optarg; break; case 'k': keystore_name = optarg; break; case 'p': keystore_password = optarg; break; case 'o': outname = optarg; break; default: printf("Usage: %s [-k <keystore>] [-o <outfilename>]\n", argv[0]); exit(1); } } if (keystore_name == NULL) keystore_name = "test.keystore"; if (aes_keystore_name == NULL) aes_keystore_name = "test.aeskeystore"; if (keystore_password == NULL) keystore_password = "******"; res = ccn_keystore_init(keystore, keystore_name, keystore_password); if (res != 0) { printf ("Initializing keystore in %s\n", keystore_name); res = ccn_keystore_file_init(keystore_name, keystore_password, "ccnxuser", 0, 3650); if (res != 0) { fprintf (stderr, "Cannot create keystore [%s]", keystore_name); return res; } res = ccn_keystore_init(keystore, keystore_name, keystore_password); if (res != 0) { printf("Failed to initialize keystore\n"); exit(1); } } res = ccn_aes_keystore_init(aes_keystore, aes_keystore_name, keystore_password); if (res != 0) { printf ("Initializing AES keystore in %s\n", aes_keystore_name); ccn_generate_symmetric_key(keybuf, 256); res = ccn_aes_keystore_file_init(aes_keystore_name, keystore_password, keybuf, 256); if (res != 0) { fprintf (stderr, "Cannot create keystore [%s]", keystore_name); return res; } res = ccn_aes_keystore_init(aes_keystore, aes_keystore_name, keystore_password); if (res != 0) { printf("Failed to initialize keystore\n"); exit(1); } } printf("Creating signed_info\n"); res = ccn_signed_info_create(signed_info, /*pubkeyid*/ccn_keystore_key_digest(keystore), /*publisher_key_id_size*/ccn_keystore_key_digest_length(keystore), /*timestamp*/NULL, /*type*/CCN_CONTENT_GONE, /*freshness*/ 42, /*finalblockid*/NULL, /*keylocator*/NULL); if (res < 0) { printf("Failed to create signed_info!\n"); } res = ccn_skeleton_decode(&dd, signed_info->buf, signed_info->length); if (!(res == signed_info->length && dd.state == 0)) { printf("Failed to decode signed_info! Result %d State %d\n", (int)res, dd.state); result = 1; } memset(&dd, 0, sizeof(dd)); printf("Done with signed_info\n"); result = encode_sample_test(ccn_keystore_key(keystore), ccn_keystore_public_key(keystore), ccn_keystore_digest_algorithm(keystore), paths, contents, signed_info, outname); if (! result) { result = encode_sample_test(ccn_keystore_key(aes_keystore), ccn_keystore_key(aes_keystore), ccn_keystore_digest_algorithm(aes_keystore), paths, contents, signed_info, outname); } /* Now exercise as unit tests */ for (i = 0; paths[i] != NULL && contents[i] != NULL; i++) { printf("Unit test case %d\n", i); cur_path = path_create(paths[i]); buffer = ccn_charbuf_create(); if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_key(keystore), ccn_keystore_digest_algorithm(keystore))) { printf("Failed encode\n"); result = 1; } else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_public_key(keystore))) { printf("Failed decode\n"); result = 1; } ccn_charbuf_destroy(&buffer); buffer = ccn_charbuf_create(); if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_key(aes_keystore), ccn_keystore_digest_algorithm(aes_keystore))) { printf("Failed encode\n"); result = 1; } else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_key(aes_keystore))) { printf("Failed decode\n"); result = 1; } path_destroy(&cur_path); ccn_charbuf_destroy(&buffer); } /* Test the uri encode / decode routines */ init_all_chars_percent_encoded(); init_all_chars_mixed_encoded(); const char *uri_tests[] = { "_+4", "ccnx:/this/is/a/test", "", "ccnx:/this/is/a/test", ".+4", "../test2?x=2", "?x=2", "ccnx:/this/is/a/test2", "_-X", "../should/error", "", "", "_+2", "/missing/scheme", "", "ccnx:/missing/scheme", ".+0", "../../../../../././#/", "#/", "ccnx:/", ".+1", all_chars_percent_encoded, "", all_chars_percent_encoded_canon, "_+1", all_chars_percent_encoded_canon, "", all_chars_percent_encoded_canon, ".+4", "ccnx:/.../.%2e./...././.....///?...", "?...", "ccnx:/.../.../..../.....", "_-X", "/%3G?bad-pecent-encode", "", "", "_-X", "/%3?bad-percent-encode", "", "", "_-X", "/%#bad-percent-encode", "", "", "_+3", "ccnx://[email protected]:42/ignore/host/part of uri", "", "ccnx:/ignore/host/part%20of%20uri", NULL, NULL, NULL, NULL }; const char **u; struct ccn_charbuf *uri_out = ccn_charbuf_create(); buffer = ccn_charbuf_create(); for (u = uri_tests; *u != NULL; u += 4, i++) { printf("Unit test case %d\n", i); if (u[0][0] != '.') buffer->length = 0; res = ccn_name_from_uri(buffer, u[1]); if (!expected_res(res, u[0][1])) { printf("Failed: ccn_name_from_uri wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (res > strlen(u[1])) { printf("Failed: ccn_name_from_uri long res %d\n", (int)res); result = 1; } else if (0 != strcmp(u[1] + res, u[2])) { printf("Failed: ccn_name_from_uri expecting leftover '%s', got '%s'\n", u[2], u[1] + res); result = 1; } uri_out->length = 0; res = ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_PERCENTESCAPE | CCN_URI_INCLUDESCHEME); if (!expected_res(res, u[0][2])) { printf("Failed: ccn_uri_append wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (uri_out->length != strlen(u[3])) { printf("Failed: ccn_uri_append produced wrong number of characters\n"); result = 1; } ccn_charbuf_reserve(uri_out, 1)[0] = 0; if (0 != strcmp((const char *)uri_out->buf, u[3])) { printf("Failed: ccn_uri_append produced wrong output\n"); printf("Expected: %s\n", u[3]); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } } } } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); printf("Name marker tests\n"); do { const char *expected_uri = "ccnx:/example.com/.../%01/%FE/%01%02%03%04%05%06%07%08/%FD%10%10%10%10%1F%FF/%00%81"; const char *expected_chopped_uri = "ccnx:/example.com/.../%01/%FE"; const char *expected_bumped_uri = "ccnx:/example.com/.../%01/%FF"; const char *expected_bumped2_uri = "ccnx:/example.com/.../%01/%00%00"; printf("Unit test case %d\n", i++); buffer = ccn_charbuf_create(); uri_out = ccn_charbuf_create(); res = ccn_name_init(buffer); res |= ccn_name_append_str(buffer, "example.com"); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1); res |= ccn_name_append_numeric(buffer, 0xFE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129); res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_PERCENTESCAPE | CCN_URI_INCLUDESCHEME); if (res < 0) { printf("Failed: name marker tests had negative res\n"); result = 1; } if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri)) { printf("Failed: name marker tests produced wrong output\n"); printf("Expected: %s\n", expected_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_chop(buffer, NULL, 100); if (res != -1) { printf("Failed: ccn_name_chop did not produce error \n"); result = 1; } res = ccn_name_chop(buffer, NULL, 4); if (res != 4) { printf("Failed: ccn_name_chop got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_INCLUDESCHEME); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_chopped_uri)) { printf("Failed: ccn_name_chop botch\n"); printf("Expected: %s\n", expected_chopped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_next_sibling(buffer); if (res != 4) { printf("Failed: ccn_name_next_sibling got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_INCLUDESCHEME); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_name_next_sibling(buffer); uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_PERCENTESCAPE | CCN_URI_INCLUDESCHEME); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped2_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped2_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); } while (0); do { const char *expected_uri_mixed = "ccnx:/example.com/.../%01/%FE/=0102030405060708/=FD101010101FFF/=0081"; printf("Unit test case %d\n", i++); buffer = ccn_charbuf_create(); uri_out = ccn_charbuf_create(); res = ccn_name_init(buffer); res |= ccn_name_append_str(buffer, "example.com"); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1); res |= ccn_name_append_numeric(buffer, 0xFE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129); res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_MIXEDESCAPE | CCN_URI_INCLUDESCHEME); if (res < 0) { printf("Failed: name marker tests had negative res\n"); result = 1; } if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri_mixed)) { printf("Failed: name marker tests produced wrong output\n"); printf("Expected: %s\n", expected_uri_mixed); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); } while (0); printf("Empty component encoding test\n"); do { struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_charbuf *expected_encoding = ccn_charbuf_create(); /* manually create an encoding of <Name><Component/></Name> to ensure * that the regular encoders do not create a 0-length blob as part of * the empty component. */ ccnb_element_begin(expected_encoding, CCN_DTAG_Name); ccnb_element_begin(expected_encoding, CCN_DTAG_Component); ccnb_element_end(expected_encoding); ccnb_element_end(expected_encoding); ccn_name_from_uri(name, "ccnx:/..."); if (expected_encoding->length != name->length) { printf("Failed: encoding length %u but expected %u\n", (unsigned) name->length, (unsigned)expected_encoding->length); result = 1; } for (i = 0; i < expected_encoding->length; i++) { if (expected_encoding->buf[i] != name->buf[i]) { printf("Failed: encoding mismatch at %d, got %d but expected %d\n", i, name->buf[i], expected_encoding->buf[i]); result = 1; } } } while (0); printf("Timestamp tests\n"); do { intmax_t sec; int nsec; int r; int f; struct ccn_charbuf *a[2]; int t0 = 1363899678; printf("Unit test case %d\n", i++); /* Run many increasing inputs and make sure the output is in order. */ a[0] = ccn_charbuf_create(); a[1] = ccn_charbuf_create(); ccnb_append_timestamp_blob(a[1], CCN_MARKER_NONE, t0 - 1, 0); for (f = 0, nsec = 0, sec = t0; sec < t0 + 20; nsec += 122099) { while (nsec >= 1000000000) { sec++; nsec -= 1000000000; } ccn_charbuf_reset(a[f]); r = ccnb_append_timestamp_blob(a[f], CCN_MARKER_NONE, sec, nsec); if (r != 0 || a[f]->length != 7 || memcmp(a[1-f]->buf, a[f]->buf, 6) > 0) { printf("Failed ccnb_append_timestamp_blob(...,%jd,%d)\n", sec, nsec); result = 1; } f = 1 - f; } ccn_charbuf_destroy(&a[0]); ccn_charbuf_destroy(&a[1]); } while (0); printf("Message digest tests\n"); do { printf("Unit test case %d\n", i++); struct ccn_digest *dg = ccn_digest_create(CCN_DIGEST_SHA256); if (dg == NULL) { printf("Failed: ccn_digest_create returned NULL\n"); result = 1; break; } printf("Unit test case %d\n", i++); const unsigned char expected_digest[] = { 0xb3, 0x82, 0xcd, 0xb0, 0xe9, 0x5d, 0xf7, 0x3b, 0xe7, 0xdc, 0x19, 0x81, 0x3a, 0xfd, 0xdf, 0x89, 0xfb, 0xd4, 0xd4, 0xa0, 0xdb, 0x11, 0xa6, 0xba, 0x24, 0x16, 0x5b, 0xad, 0x9d, 0x90, 0x72, 0xb0 }; unsigned char actual_digest[sizeof(expected_digest)] = {0}; const char *data = "Content-centric"; if (ccn_digest_size(dg) != sizeof(expected_digest)) { printf("Failed: wrong digest size\n"); result = 1; break; } printf("Unit test case %d\n", i++); ccn_digest_init(dg); res = ccn_digest_update(dg, data, strlen(data)); if (res != 0) printf("Warning: check res %d\n", (int)res); printf("Unit test case %d\n", i++); res = ccn_digest_final(dg, actual_digest, sizeof(expected_digest)); if (res != 0) printf("Warning: check res %d\n", (int)res); if (0 != memcmp(actual_digest, expected_digest, sizeof(expected_digest))) { printf("Failed: wrong digest\n"); result = 1; break; } } while (0); printf("Really basic PRNG test\n"); do { unsigned char r1[42]; unsigned char r2[42]; printf("Unit test case %d\n", i++); ccn_add_entropy(&i, sizeof(i), 0); /* Not much entropy, really. */ ccn_random_bytes(r1, sizeof(r1)); memcpy(r2, r1, sizeof(r2)); ccn_random_bytes(r2, sizeof(r2)); if (0 == memcmp(r1, r2, sizeof(r2))) { printf("Failed: badly broken PRNG\n"); result = 1; break; } } while (0); printf("Bloom filter tests\n"); do { unsigned char seed1[4] = "1492"; const char *a[13] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen" }; struct ccn_bloom *b1 = NULL; struct ccn_bloom *b2 = NULL; int j, k, t1, t2; unsigned short us; printf("Unit test case %d\n", i++); b1 = ccn_bloom_create(13, seed1); for (j = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" matched empty Bloom filter\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0; j < 13; j++) ccn_bloom_insert(b1, a[j], strlen(a[j])); for (j = 0; j < 13; j++) if (!ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" not found when it should have been\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0, k = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j]+1, strlen(a[j]+1))) k++; if (k > 0) { printf("Mmm, found %d false positives\n", k); if (k > 2) { result = 1; break; } } unsigned char seed2[5] = "aqfb\0"; for (; seed2[3] <= 'f'; seed2[3]++) { printf("Unit test case %d (%4s) ", i++, seed2); b2 = ccn_bloom_create(13, seed2); for (j = 0; j < 13; j++) ccn_bloom_insert(b2, a[j], strlen(a[j])); for (j = 0, k = 0, us = ~0; us > 0; us--) { t1 = ccn_bloom_match(b1, &us, sizeof(us)); t2 = ccn_bloom_match(b2, &us, sizeof(us)); j += (t1 | t2); k += (t1 & t2); } printf("either=%d both=%d wiresize=%d\n", j, k, ccn_bloom_wiresize(b1)); if (k > 12) { printf("Failed: Bloom seeding may not be effective\n"); result = 1; } ccn_bloom_destroy(&b2); } ccn_bloom_destroy(&b1); } while (0); printf("ccn_sign_content() tests\n"); do { struct ccn *h = ccn_create(); int res; res = unit_tests_for_signing(h, &i, 0); if (res == 1) result = 1; printf("Unit test case %d\n", i++); ccn_destroy(&h); } while (0); do { struct ccn *h = ccn_create(); int res; res = ccn_load_default_key(h, aes_keystore_name, keystore_password); if (res < 0) { result = 1; printf("Failed: res == %d\n", (int)res); } else res = unit_tests_for_signing(h, &i, 1); if (res == 1) result = 1; printf("Unit test case %d\n", i++); ccn_destroy(&h); } while (0); printf("link tests\n"); printf("link tests\n"); do { struct ccn_charbuf *l = ccn_charbuf_create(); struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_parsed_Link pl = {0}; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; struct ccn_indexbuf *comps = ccn_indexbuf_create(); printf("Unit test case %d\n", i++); ccn_name_from_uri(name, "ccnx:/test/link/name"); ccnb_append_Link(l, name, "label", NULL); d = ccn_buf_decoder_start(&decoder, l->buf, l->length); res = ccn_parse_Link(d, &pl, comps); if (res != 3 /* components in name */) { printf("Failed: ccn_parse_Link res == %d\n", (int)res); result = 1; } } while (0); exit(result); }
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; }