From f851c5976c4c4fb79739653deec981f4ae0465f1 Mon Sep 17 00:00:00 2001 From: Christopher Scherb Date: Thu, 17 Apr 2014 14:32:28 +0200 Subject: [PATCH 1/5] Change compare for computation --- krivine-common.c | 6 +++--- krivine.c | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/krivine-common.c b/krivine-common.c index 262255c0f020..b84eff694c2d 100644 --- a/krivine-common.c +++ b/krivine-common.c @@ -280,8 +280,8 @@ ccnl_nfn_local_content_search(struct ccnl_relay_s *ccnl, struct ccnl_interest_s struct ccnl_content_s *c_iter; for(c_iter = ccnl->contents; c_iter; c_iter = c_iter->next){ unsigned char *md; - md = i->prefix->compcnt - c_iter->name->compcnt == 1 ? compute_ccnx_digest(c_iter->pkt) : NULL; - if(ccnl_prefix_cmp(c_iter->name, md, i->prefix, type)){ + md = c_iter->name->compcnt; //i->prefix->compcnt - c_iter->name->compcnt == 1 ? compute_ccnx_digest(c_iter->pkt) : NULL; + if(ccnl_prefix_cmp(c_iter->name, md, i->prefix, type)){ //FIXME: discuss how to compare WHAT IS MD? return c_iter; } } @@ -397,7 +397,7 @@ ccnl_nfn_global_content_search(struct ccnl_relay_s *ccnl, struct configuration_s pthread_cond_wait(&config->thread->cond, &config->thread->mutex); //local search. look if content is now available! DEBUGMSG(99,"Got signal CONTINUE\n"); - if((c = ccnl_nfn_local_content_search(ccnl, interest, CMP_MATCH)) != NULL){ + if((c = ccnl_nfn_local_content_search(ccnl, interest, CMP_EXACT)) != NULL){ DEBUGMSG(49, "Content now available: %s\n", c->content); return c; } diff --git a/krivine.c b/krivine.c index bdd548f737fc..a591623804a2 100644 --- a/krivine.c +++ b/krivine.c @@ -338,7 +338,7 @@ ccnl_nfn_handle_network_search(struct ccnl_relay_s *ccnl, struct configuration_s //search struct ccnl_interest_s *interest = ccnl_nfn_create_interest_object(ccnl, config, out, len, namecomp[0]); //FIXME: NAMECOMP[0]??? interest->from->faceid = config->thread->id; - if((c = ccnl_nfn_local_content_search(ccnl, interest, CMP_MATCH)) != NULL){ + if((c = ccnl_nfn_local_content_search(ccnl, interest, CMP_EXACT)) != NULL){ DEBUGMSG(49, "Content locally found\n"); //ccnl_interest_remove(ccnl, interest); return c; @@ -389,10 +389,9 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, char *pending, *p, *cp; int len; char *prog = config->prog; - DEBUGMSG(99, "DUMMYBUF: %s \n", dummybuf); memset(dummybuf, 0, 2000); + //pop closure - if (!prog || strlen(prog) == 0) { if(config->result_stack){ return config->result_stack->content; From f9bb746de77735bb386407f61f452e87a22269c5 Mon Sep 17 00:00:00 2001 From: Christopher Scherb Date: Thu, 17 Apr 2014 15:26:16 +0200 Subject: [PATCH 2/5] Compare bugfix --- krivine-common.c | 9 ++++----- krivine.c | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/krivine-common.c b/krivine-common.c index b84eff694c2d..5201fab28911 100644 --- a/krivine-common.c +++ b/krivine-common.c @@ -274,14 +274,13 @@ create_content_object(struct ccnl_relay_s *ccnl, struct ccnl_prefix_s *prefix, } struct ccnl_content_s * -ccnl_nfn_local_content_search(struct ccnl_relay_s *ccnl, struct ccnl_interest_s *i, int type){ +ccnl_nfn_local_content_search(struct ccnl_relay_s *ccnl, struct ccnl_interest_s *i){ DEBUGMSG(2, "ccnl_nfn_local_content_search()\n"); struct ccnl_content_s *c_iter; for(c_iter = ccnl->contents; c_iter; c_iter = c_iter->next){ unsigned char *md; - md = c_iter->name->compcnt; //i->prefix->compcnt - c_iter->name->compcnt == 1 ? compute_ccnx_digest(c_iter->pkt) : NULL; - if(ccnl_prefix_cmp(c_iter->name, md, i->prefix, type)){ //FIXME: discuss how to compare WHAT IS MD? + if(!ccnl_prefix_cmp(c_iter->name, NULL, i->prefix, CMP_EXACT)){ return c_iter; } } @@ -397,7 +396,7 @@ ccnl_nfn_global_content_search(struct ccnl_relay_s *ccnl, struct configuration_s pthread_cond_wait(&config->thread->cond, &config->thread->mutex); //local search. look if content is now available! DEBUGMSG(99,"Got signal CONTINUE\n"); - if((c = ccnl_nfn_local_content_search(ccnl, interest, CMP_EXACT)) != NULL){ + if((c = ccnl_nfn_local_content_search(ccnl, interest)) != NULL){ DEBUGMSG(49, "Content now available: %s\n", c->content); return c; } @@ -449,7 +448,7 @@ isLocalAvailable(struct ccnl_relay_s *ccnl, struct configuration_s *config, char interest->propagate = 0; int found = 0; struct ccnl_content_s *c; - if((c = ccnl_nfn_local_content_search(ccnl, interest, CMP_EXACT)) != NULL){ //todo: exact match not only prefix + if((c = ccnl_nfn_local_content_search(ccnl, interest)) != NULL){ //todo: exact match not only prefix found = 1; } interest = ccnl_interest_remove(ccnl, interest); diff --git a/krivine.c b/krivine.c index a591623804a2..301299917d13 100644 --- a/krivine.c +++ b/krivine.c @@ -338,7 +338,7 @@ ccnl_nfn_handle_network_search(struct ccnl_relay_s *ccnl, struct configuration_s //search struct ccnl_interest_s *interest = ccnl_nfn_create_interest_object(ccnl, config, out, len, namecomp[0]); //FIXME: NAMECOMP[0]??? interest->from->faceid = config->thread->id; - if((c = ccnl_nfn_local_content_search(ccnl, interest, CMP_EXACT)) != NULL){ + if((c = ccnl_nfn_local_content_search(ccnl, interest)) != NULL){ DEBUGMSG(49, "Content locally found\n"); //ccnl_interest_remove(ccnl, interest); return c; From dc1179c03cf205d24e6c2e97cdded65b07c7dfc5 Mon Sep 17 00:00:00 2001 From: Christopher Scherb Date: Fri, 18 Apr 2014 17:04:06 +0200 Subject: [PATCH 3/5] Fix: do not start a thread if a matching computation is already running Some refactoring --- ccn-lite-lnxkernel.c | 4 +-- ccn-lite-relay.c | 58 +++++++++++++++---------------- ccnl-core.c | 61 +++++++++++++++++---------------- ccnl-ext-nfn.c | 60 +++++++++++++++++++++----------- krivine-common.c | 37 ++++++++++---------- krivine.c | 20 +++++------ test/scripts/nfn/dummyanswer.py | 2 +- 7 files changed, 130 insertions(+), 112 deletions(-) diff --git a/ccn-lite-lnxkernel.c b/ccn-lite-lnxkernel.c index 39dd84c20a9c..354d3c028e13 100644 --- a/ccn-lite-lnxkernel.c +++ b/ccn-lite-lnxkernel.c @@ -655,7 +655,7 @@ ccnl_lnxkernel_cleanup(void) struct dentry *dir = dget_parent(p.dentry); mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT); - rc = vfs_unlink(dir->d_inode, p.dentry); + rc = vfs_unlink(dir->d_inode, p.dentry, NULL); mutex_unlock(&dir->d_inode->i_mutex); dput(dir); path_put(&p); @@ -671,7 +671,7 @@ ccnl_lnxkernel_cleanup(void) struct dentry *dir = dget_parent(px.dentry); mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT); - rc = vfs_unlink(dir->d_inode, px.dentry); + rc = vfs_unlink(dir->d_inode, px.dentry, NULL); mutex_unlock(&dir->d_inode->i_mutex); dput(dir); path_put(&px); diff --git a/ccn-lite-relay.c b/ccn-lite-relay.c index 284ed5f4e3f2..7c175ede4ffe 100644 --- a/ccn-lite-relay.c +++ b/ccn-lite-relay.c @@ -310,7 +310,7 @@ void ccnl_ageing(void *relay, void *aux) // ---------------------------------------------------------------------- void -ccnl_relay_config(struct ccnl_relay_s *relay, char *ethdev, int udpport, +ccnl_relay_config(struct ccnl_relay_s *ccnl, char *ethdev, int udpport, int tcpport, char *uxpath, int max_cache_entries, char *crypto_face_path) { @@ -319,26 +319,26 @@ ccnl_relay_config(struct ccnl_relay_s *relay, char *ethdev, int udpport, DEBUGMSG(99, "ccnl_relay_config\n"); - relay->max_cache_entries = max_cache_entries; + ccnl->max_cache_entries = max_cache_entries; #ifdef USE_SCHEDULER - relay->defaultFaceScheduler = ccnl_relay_defaultFaceScheduler; - relay->defaultInterfaceScheduler = ccnl_relay_defaultInterfaceScheduler; + ccnl->defaultFaceScheduler = ccnl_relay_defaultFaceScheduler; + ccnl->defaultInterfaceScheduler = ccnl_relay_defaultInterfaceScheduler; #endif #ifdef USE_ETHERNET // add (real) eth0 interface with index 0: if (ethdev) { - i = &relay->ifs[relay->ifcount]; + i = &ccnl->ifs[ccnl->ifcount]; i->sock = ccnl_open_ethdev(ethdev, &i->addr.eth, CCNL_ETH_TYPE); i->mtu = 1500; i->reflect = 1; i->fwdalli = 1; if (i->sock >= 0) { - relay->ifcount++; + ccnl->ifcount++; DEBUGMSG(99, "new ETH interface (%s %s) configured\n", ethdev, ccnl_addr2ascii(&i->addr)); - if (relay->defaultInterfaceScheduler) - i->sched = relay->defaultInterfaceScheduler(relay, + if (ccnl->defaultInterfaceScheduler) + i->sched = ccnl->defaultInterfaceScheduler(ccnl, ccnl_interface_CTS); } else fprintf(stderr, "sorry, could not open eth device\n"); @@ -346,17 +346,17 @@ ccnl_relay_config(struct ccnl_relay_s *relay, char *ethdev, int udpport, #endif // USE_ETHERNET if (udpport > 0) { - i = &relay->ifs[relay->ifcount]; + i = &ccnl->ifs[ccnl->ifcount]; i->sock = ccnl_open_udpdev(udpport, &i->addr.ip4); // i->frag = CCNL_DGRAM_FRAG_NONE; i->mtu = CCN_DEFAULT_MTU; i->fwdalli = 1; if (i->sock >= 0) { - relay->ifcount++; + ccnl->ifcount++; DEBUGMSG(99, "new UDP interface (ip4 %s) configured\n", ccnl_addr2ascii(&i->addr)); - if (relay->defaultInterfaceScheduler) - i->sched = relay->defaultInterfaceScheduler(relay, + if (ccnl->defaultInterfaceScheduler) + i->sched = ccnl->defaultInterfaceScheduler(ccnl, ccnl_interface_CTS); } else fprintf(stderr, "sorry, could not open udp device\n"); @@ -364,21 +364,21 @@ ccnl_relay_config(struct ccnl_relay_s *relay, char *ethdev, int udpport, #ifdef USE_HTTP_STATUS if (tcpport) { - relay->http = ccnl_http_new(relay, tcpport); + ccnl->http = ccnl_http_new(ccnl, tcpport); } #endif // USE_HTTP_STATUS #ifdef USE_UNIXSOCKET if (uxpath) { - i = &relay->ifs[relay->ifcount]; + i = &ccnl->ifs[ccnl->ifcount]; i->sock = ccnl_open_unixpath(uxpath, &i->addr.ux); i->mtu = 4096; if (i->sock >= 0) { - relay->ifcount++; + ccnl->ifcount++; DEBUGMSG(99, "new UNIX interface (%s) configured\n", ccnl_addr2ascii(&i->addr)); - if (relay->defaultInterfaceScheduler) - i->sched = relay->defaultInterfaceScheduler(relay, + if (ccnl->defaultInterfaceScheduler) + i->sched = ccnl->defaultInterfaceScheduler(ccnl, ccnl_interface_CTS); } else fprintf(stderr, "sorry, could not open unix datagram device\n"); @@ -387,33 +387,33 @@ ccnl_relay_config(struct ccnl_relay_s *relay, char *ethdev, int udpport, if(crypto_face_path) { //sending interface + face - i = &relay->ifs[relay->ifcount]; + i = &ccnl->ifs[ccnl->ifcount]; i->sock = ccnl_open_unixpath(crypto_face_path, &i->addr.ux); i->mtu = 4096; if (i->sock >= 0) { - relay->ifcount++; + ccnl->ifcount++; DEBUGMSG(99, "new UNIX interface (%s) configured\n", ccnl_addr2ascii(&i->addr)); - if (relay->defaultInterfaceScheduler) - i->sched = relay->defaultInterfaceScheduler(relay, + if (ccnl->defaultInterfaceScheduler) + i->sched = ccnl->defaultInterfaceScheduler(ccnl, ccnl_interface_CTS); - ccnl_crypto_create_ccnl_crypto_face(relay, crypto_face_path); - relay->crypto_path = crypto_face_path; + ccnl_crypto_create_ccnl_crypto_face(ccnl, crypto_face_path); + ccnl->crypto_path = crypto_face_path; } else fprintf(stderr, "sorry, could not open unix datagram device\n"); //receiving interface memset(h,0,sizeof(h)); sprintf(h,"%s-2",crypto_face_path); - i = &relay->ifs[relay->ifcount]; + i = &ccnl->ifs[ccnl->ifcount]; i->sock = ccnl_open_unixpath(h, &i->addr.ux); i->mtu = 4096; if (i->sock >= 0) { - relay->ifcount++; + ccnl->ifcount++; DEBUGMSG(99, "new UNIX interface (%s) configured\n", ccnl_addr2ascii(&i->addr)); - if (relay->defaultInterfaceScheduler) - i->sched = relay->defaultInterfaceScheduler(relay, + if (ccnl->defaultInterfaceScheduler) + i->sched = ccnl->defaultInterfaceScheduler(ccnl, ccnl_interface_CTS); //create_ccnl_crypto_face(relay, crypto_face_path); } else @@ -421,7 +421,7 @@ ccnl_relay_config(struct ccnl_relay_s *relay, char *ethdev, int udpport, } #endif //USE_SIGNATURES #endif // USE_UNIXSOCKET - ccnl_set_timer(1000000, ccnl_ageing, relay, 0); + ccnl_set_timer(1000000, ccnl_ageing, ccnl, 0); } // ---------------------------------------------------------------------- @@ -658,7 +658,7 @@ main(int argc, char **argv) } } - main_thread = new_thread(0); + main_thread = new_thread(0, NULL); DEBUGMSG(1, "This is ccn-lite-relay, starting at %s", ctime(&theRelay.startup_time) + 4); DEBUGMSG(1, " ccnl-core: %s\n", CCNL_VERSION); diff --git a/ccnl-core.c b/ccnl-core.c index 896ecbff8e27..223e02af039c 100644 --- a/ccnl-core.c +++ b/ccnl-core.c @@ -638,7 +638,7 @@ ccnl_interest_propagate(struct ccnl_relay_s *ccnl, struct ccnl_interest_s *i) { struct ccnl_forward_s *fwd; DEBUGMSG(99, "ccnl_interest_propagate\n"); - + ccnl_print_stats(ccnl, STAT_SND_I); // log_send_i // CONFORM: "A node MUST implement some strategy rule, even if it is only to @@ -662,8 +662,11 @@ 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); - + DEBUGMSG(40, "ccnl_interest_remove %p ", (void *) i); + int it; + for(it = 0; it < i->prefix->compcnt; ++it){ + fprintf(stderr, "/%s", i->prefix->comp[it]); + } while (i->pending) { struct ccnl_pendint_s *tmp = i->pending->next; \ ccnl_free(i->pending); @@ -878,7 +881,7 @@ ccnl_core_cleanup(struct ccnl_relay_s *ccnl) // the core logic of CCN: int -ccnl_core_RX_i_or_c(struct ccnl_relay_s *relay, struct ccnl_face_s *from, +ccnl_core_RX_i_or_c(struct ccnl_relay_s *ccnl, 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; @@ -894,32 +897,32 @@ ccnl_core_RX_i_or_c(struct ccnl_relay_s *relay, struct ccnl_face_s *from, if (!buf) { DEBUGMSG(6, " parsing error or no prefix\n"); goto Done; } - if (nonce && ccnl_nonce_find_or_append(relay, nonce)) { + if (nonce && ccnl_nonce_find_or_append(ccnl, nonce)) { DEBUGMSG(6, " dropped because of duplicate nonce\n"); //goto Skip; //FIXME //TODO enable 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 + ccnl_print_stats(ccnl, 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; + rc = ccnl_mgmt(ccnl, 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) { + for (c = ccnl->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); - ccnl_print_stats(relay, STAT_SND_C); //log sent_c + ccnl_print_stats(ccnl, STAT_SND_C); //log sent_c if (from->ifndx >= 0) - ccnl_face_enqueue(relay, from, buf_dup(c->pkt)); + ccnl_face_enqueue(ccnl, from, buf_dup(c->pkt)); else - ccnl_app_RX(relay, c); + ccnl_app_RX(ccnl, c); goto Skip; } } // CONFORM: Step 2: check whether interest is already known - for (i = relay->pit; i; i = i->next) { + for (i = ccnl->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)) ) @@ -931,22 +934,22 @@ ccnl_core_RX_i_or_c(struct ccnl_relay_s *relay, struct ccnl_face_s *from, if(!memcmp(p->comp[p->compcnt-1], "NFN", 3)){ struct ccnl_buf_s *buf2 = buf; struct ccnl_prefix_s *p2 = p; - i = ccnl_interest_new(relay, from, &buf, &p, minsfx, maxsfx, &ppkd); + i = ccnl_interest_new(ccnl, from, &buf, &p, minsfx, maxsfx, &ppkd); i->propagate = 0; //TODO: mechanism to set propagate in a meaningful way ccnl_interest_append_pending(i, from); - if(!i->propagate)ccnl_nfn(relay, buf2, p2, from, 0); + if(!i->propagate)ccnl_nfn(ccnl, buf2, p2, from, 0); goto Done; } #endif /*CCNL_NFN*/ - i = ccnl_interest_new(relay, from, &buf, &p, minsfx, maxsfx, &ppkd); + i = ccnl_interest_new(ccnl, 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); + ccnl_interest_propagate(ccnl, 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); + ccnl_interest_propagate(ccnl, i); } if (i) { // store the I request, for the incoming face (Step 3) DEBUGMSG(7, " appending interest entry %p\n", (void *) i); @@ -954,27 +957,27 @@ ccnl_core_RX_i_or_c(struct ccnl_relay_s *relay, struct ccnl_face_s *from, } } else { // content DEBUGMSG(6, " content=<%s>\n", ccnl_prefix_to_path(p)); - ccnl_print_stats(relay, STAT_RCV_C); //log count recv_content + ccnl_print_stats(ccnl, 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; + from == ccnl->crypto_face) { + rc = ccnl_crypto(ccnl, buf, p, from); goto Done; } #endif /*USE_SIGNATURES*/ // CONFORM: Step 1: - for (c = relay->contents; c; c = c->next) + for (c = ccnl->contents; c; c = c->next) if (buf_equal(c->pkt, buf)) goto Skip; // content is dup - c = ccnl_content_new(relay, &buf, &p, &ppkd, content, contlen); + c = ccnl_content_new(ccnl, &buf, &p, &ppkd, content, contlen); if (c) { // CONFORM: Step 2 (and 3) #ifdef CCNL_NFN fprintf(stderr, "PIT Entries: \n"); struct ccnl_interest_s *i_it; - for(i_it = relay->pit; i_it; i_it = i_it->next){ + for(i_it = ccnl->pit; i_it; i_it = i_it->next){ int it; fprintf(stderr, " - "); for(it = 0; it < i_it->prefix->compcnt; ++it){ @@ -990,16 +993,16 @@ ccnl_core_RX_i_or_c(struct ccnl_relay_s *relay, struct ccnl_face_s *from, if(!memcmp(c->name->comp[c->name->compcnt-1], "NFN", 3)){ struct ccnl_interest_s *i_it = NULL; int found = 0; - for(i_it = relay->pit; i_it; i_it = i_it->next){ + for(i_it = ccnl->pit; i_it; i_it = i_it->next){ int md = i_it->prefix->compcnt - c->name->compcnt == 1 ? compute_ccnx_digest(c->pkt) : NULL; //Check if prefix match and it is a nfn request int cmp = ccnl_prefix_cmp(c->name, md, i_it->prefix, CMP_MATCH); DEBUGMSG(99, "CMP: %d, faceid: %d \n", cmp, i_it->from->faceid); if( ccnl_prefix_cmp(c->name, md, i_it->prefix, CMP_MATCH) && i_it->from->faceid < 0){ - ccnl_content_add2cache(relay, c); + ccnl_content_add2cache(ccnl, c); int threadid = -i_it->from->faceid; - i_it = ccnl_interest_remove(relay, i_it); + i_it = ccnl_interest_remove(ccnl, i_it); DEBUGMSG(49, "Send signal for threadid: %d\n", threadid); ccnl_nfn_send_signal(threadid); DEBUGMSG(49, "Done\n"); @@ -1011,15 +1014,15 @@ ccnl_core_RX_i_or_c(struct ccnl_relay_s *relay, struct ccnl_face_s *from, DEBUGMSG(99, "no running computation found \n"); } #endif - if (!ccnl_content_serve_pending(relay, c)) { // unsolicited content + if (!ccnl_content_serve_pending(ccnl, 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 + if (ccnl->max_cache_entries != 0) { // it's set to -1 or a limit DEBUGMSG(7, " adding content to cache\n"); - ccnl_content_add2cache(relay, c); + ccnl_content_add2cache(ccnl, c); } else { DEBUGMSG(7, " content not added to cache\n"); free_content(c); diff --git a/ccnl-ext-nfn.c b/ccnl-ext-nfn.c index 275b78fa2b11..14b28bfc5124 100644 --- a/ccnl-ext-nfn.c +++ b/ccnl-ext-nfn.c @@ -26,7 +26,6 @@ #include "ccnl-core.h" #include "krivine.c" #include "krivine-common.c" -#include "ccnl-includes.h" static int @@ -43,11 +42,18 @@ ccnl_nfn_count_required_thunks(char *str) return num; } +static void +ccnl_nfn_remove_thunk_from_prefix(struct ccnl_prefix_s *prefix){ + prefix->comp[prefix->compcnt-2] = prefix->comp[prefix->compcnt-1]; + prefix->complen[prefix->compcnt-2] = prefix->complen[prefix->compcnt-1]; + --prefix->compcnt; +} void * ccnl_nfn_thread(void *arg) { + DEBUGMSG(49, "ccnl_nfn_thread()\n"); struct thread_parameter_s *t = ((struct thread_parameter_s*)arg); struct ccnl_relay_s *ccnl = t->ccnl; @@ -55,23 +61,12 @@ ccnl_nfn_thread(void *arg) struct ccnl_prefix_s *prefix = t->prefix; struct ccnl_face_s *from = t->from; struct thread_s *thread = t->thread; - int thunk_request = 0; int num_of_thunks = 0; - struct ccnl_prefix_s *original_prefix; - DEBUGMSG(49, "ccnl_nfn(%p, %p, %p, %p)\n", ccnl, orig, prefix, from); + if(!memcmp(prefix->comp[prefix->compcnt-2], "THUNK", 5)) { - - ccnl_nfn_copy_prefix(prefix, &original_prefix); thunk_request = 1; - //FIXME: WARUM COPY VON PREFIX NĂ–TIG? - - DEBUGMSG(99, " Thunk-request, currently not implementd\n"); - //TODO: search for num of required thunks??? - } - else{ - original_prefix = prefix; } char str[CCNL_MAX_PACKET_SIZE]; int i, len = 0; @@ -91,17 +86,15 @@ ccnl_nfn_thread(void *arg) if(thunk_request){ num_of_thunks = ccnl_nfn_count_required_thunks(str); } - char *res = Krivine_reduction(ccnl, str, thunk_request, &num_of_thunks, - original_prefix, thread); + char *res = Krivine_reduction(ccnl, str, thunk_request, + &num_of_thunks, thread); //stores result if computed if(res){ DEBUGMSG(2,"Computation finshed: %s\n", res); if(thunk_request){ - original_prefix->comp[original_prefix->compcnt-2] = original_prefix->comp[original_prefix->compcnt-1]; - original_prefix->complen[original_prefix->compcnt-2] = original_prefix->complen[original_prefix->compcnt-1]; - --original_prefix->compcnt; + ccnl_nfn_remove_thunk_from_prefix(thread->prefix); } - struct ccnl_content_s *c = create_content_object(ccnl, original_prefix, res, strlen(res)); + struct ccnl_content_s *c = create_content_object(ccnl, thread->prefix, res, strlen(res)); c->flags = CCNL_CONTENT_FLAGS_STATIC; if(!thunk_request)ccnl_content_serve_pending(ccnl,c); @@ -122,18 +115,45 @@ ccnl_nfn_thread(void *arg) void ccnl_nfn_send_signal(int threadid){ + DEBUGMSG(49, "ccnl_nfn_send_signal()\n"); struct thread_s *thread = threads[threadid]; pthread_cond_broadcast(&thread->cond); struct thread_s *thread1 = main_thread; pthread_cond_wait(&(thread1->cond), &thread1->mutex); } +int +ccnl_nfn_thunk_already_computing(struct ccnl_prefix_s *prefix) +{ + DEBUGMSG(49, "ccnl_nfn_thunk_already_computing()\n"); + int i = 0; + for(i = 0; i < -threadid; ++i){ + struct ccnl_prefix_s *copy; + struct thread_s *thread = threads[i]; + if(!thread) continue; + ccnl_nfn_copy_prefix(thread->prefix ,©); + ccnl_nfn_remove_thunk_from_prefix(copy); + if(!ccnl_prefix_cmp(copy, NULL, prefix, CMP_EXACT)){ + return 1; + } + + } + return 0; +} int ccnl_nfn(struct ccnl_relay_s *ccnl, struct ccnl_buf_s *orig, struct ccnl_prefix_s *prefix, struct ccnl_face_s *from) { - struct thread_s *thread = new_thread(threadid); + DEBUGMSG(49, "ccnl_nfn(%p, %p, %p, %p)\n", ccnl, orig, prefix, from); + + if(ccnl_nfn_thunk_already_computing(prefix)){ + DEBUGMSG(9, "Computation for this interest is already running\n"); + return -1; + } + struct ccnl_prefix_s *original_prefix; + ccnl_nfn_copy_prefix(prefix, &original_prefix); + struct thread_s *thread = new_thread(threadid, original_prefix); struct thread_parameter_s *arg = malloc(sizeof(struct thread_parameter_s *)); char *h = malloc(10); arg->ccnl = ccnl; diff --git a/krivine-common.c b/krivine-common.c index 5201fab28911..3d90f0a9b504 100644 --- a/krivine-common.c +++ b/krivine-common.c @@ -38,6 +38,7 @@ struct thread_s{ pthread_cond_t cond; pthread_mutex_t mutex; pthread_t thread; + struct ccnl_prefix_s *prefix; }; struct threads_s *threads[1024]; @@ -54,18 +55,19 @@ struct thread_parameter_s{ }; struct thread_s * -new_thread(int thread_id){ +new_thread(int thread_id, struct ccnl_prefix_s *prefix){ struct thread_s *t = malloc(sizeof(struct thread_s)); t->id = thread_id; t->cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER; t->mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; + t->prefix = prefix; return t; } struct thunk_s{ struct thunk_s *next, *prev; char thunkid[10]; - struct ccnl_interest_s *i; + struct ccnl_prefix_s *prefix; }; struct thunk_s *thunk_list; @@ -152,6 +154,7 @@ mkInterestCompute(char **namecomp, char *computation, int computationlen, int th void ccnl_nfn_copy_prefix(struct ccnl_prefix_s *prefix, struct ccnl_prefix_s **copy){ + DEBUGMSG(2, "ccnl_nfn_copy_prefix()\n"); int i = 0; (*copy) = ccnl_malloc(sizeof(struct ccnl_prefix_s)); (*copy)->compcnt = prefix->compcnt; @@ -169,11 +172,11 @@ ccnl_nfn_copy_prefix(struct ccnl_prefix_s *prefix, struct ccnl_prefix_s **copy){ void ccnl_nfn_delete_prefix(struct ccnl_prefix_s *prefix){ int i; - prefix->compcnt = 0; if(prefix->complen)free(prefix->complen); for(i = 0; i < prefix->compcnt; ++i){ if(prefix->comp[i])free(prefix->comp[i]); } + prefix->compcnt = 0; } int @@ -390,7 +393,7 @@ ccnl_nfn_global_content_search(struct ccnl_relay_s *ccnl, struct configuration_s interest->from->faceid = config->thread->id; ccnl_interest_propagate(ccnl, interest); - DEBUGMSG(99, "WAITING on Signal; Threadid : %d \n", config->thread->id); + DEBUGMSG(99, "Waiting on Signal; Threadid : %d \n", -config->thread->id); struct thread_s *thread1 = main_thread; pthread_cond_broadcast(&thread1->cond); pthread_cond_wait(&config->thread->cond, &config->thread->mutex); @@ -467,25 +470,16 @@ ccnl_nfn_add_thunk(struct ccnl_relay_s *ccnl, struct configuration_s *config, st new_prefix->comp[new_prefix->compcnt-1] = NULL; --new_prefix->compcnt; } - char *out = ccnl_malloc(sizeof(char) * CCNL_MAX_PACKET_SIZE); - memset(out, 0, CCNL_MAX_PACKET_SIZE); - - int len = mkInterest(new_prefix->comp, NULL, out); - struct ccnl_interest_s *interest = ccnl_nfn_create_interest_object(ccnl, config, out, len, new_prefix->comp[0]); - - if(!interest) - return NULL; - struct thunk_s *thunk = ccnl_malloc(sizeof(struct thunk_s)); - thunk->i = interest; + thunk->prefix = new_prefix; sprintf(thunk->thunkid, "THUNK%d", thunkid++); DBL_LINKED_LIST_ADD(thunk_list, thunk); - printf("NEWTHUNK: %s\n", thunk->thunkid); + DEBUGMSG(99, "Created new thunk with id: %s\n", thunk->thunkid); return strdup(thunk->thunkid); } struct ccnl_interest_s * -ccnl_nfn_get_interest_for_thunk(char *thunkid){ +ccnl_nfn_get_interest_for_thunk(struct ccnl_relay_s *ccnl, struct configuration_s *config, char *thunkid){ DEBUGMSG(2, "ccnl_nfn_get_interest_for_thunk()\n"); struct thunk_s *thunk; for(thunk = thunk_list; thunk; thunk = thunk->next){ @@ -495,7 +489,11 @@ ccnl_nfn_get_interest_for_thunk(char *thunkid){ } } if(thunk){ - return thunk->i; + char *out = ccnl_malloc(sizeof(char) * CCNL_MAX_PACKET_SIZE); + memset(out, 0, CCNL_MAX_PACKET_SIZE); + int len = mkInterest(thunk->prefix->comp, NULL, out); + struct ccnl_interest_s *interest = ccnl_nfn_create_interest_object(ccnl, config, out, len, thunk->prefix->comp[0]); + return interest; } return NULL; } @@ -524,9 +522,10 @@ ccnl_nfn_reply_thunk(struct ccnl_relay_s *ccnl, struct ccnl_prefix *original_pre struct ccnl_content_s * ccnl_nfn_resolve_thunk(struct ccnl_relay_s *ccnl, struct configuration_s *config, char *thunk){ DEBUGMSG(2, "ccnl_nfn_resolve_thunk()\n"); - struct ccnl_interest_s *interest = ccnl_nfn_get_interest_for_thunk(thunk); - interest->retries = 20; // FIXME: set by thunk + struct ccnl_interest_s *interest = ccnl_nfn_get_interest_for_thunk(ccnl, config, thunk); + if(interest){ + interest->last_used = CCNL_NOW(); struct ccnl_content_s *c; if((c = ccnl_nfn_global_content_search(ccnl, config, interest)) != NULL){ DEBUGMSG(49, "Thunk was resolved\n"); diff --git a/krivine.c b/krivine.c index 301299917d13..8e6524d4cd24 100644 --- a/krivine.c +++ b/krivine.c @@ -83,7 +83,7 @@ pop_or_resolve_from_result_stack(struct ccnl_relay_s *ccnl, struct configuration char *ret = res; struct ccnl_content_s *c; if(!strncmp(res, "THUNK", 5)){ - printf("Resolve Thunk %s \n", res); + DEBUGMSG(49, "Resolve Thunk %s \n", res); //resolve_thunk() c = ccnl_nfn_resolve_thunk(ccnl, config, res); ret = c->content; @@ -298,13 +298,11 @@ ccnl_nfn_handle_local_computation(struct ccnl_relay_s *ccnl, struct configuratio namecomp[i++] = NULL; len = mkInterest(namecomp, 0, out); interest = ccnl_nfn_create_interest_object(ccnl, config, out, len, namecomp[0]); - for(i = 0; i < interest->prefix->compcnt; ++i){ printf("/%s", interest->prefix->comp[i]); }printf("\n"); //TODO: Check if it is already available locally - interest->from->faceid = config->thread->id; if((c = ccnl_nfn_global_content_search(ccnl, config, interest)) != NULL){ DEBUGMSG(49, "Content found in the network\n"); return c; @@ -337,7 +335,6 @@ ccnl_nfn_handle_network_search(struct ccnl_relay_s *ccnl, struct configuration_s free(param); //search struct ccnl_interest_s *interest = ccnl_nfn_create_interest_object(ccnl, config, out, len, namecomp[0]); //FIXME: NAMECOMP[0]??? - interest->from->faceid = config->thread->id; if((c = ccnl_nfn_local_content_search(ccnl, interest)) != NULL){ DEBUGMSG(49, "Content locally found\n"); //ccnl_interest_remove(ccnl, interest); @@ -383,7 +380,7 @@ ccnl_nfn_handle_routable_content(struct ccnl_relay_s *ccnl, struct configuration char* ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, int thunk_request, int *num_of_required_thunks, - struct ccnl_prefix_s *original_prefix, int *halt, char *dummybuf) + int *halt, char *dummybuf) { struct term_s *t; char *pending, *p, *cp; @@ -396,7 +393,7 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, if(config->result_stack){ return config->result_stack->content; } - printf("no result returned\n"); + DEBUGMSG(2, "no result returned\n"); return NULL; } @@ -422,7 +419,7 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, if (!closure) { closure = search_in_environment(config->global_dict, cp); if(!closure){ - printf("?? could not lookup var %s\n", cp); + DEBUGMSG(2, "?? could not lookup var %s\n", cp); return 0; } } @@ -704,7 +701,7 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, push_to_stack(&config->result_stack, thunkid); if( *num_of_required_thunks <= 0){ DEBUGMSG(99, "All thunks are available\n"); - ccnl_nfn_reply_thunk(ccnl, original_prefix); + ccnl_nfn_reply_thunk(ccnl, config->thread->prefix); } } else{ @@ -727,7 +724,7 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, return config->result_stack->content; } - printf("unknown built-in command <%s>\n", prog); + DEBUGMSG(2, "unknown built-in command <%s>\n", prog); return 0; } @@ -773,8 +770,7 @@ setup_global_environment(struct environment_s **env){ char * Krivine_reduction(struct ccnl_relay_s *ccnl, char *expression, int thunk_request, - int *num_of_required_thunks, struct ccnl_prefix_s *original_prefix, - struct thread_s *thread){ + int *num_of_required_thunks, struct thread_s *thread){ int steps = 0; int halt = 0; int len = strlen("CLOSURE(halt);RESOLVENAME()") + strlen(expression); @@ -792,7 +788,7 @@ Krivine_reduction(struct ccnl_relay_s *ccnl, char *expression, int thunk_request steps++; DEBUGMSG(1, "Step %d: %s\n", steps, config->prog); config->prog = ZAM_term(ccnl, config, thunk_request, - num_of_required_thunks, original_prefix, &halt, dummybuf); + num_of_required_thunks, &halt, dummybuf); } free(dummybuf); return pop_or_resolve_from_result_stack(ccnl, config);//config->result_stack->content; diff --git a/test/scripts/nfn/dummyanswer.py b/test/scripts/nfn/dummyanswer.py index db71b047c2cd..85d0587653e6 100644 --- a/test/scripts/nfn/dummyanswer.py +++ b/test/scripts/nfn/dummyanswer.py @@ -20,9 +20,9 @@ while True: data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes print "received message:", data -# time.sleep(2) if "THUNK" in data: sock.sendto(c_t, ("127.0.0.1", 9001)) else: + time.sleep(1) sock.sendto(c, ("127.0.0.1", 9001)) From 56cb039363703e980d1d9e3cf45c9776f8903c1b Mon Sep 17 00:00:00 2001 From: Christopher Scherb Date: Fri, 18 Apr 2014 17:10:58 +0200 Subject: [PATCH 4/5] Output fix --- ccnl-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ccnl-core.c b/ccnl-core.c index 223e02af039c..7cc3ed816a2a 100644 --- a/ccnl-core.c +++ b/ccnl-core.c @@ -667,6 +667,7 @@ ccnl_interest_remove(struct ccnl_relay_s *ccnl, struct ccnl_interest_s *i) for(it = 0; it < i->prefix->compcnt; ++it){ fprintf(stderr, "/%s", i->prefix->comp[it]); } + fprintf(stderr, "\n"); while (i->pending) { struct ccnl_pendint_s *tmp = i->pending->next; \ ccnl_free(i->pending); From ace550d0363517cdda72c4ee023c72efe54629e0 Mon Sep 17 00:00:00 2001 From: Christopher Scherb Date: Mon, 21 Apr 2014 17:34:03 +0200 Subject: [PATCH 5/5] Async Model without threads --- ccn-lite-relay.c | 2 - ccnl-core.c | 12 +-- ccnl-ext-nfn.c | 121 +++++++++++----------------- krivine-common.c | 69 +++++----------- krivine-common.h | 9 ++- krivine.c | 199 ++++++++++++++++++++++++++++++----------------- 6 files changed, 206 insertions(+), 206 deletions(-) diff --git a/ccn-lite-relay.c b/ccn-lite-relay.c index 7c175ede4ffe..dde157af2e49 100644 --- a/ccn-lite-relay.c +++ b/ccn-lite-relay.c @@ -657,8 +657,6 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } } - - main_thread = new_thread(0, NULL); DEBUGMSG(1, "This is ccn-lite-relay, starting at %s", ctime(&theRelay.startup_time) + 4); DEBUGMSG(1, " ccnl-core: %s\n", CCNL_VERSION); diff --git a/ccnl-core.c b/ccnl-core.c index 7cc3ed816a2a..ab2c07f27f89 100644 --- a/ccnl-core.c +++ b/ccnl-core.c @@ -32,7 +32,7 @@ int ccnl_crypto(struct ccnl_relay_s *ccnl, struct ccnl_buf_s *orig, struct ccnl_prefix_s *prefix, struct ccnl_face_s *from); void -ccnl_nfn_send_signal(int threadid); +ccnl_nfn_continue_computation(struct ccnl_relay_s *ccnl, int configid); static struct ccnl_interest_s* ccnl_interest_remove(struct ccnl_relay_s *ccnl, struct ccnl_interest_s *i); @@ -677,6 +677,7 @@ ccnl_interest_remove(struct ccnl_relay_s *ccnl, struct ccnl_interest_s *i) DBL_LINKED_LIST_REMOVE(ccnl->pit, i); //free_prefix(i->prefix); //TODO: //FIXME: IMPORTANT: memory leak free_3ptr_list(i->ppkd, i->pkt, i); + return i2; } @@ -938,7 +939,7 @@ ccnl_core_RX_i_or_c(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from, i = ccnl_interest_new(ccnl, from, &buf, &p, minsfx, maxsfx, &ppkd); i->propagate = 0; //TODO: mechanism to set propagate in a meaningful way ccnl_interest_append_pending(i, from); - if(!i->propagate)ccnl_nfn(ccnl, buf2, p2, from, 0); + if(!i->propagate)ccnl_nfn(ccnl, buf2, p2, from, NULL); goto Done; } #endif /*CCNL_NFN*/ @@ -1002,11 +1003,10 @@ ccnl_core_RX_i_or_c(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from, if( ccnl_prefix_cmp(c->name, md, i_it->prefix, CMP_MATCH) && i_it->from->faceid < 0){ ccnl_content_add2cache(ccnl, c); - int threadid = -i_it->from->faceid; + int configid = -i_it->from->faceid; i_it = ccnl_interest_remove(ccnl, i_it); - DEBUGMSG(49, "Send signal for threadid: %d\n", threadid); - ccnl_nfn_send_signal(threadid); - DEBUGMSG(49, "Done\n"); + DEBUGMSG(49, "Continue configuration for configid: %d\n", configid); + ccnl_nfn_continue_computation(ccnl, configid); ++found; goto Done; } diff --git a/ccnl-ext-nfn.c b/ccnl-ext-nfn.c index 14b28bfc5124..51ef9d4dfae6 100644 --- a/ccnl-ext-nfn.c +++ b/ccnl-ext-nfn.c @@ -44,23 +44,52 @@ ccnl_nfn_count_required_thunks(char *str) static void ccnl_nfn_remove_thunk_from_prefix(struct ccnl_prefix_s *prefix){ + DEBUGMSG(49, "ccnl_nfn_remove_thunk_from_prefix()\n"); prefix->comp[prefix->compcnt-2] = prefix->comp[prefix->compcnt-1]; prefix->complen[prefix->compcnt-2] = prefix->complen[prefix->compcnt-1]; --prefix->compcnt; } +void +ccnl_nfn_continue_computation(struct ccnl_relay_s *ccnl, int configid){ + DEBUGMSG(49, "ccnl_nfn_send_signal()\n"); + ccnl_nfn(ccnl, NULL, NULL, NULL, configuration_list[configid]); +} + +int +ccnl_nfn_thunk_already_computing(struct ccnl_prefix_s *prefix) +{ + DEBUGMSG(49, "ccnl_nfn_thunk_already_computing()\n"); + int i = 0; + for(i = 0; i < -configid; ++i){ + struct ccnl_prefix_s *copy; + struct configuration_s *config = configuration_list[i]; + if(!config) continue; + ccnl_nfn_copy_prefix(config->prefix ,©); + ccnl_nfn_remove_thunk_from_prefix(copy); + if(!ccnl_prefix_cmp(copy, NULL, prefix, CMP_EXACT)){ + return 1; + } + } + return 0; +} -void * -ccnl_nfn_thread(void *arg) +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) { - DEBUGMSG(49, "ccnl_nfn_thread()\n"); - struct thread_parameter_s *t = ((struct thread_parameter_s*)arg); + DEBUGMSG(49, "ccnl_nfn(%p, %p, %p, %p, %p)\n", ccnl, orig, prefix, from, config); + + if(config) goto restart; //do not do parsing thinks again - struct ccnl_relay_s *ccnl = t->ccnl; - struct ccnl_buf_s *orig = t->orig; - struct ccnl_prefix_s *prefix = t->prefix; - struct ccnl_face_s *from = t->from; - struct thread_s *thread = t->thread; + if(ccnl_nfn_thunk_already_computing(prefix)){ + DEBUGMSG(9, "Computation for this interest is already running\n"); + return -1; + } + char *res = NULL; + struct ccnl_prefix_s *original_prefix; + ccnl_nfn_copy_prefix(prefix, &original_prefix); int thunk_request = 0; int num_of_thunks = 0; @@ -86,15 +115,17 @@ ccnl_nfn_thread(void *arg) if(thunk_request){ num_of_thunks = ccnl_nfn_count_required_thunks(str); } - char *res = Krivine_reduction(ccnl, str, thunk_request, - &num_of_thunks, thread); +restart: + res = Krivine_reduction(ccnl, str, thunk_request, + &num_of_thunks, config, original_prefix); + //stores result if computed if(res){ DEBUGMSG(2,"Computation finshed: %s\n", res); - if(thunk_request){ - ccnl_nfn_remove_thunk_from_prefix(thread->prefix); + if(config && config->fox_state->thunk_request){ + ccnl_nfn_remove_thunk_from_prefix(config->prefix); } - struct ccnl_content_s *c = create_content_object(ccnl, thread->prefix, res, strlen(res)); + struct ccnl_content_s *c = create_content_object(ccnl, config->prefix, res, strlen(res)); c->flags = CCNL_CONTENT_FLAGS_STATIC; if(!thunk_request)ccnl_content_serve_pending(ccnl,c); @@ -107,68 +138,6 @@ ccnl_nfn_thread(void *arg) { ccnl_nfn_delete_prefix(prefix); }*/ - struct thread_s *thread1 = main_thread; - pthread_cond_broadcast(&thread1->cond); - pthread_exit ((void *) 0); - return 0; -} - -void -ccnl_nfn_send_signal(int threadid){ - DEBUGMSG(49, "ccnl_nfn_send_signal()\n"); - struct thread_s *thread = threads[threadid]; - pthread_cond_broadcast(&thread->cond); - struct thread_s *thread1 = main_thread; - pthread_cond_wait(&(thread1->cond), &thread1->mutex); -} - -int -ccnl_nfn_thunk_already_computing(struct ccnl_prefix_s *prefix) -{ - DEBUGMSG(49, "ccnl_nfn_thunk_already_computing()\n"); - int i = 0; - for(i = 0; i < -threadid; ++i){ - struct ccnl_prefix_s *copy; - struct thread_s *thread = threads[i]; - if(!thread) continue; - ccnl_nfn_copy_prefix(thread->prefix ,©); - ccnl_nfn_remove_thunk_from_prefix(copy); - if(!ccnl_prefix_cmp(copy, NULL, prefix, CMP_EXACT)){ - return 1; - } - - } - return 0; -} - -int -ccnl_nfn(struct ccnl_relay_s *ccnl, struct ccnl_buf_s *orig, - struct ccnl_prefix_s *prefix, struct ccnl_face_s *from) -{ - DEBUGMSG(49, "ccnl_nfn(%p, %p, %p, %p)\n", ccnl, orig, prefix, from); - - if(ccnl_nfn_thunk_already_computing(prefix)){ - DEBUGMSG(9, "Computation for this interest is already running\n"); - return -1; - } - struct ccnl_prefix_s *original_prefix; - ccnl_nfn_copy_prefix(prefix, &original_prefix); - struct thread_s *thread = new_thread(threadid, original_prefix); - struct thread_parameter_s *arg = malloc(sizeof(struct thread_parameter_s *)); - char *h = malloc(10); - arg->ccnl = ccnl; - arg->orig = orig; - arg->prefix = prefix; - arg->from = from; - arg->thread = thread; - - int threadpos = -threadid; - threads[threadpos] = thread; - --threadid; - DEBUGMSG(99, "New Thread with threadid %d\n", -arg->thread->id); - pthread_create(&thread->thread, NULL, ccnl_nfn_thread, (void *)arg); - struct thread_s *thread1 = main_thread; - pthread_cond_wait(&(thread1->cond), &thread1->mutex); return 0; } diff --git a/krivine-common.c b/krivine-common.c index 3d90f0a9b504..3bf010022ae9 100644 --- a/krivine-common.c +++ b/krivine-common.c @@ -10,7 +10,7 @@ #ifndef KRIVINE_COMMON_C #define KRIVINE_COMMON_C -//#include "krivine-common.h" +#include "krivine-common.h" #include "ccnl.h" #include "ccnx.h" @@ -18,52 +18,19 @@ #include "ccnl-pdu.c" -#include - - -#define NFN_FACE -1; struct configuration_s{ + int configid; char *prog; struct stack_s *result_stack; struct stack_s *argument_stack; struct environment_s *env; struct environment_s *global_dict; - struct thread_s *thread; -}; - -struct thread_s{ - int id; - pthread_cond_t cond; - pthread_mutex_t mutex; - pthread_t thread; - struct ccnl_prefix_s *prefix; -}; - -struct threads_s *threads[1024]; -struct threads_s *main_thread; -int threadid = -1; - -struct thread_parameter_s{ - struct ccnl_relay_s *ccnl; - struct ccnl_buf_s *orig; + struct fox_machine_state_s *fox_state; struct ccnl_prefix_s *prefix; - struct thread_s *thread; - struct ccnl_face_s *from; - }; -struct thread_s * -new_thread(int thread_id, struct ccnl_prefix_s *prefix){ - struct thread_s *t = malloc(sizeof(struct thread_s)); - t->id = thread_id; - t->cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER; - t->mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; - t->prefix = prefix; - return t; -} - struct thunk_s{ struct thunk_s *next, *prev; char thunkid[10]; @@ -73,6 +40,9 @@ struct thunk_s{ struct thunk_s *thunk_list; int thunkid = 0; +struct configuration_s *configuration_list[1024]; +int configid = -1; + int hex2int(char c) { @@ -246,17 +216,19 @@ mkContent(char **namecomp, struct ccnl_content_s * create_content_object(struct ccnl_relay_s *ccnl, struct ccnl_prefix_s *prefix, char *res, int reslen){ - + DEBUGMSG(49, "create_content_object()\n"); int i = 0; char *out = ccnl_malloc(CCNL_MAX_PACKET_SIZE); memset(out, 0, CCNL_MAX_PACKET_SIZE); char **prefixcomps = ccnl_malloc(sizeof(char *) * prefix->compcnt+1); prefixcomps[prefix->compcnt] = 0; + fprintf(stderr, "NAME: "); for(i = 0; i < prefix->compcnt; ++i) { + fprintf(stderr, "/%s", prefix->comp[i]); prefixcomps[i] = strdup(prefix->comp[i]); - } + } fprintf(stderr, "\n"); int len = mkContent(prefixcomps, NULL, 0, res, reslen, out); @@ -284,6 +256,7 @@ ccnl_nfn_local_content_search(struct ccnl_relay_s *ccnl, struct ccnl_interest_s for(c_iter = ccnl->contents; c_iter; c_iter = c_iter->next){ unsigned char *md; if(!ccnl_prefix_cmp(c_iter->name, NULL, i->prefix, CMP_EXACT)){ + i = ccnl_interest_remove(ccnl, i); return c_iter; } } @@ -387,22 +360,18 @@ ccnl_receive_content_synchronous(struct ccnl_relay_s *ccnl, struct ccnl_interest struct ccnl_content_s * ccnl_nfn_global_content_search(struct ccnl_relay_s *ccnl, struct configuration_s *config, struct ccnl_interest_s *interest){ - DEBUGMSG(2, "ccnl_nfn_global_content_search()\n"); - struct ccnl_content_s *c; - interest->from->faceid = config->thread->id; - ccnl_interest_propagate(ccnl, interest); - DEBUGMSG(99, "Waiting on Signal; Threadid : %d \n", -config->thread->id); - struct thread_s *thread1 = main_thread; - pthread_cond_broadcast(&thread1->cond); - pthread_cond_wait(&config->thread->cond, &config->thread->mutex); - //local search. look if content is now available! - DEBUGMSG(99,"Got signal CONTINUE\n"); + DEBUGMSG(2, "ccnl_nfn_global_content_search()\n"); + + //local search. look if content is available! if((c = ccnl_nfn_local_content_search(ccnl, interest)) != NULL){ DEBUGMSG(49, "Content now available: %s\n", c->content); return c; } + + interest->from->faceid = config->configid; + ccnl_interest_propagate(ccnl, interest); return NULL; } @@ -433,7 +402,7 @@ ccnl_nfn_create_interest_object(struct ccnl_relay_s *ccnl, struct configuration_ &maxsfx, &p, &nonce, &ppkd, &content, &contlen); struct ccnl_face_s * from = ccnl_malloc(sizeof(struct ccnl_face_s *)); - from->faceid = config->thread->id; + from->faceid = config->configid; from->last_used = CCNL_NOW(); from->outq = malloc(sizeof(struct ccnl_buf_s)); from->outq->data[0] = strdup(name); @@ -528,7 +497,7 @@ ccnl_nfn_resolve_thunk(struct ccnl_relay_s *ccnl, struct configuration_s *config interest->last_used = CCNL_NOW(); struct ccnl_content_s *c; if((c = ccnl_nfn_global_content_search(ccnl, config, interest)) != NULL){ - DEBUGMSG(49, "Thunk was resolved\n"); + DEBUGMSG(49, "Thunk was resolved: %s\n", c->content); return c; } } diff --git a/krivine-common.h b/krivine-common.h index 456af76d27bf..3755e8687805 100644 --- a/krivine-common.h +++ b/krivine-common.h @@ -10,6 +10,13 @@ #ifndef KRIVINE_COMMON_H #define KRIVINE_COMMON_H - +struct fox_machine_state_s{ + int num_of_params; + char **params; + int it_routable_param; + int thunk_request; + int num_of_required_thunks; + char *thunk; +}; #endif //KRIVINE_COMMON_H \ No newline at end of file diff --git a/krivine.c b/krivine.c index 8e6524d4cd24..1795726f61ce 100644 --- a/krivine.c +++ b/krivine.c @@ -40,14 +40,27 @@ new_closure(char *term, struct environment_s *env){ return ret; } +struct fox_machine_state_s * +new_machine_state(int thunk_request, int num_of_required_thunks){ + struct fox_machine_state_s *ret = malloc(sizeof(struct fox_machine_state_s)); + ret->thunk_request = thunk_request; + ret->num_of_required_thunks = num_of_required_thunks; + + return ret; +} + struct configuration_s * -new_config(char *prog, struct environment_s *global_dict){ +new_config(char *prog, struct environment_s *global_dict, int thunk_request, + int num_of_required_thunks, struct ccnl_prefix_s *prefix, int configid){ struct configuration_s *ret = malloc(sizeof(struct configuration_s)); ret->prog = prog; ret->result_stack = NULL; ret->argument_stack = NULL; ret->env = NULL; ret->global_dict = global_dict; + ret->fox_state = new_machine_state(thunk_request, num_of_required_thunks); + ret->configid = configid; + ret->prefix = prefix; return ret; } @@ -78,17 +91,27 @@ pop_from_stack(struct stack_s **top){ } char * -pop_or_resolve_from_result_stack(struct ccnl_relay_s *ccnl, struct configuration_s *config){ - char *res = (char*) pop_from_stack(&config->result_stack); - char *ret = res; +pop_or_resolve_from_result_stack(struct ccnl_relay_s *ccnl, struct configuration_s *config, + int *restart){ + char *res = NULL; + /*if(*restart){ + DEBUGMSG(99, "pop_or_resolve_from_result_stack: Check for content: %s \n", config->fox_state->thunk); + res = config->fox_state->thunk; + } + else{*/ + res = (char*) pop_from_stack(&config->result_stack); + //} struct ccnl_content_s *c; if(!strncmp(res, "THUNK", 5)){ - DEBUGMSG(49, "Resolve Thunk %s \n", res); - //resolve_thunk() + DEBUGMSG(49, "Resolve Thunk: %s \n", res); c = ccnl_nfn_resolve_thunk(ccnl, config, res); - ret = c->content; + if(c == NULL){ + push_to_stack(&config->result_stack, res); + return NULL; + } + res = c->content; } - return ret; + return res; } void @@ -281,19 +304,19 @@ int iscontent(char *cp){ //------------------------------------------------------------ struct ccnl_content_s * ccnl_nfn_handle_local_computation(struct ccnl_relay_s *ccnl, struct configuration_s *config, - char **params, int num_params, char **namecomp, char *out, char *comp, int thunk_request){ - int complen = sprintf(comp, "call %d ", num_params); + char **namecomp, char *out, char *comp, int *halt){ + int complen = sprintf(comp, "call %d ", config->fox_state->num_of_params); struct ccnl_interest_s * interest; struct ccnl_content_s *c; int i, len; DEBUGMSG(99, "ccnl_nfn_handle_local_computation()\n"); - for(i = 0; i < num_params; ++i){ - complen += sprintf(comp+complen, "%s ", params[i]); + for(i = 0; i < config->fox_state->num_of_params; ++i){ + complen += sprintf(comp+complen, "%s ", config->fox_state->params[i]); } i = 0; namecomp[i++] = "COMPUTE"; namecomp[i++] = strdup(comp); - if(thunk_request) namecomp[i++] = "THUNK"; + if(config->fox_state->thunk_request) namecomp[i++] = "THUNK"; namecomp[i++] = "NFN"; namecomp[i++] = NULL; len = mkInterest(namecomp, 0, out); @@ -308,48 +331,44 @@ ccnl_nfn_handle_local_computation(struct ccnl_relay_s *ccnl, struct configuratio return c; } //ccnl_interest_remove(ccnl, interest); + *halt = -1; return 0; } struct ccnl_content_s * -ccnl_nfn_handle_network_search(struct ccnl_relay_s *ccnl, struct configuration_s *config, int current_param, char **params, - int num_params, char **namecomp, char *out, char *comp, char *param, - int thunk_request){ +ccnl_nfn_handle_network_search(struct ccnl_relay_s *ccnl, struct configuration_s *config, + char **namecomp, char *out, char *comp, int *halt){ + struct ccnl_content_s *c; int j; - int complen = sprintf(comp, "(@x call %d ", num_params); + int complen = sprintf(comp, "(@x call %d ", config->fox_state->num_of_params); DEBUGMSG(2, "ccnl_nfn_handle_network_search()\n"); - for(j = 0; j < num_params; ++j){ - if(current_param == j){ + for(j = 0; j < config->fox_state->num_of_params; ++j){ + if(config->fox_state->it_routable_param == j){ complen += sprintf(comp + complen, "x "); } else{ - complen += sprintf(comp + complen, "%s ", params[j]); + complen += sprintf(comp + complen, "%s ", config->fox_state->params[j]); } } complen += sprintf(comp + complen, ")"); - DEBUGMSG(49, "Computation request: %s %s\n", comp, params[current_param]); + DEBUGMSG(49, "Computation request: %s %s\n", comp, config->fox_state->params[config->fox_state->it_routable_param]); //make interest - int len = mkInterestCompute(namecomp, comp, complen, thunk_request, out); //TODO: no thunk request for local search - free(param); + int len = mkInterestCompute(namecomp, comp, complen, config->fox_state->thunk_request, out); //TODO: no thunk request for local search //search struct ccnl_interest_s *interest = ccnl_nfn_create_interest_object(ccnl, config, out, len, namecomp[0]); //FIXME: NAMECOMP[0]??? - if((c = ccnl_nfn_local_content_search(ccnl, interest)) != NULL){ - DEBUGMSG(49, "Content locally found\n"); - //ccnl_interest_remove(ccnl, interest); - return c; - } - else if((c = ccnl_nfn_global_content_search(ccnl, config, interest)) != NULL){ + if((c = ccnl_nfn_global_content_search(ccnl, config, interest)) != NULL){ DEBUGMSG(49, "Content found in the network\n"); return c; } + *halt = -1; return NULL; } struct ccnl_content_s * -ccnl_nfn_handle_routable_content(struct ccnl_relay_s *ccnl, struct configuration_s *config, - int current_param, char **params, int num_params, int thunk_request){ +ccnl_nfn_handle_routable_content(struct ccnl_relay_s *ccnl, + struct configuration_s *config, int *halt){ char *out = ccnl_malloc(sizeof(char) * CCNL_MAX_PACKET_SIZE); char *comp = ccnl_malloc(sizeof(char) * CCNL_MAX_PACKET_SIZE); char *namecomp[CCNL_MAX_NAME_COMP]; @@ -359,20 +378,17 @@ ccnl_nfn_handle_routable_content(struct ccnl_relay_s *ccnl, struct configuration memset(comp, 0, CCNL_MAX_PACKET_SIZE); memset(out, 0, CCNL_MAX_PACKET_SIZE); - param = strdup(params[current_param]); + param = strdup(config->fox_state->params[config->fox_state->it_routable_param]); j = splitComponents(param, namecomp); if(isLocalAvailable(ccnl, config, namecomp)){ DEBUGMSG(49, "Routable content %s is local availabe --> start computation\n", - params[current_param]); - c = ccnl_nfn_handle_local_computation(ccnl, config, params, num_params, - namecomp, out, comp, thunk_request); + config->fox_state->params[config->fox_state->it_routable_param]); + c = ccnl_nfn_handle_local_computation(ccnl, config, namecomp, out, comp, halt); }else{ DEBUGMSG(49, "Routable content %s is not local availabe --> start search in the network\n", - params[current_param]); - c = ccnl_nfn_handle_network_search(ccnl, config, current_param, params, num_params, - namecomp, out, comp, param, thunk_request); - + config->fox_state->params[config->fox_state->it_routable_param]); + c = ccnl_nfn_handle_network_search(ccnl, config, namecomp, out, comp, halt); } return c; } @@ -380,7 +396,7 @@ ccnl_nfn_handle_routable_content(struct ccnl_relay_s *ccnl, struct configuration char* ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, int thunk_request, int *num_of_required_thunks, - int *halt, char *dummybuf) + int *halt, char *dummybuf, int *restart) { struct term_s *t; char *pending, *p, *cp; @@ -577,9 +593,9 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, char res[1000]; memset(res, 0, sizeof(res)); DEBUGMSG(2, "---to do: OP_CMPEQ <%s>/<%s>\n", cp, pending); - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); i1 = atoi(h); - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); i2 = atoi(h); acc = i1 == i2; cp = acc ? "@x@y x" : "@x@y y"; @@ -595,9 +611,9 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, char res[1000]; memset(res, 0, sizeof(res)); DEBUGMSG(2, "---to do: OP_CMPLEQ <%s>/%s\n", cp, pending); - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); i1 = atoi(h); - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); i2 = atoi(h); acc = i2 <= i1; cp = acc ? "@x@y x" : "@x@y y"; @@ -611,9 +627,18 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, int i1, i2, res; char *h; DEBUGMSG(2, "---to do: OP_ADD <%s>\n", prog+7); - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); + if(h == NULL){ + *halt = -1; + DEBUGMSG(99, "Add-Prog: %s\n", prog); + return prog; + } i1 = atoi(h); - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); + if(h == NULL){ + *halt = -1; + return prog; + } i2 = atoi(h); res = i1+i2; h = malloc(sizeof(char)*10); @@ -626,9 +651,9 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, int i1, i2, res; char *h; DEBUGMSG(2, "---to do: OP_SUB <%s>\n", prog+7); - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); i1 = atoi(h); - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); i2 = atoi(h); res = i2-i1; h = malloc(sizeof(char)*10); @@ -641,9 +666,9 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, int i1, i2, res; char *h; DEBUGMSG(2, "---to do: OP_MULT <%s>\n", prog+8); - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); i1 = atoi(h); - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); i2 = atoi(h); res = i1*i2; h = malloc(sizeof(char)*10); @@ -656,7 +681,7 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, char *h; int i, offset; char name[5]; - h = pop_or_resolve_from_result_stack(ccnl, config); + h = pop_or_resolve_from_result_stack(ccnl, config, restart); int num_params = atoi(h); memset(dummybuf, 0, sizeof(dummybuf)); sprintf(dummybuf, "CLOSURE(OP_FOX);RESOLVENAME(@op(");///x(/y y x 2 op)));TAILAPPLY"; @@ -678,30 +703,37 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, return strdup(dummybuf); } if(!strncmp(prog, "OP_FOX", 6)){ - char *h = pop_or_resolve_from_result_stack(ccnl, config); - int num_params = atoi(h); + if(*restart) { + *restart = 0; + goto recontinue; + } + char *h = pop_or_resolve_from_result_stack(ccnl, config, restart); + config->fox_state->num_of_params = atoi(h); int i; - char **params = malloc(sizeof(char * ) * num_params); + config->fox_state->params = malloc(sizeof(char * ) * config->fox_state->num_of_params); - for(i = 0; i < num_params; ++i){ //pop parameter from stack - params[i] = pop_or_resolve_from_result_stack(ccnl, config); + for(i = 0; i < config->fox_state->num_of_params; ++i){ //pop parameter from stack + config->fox_state->params[i] = pop_or_resolve_from_result_stack(ccnl, config, restart); } //as long as there is a routable parameter: try to find a result - for(i = num_params - 1; i >= 0; --i){ - if(iscontent(params[i])){ + config->fox_state->it_routable_param = config->fox_state->num_of_params - 1; +recontinue: + for(; config->fox_state->it_routable_param >= 0; --config->fox_state->it_routable_param){ + if(iscontent(config->fox_state->params[config->fox_state->it_routable_param])){ struct ccnl_content_s *c = ccnl_nfn_handle_routable_content(ccnl, - config, i, params, num_params, thunk_request); + config, halt); + if(*halt < 0) return prog; if(c){ if(thunk_request){ //if thunk_request push thunkid on the stack --(*num_of_required_thunks); - DEBUGMSG(99, "%d thunks are required\n", *num_of_required_thunks); char * thunkid = ccnl_nfn_add_thunk(ccnl, config, c->name); + DEBUGMSG(99, "Got thunk %s, now %d thunks are required\n", thunkid, *num_of_required_thunks); push_to_stack(&config->result_stack, thunkid); if( *num_of_required_thunks <= 0){ DEBUGMSG(99, "All thunks are available\n"); - ccnl_nfn_reply_thunk(ccnl, config->thread->prefix); + ccnl_nfn_reply_thunk(ccnl, config->prefix); } } else{ @@ -711,17 +743,19 @@ ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config, } }//endif }//endfor - DEBUGMSG(2, "Could not compute the result!\n"); + if(! *halt)DEBUGMSG(2, "Could not compute the result!\n"); return 0; tail: + DEBUGMSG(99, "Pending: %s\n", pending+1); return pending+1; } if(!strncmp(prog, "halt", 4)){ *halt = 1; + return pending; //FIXME: create string from stack, allow particular reduced - return config->result_stack->content; + //return config->result_stack->content; } DEBUGMSG(2, "unknown built-in command <%s>\n", prog); @@ -770,9 +804,12 @@ setup_global_environment(struct environment_s **env){ char * Krivine_reduction(struct ccnl_relay_s *ccnl, char *expression, int thunk_request, - int *num_of_required_thunks, struct thread_s *thread){ + int *num_of_required_thunks, struct configuration_s *config, + struct ccnl_prefix_s *prefix){ + int steps = 0; int halt = 0; + int restart = 1; int len = strlen("CLOSURE(halt);RESOLVENAME()") + strlen(expression); char *prog; struct environment_s *global_dict = NULL; @@ -781,15 +818,35 @@ Krivine_reduction(struct ccnl_relay_s *ccnl, char *expression, int thunk_request if(strlen(expression) == 0) return 0; prog = malloc(len*sizeof(char)); sprintf(prog, "CLOSURE(halt);RESOLVENAME(%s)", expression); - struct configuration_s *config = new_config(prog, global_dict); - config->thread = thread; - + if(!config){ + config = new_config(prog, global_dict, thunk_request, + *num_of_required_thunks ,prefix, configid); + restart = 0; + --configid; + } + DEBUGMSG(99, "Prog: %s\n", config->prog); + while (config->prog && !halt && config->prog != 1){ steps++; DEBUGMSG(1, "Step %d: %s\n", steps, config->prog); - config->prog = ZAM_term(ccnl, config, thunk_request, - num_of_required_thunks, &halt, dummybuf); + config->prog = ZAM_term(ccnl, config, config->fox_state->thunk_request, + &config->fox_state->num_of_required_thunks, &halt, dummybuf, &restart); + } + if(halt < 0){ + //put config in stack + configuration_list[-config->configid] = config; + DEBUGMSG(99,"Pause computation: %d\n", -config->configid); + DEBUGMSG(99, "Prog: %s %d\n", config->prog, config->fox_state->it_routable_param); + return 0; + } + else{ + free(dummybuf); + DEBUGMSG(99, "end\n"); + char *h = pop_or_resolve_from_result_stack(ccnl, config, &restart);//config->result_stack->content; + if(h == NULL){ + halt = -1; + return 0; + } + return h; } - free(dummybuf); - return pop_or_resolve_from_result_stack(ccnl, config);//config->result_stack->content; } \ No newline at end of file