void ccnl_nfn_continue_computation(struct ccnl_relay_s *ccnl, int configid, int continue_from_remove){ DEBUGMSG(TRACE, "ccnl_nfn_continue_computation()\n"); struct configuration_s *config = ccnl_nfn_findConfig(ccnl->km->configuration_list, -configid); if(!config){ DEBUGMSG(DEBUG, "nfn_continue_computation: %d not found\n", configid); return; } //update original interest prefix to stay longer...reenable if propagate=0 do not protect interests struct ccnl_interest_s *original_interest; for(original_interest = ccnl->pit; original_interest; original_interest = original_interest->next){ if(!ccnl_prefix_cmp(config->prefix, 0, original_interest->prefix, CMP_EXACT)){ original_interest->last_used = CCNL_NOW(); original_interest->retries = 0; original_interest->from->last_used = CCNL_NOW(); break; } } if(config->thunk && CCNL_NOW() > config->endtime){ DEBUGMSG(INFO, "NFN: Exit computation: timeout when resolving thunk\n"); DBL_LINKED_LIST_REMOVE(ccnl->km->configuration_list, config); //Reply error! //config->thunk = 0; return; } ccnl_nfn(ccnl, NULL, NULL, config, NULL, 0, 0); }
struct ccnl_interest_s* ccnl_interest_remove(struct ccnl_relay_s *ccnl, struct ccnl_interest_s *i) { struct ccnl_interest_s *i2; /* if (!i) return NULL; */ DEBUGMSG_CORE(TRACE, "ccnl_interest_remove %p\n", (void *) i); /* #ifdef USE_NFN if (!(i->flags & CCNL_PIT_COREPROPAGATES)) return i->next; #endif */ while (i->pending) { struct ccnl_pendint_s *tmp = i->pending->next; \ ccnl_free(i->pending); i->pending = tmp; } i2 = i->next; DBL_LINKED_LIST_REMOVE(ccnl->pit, i); free_packet(i->pkt); ccnl_free(i); return i2; }
struct ccnl_content_s * ccnl_content_remove(struct ccnl_relay_s *ccnl, struct ccnl_content_s *c) { struct ccnl_content_s *c2; DEBUGMSG(99, "ccnl_content_remove: %s\n", ccnl_prefix_to_path(c->name)); c2 = c->next; DBL_LINKED_LIST_REMOVE(ccnl->contents, c); free_content(c); ccnl->contentcnt--; return c2; }
struct ccnl_nonce_s *ccnl_nonce_remove(struct ccnl_relay_s *ccnl, struct ccnl_nonce_s *nonce) { DEBUGMSG(99, "ccnl_nonce_remove: %u:%u:%u:%u\n", nonce->buf->data[0], nonce->buf->data[1], nonce->buf->data[2], nonce->buf->data[3]); struct ccnl_nonce_s *next = nonce->next; DBL_LINKED_LIST_REMOVE(ccnl->nonces, nonce); free(nonce->buf); free(nonce); return next; }
struct ccnl_interest_s * ccnl_interest_remove(struct ccnl_relay_s *ccnl, struct ccnl_interest_s *i) { struct ccnl_interest_s *i2; DEBUGMSG(40, "ccnl_interest_remove %p\n", (void *) i); while (i->pending) { struct ccnl_pendint_s *tmp = i->pending->next; ccnl_free(i->pending); i->pending = tmp; } i2 = i->next; DBL_LINKED_LIST_REMOVE(ccnl->pit, i); free_prefix(i->prefix); free_3ptr_list(i->ppkd, i->pkt, i); return i2; }
struct ccnl_forward_s * ccnl_forward_remove(struct ccnl_relay_s *ccnl, struct ccnl_forward_s *fwd) { struct ccnl_forward_s *fwd2; DEBUGMSG(40, "ccnl_forward_remove %p\n", (void *) fwd); fwd2 = fwd->next; DBL_LINKED_LIST_REMOVE(ccnl->fib, fwd); for (struct ccnl_interest_s *p = ccnl->pit; p; p = p->next) { if (p->forwarded_over == fwd) { p->forwarded_over = NULL; } } DEBUGMSG(40, " ccnl_forward_remove next=%p\n", (void *) fwd2); free_forward(fwd); return fwd2; }
struct ccnl_content_s* ccnl_content_remove(struct ccnl_relay_s *ccnl, struct ccnl_content_s *c) { struct ccnl_content_s *c2; c2 = c->next; DBL_LINKED_LIST_REMOVE(ccnl->contents, c); // free_content(c); if (c->pkt) { free_prefix(c->pkt->pfx); ccnl_free(c->pkt->buf); ccnl_free(c->pkt); } // free_prefix(c->name); ccnl_free(c); ccnl->contentcnt--; DEBUGMSG_CORE(INFO, " ICNIoT: remove_contentFromCache:%d\n",ccnl->contentcnt); return c2; }
struct ccnl_content_s* ccnl_content_remove(struct ccnl_relay_s *ccnl, struct ccnl_content_s *c) { struct ccnl_content_s *c2; DEBUGMSG_CORE(TRACE, "ccnl_content_remove\n"); c2 = c->next; DBL_LINKED_LIST_REMOVE(ccnl->contents, c); // free_content(c); if (c->pkt) { free_prefix(c->pkt->pfx); ccnl_free(c->pkt->buf); ccnl_free(c->pkt); } // free_prefix(c->name); ccnl_free(c); ccnl->contentcnt--; return c2; }
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); }
int ccnl_nfn(struct ccnl_relay_s *ccnl, // struct ccnl_buf_s *orig, struct ccnl_prefix_s *prefix, struct ccnl_face_s *from, struct configuration_s *config, struct ccnl_interest_s *interest, int suite, int start_locally) { int num_of_required_thunks = 0; int thunk_request = 0; struct ccnl_buf_s *res = NULL; char str[CCNL_MAX_PACKET_SIZE]; int i, len = 0; DEBUGMSG(TRACE, "ccnl_nfn(%p, %s, %p, config=%p)\n", (void*)ccnl, ccnl_prefix_to_path(prefix), (void*)from, (void*)config); // prefix = ccnl_prefix_dup(prefix); DEBUGMSG(DEBUG, "Namecomps: %s \n", ccnl_prefix_to_path(prefix)); if (config){ suite = config->suite; thunk_request = config->fox_state->thunk_request; goto restart; //do not do parsing thunks again } from->flags = CCNL_FACE_FLAGS_STATIC; if (ccnl_nfn_thunk_already_computing(ccnl, prefix)) { DEBUGMSG(DEBUG, "Computation for this interest is already running\n"); return -1; } if (ccnl_nfnprefix_isTHUNK(prefix)) thunk_request = 1; // Checks first if the interest has a routing hint and then searches for it locally. // If it exisits, the computation is started locally, otherwise it is directly forwarded without entering the AM. // Without this mechanism, there will be situations where several nodes "overtake" a computation // applying the same strategy and, potentially, all executing it locally (after trying all arguments). // TODO: this is not an elegant solution and should be improved on, because the clients cannot send a // computation with a routing hint on which the network applies a strategy if the routable name // does not exist (because each node will just forward it without ever taking it into an abstract machine). // encoding the routing hint more explicitely as well as additonal information (e.g. already tried names) // could solve the problem. More generally speaking, additional state describing the exact situation will be required. if (interest && interest->prefix->compcnt > 1) { // forward interests with outsourced components struct ccnl_prefix_s *copy = ccnl_prefix_dup(prefix); copy->compcnt -= (1 + thunk_request); DEBUGMSG(DEBUG, " checking local available of %s\n", ccnl_prefix_to_path(copy)); ccnl_nfnprefix_clear(copy, CCNL_PREFIX_NFN | CCNL_PREFIX_THUNK); if (!ccnl_nfn_local_content_search(ccnl, NULL, copy)) { free_prefix(copy); ccnl_interest_propagate(ccnl, interest); return 0; } free_prefix(copy); start_locally = 1; } //put packet together #ifdef USE_SUITE_CCNTLV if (prefix->suite == CCNL_SUITE_CCNTLV) { len = prefix->complen[prefix->compcnt-1] - 4; memcpy(str, prefix->comp[prefix->compcnt-1] + 4, len); str[len] = '\0'; } else #endif { len = prefix->complen[prefix->compcnt-1]; memcpy(str, prefix->comp[prefix->compcnt-1], len); str[len] = '\0'; } if (prefix->compcnt > 1) len += sprintf(str + len, " "); for (i = 0; i < prefix->compcnt-1; i++) { #ifdef USE_SUITE_CCNTLV if (prefix->suite == CCNL_SUITE_CCNTLV) len += sprintf(str+len,"/%.*s",prefix->complen[i]-4,prefix->comp[i]+4); else #endif len += sprintf(str+len,"/%.*s",prefix->complen[i],prefix->comp[i]); } DEBUGMSG(DEBUG, "expr is <%s>\n", str); //search for result here... if found return... if (thunk_request) num_of_required_thunks = ccnl_nfn_count_required_thunks(str); ++ccnl->km->numOfRunningComputations; restart: res = Krivine_reduction(ccnl, str, thunk_request, start_locally, num_of_required_thunks, &config, prefix, suite); //stores result if computed if (res) { struct ccnl_prefix_s *copy; struct ccnl_content_s *c; DEBUGMSG(INFO,"Computation finished: res: %.*s size: %d bytes. Running computations: %d\n", res->datalen, res->data, res->datalen, ccnl->km->numOfRunningComputations); if (config && config->fox_state->thunk_request) { // ccnl_nfn_remove_thunk_from_prefix(config->prefix); ccnl_nfnprefix_clear(config->prefix, CCNL_PREFIX_THUNK); } copy = ccnl_prefix_dup(config->prefix); c = ccnl_nfn_result2content(ccnl, ©, res->data, res->datalen); c->flags = CCNL_CONTENT_FLAGS_STATIC; set_propagate_of_interests_to_1(ccnl, c->name); ccnl_content_serve_pending(ccnl,c); ccnl_content_add2cache(ccnl, c); --ccnl->km->numOfRunningComputations; DBL_LINKED_LIST_REMOVE(ccnl->km->configuration_list, config); ccnl_nfn_freeConfiguration(config); ccnl_free(res); } #ifdef USE_NACK else if(config->local_done){ struct ccnl_content_s *nack; nack = ccnl_nfn_result2content(ccnl, &config->prefix, (unsigned char*)":NACK", 5); ccnl_content_serve_pending(ccnl, nack); } #endif return 0; }
struct ccnl_face_s* ccnl_face_remove(struct ccnl_relay_s *ccnl, struct ccnl_face_s *f) { struct ccnl_face_s *f2; struct ccnl_interest_s *pit; struct ccnl_forward_s **ppfwd; DEBUGMSG_CORE(DEBUG, "face_remove relay=%p face=%p\n", (void*)ccnl, (void*)f); ccnl_sched_destroy(f->sched); ccnl_frag_destroy(f->frag); DEBUGMSG_CORE(TRACE, "face_remove: cleaning PIT\n"); for (pit = ccnl->pit; pit; ) { struct ccnl_pendint_s **ppend, *pend; if (pit->from == f) pit->from = NULL; for (ppend = &pit->pending; *ppend;) { if ((*ppend)->face == f) { pend = *ppend; *ppend = pend->next; ccnl_free(pend); } else ppend = &(*ppend)->next; } if (pit->pending) pit = pit->next; else { DEBUGMSG_CORE(TRACE, "before NFN interest_remove 0x%p\n", (void*)pit); pit = ccnl_nfn_interest_remove(ccnl, pit); } } DEBUGMSG_CORE(TRACE, "face_remove: cleaning fwd table\n"); for (ppfwd = &ccnl->fib; *ppfwd;) { if ((*ppfwd)->face == f) { struct ccnl_forward_s *pfwd = *ppfwd; free_prefix(pfwd->prefix); *ppfwd = pfwd->next; ccnl_free(pfwd); } else ppfwd = &(*ppfwd)->next; } DEBUGMSG_CORE(TRACE, "face_remove: cleaning pkt queue\n"); while (f->outq) { struct ccnl_buf_s *tmp = f->outq->next; ccnl_free(f->outq); f->outq = tmp; } DEBUGMSG_CORE(TRACE, "face_remove: unlinking1 %p %p\n", (void*)f->next, (void*)f->prev); f2 = f->next; DEBUGMSG_CORE(TRACE, "face_remove: unlinking2\n"); DBL_LINKED_LIST_REMOVE(ccnl->faces, f); DEBUGMSG_CORE(TRACE, "face_remove: unlinking3\n"); ccnl_free(f); TRACEOUT(); return f2; }
struct ccnl_face_s * ccnl_face_remove(struct ccnl_relay_s *ccnl, struct ccnl_face_s *f) { struct ccnl_face_s *f2; struct ccnl_interest_s *pit; struct ccnl_forward_s **ppfwd; DEBUGMSG(1, "ccnl_face_remove relay=%p face=%p\n", (void *) ccnl, (void *) f); ccnl_sched_destroy(f->sched); ccnl_frag_destroy(f->frag); for (pit = ccnl->pit; pit;) { struct ccnl_pendint_s **ppend, *pend; if (pit->from == f) { pit->from = NULL; } for (ppend = &pit->pending; *ppend;) { if ((*ppend)->face == f) { pend = *ppend; *ppend = pend->next; ccnl_free(pend); } else { ppend = &(*ppend)->next; } } if (pit->pending) { pit = pit->next; } else { pit = ccnl_interest_remove(ccnl, pit); } } for (ppfwd = &ccnl->fib; *ppfwd;) { if ((*ppfwd)->face == f) { struct ccnl_forward_s *pfwd = *ppfwd; *ppfwd = pfwd->next; ccnl_forward_remove(ccnl, pfwd); } else { ppfwd = &(*ppfwd)->next; } } while (f->outq) { struct ccnl_buf_s *tmp = f->outq->next; ccnl_free(f->outq); f->outq = tmp; } #if ENABLE_DEBUG ccnl_face_print_stat(f); #endif f2 = f->next; DBL_LINKED_LIST_REMOVE(ccnl->faces, f); ccnl_free(f); return f2; }