struct ccnl_interest_s * ccnl_interest_new(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from, struct ccnl_buf_s **pkt, struct ccnl_prefix_s **prefix, int minsuffix, int maxsuffix, struct ccnl_buf_s **ppkd) { struct ccnl_interest_s *i = (struct ccnl_interest_s *) ccnl_calloc(1, sizeof(struct ccnl_interest_s)); DEBUGMSG(99, "ccnl_new_interest\n"); if (!i) { puts("can't get more memory from malloc, dropping ccn msg..."); return NULL; } i->from = from; i->prefix = *prefix; *prefix = 0; i->pkt = *pkt; *pkt = 0; i->ppkd = *ppkd; *ppkd = 0; i->minsuffix = minsuffix; i->maxsuffix = maxsuffix; ccnl_get_timeval(&i->last_used); DBL_LINKED_LIST_ADD(ccnl->pit, i); return i; }
struct ccnl_content_s* ccnl_content_add2cache(struct ccnl_relay_s *ccnl, struct ccnl_content_s *c) { struct ccnl_content_s *cit; DEBUGMSG_CORE(DEBUG, "ccnl_content_add2cache (%d/%d) --> %p = %s [%d]\n", ccnl->contentcnt, ccnl->max_cache_entries, (void*)c, ccnl_prefix_to_path(c->pkt->pfx), (c->pkt->pfx->chunknum)? *(c->pkt->pfx->chunknum) : -1); for (cit = ccnl->contents; cit; cit = cit->next) { if (c == cit) { DEBUGMSG_CORE(DEBUG, "--- Already in cache ---\n"); return NULL; } } #ifdef USE_NACK if (ccnl_nfnprefix_contentIsNACK(c)) return NULL; #endif if (ccnl->max_cache_entries > 0 && ccnl->contentcnt >= ccnl->max_cache_entries) { // remove oldest content struct ccnl_content_s *c2; int age = 0; for (c2 = ccnl->contents; c2; c2 = c2->next) if (!(c2->flags & CCNL_CONTENT_FLAGS_STATIC) && ((age == 0) || c2->last_used < age)) age = c2->last_used; if (c2) ccnl_content_remove(ccnl, c2); } DBL_LINKED_LIST_ADD(ccnl->contents, c); ccnl->contentcnt++; return c; }
int ccnl_nonce_find_or_append(struct ccnl_relay_s *ccnl, struct ccnl_buf_s *nonce) { struct ccnl_nonce_s *n, *last; int i; DEBUGMSG(99, "ccnl_nonce_find_or_append: %u:%u:%u:%u\n", nonce->data[0], nonce->data[1], nonce->data[2], nonce->data[3]); /* test for noce in nonce cache */ for (n = ccnl->nonces, i = 0; n; n = n->next, i++) { DEBUGMSG(1, "known: %u:%u:%u:%u\n", n->buf->data[0], n->buf->data[1], n->buf->data[2], n->buf->data[3]); if (buf_equal(n->buf, nonce)) { /* nonce in cache -> known */ return -1; } if (n->next) { last = n->next; } } /* nonce not in local cache, add it */ n = ccnl_nonce_new(nonce); DBL_LINKED_LIST_ADD(ccnl->nonces, n); /* nonce chache full? */ if (i >= CCNL_MAX_NONCES) { /* cache is full, drop oldest nonce: its the last element in the list */ ccnl_nonce_remove(ccnl, last); } return 0; }
// executes (loops over) a Lambda expression: tries to run to termination, // or returns after having emitted further remote lookup/reduction requests // the return val is a buffer with the result stack's (concatenated) content struct ccnl_buf_s* Krivine_reduction(struct ccnl_relay_s *ccnl, char *expression, int start_locally, struct configuration_s **config, struct ccnl_prefix_s *prefix, int suite) { int steps = 0, halt = 0, restart = 1; int len = strlen("CLOSURE(HALT);RESOLVENAME()") + strlen(expression) + 1; char *dummybuf; DEBUGMSG(TRACE, "Krivine_reduction()\n"); if (!*config && strlen(expression) == 0) return 0; dummybuf = ccnl_malloc(2000); if (!*config) { char *prog; struct environment_s *global_dict = NULL; prog = ccnl_malloc(len*sizeof(char)); sprintf(prog, "CLOSURE(HALT);RESOLVENAME(%s)", expression); setup_global_environment(&global_dict); DEBUGMSG(DEBUG, "PREFIX %s\n", ccnl_prefix_to_path(prefix)); *config = new_config(ccnl, prog, global_dict, start_locally, prefix, ccnl->km->configid, suite); DBL_LINKED_LIST_ADD(ccnl->km->configuration_list, (*config)); restart = 0; --ccnl->km->configid; } DEBUGMSG(INFO, "Prog: %s\n", (*config)->prog); while ((*config)->prog && !halt) { char *oldprog = (*config)->prog; steps++; DEBUGMSG(DEBUG, "Step %d (%d/%d): %s\n", steps, stack_len((*config)->argument_stack), stack_len((*config)->result_stack), (*config)->prog); (*config)->prog = ZAM_term(ccnl, *config, &halt, dummybuf, &restart); ccnl_free(oldprog); } ccnl_free(dummybuf); if (halt < 0) { //HALT < 0 means pause computation DEBUGMSG(INFO,"Pause computation: %d\n", -(*config)->configid); return NULL; } //HALT > 0 means computation finished DEBUGMSG(INFO, "end-of-computation (%d/%d)\n", stack_len((*config)->argument_stack), stack_len((*config)->result_stack)); /* print_argument_stack((*config)->argument_stack); print_result_stack((*config)->result_stack); */ return Krivine_exportResultStack(ccnl, *config); }
void ccnl_content_learn_name_route(struct ccnl_relay_s *ccnl, struct ccnl_prefix_s *p, struct ccnl_face_s *f, int threshold_prefix, int flags) { /* * we want to insert a new dynamic route in the fib, let's try to aggregate! * for aggregation we ask the fib for a prefix match */ int match_len; struct ccnl_forward_s *fwd = ccn_forward_find_common_prefix_to_aggregate(ccnl, p, &match_len); if (!fwd) { /* there was no prefix match with the user defined creteria. */ /* create a new fib entry */ fwd = ccnl_forward_new(p, f, threshold_prefix, flags); DBL_LINKED_LIST_ADD(ccnl->fib, fwd); DEBUGMSG(999, "ccnl_content_learn_name_route: new route '%s' on face %d learned\n", ccnl_prefix_to_path(fwd->prefix), f->faceid); } else { /* there was a prefix match with the user defined creteria. */ /* if the new entry has shorter prefix */ if (p->compcnt < fwd->prefix->compcnt) { /* we need to aggregate! */ DBL_LINKED_LIST_REMOVE(ccnl->fib, fwd); /* create a new fib entry */ fwd = ccnl_forward_new(p, f, (p->compcnt - match_len), flags); DBL_LINKED_LIST_ADD(ccnl->fib, fwd); DEBUGMSG(999, "ccnl_content_learn_name_route: route '%s' on face %d replaced\n", ccnl_prefix_to_path(fwd->prefix), f->faceid); } else { /* we don't need to do an update, because we know a shorter prefix already */ } } /* refresh fwd entry */ DEBUGMSG(999, "ccnl_content_learn_name_route refresh route '%s' on face %d\n", ccnl_prefix_to_path(fwd->prefix), f->faceid); ccnl_get_timeval(&fwd->last_used); }
struct ccnl_interest_s* ccnl_interest_new(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from, struct ccnl_pkt_s **pkt) { struct ccnl_interest_s *i = (struct ccnl_interest_s *) ccnl_calloc(1, sizeof(struct ccnl_interest_s)); DEBUGMSG_CORE(TRACE, "ccnl_new_interest(prefix=%s, suite=%s)\n", ccnl_prefix_to_path((*pkt)->pfx), ccnl_suite2str((*pkt)->pfx->suite)); if (!i) return NULL; i->pkt = *pkt; *pkt = NULL; i->flags |= CCNL_PIT_COREPROPAGATES; i->from = from; i->last_used = CCNL_NOW(); DBL_LINKED_LIST_ADD(ccnl->pit, i); return i; }
struct ccnl_content_s * ccnl_content_add2cache(struct ccnl_relay_s *ccnl, struct ccnl_content_s *c) { DEBUGMSG(99, "ccnl_content_add2cache (%d/%d)\n", ccnl->contentcnt, ccnl->max_cache_entries); if (ccnl->max_cache_entries <= 0) { DEBUGMSG(1, " content store disabled...\n"); return NULL; } while (ccnl->max_cache_entries <= ccnl->contentcnt) { DEBUGMSG(1, " remove Least Recently Used content...\n"); struct ccnl_content_s *c2, *lru = NULL; for (c2 = ccnl->contents; c2; c2 = c2->next) { DEBUGMSG(1, " '%s' -> %ld:%ld\n", ccnl_prefix_to_path(c2->name), c2->last_used.tv_sec, c2->last_used.tv_usec); if (!(c2->flags & CCNL_CONTENT_FLAGS_STATIC) && ((!lru) || timevaldelta(&c2->last_used, &lru->last_used) < 0)) { lru = c2; } } if (lru) { DEBUGMSG(1, " replaced: '%s'\n", ccnl_prefix_to_path(lru->name)); ccnl_content_remove(ccnl, lru); } else { DEBUGMSG(1, " no dynamic content to remove...\n"); break; } } DEBUGMSG(1, " add new content to store: '%s'\n", ccnl_prefix_to_path(c->name)); DBL_LINKED_LIST_ADD(ccnl->contents, c); ccnl->contentcnt++; return c; }
struct ccnl_interest_s* ccnl_interest_new(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from, struct ccnl_pkt_s **pkt) { struct ccnl_interest_s *i = (struct ccnl_interest_s *) ccnl_calloc(1, sizeof(struct ccnl_interest_s)); DEBUGMSG_CORE(TRACE, "ccnl_new_interest\n"); // ccnl_prefix_to_path((*pkt)->pfx), // ccnl_suite2str((*pkt)->pfx->suite)); if (!i) return NULL; i->pkt = *pkt; *pkt = NULL; i->flags |= CCNL_PIT_COREPROPAGATES; i->from = from; i->last_used = CCNL_NOW(); DBL_LINKED_LIST_ADD(ccnl->pit, i); //akhila 16-10-2015 ccnl->pitcnt++; DEBUGMSG_CORE(TRACE, ": pit_entry_added:%d\n",ccnl->pitcnt); return i; }
struct ccnl_face_s* ccnl_get_face_or_create(struct ccnl_relay_s *ccnl, int ifndx, struct sockaddr *sa, int addrlen) // sa==NULL means: local(=in memory) client, search for existing ifndx being -1 // sa!=NULL && ifndx==-1: search suitable interface for given sa_family // sa!=NULL && ifndx!=-1: use this (incoming) interface for outgoing { static int seqno; int i; struct ccnl_face_s *f; DEBUGMSG_CORE(TRACE, "ccnl_get_face_or_create src=%s\n", ccnl_addr2ascii((sockunion*)sa)); for (f = ccnl->faces; f; f = f->next) { if (!sa) { if (f->ifndx == -1) return f; continue; } if (ifndx != -1 && !ccnl_addr_cmp(&f->peer, (sockunion*)sa)) { f->last_used = CCNL_NOW(); return f; } } if (sa && ifndx == -1) { for (i = 0; i < ccnl->ifcount; i++) { if (sa->sa_family != ccnl->ifs[i].addr.sa.sa_family) continue; ifndx = i; break; } if (ifndx == -1) // no suitable interface found return NULL; } DEBUGMSG_CORE(VERBOSE, " found suitable interface %d for %s\n", ifndx, ccnl_addr2ascii((sockunion*)sa)); f = (struct ccnl_face_s *) ccnl_calloc(1, sizeof(struct ccnl_face_s)); if (!f) { DEBUGMSG_CORE(VERBOSE, " no memory for face\n"); return NULL; } f->faceid = ++seqno; f->ifndx = ifndx; if (ifndx >= 0) { if (ccnl->defaultFaceScheduler) f->sched = ccnl->defaultFaceScheduler(ccnl, (void(*)(void*,void*))ccnl_face_CTS); if (ccnl->ifs[ifndx].reflect) f->flags |= CCNL_FACE_FLAGS_REFLECT; if (ccnl->ifs[ifndx].fwdalli) f->flags |= CCNL_FACE_FLAGS_FWDALLI; } if (sa) memcpy(&f->peer, sa, addrlen); else // local client f->ifndx = -1; f->last_used = CCNL_NOW(); DBL_LINKED_LIST_ADD(ccnl->faces, f); TRACEOUT(); return f; }
struct ccnl_content_s* ccnl_content_add2cache(struct ccnl_relay_s *ccnl, struct ccnl_content_s *c) { struct ccnl_content_s *cit; for (cit = ccnl->contents; cit; cit = cit->next) { if (c == cit) { DEBUGMSG_CORE(DEBUG, "--- Already in cache ---\n"); return NULL; } } #ifdef USE_NACK if (ccnl_nfnprefix_contentIsNACK(c)) return NULL; #endif if (c->flags & CCNL_CONTENT_FLAGS_STATIC){ // DEBUGMSG_CORE(INFO, " ICNIoT: going to add self published content to cache \n"); DBL_LINKED_LIST_ADD(ccnl->contents, c); DEBUGMSG_CORE(INFO, " ICNIoT: added_content2cache without incrementing count:%d\n",ccnl->contentcnt); return c; } // not self published content if (ccnl->max_cache_entries > 0 && ccnl->contentcnt >= ccnl->max_cache_entries) { //Cache replacement strategy struct ccnl_content_s *c2; struct ccnl_content_s *c3 = NULL; int age = 0; // char* prefixBuf = NULL; #ifdef UPDATE_TIME_SERIES if(IsTimeSeriesContent(c->pkt->pfx)){ DEBUGMSG_CORE(INFO, " ICNIoT: UTS-LRU The new received content is time series content\n"); c3 = findOlderVersion(ccnl, c->pkt->pfx); } #endif #ifdef RECOMMENDED_CACHE_TIME c3 = oldestCacheTimeExpiredContent(ccnl); if(c3) DEBUGMSG_CORE(INFO, " ICNIoT: RCT, Found a content object with expired RCT\n"); #endif if (!c3){//if not time series CO OR if time series CO but older version of stream doesnt //exist in cache. For both cases use LRU DEBUGMSG_CORE(INFO, " ICNIoT: using LRU\n"); for (c2 = ccnl->contents; c2; c2 = c2->next){ if (!(c2->flags & CCNL_CONTENT_FLAGS_STATIC) && ((age == 0) || c2->last_used < age)){ age = c2->last_used; c3 = c2; } } } // prefixBuf = ccnl_prefix_to_path(c3->pkt->pfx); // DEBUGMSG_CORE(INFO, " ICNIoT: yes ! removed content\n"); // free(prefixBuf); ccnl_content_remove(ccnl, c3); } if(ccnl->contentcnt < ccnl->max_cache_entries){ // char* prefixBuf2 = NULL; // prefixBuf2 = ccnl_prefix_to_path(c->pkt->pfx); // DEBUGMSG_CORE(INFO, " ICNIoT: going to add %s content to cache\n",prefixBuf2); // free(prefixBuf2); DBL_LINKED_LIST_ADD(ccnl->contents, c); ccnl->contentcnt++; DEBUGMSG_CORE(INFO, " ICNIoT: added_content2cache count:%d\n",ccnl->contentcnt); } return c; }
struct ccnl_face_s * ccnl_get_face_or_create(struct ccnl_relay_s *ccnl, int ifndx, uint16_t sender_id) { struct ccnl_face_s *f; for (f = ccnl->faces; f; f = f->next) { if (ifndx == f->ifndx && (f->faceid == sender_id)) { DEBUGMSG(1, "face found! ifidx=%d sender_id=%d faceid=%d\n", ifndx, sender_id, f->faceid); ccnl_get_timeval(&f->last_used); return f; } } f = (struct ccnl_face_s *) ccnl_calloc(1, sizeof(struct ccnl_face_s)); if (!f) { return NULL; } f->faceid = sender_id; f->ifndx = ifndx; if (sender_id == RIOT_BROADCAST) { f->flags |= CCNL_FACE_FLAGS_BROADCAST; } if (ifndx >= 0) { if (ccnl->defaultFaceScheduler) f->sched = ccnl->defaultFaceScheduler(ccnl, (void ( *)(void *, void *)) ccnl_face_CTS); if (ccnl->ifs[ifndx].reflect) { f->flags |= CCNL_FACE_FLAGS_REFLECT; } if (ccnl->ifs[ifndx].fwdalli) { f->flags |= CCNL_FACE_FLAGS_FWDALLI; } } f->peer.id = sender_id; #ifdef USE_FRAG if (ifndx == RIOT_TRANS_IDX) { // if newly created face, no fragment policy is defined yet // turning on fragmentation for riot trans dev based faces int flagval = CCNL_FACE_FLAGS_STATIC; f->flags = flagval & (CCNL_FACE_FLAGS_STATIC | CCNL_FACE_FLAGS_REFLECT); if (f->frag) { ccnl_frag_destroy(f->frag); f->frag = NULL; } int mtu = ccnl->ifs[f->ifndx].mtu; f->frag = ccnl_frag_new(CCNL_FRAG_CCNx2013, mtu); //TODO } #endif ccnl_get_timeval(&f->last_used); DBL_LINKED_LIST_ADD(ccnl->faces, f); return f; }
char* ZAM_fox(struct ccnl_relay_s *ccnl, struct configuration_s *config, int *restart, int *halt, char *prog, char *arg, char *contd) { int local_search = 0, i; int parameter_number = 0; struct ccnl_content_s *c = NULL; struct ccnl_prefix_s *pref; struct ccnl_interest_s *interest; DEBUGMSG(DEBUG, "---to do: FOX <%s>\n", arg); ccnl_free(arg); if (*restart) { *restart = 0; local_search = 1; goto recontinue; } { struct stack_s *h; h = pop_or_resolve_from_result_stack(ccnl, config); assert(h); //TODO CHECK IF INT config->fox_state->num_of_params = *(int*)h->content; h->next = NULL; ccnl_nfn_freeStack(h); } DEBUGMSG(DEBUG, "NUM OF PARAMS: %d\n", config->fox_state->num_of_params); config->fox_state->params = ccnl_malloc(sizeof(struct ccnl_stack_s *) * config->fox_state->num_of_params); for (i = 0; i < config->fox_state->num_of_params; ++i) { //pop parameter from stack config->fox_state->params[i] = pop_from_stack(&config->result_stack); switch (config->fox_state->params[i]->type) { case STACK_TYPE_INT: DEBUGMSG(DEBUG, " info: Parameter %d %d\n", i, *(int *)config->fox_state->params[i]->content); break; case STACK_TYPE_PREFIX: DEBUGMSG(DEBUG, " info: Parameter %d %s\n", i, ccnl_prefix_to_path((struct ccnl_prefix_s*) config->fox_state->params[i]->content)); break; default: break; } } //as long as there is a routable parameter: try to find a result config->fox_state->it_routable_param = 0; //check if last result is now available recontinue: //loop by reentering after timeout of the interest... if (local_search) { DEBUGMSG(DEBUG, "Checking if result was received\n"); parameter_number = choose_parameter(config); pref = create_namecomps(ccnl, config, parameter_number, config->fox_state->params[parameter_number]->content); // search for a result c = ccnl_nfn_local_content_search(ccnl, config, pref); set_propagate_of_interests_to_1(ccnl, pref); free_prefix(pref); //TODO Check? //TODO remove interest here? if (c) { DEBUGMSG(DEBUG, "Result was found\n"); DEBUGMSG_CFWD(INFO, "data after result was found %.*s\n", c->pkt->contlen, c->pkt->content); goto handlecontent; } } //result was not delivered --> choose next parameter ++config->fox_state->it_routable_param; parameter_number = choose_parameter(config); if (parameter_number < 0) //no more parameter --> no result found, can try a local computation goto local_compute; // create new prefix with name components!!!! pref = create_namecomps(ccnl, config, parameter_number, config->fox_state->params[parameter_number]->content); c = ccnl_nfn_local_content_search(ccnl, config, pref); if (c) { free_prefix(pref); goto handlecontent; } // Result not in cache, search over the network // pref2 = ccnl_prefix_dup(pref); interest = ccnl_nfn_query2interest(ccnl, &pref, config); if (pref) free_prefix(pref); if (interest) { ccnl_interest_propagate(ccnl, interest); DEBUGMSG(DEBUG, " new interest's face is %d\n", interest->from->faceid); } // wait for content, return current program to continue later *halt = -1; //set halt to -1 for async computations return ccnl_strdup(prog); local_compute: if (config->local_done) return NULL; config->local_done = 1; pref = ccnl_nfnprefix_mkComputePrefix(config, config->suite); DEBUGMSG(DEBUG, "Prefix local computation: %s\n", ccnl_prefix_to_path(pref)); interest = ccnl_nfn_query2interest(ccnl, &pref, config); if (pref) free_prefix(pref); if (interest) ccnl_interest_propagate(ccnl, interest); handlecontent: //if result was found ---> handle it if (c) { #ifdef USE_NACK if (!strncmp((char*)c->pkt->content, ":NACK", 5)) { DEBUGMSG(DEBUG, "NACK RECEIVED, going to next parameter\n"); ++config->fox_state->it_routable_param; return prog ? ccnl_strdup(prog) : NULL; } #endif int isANumber = 1, i = 0; for(i = 0; i < c->pkt->contlen; ++i){ if(!isdigit(c->pkt->content[i])){ isANumber = 0; break; } } if (isANumber){ int *integer = ccnl_malloc(sizeof(int)); *integer = strtol((char*)c->pkt->content, 0, 0); push_to_stack(&config->result_stack, integer, STACK_TYPE_INT); } else { struct prefix_mapping_s *mapping; struct ccnl_prefix_s *name = create_prefix_for_content_on_result_stack(ccnl, config); push_to_stack(&config->result_stack, name, STACK_TYPE_PREFIX); mapping = ccnl_malloc(sizeof(struct prefix_mapping_s)); mapping->key = ccnl_prefix_dup(name); //TODO COPY mapping->value = ccnl_prefix_dup(c->pkt->pfx); DBL_LINKED_LIST_ADD(config->fox_state->prefix_mapping, mapping); DEBUGMSG(DEBUG, "Created a mapping %s - %s\n", ccnl_prefix_to_path(mapping->key), ccnl_prefix_to_path(mapping->value)); } } DEBUGMSG(DEBUG, " FOX continuation: %s\n", contd); return ccnl_strdup(contd); }