int ccnl_nfn_thunk_already_computing(struct ccnl_relay_s *ccnl, struct ccnl_prefix_s *prefix) { int i = 0; struct ccnl_prefix_s *copy; DEBUGMSG(TRACE, "ccnl_nfn_thunk_already_computing()\n"); copy = ccnl_prefix_dup(prefix); // ccnl_nfn_remove_thunk_from_prefix(copy); ccnl_nfnprefix_set(copy, CCNL_PREFIX_NFN | CCNL_PREFIX_THUNK); for (i = 0; i < -ccnl->km->configid; ++i) { struct configuration_s *config; config = ccnl_nfn_findConfig(ccnl->km->configuration_list, -i); if (!config) continue; if (!ccnl_prefix_cmp(config->prefix, NULL, copy, CMP_EXACT)) { free_prefix(copy); return 1; } } free_prefix(copy); return 0; }
void ccnl_client_TX(char node, char *name, int seqn, int nonce) { char tmp[512]; struct ccnl_prefix_s *p; struct ccnl_buf_s *buf; struct ccnl_relay_s *relay = char2relay(node); DEBUGMSG(TRACE, "ccnl_client_tx node=%c: request %s #%d\n", node, name, seqn); if (!relay) return; sprintf(tmp, "%s/.%d", name, seqn); // p = ccnl_path_to_prefix(tmp); // p->suite = suite; p = ccnl_URItoPrefix(tmp, theSuite, NULL, NULL); DEBUGMSG(TRACE, " create interest for %s\n", ccnl_prefix_to_path(p)); buf = ccnl_mkSimpleInterest(p, &nonce); free_prefix(p); // inject it into the relay: if (buf) { ccnl_core_RX(relay, -1, buf->data, buf->datalen, 0, 0); ccnl_free(buf); } }
struct ccnl_prefix_s * ccnl_iottlv_parseHierarchicalName(unsigned char *data, int datalen) { int len = datalen; unsigned int typ, len2; struct ccnl_prefix_s *p; p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s)); if (!p) return NULL; p->suite = CCNL_SUITE_IOTTLV; p->comp = (unsigned char**) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(unsigned char**)); p->complen = (int*) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(int)); if (!p->comp || !p->complen) return NULL; p->nameptr = data; p->namelen = len; while (len > 0) { if (ccnl_iottlv_dehead(&data, &len, &typ, &len2)) goto Bail; if (typ == IOT_TLV_PN_Component && p->compcnt < CCNL_MAX_NAME_COMP) { p->comp[p->compcnt] = data; p->complen[p->compcnt] = len2; p->compcnt++; } data += len2; len -= len2; } datalen -= p->namelen; #ifdef USE_NFN if (p->compcnt > 0 && p->complen[p->compcnt-1] == 3 && !memcmp(p->comp[p->compcnt-1], "NFN", 3)) { p->nfnflags |= CCNL_PREFIX_NFN; p->compcnt--; if (p->compcnt > 0 && p->complen[p->compcnt-1] == 5 && !memcmp(p->comp[p->compcnt-1], "THUNK", 5)) { p->nfnflags |= CCNL_PREFIX_THUNK; p->compcnt--; } } #endif return p; Bail: free_prefix(p); return NULL; }
void ccnl_populate_cache(struct ccnl_relay_s *ccnl, unsigned char *buf, int datalen) { if (buf[0] == 0x04 && buf[1] == 0x82) { struct ccnl_prefix_s *prefix = 0; struct ccnl_content_s *c = 0; struct ccnl_buf_s *nonce = 0, *ppkd = 0, *pkt = 0; unsigned char *content, *data = buf + 2; int contlen; datalen -= 2; pkt = ccnl_extract_prefix_nonce_ppkd(&data, &datalen, 0, 0, 0, 0, &prefix, &nonce, &ppkd, &content, &contlen); if (!pkt) { DEBUGMSG(6, " parsing error\n"); goto Done; } if (!prefix) { DEBUGMSG(6, " no prefix error\n"); goto Done; } printf("populating: %s\n", ccnl_prefix_to_path(prefix)); c = ccnl_content_new(ccnl, &pkt, &prefix, &ppkd, content, contlen); if (!c) { goto Done; } c->flags |= CCNL_CONTENT_FLAGS_STATIC; if (!ccnl_content_add2cache(ccnl, c)) { // content store error free_content(c); } Done: free_prefix(prefix); ccnl_free(pkt); ccnl_free(nonce); ccnl_free(ppkd); } else { DEBUGMSG(6, " not a content object\n"); } }
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_prefix_s* ccnl_prefix_new(int suite, int cnt) { struct ccnl_prefix_s *p; p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s)); if (!p) return NULL; p->comp = (unsigned char**) ccnl_malloc(cnt * sizeof(unsigned char*)); p->complen = (int*) ccnl_malloc(cnt * sizeof(int)); if (!p->comp || !p->complen) { free_prefix(p); return NULL; } p->compcnt = cnt; p->suite = suite; p->chunknum = NULL; return p; }
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; }
struct ccnl_prefix_s* ccnl_prefix_dup(struct ccnl_prefix_s *prefix) { int i = 0, len; struct ccnl_prefix_s *p; if (!prefix) return NULL; p = ccnl_prefix_new(prefix->suite, prefix->compcnt); if (!p) return p; p->compcnt = prefix->compcnt; p->chunknum = prefix->chunknum; #ifdef USE_NFN p->nfnflags = prefix->nfnflags; #endif for (i = 0, len = 0; i < prefix->compcnt; i++) len += prefix->complen[i]; p->bytes = (unsigned char*) ccnl_malloc(len); if (!p->bytes) { free_prefix(p); return NULL; } for (i = 0, len = 0; i < prefix->compcnt; i++) { p->complen[i] = prefix->complen[i]; p->comp[i] = p->bytes + len; memcpy(p->bytes + len, prefix->comp[i], p->complen[i]); len += p->complen[i]; } if (prefix->chunknum) { p->chunknum = ccnl_malloc(sizeof(int)); *p->chunknum = *prefix->chunknum; } return p; }
int _ccnl_fib(int argc, char **argv) { if (argc < 2) { ccnl_fib_show(&ccnl_relay); } else if ((argc == 3) && (strncmp(argv[1], "del", 3) == 0)) { int suite = CCNL_SUITE_NDNTLV; if (strchr(argv[2], '/')) { struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(argv[2], suite, NULL, 0); if (!prefix) { puts("Error: prefix could not be created!"); return -1; } int res = ccnl_fib_rem_entry(&ccnl_relay, prefix, NULL); free_prefix(prefix); return res; } else { struct ccnl_face_s *face = _intern_face_get(argv[2]); if (face == NULL) { printf("There is no face for address %s\n", argv[1]); return -1; } int res = ccnl_fib_rem_entry(&ccnl_relay, NULL, face); return res; } } else if ((argc == 4) && (strncmp(argv[1], "add", 3) == 0)) { if (_intern_fib_add(argv[2], argv[3]) < 0) { _ccnl_fib_usage(argv[0]); return -1; } } else { _ccnl_fib_usage(argv[0]); return -1; } return 0; }
struct ccnl_interest_s* ccnl_nfn_RX_request(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from, int suite, struct ccnl_buf_s **buf, struct ccnl_prefix_s **p, int minsfx, int maxsfx) { struct ccnl_interest_s *i; struct ccnl_prefix_s *p2; if (ccnl->km->numOfRunningComputations >= NFN_MAX_RUNNING_COMPUTATIONS) return 0; p2 = ccnl_prefix_dup(*p); i = ccnl_interest_new(ccnl, from, (*p)->suite, buf, p, minsfx, maxsfx); i->flags &= ~CCNL_PIT_COREPROPAGATES; // do not forward interests for running computations ccnl_interest_append_pending(i, from); if (!(i->flags & CCNL_PIT_COREPROPAGATES)) ccnl_nfn(ccnl, p2, from, NULL, i, suite, 0); else { free_prefix(p2); } return i; }
static int _debug_cache_date(int argc, char **argv) { if ((argc < 3) || (strlen(argv[1]) > 8) || (strlen(argv[2]) > 8)) { puts("Usage: dc <ID> <timestamp>"); return 1; } /* get data into cache by sending to loopback */ LOG_DEBUG("main: put data into cache via loopback\n"); size_t prefix_len = sizeof(CCNLRIOT_SITE_PREFIX) + sizeof(CCNLRIOT_TYPE_PREFIX) + 9 + 9; char pfx[prefix_len]; snprintf(pfx, prefix_len, "%s%s/%s/%s", CCNLRIOT_SITE_PREFIX, CCNLRIOT_TYPE_PREFIX, argv[1], argv[2]); LOG_INFO("main: DEBUG DATA: %s\n", pfx); struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(pfx, CCNL_SUITE_NDNTLV, NULL, 0); if (prefix == NULL) { LOG_ERROR("caching: We're doomed, WE ARE ALL DOOMED!\n"); } else { ccnl_helper_create_cont(prefix, (unsigned char*) argv[2], strlen(argv[2]) + 1, true, false); free_prefix(prefix); } return 0; }
void ccnl_core_cleanup(struct ccnl_relay_s *ccnl) { int k; DEBUGMSG_CORE(TRACE, "ccnl_core_cleanup %p\n", (void *) ccnl); while (ccnl->pit) ccnl_interest_remove(ccnl, ccnl->pit); while (ccnl->faces) ccnl_face_remove(ccnl, ccnl->faces); // removes allmost all FWD entries while (ccnl->fib) { struct ccnl_forward_s *fwd = ccnl->fib->next; free_prefix(ccnl->fib->prefix); ccnl_free(ccnl->fib); ccnl->fib = fwd; } while (ccnl->contents) ccnl_content_remove(ccnl, ccnl->contents); while (ccnl->nonces) { struct ccnl_buf_s *tmp = ccnl->nonces->next; ccnl_free(ccnl->nonces); ccnl->nonces = tmp; } for (k = 0; k < ccnl->ifcount; k++) ccnl_interface_cleanup(ccnl->ifs + k); while (bufCleanUpList) { struct ccnl_buf_s *tmp = bufCleanUpList->next; ccnl_free(bufCleanUpList); bufCleanUpList = tmp; } #ifdef USE_NFN ccnl_nfn_freeKrivine(ccnl); #endif }
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; }
void ccnl_populate_cache(struct ccnl_relay_s *ccnl, char *path, int suite) { DIR *dir; struct dirent *de; int datalen; char *suffix; DEBUGMSG(99, "ccnl_populate_cache %s\n", path); switch (suite) { #ifdef USE_SUITE_CCNB case CCNL_SUITE_CCNB: suffix = "*.ccnb"; break; #endif #ifdef USE_SUITE_NDNTLV case CCNL_SUITE_NDNTLV: suffix = "*.ndntlv"; break; #endif default: fprintf(stderr, "unknown suite and encoding, cannot populate cache.\n"); return; } dir = opendir(path); if (!dir) return; while ((de = readdir(dir))) { if (!fnmatch(suffix, de->d_name, FNM_NOESCAPE)) { char fname[1000]; struct stat s; strcpy(fname, path); strcat(fname, "/"); strcat(fname, de->d_name); if (stat(fname, &s)) { perror("stat"); } else { struct ccnl_buf_s *buf = 0; int fd; DEBUGMSG(6, "loading file %s, %d bytes\n", de->d_name, (int) s.st_size); fd = open(fname, O_RDONLY); if (!fd) { perror("open"); continue; } buf = (struct ccnl_buf_s *) ccnl_malloc(sizeof(*buf) + s.st_size); datalen = read(fd, buf->data, s.st_size); close(fd); if (datalen == s.st_size && datalen >= 2) { struct ccnl_prefix_s *prefix = 0; struct ccnl_content_s *c = 0; struct ccnl_buf_s *nonce=0, *ppkd=0, *pkt = 0; unsigned char *content, *data; int contlen, typ, len; buf->datalen = datalen; switch (suite) { #ifdef USE_SUITE_CCNB case CCNL_SUITE_CCNB: if (buf->data[0] != 0x04 || buf->data[1] != 0x82) goto notacontent; data = buf->data + 2; datalen -= 2; pkt = ccnl_ccnb_extract(&data, &datalen, 0, 0, 0, 0, &prefix, &nonce, &ppkd, &content, &contlen); break; #endif #ifdef USE_SUITE_NDNTLV case CCNL_SUITE_NDNTLV: data = buf->data; if (ccnl_ndntlv_dehead(&data, &datalen, &typ, &len) || typ != NDN_TLV_Data) goto notacontent; pkt = ccnl_ndntlv_extract(data - buf->data, &data, &datalen, 0, 0, 0, 0, &prefix, &nonce, &ppkd, &content, &contlen); break; #endif default: goto Done; } if (!pkt) { DEBUGMSG(6, " parsing error\n"); goto Done; } if (!prefix) { DEBUGMSG(6, " no prefix error\n"); goto Done; } c = ccnl_content_new(ccnl, suite, &pkt, &prefix, &ppkd, content, contlen); if (!c) goto Done; ccnl_content_add2cache(ccnl, c); c->flags |= CCNL_CONTENT_FLAGS_STATIC; Done: free_prefix(prefix); ccnl_free(buf); ccnl_free(pkt); ccnl_free(nonce); ccnl_free(ppkd); } else { notacontent: DEBUGMSG(6, " not a content object\n"); ccnl_free(buf); } } } } }
int ccnl_core_RX_i_or_c(struct ccnl_relay_s *relay, struct ccnl_face_s *from, unsigned char **data, int *datalen) { int rc = -1, scope = 3, aok = 3, minsfx = 0, maxsfx = CCNL_MAX_NAME_COMP, contlen; struct ccnl_buf_s *buf = 0, *nonce = 0, *ppkd = 0; struct ccnl_interest_s *i = 0; struct ccnl_content_s *c = 0; struct ccnl_prefix_s *p = 0; unsigned char *content = 0; DEBUGMSG(1, "ccnl_core_RX_i_or_c: (%d bytes left)\n", *datalen); buf = ccnl_extract_prefix_nonce_ppkd(data, datalen, &scope, &aok, &minsfx, &maxsfx, &p, &nonce, &ppkd, &content, &contlen); if (!buf) { DEBUGMSG(6, " parsing error or no prefix\n"); goto Done; } if (nonce && ccnl_nonce_find_or_append(relay, nonce)) { DEBUGMSG(6, " dropped because of duplicate nonce\n"); goto Skip; } if (buf->data[0] == 0x01 && buf->data[1] == 0xd2) { // interest DEBUGMSG(1, "ccnl_core_RX_i_or_c: interest=<%s>\n", ccnl_prefix_to_path(p)); from->stat.received_interest++; if (p->compcnt > 0 && p->comp[0][0] == (unsigned char) 0xc1) { goto Skip; } if (p->compcnt == 4 && !memcmp(p->comp[0], "ccnx", 4)) { DEBUGMSG(1, "it's a mgnt msg!\n"); rc = ccnl_mgmt(relay, buf, p, from); DEBUGMSG(1, "mgnt processing done!\n"); goto Done; } // CONFORM: Step 1: if (aok & 0x01) { // honor "answer-from-existing-content-store" flag for (c = relay->contents; c; c = c->next) { if (!ccnl_i_prefixof_c(p, ppkd, minsfx, maxsfx, c)) { continue; } // FIXME: should check stale bit in aok here DEBUGMSG(7, " matching content for interest, content %p\n", (void *) c); from->stat.send_content[c->served_cnt % CCNL_MAX_CONTENT_SERVED_STAT]++; c->served_cnt++; if (from->ifndx >= 0) { ccnl_face_enqueue(relay, from, buf_dup(c->pkt)); } goto Skip; } } // CONFORM: Step 2: check whether interest is already known for (i = relay->pit; i; i = i->next) { if (!ccnl_prefix_cmp(i->prefix, NULL, p, CMP_EXACT) && i->minsuffix == minsfx && i->maxsuffix == maxsfx && ((!ppkd && !i->ppkd) || buf_equal(ppkd, i->ppkd))) { break; } } if (!i) { // this is a new/unknown I request: create and propagate i = ccnl_interest_new(relay, from, &buf, &p, minsfx, maxsfx, &ppkd); if (i) { // CONFORM: Step 3 (and 4) DEBUGMSG(7, " created new interest entry %p\n", (void *) i); if (scope > 2) { ccnl_interest_propagate(relay, i); } } } else if (scope > 2 && (from->flags & CCNL_FACE_FLAGS_FWDALLI)) { DEBUGMSG(7, " old interest, nevertheless propagated %p\n", (void *) i); ccnl_interest_propagate(relay, i); } if (i) { // store the I request, for the incoming face (Step 3) DEBUGMSG(7, " appending interest entry %p\n", (void *) i); ccnl_interest_append_pending(i, from); } } else { // content DEBUGMSG(6, " content=<%s>\n", ccnl_prefix_to_path(p)); from->stat.received_content++; // CONFORM: Step 1: for (c = relay->contents; c; c = c->next) { if (buf_equal(c->pkt, buf)) { DEBUGMSG(1, "content is dup: skip\n"); goto Skip; } } c = ccnl_content_new(relay, &buf, &p, &ppkd, content, contlen); if (c) { // CONFORM: Step 2 (and 3) if (!ccnl_content_serve_pending(relay, c, from)) { // unsolicited content // CONFORM: "A node MUST NOT forward unsolicited data [...]" DEBUGMSG(7, " removed because no matching interest\n"); free_content(c); goto Skip; } #if CCNL_DYNAMIC_FIB else { /* content has matched an interest, we consider this name as available on this face */ ccnl_content_learn_name_route(relay, c->name, from, relay->fib_threshold_prefix, 0); } #endif if (relay->max_cache_entries != 0) { // it's set to -1 or a limit DEBUGMSG(7, " adding content to cache\n"); ccnl_content_add2cache(relay, c); } else { DEBUGMSG(7, " content not added to cache\n"); free_content(c); } } } Skip: rc = 0; Done: free_prefix(p); free_3ptr_list(buf, nonce, ppkd); DEBUGMSG(1, "leaving\n"); return rc; }
struct ccnl_buf_s * ccnl_extract_prefix_nonce_ppkd(unsigned char **data, int *datalen, int *scope, int *aok, int *min, int *max, struct ccnl_prefix_s **prefix, struct ccnl_buf_s **nonce, struct ccnl_buf_s **ppkd, unsigned char **content, int *contlen) { unsigned char *start = *data - 2, *cp; int num, typ, len; struct ccnl_prefix_s *p; struct ccnl_buf_s *buf, *n = 0, *pub = 0; DEBUGMSG(99, "ccnl_extract_prefix\n"); p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s)); if (!p) { puts("can't get more memory from malloc, dropping ccn msg..."); return NULL; } p->comp = (unsigned char **) ccnl_malloc( CCNL_MAX_NAME_COMP * sizeof(unsigned char **)); p->complen = (int *) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(int)); if (!p->comp || !p->complen) { puts("can't get more memory from malloc, dropping ccn msg..."); goto Bail; } while (dehead(data, datalen, &num, &typ) == 0) { if (num == 0 && typ == 0) { break; // end } if (typ == CCN_TT_DTAG) { if (num == CCN_DTAG_NAME) { while (1) { if (dehead(data, datalen, &num, &typ) != 0) { goto Bail; } if (num == 0 && typ == 0) { break; } if (typ == CCN_TT_DTAG && num == CCN_DTAG_COMPONENT && p->compcnt < CCNL_MAX_NAME_COMP) { if (hunt_for_end(data, datalen, p->comp + p->compcnt, p->complen + p->compcnt) < 0) { goto Bail; } p->compcnt++; } else { if (consume(typ, num, data, datalen, 0, 0) < 0) { goto Bail; } } } continue; } if (num == CCN_DTAG_SCOPE || num == CCN_DTAG_NONCE || num == CCN_DTAG_MINSUFFCOMP || num == CCN_DTAG_MAXSUFFCOMP || num == CCN_DTAG_PUBPUBKDIGEST) { if (hunt_for_end(data, datalen, &cp, &len) < 0) { goto Bail; } if (num == CCN_DTAG_SCOPE && len == 1 && scope) { *scope = isdigit(*cp) && (*cp < '3') ? *cp - '0' : -1; } if (num == CCN_DTAG_ANSWERORIGKIND && aok) { *aok = data2uint(cp, len); } if (num == CCN_DTAG_MINSUFFCOMP && min) { *min = data2uint(cp, len); } if (num == CCN_DTAG_MAXSUFFCOMP && max) { *max = data2uint(cp, len); } if (num == CCN_DTAG_NONCE && !n) { n = ccnl_buf_new(cp, len); } if (num == CCN_DTAG_PUBPUBKDIGEST && !pub) { pub = ccnl_buf_new(cp, len); } if (num == CCN_DTAG_EXCLUDE) { DEBUGMSG(49, "warning: 'exclude' field ignored\n"); } else { continue; } } if (num == CCN_DTAG_CONTENT || num == CCN_DTAG_CONTENTOBJ) { if (consume(typ, num, data, datalen, content, contlen) < 0) { goto Bail; } continue; } } if (consume(typ, num, data, datalen, 0, 0) < 0) { goto Bail; } } if (prefix) { p->comp[p->compcnt] = NULL; *prefix = p; } else { free_prefix(p); } if (nonce) { *nonce = n; } else { ccnl_free(n); } if (ppkd) { *ppkd = pub; } else { ccnl_free(pub); } buf = ccnl_buf_new(start, *data - start); if (!buf) { puts("can't get more memory from malloc, dropping ccn msg..."); goto Bail; } // carefully rebase ptrs to new buf because of 64bit pointers: if (content) { *content = buf->data + (*content - start); } for (num = 0; num < p->compcnt; num++) { p->comp[num] = buf->data + (p->comp[num] - start); } return buf; Bail: free_prefix(p); free_2ptr_list(n, pub); return NULL; }
// turn an URI into an internal prefix (watch out: this modifies the uri string) struct ccnl_prefix_s * ccnl_URItoPrefix(char* uri, int suite, char *nfnexpr, unsigned int *chunknum) { struct ccnl_prefix_s *p; char *compvect[CCNL_MAX_NAME_COMP]; unsigned int complens[CCNL_MAX_NAME_COMP]; int cnt, i, len, tlen; DEBUGMSG_CPFX(TRACE, "ccnl_URItoPrefix(suite=%s, uri=%s, nfn=%s)\n", ccnl_suite2str(suite), uri, nfnexpr); if (strlen(uri)) cnt = ccnl_URItoComponents(compvect, complens, uri); else cnt = 0; if (nfnexpr && *nfnexpr) cnt += 1; p = ccnl_prefix_new(suite, cnt); if (!p) return NULL; for (i = 0, len = 0; i < cnt; i++) { if (i == (cnt-1) && nfnexpr && *nfnexpr) len += strlen(nfnexpr); else len += complens[i];//strlen(compvect[i]); } #ifdef USE_SUITE_CCNTLV if (suite == CCNL_SUITE_CCNTLV) len += cnt * 4; // add TL size #endif #ifdef USE_SUITE_CISTLV if (suite == CCNL_SUITE_CISTLV) len += cnt * 4; // add TL size #endif p->bytes = (unsigned char*) ccnl_malloc(len); if (!p->bytes) { free_prefix(p); return NULL; } for (i = 0, len = 0, tlen = 0; i < cnt; i++) { int isnfnfcomp = i == (cnt-1) && nfnexpr && *nfnexpr; char *cp = isnfnfcomp ? nfnexpr : (char*) compvect[i]; if (isnfnfcomp) tlen = strlen(nfnexpr); else tlen = complens[i]; p->comp[i] = p->bytes + len; tlen = ccnl_pkt_mkComponent(suite, p->comp[i], cp, tlen); p->complen[i] = tlen; len += tlen; } p->compcnt = cnt; #ifdef USE_NFN if (nfnexpr && *nfnexpr) p->nfnflags |= CCNL_PREFIX_NFN; #endif if(chunknum) { p->chunknum = ccnl_malloc(sizeof(int)); *p->chunknum = *chunknum; } return p; }
void free_content(struct ccnl_content_s *c) { free_prefix(c->name); free_2ptr_list(c->pkt, c); }
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_buf_s* ccnl_ccnb_extract(unsigned char **data, int *datalen, int *scope, int *aok, int *min, int *max, struct ccnl_prefix_s **prefix, struct ccnl_buf_s **nonce, struct ccnl_buf_s **ppkd, unsigned char **content, int *contlen) { unsigned char *start = *data - 2 /* account for outer TAG hdr */, *cp; int num, typ, len; struct ccnl_prefix_s *p; struct ccnl_buf_s *buf, *n = 0, *pub = 0; DEBUGMSG(99, "ccnl_ccnb_extract\n"); p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s)); if (!p) return NULL; p->comp = (unsigned char**) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(unsigned char**)); p->complen = (int*) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(int)); if (!p->comp || !p->complen) goto Bail; while (ccnl_ccnb_dehead(data, datalen, &num, &typ) == 0) { if (num==0 && typ==0) break; // end if (typ == CCN_TT_DTAG) { if (num == CCN_DTAG_NAME) { for (;;) { if (ccnl_ccnb_dehead(data, datalen, &num, &typ) != 0) goto Bail; if (num==0 && typ==0) break; if (typ == CCN_TT_DTAG && num == CCN_DTAG_COMPONENT && p->compcnt < CCNL_MAX_NAME_COMP) { if (ccnl_ccnb_hunt_for_end(data, datalen, p->comp + p->compcnt, p->complen + p->compcnt) < 0) goto Bail; p->compcnt++; } else { if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0) goto Bail; } } continue; } if (num == CCN_DTAG_SCOPE || num == CCN_DTAG_NONCE || num == CCN_DTAG_MINSUFFCOMP || num == CCN_DTAG_MAXSUFFCOMP || num == CCN_DTAG_PUBPUBKDIGEST) { if (ccnl_ccnb_hunt_for_end(data, datalen, &cp, &len) < 0) goto Bail; if (num == CCN_DTAG_SCOPE && len == 1 && scope) *scope = isdigit(*cp) && (*cp < '3') ? *cp - '0' : -1; if (num == CCN_DTAG_ANSWERORIGKIND && aok) *aok = ccnl_ccnb_data2uint(cp, len); if (num == CCN_DTAG_MINSUFFCOMP && min) *min = ccnl_ccnb_data2uint(cp, len); if (num == CCN_DTAG_MAXSUFFCOMP && max) *max = ccnl_ccnb_data2uint(cp, len); if (num == CCN_DTAG_NONCE && !n) n = ccnl_buf_new(cp, len); if (num == CCN_DTAG_PUBPUBKDIGEST && !pub) pub = ccnl_buf_new(cp, len); if (num == CCN_DTAG_EXCLUDE) { DEBUGMSG(49, "warning: 'exclude' field ignored\n"); } else continue; } if (num == CCN_DTAG_CONTENT) { if (ccnl_ccnb_consume(typ, num, data, datalen, content, contlen) < 0) goto Bail; continue; } } if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0) goto Bail; } if (prefix) *prefix = p; else free_prefix(p); if (nonce) *nonce = n; else ccnl_free(n); if (ppkd) *ppkd = pub; else ccnl_free(pub); buf = ccnl_buf_new(start, *data - start); // carefully rebase ptrs to new buf because of 64bit pointers: if (content) *content = buf->data + (*content - start); for (num = 0; num < p->compcnt; num++) p->comp[num] = buf->data + (p->comp[num] - start); return buf; Bail: free_prefix(p); free_2ptr_list(n, pub); return NULL; }
int ccnl_riot_client_get(kernel_pid_t relay_pid, char *name, char *reply_buf) { char *prefix[CCNL_MAX_NAME_COMP]; char *cp = strtok(name, "/"); int i = 0; while (i < (CCNL_MAX_NAME_COMP - 1) && cp) { prefix[i++] = cp; cp = strtok(NULL, "/"); } //prefix[i] = 0; //segment to request prefix[i + 1] = 0; int content_len = 0; for (int segment = 0; ; segment++) { char segment_string[16]; //max=999\0 memset(segment_string, 0, 16); snprintf(segment_string, 16, "%d", segment); prefix[i] = segment_string; unsigned char *interest_pkg = malloc(PAYLOAD_SIZE); if (!interest_pkg) { puts("ccnl_riot_client_get: malloc failed"); return 0; } unsigned int interest_nonce = genrand_uint32(); int interest_len = mkInterest(prefix, &interest_nonce, interest_pkg); DEBUGMSG(1, "relay_pid=%" PRIkernel_pid " interest_len=%d\n", relay_pid, interest_len); riot_ccnl_msg_t rmsg; rmsg.payload = interest_pkg; rmsg.size = interest_len; msg_t m, rep; m.content.ptr = (char *) &rmsg; m.type = CCNL_RIOT_MSG; msg_send(&m, relay_pid, 1); /* ######################################################################### */ msg_receive(&rep); free(interest_pkg); if (rep.type == CCNL_RIOT_NACK) { /* network stack was not able to fetch this chunk */ return 0; } /* we got a chunk of data from the network stack */ riot_ccnl_msg_t *rmsg_reply = (riot_ccnl_msg_t *) rep.content.ptr; unsigned char *data = rmsg_reply->payload; int datalen = (int) rmsg_reply->size; DEBUGMSG(1, "%d bytes left; msg from=%" PRIkernel_pid "\n", datalen, rep.sender_pid); int scope = 3, aok = 3, minsfx = 0, maxsfx = CCNL_MAX_NAME_COMP, contlen = 0; struct ccnl_buf_s *buf = 0, *nonce = 0, *ppkd = 0; struct ccnl_prefix_s *p = 0; unsigned char *content = 0; buf = ccnl_extract_prefix_nonce_ppkd(&data, &datalen, &scope, &aok, &minsfx, &maxsfx, &p, &nonce, &ppkd, &content, &contlen); if (!buf) { DEBUGMSG(6, " parsing error or no prefix\n"); return 0; } DEBUGMSG(1, "content_len=%d contlen=%d\n", content_len, contlen); memcpy(reply_buf + content_len, content, contlen); content_len += contlen; free_prefix(p); free_3ptr_list(buf, nonce, ppkd); ccnl_free(rmsg_reply); DEBUGMSG(1, "contentlen=%d CCNL_RIOT_CHUNK_SIZE=%d\n", contlen, CCNL_RIOT_CHUNK_SIZE); if (contlen < CCNL_RIOT_CHUNK_SIZE || CCNL_RIOT_CHUNK_SIZE < contlen) { /* last chunk */ break; } } return content_len; }
void ccnl_populate_cache(struct ccnl_relay_s *ccnl, char *path) { DIR *dir; struct dirent *de; int datalen; DEBUGMSG(99, "ccnl_populate_cache %s\n", path); dir = opendir(path); if (!dir) return; while ((de = readdir(dir))) { if (!fnmatch("*.ccnb", de->d_name, FNM_NOESCAPE)) { char fname[1000]; struct stat s; strcpy(fname, path); strcat(fname, "/"); strcat(fname, de->d_name); if (stat(fname, &s)) { perror("stat"); } else { struct ccnl_buf_s *buf = 0; int fd; DEBUGMSG(6, "loading file %s, %d bytes\n", de->d_name, (int) s.st_size); fd = open(fname, O_RDONLY); if (!fd) { perror("open"); continue; } buf = (struct ccnl_buf_s *) ccnl_malloc(sizeof(*buf) + s.st_size); datalen = read(fd, buf->data, s.st_size); close(fd); if (datalen == s.st_size && datalen >= 2 && buf->data[0] == 0x04 && buf->data[1] == 0x82) { struct ccnl_prefix_s *prefix = 0; struct ccnl_content_s *c = 0; struct ccnl_buf_s *nonce=0, *ppkd=0, *pkt = 0; unsigned char *content, *data = buf->data + 2; int contlen; buf->datalen = datalen; datalen -= 2; pkt = ccnl_extract_prefix_nonce_ppkd(&data, &datalen, 0, 0, 0, 0, &prefix, &nonce, &ppkd, &content, &contlen); if (!pkt) { DEBUGMSG(6, " parsing error\n"); goto Done; } if (!prefix) { DEBUGMSG(6, " no prefix error\n"); goto Done; } c = ccnl_content_new(ccnl, &pkt, &prefix, &ppkd, content, contlen); if (!c) goto Done; ccnl_content_add2cache(ccnl, c); c->flags |= CCNL_CONTENT_FLAGS_STATIC; Done: free_prefix(prefix); ccnl_free(buf); ccnl_free(pkt); ccnl_free(nonce); ccnl_free(ppkd); } else { DEBUGMSG(6, " not a content object\n"); ccnl_free(buf); } } } } }
void free_forward(struct ccnl_forward_s *fwd) { free_prefix(fwd->prefix); ccnl_free(fwd); }
int ccnl_ccnb_forwarder(struct ccnl_relay_s *relay, struct ccnl_face_s *from, unsigned char **data, int *datalen) { int rc= -1, scope=3, aok=3, minsfx=0, maxsfx=CCNL_MAX_NAME_COMP, contlen; struct ccnl_buf_s *buf = 0, *nonce=0, *ppkd=0; struct ccnl_interest_s *i = 0; struct ccnl_content_s *c = 0; struct ccnl_prefix_s *p = 0; unsigned char *content = 0; DEBUGMSG(99, "ccnl/ccnb forwarder (%d bytes left)\n", *datalen); buf = ccnl_ccnb_extract(data, datalen, &scope, &aok, &minsfx, &maxsfx, &p, &nonce, &ppkd, &content, &contlen); if (!buf) { DEBUGMSG(6, " parsing error or no prefix\n"); goto Done; } if (nonce && ccnl_nonce_find_or_append(relay, nonce)) { DEBUGMSG(6, " dropped because of duplicate nonce\n"); goto Skip; } if (buf->data[0] == 0x01 && buf->data[1] == 0xd2) { // interest DEBUGMSG(6, " interest=<%s>\n", ccnl_prefix_to_path(p)); ccnl_print_stats(relay, STAT_RCV_I); //log count recv_interest if (p->compcnt > 0 && p->comp[0][0] == (unsigned char) 0xc1) goto Skip; if (p->compcnt == 4 && !memcmp(p->comp[0], "ccnx", 4)) { rc = ccnl_mgmt(relay, buf, p, from); goto Done; } // CONFORM: Step 1: if ( aok & 0x01 ) { // honor "answer-from-existing-content-store" flag for (c = relay->contents; c; c = c->next) { if (c->suite != CCNL_SUITE_CCNB) continue; if (!ccnl_i_prefixof_c(p, minsfx, maxsfx, c)) continue; if (ppkd && !buf_equal(ppkd, c->details.ccnb.ppkd)) continue; // FIXME: should check stale bit in aok here DEBUGMSG(7, " matching content for interest, content %p\n", (void *) c); ccnl_print_stats(relay, STAT_SND_C); //log sent_c if (from->ifndx >= 0) ccnl_face_enqueue(relay, from, buf_dup(c->pkt)); else ccnl_app_RX(relay, c); goto Skip; } } // CONFORM: Step 2: check whether interest is already known for (i = relay->pit; i; i = i->next) { if (i->suite == CCNL_SUITE_CCNB && !ccnl_prefix_cmp(i->prefix, NULL, p, CMP_EXACT) && i->details.ccnb.minsuffix == minsfx && i->details.ccnb.maxsuffix == maxsfx && ((!ppkd && !i->details.ccnb.ppkd) || buf_equal(ppkd, i->details.ccnb.ppkd)) ) break; } if (!i) { // this is a new/unknown I request: create and propagate i = ccnl_interest_new(relay, from, CCNL_SUITE_CCNB, &buf, &p, minsfx, maxsfx); if (ppkd) i->details.ccnb.ppkd = ppkd, ppkd = NULL; if (i) { // CONFORM: Step 3 (and 4) DEBUGMSG(7, " created new interest entry %p\n", (void *) i); if (scope > 2) ccnl_interest_propagate(relay, i); } } else if (scope > 2 && (from->flags & CCNL_FACE_FLAGS_FWDALLI)) { DEBUGMSG(7, " old interest, nevertheless propagated %p\n", (void *) i); ccnl_interest_propagate(relay, i); } if (i) { // store the I request, for the incoming face (Step 3) DEBUGMSG(7, " appending interest entry %p\n", (void *) i); ccnl_interest_append_pending(i, from); } } else { // content DEBUGMSG(6, " content=<%s>\n", ccnl_prefix_to_path(p)); ccnl_print_stats(relay, STAT_RCV_C); //log count recv_content #ifdef USE_SIGNATURES if (p->compcnt == 2 && !memcmp(p->comp[0], "ccnx", 4) && !memcmp(p->comp[1], "crypto", 6) && from == relay->crypto_face) { rc = ccnl_crypto(relay, buf, p, from); goto Done; } #endif /*USE_SIGNATURES*/ // CONFORM: Step 1: for (c = relay->contents; c; c = c->next) if (buf_equal(c->pkt, buf)) goto Skip; // content is dup c = ccnl_content_new(relay, CCNL_SUITE_CCNB, &buf, &p, &ppkd, content, contlen); if (c) { // CONFORM: Step 2 (and 3) if (!ccnl_content_serve_pending(relay, c)) { // unsolicited content // CONFORM: "A node MUST NOT forward unsolicited data [...]" DEBUGMSG(7, " removed because no matching interest\n"); free_content(c); goto Skip; } if (relay->max_cache_entries != 0) { // it's set to -1 or a limit DEBUGMSG(7, " adding content to cache\n"); ccnl_content_add2cache(relay, c); } else { DEBUGMSG(7, " content not added to cache\n"); free_content(c); } } } Skip: rc = 0; Done: free_prefix(p); free_3ptr_list(buf, nonce, ppkd); return rc; }
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); }