Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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);
}
Exemple #5
0
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);
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #9
0
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;
}
Exemple #11
0
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);
}