int ccnl_interest_append_pending(struct ccnl_interest_s *i, struct ccnl_face_s *from) { struct ccnl_pendint_s *pi, *last = NULL; DEBUGMSG_CORE(TRACE, "ccnl_append_pending\n"); for (pi = i->pending; pi; pi = pi->next) { // check whether already listed if (pi->face == from) { DEBUGMSG_CORE(DEBUG, " we found a matching interest, updating time\n"); pi->last_used = CCNL_NOW(); return 0; } last = pi; } pi = (struct ccnl_pendint_s *) ccnl_calloc(1,sizeof(struct ccnl_pendint_s)); if (!pi) { DEBUGMSG_CORE(DEBUG, " no mem\n"); return -1; } DEBUGMSG_CORE(DEBUG, " appending a new pendint entry %p\n", (void *) pi); pi->face = from; pi->last_used = CCNL_NOW(); if (last) last->next = pi; else i->pending = pi; return 0; }
void ccnl_nfn_continue_computation(struct ccnl_relay_s *ccnl, int configid, int continue_from_remove){ DEBUGMSG(TRACE, "ccnl_nfn_continue_computation()\n"); struct configuration_s *config = ccnl_nfn_findConfig(ccnl->km->configuration_list, -configid); if(!config){ DEBUGMSG(DEBUG, "nfn_continue_computation: %d not found\n", configid); return; } //update original interest prefix to stay longer...reenable if propagate=0 do not protect interests struct ccnl_interest_s *original_interest; for(original_interest = ccnl->pit; original_interest; original_interest = original_interest->next){ if(!ccnl_prefix_cmp(config->prefix, 0, original_interest->prefix, CMP_EXACT)){ original_interest->last_used = CCNL_NOW(); original_interest->retries = 0; original_interest->from->last_used = CCNL_NOW(); break; } } if(config->thunk && CCNL_NOW() > config->endtime){ DEBUGMSG(INFO, "NFN: Exit computation: timeout when resolving thunk\n"); DBL_LINKED_LIST_REMOVE(ccnl->km->configuration_list, config); //Reply error! //config->thunk = 0; return; } ccnl_nfn(ccnl, NULL, NULL, config, NULL, 0, 0); }
struct ccnl_content_s* ccnl_content_new(struct ccnl_relay_s *ccnl, struct ccnl_pkt_s **pkt) { struct ccnl_content_s *c; // DEBUGMSG_CORE(TRACE, "ccnl_content_new %p <%s [%d]>\n", // (void*) *pkt, ccnl_prefix_to_path((*pkt)->pfx), ((*pkt)->pfx->chunknum)? *((*pkt)->pfx->chunknum) : -1); c = (struct ccnl_content_s *) ccnl_calloc(1, sizeof(struct ccnl_content_s)); if (!c) return NULL; c->pkt = *pkt; *pkt = NULL; c->last_used = CCNL_NOW(); c->recommended_cache_time = CCNL_NOW() + PUBLISHING_TIMEPERIOD; return c; }
void ccnl_do_ageing(void *ptr, void *dummy) { (void) dummy; struct ccnl_relay_s *relay = (struct ccnl_relay_s*) ptr; struct ccnl_content_s *c = relay->contents; struct ccnl_interest_s *i = relay->pit; struct ccnl_face_s *f = relay->faces; time_t t = CCNL_NOW(); DEBUGMSG_CORE(TRACE, "ageing t=%d\n", (int)t); while (c) { if ((c->last_used + CCNL_CONTENT_TIMEOUT) <= t && !(c->flags & CCNL_CONTENT_FLAGS_STATIC)){ DEBUGMSG_CORE(TRACE, "AGING: CONTENT REMOVE %p\n", (void*) c); c = ccnl_content_remove(relay, c); } else c = c->next; } while (i) { // CONFORM: "Entries in the PIT MUST timeout rather // than being held indefinitely." if ((i->last_used + CCNL_INTEREST_TIMEOUT) <= t || i->retries > CCNL_MAX_INTEREST_RETRANSMIT) { DEBUGMSG_CORE(TRACE, "AGING: INTEREST REMOVE %p\n", (void*) i); DEBUGMSG_CORE(DEBUG, " timeout: remove interest 0x%p <%s>\n", (void*)i, ccnl_prefix_to_path(i->pkt->pfx)); i = ccnl_nfn_interest_remove(relay, i); } else { // CONFORM: "A node MUST retransmit Interest Messages // periodically for pending PIT entries." DEBUGMSG_CORE(DEBUG, " retransmit %d <%s>\n", i->retries, ccnl_prefix_to_path(i->pkt->pfx)); #ifdef USE_NFN if (i->flags & CCNL_PIT_COREPROPAGATES){ #endif DEBUGMSG_CORE(TRACE, "AGING: PROPAGATING INTEREST %p\n", (void*) i); ccnl_interest_propagate(relay, i); #ifdef USE_NFN } #endif i->retries++; i = i->next; } } while (f) { if (!(f->flags & CCNL_FACE_FLAGS_STATIC) && (f->last_used + CCNL_FACE_TIMEOUT) <= t){ DEBUGMSG_CORE(TRACE, "AGING: FACE REMOVE %p\n", (void*) f); f = ccnl_face_remove(relay, f); } else f = f->next; } }
char* timestamp(void) { static char ts[30], *cp; sprintf(ts, "%.4g", CCNL_NOW()); cp = strchr(ts, '.'); if (!cp) strcat(ts, ".0000"); else if (strlen(cp) > 5) cp[5] = '\0'; else while (strlen(cp) < 5) strcat(cp, "0"); return ts; }
struct ccnl_content_s* ccnl_content_new(struct ccnl_relay_s *ccnl, struct ccnl_pkt_s **pkt) { struct ccnl_content_s *c; DEBUGMSG_CORE(TRACE, "ccnl_content_new %p <%s [%d]>\n", (void*) *pkt, ccnl_prefix_to_path((*pkt)->pfx), ((*pkt)->pfx->chunknum)? *((*pkt)->pfx->chunknum) : -1); c = (struct ccnl_content_s *) ccnl_calloc(1, sizeof(struct ccnl_content_s)); if (!c) return NULL; c->pkt = *pkt; *pkt = NULL; c->last_used = CCNL_NOW(); return c; }
struct ccnl_content_s * oldestCacheTimeExpiredContent(struct ccnl_relay_s *ccnl){ struct ccnl_content_s *cit; struct ccnl_content_s *cacheTimeExpiredContent = NULL; double leastCacheTimeLeft = 10; // set initial value to anything greater than zero because of first time entry into the if condition below double cacheTimeLeft =0; for (cit = ccnl->contents; cit; cit = cit->next) { cacheTimeLeft = cit->recommended_cache_time - CCNL_NOW(); // DEBUGMSG_CORE(DEBUG, " ICNIoT: RCT is %f, time now is %f cacheTimeLeft is %f\n",cit->recommended_cache_time, CCNL_NOW(), cacheTimeLeft); if ((cacheTimeLeft <= 0) && (leastCacheTimeLeft > cacheTimeLeft)){ DEBUGMSG_CORE(DEBUG, " ICNIoT: RCT cacheTime expired\n"); leastCacheTimeLeft = cacheTimeLeft; cacheTimeExpiredContent = cit; } } return cacheTimeExpiredContent; }
struct ccnl_interest_s* ccnl_interest_new(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from, struct ccnl_pkt_s **pkt) { struct ccnl_interest_s *i = (struct ccnl_interest_s *) ccnl_calloc(1, sizeof(struct ccnl_interest_s)); DEBUGMSG_CORE(TRACE, "ccnl_new_interest(prefix=%s, suite=%s)\n", ccnl_prefix_to_path((*pkt)->pfx), ccnl_suite2str((*pkt)->pfx->suite)); if (!i) return NULL; i->pkt = *pkt; *pkt = NULL; i->flags |= CCNL_PIT_COREPROPAGATES; i->from = from; i->last_used = CCNL_NOW(); DBL_LINKED_LIST_ADD(ccnl->pit, i); return i; }
struct ccnl_interest_s* ccnl_interest_new(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from, struct ccnl_pkt_s **pkt) { struct ccnl_interest_s *i = (struct ccnl_interest_s *) ccnl_calloc(1, sizeof(struct ccnl_interest_s)); DEBUGMSG_CORE(TRACE, "ccnl_new_interest\n"); // ccnl_prefix_to_path((*pkt)->pfx), // ccnl_suite2str((*pkt)->pfx->suite)); if (!i) return NULL; i->pkt = *pkt; *pkt = NULL; i->flags |= CCNL_PIT_COREPROPAGATES; i->from = from; i->last_used = CCNL_NOW(); DBL_LINKED_LIST_ADD(ccnl->pit, i); //akhila 16-10-2015 ccnl->pitcnt++; DEBUGMSG_CORE(TRACE, ": pit_entry_added:%d\n",ccnl->pitcnt); return i; }
struct ccnl_face_s* ccnl_get_face_or_create(struct ccnl_relay_s *ccnl, int ifndx, struct sockaddr *sa, int addrlen) // sa==NULL means: local(=in memory) client, search for existing ifndx being -1 // sa!=NULL && ifndx==-1: search suitable interface for given sa_family // sa!=NULL && ifndx!=-1: use this (incoming) interface for outgoing { static int seqno; int i; struct ccnl_face_s *f; DEBUGMSG_CORE(TRACE, "ccnl_get_face_or_create src=%s\n", ccnl_addr2ascii((sockunion*)sa)); for (f = ccnl->faces; f; f = f->next) { if (!sa) { if (f->ifndx == -1) return f; continue; } if (ifndx != -1 && !ccnl_addr_cmp(&f->peer, (sockunion*)sa)) { f->last_used = CCNL_NOW(); return f; } } if (sa && ifndx == -1) { for (i = 0; i < ccnl->ifcount; i++) { if (sa->sa_family != ccnl->ifs[i].addr.sa.sa_family) continue; ifndx = i; break; } if (ifndx == -1) // no suitable interface found return NULL; } DEBUGMSG_CORE(VERBOSE, " found suitable interface %d for %s\n", ifndx, ccnl_addr2ascii((sockunion*)sa)); f = (struct ccnl_face_s *) ccnl_calloc(1, sizeof(struct ccnl_face_s)); if (!f) { DEBUGMSG_CORE(VERBOSE, " no memory for face\n"); return NULL; } f->faceid = ++seqno; f->ifndx = ifndx; if (ifndx >= 0) { if (ccnl->defaultFaceScheduler) f->sched = ccnl->defaultFaceScheduler(ccnl, (void(*)(void*,void*))ccnl_face_CTS); if (ccnl->ifs[ifndx].reflect) f->flags |= CCNL_FACE_FLAGS_REFLECT; if (ccnl->ifs[ifndx].fwdalli) f->flags |= CCNL_FACE_FLAGS_FWDALLI; } if (sa) memcpy(&f->peer, sa, addrlen); else // local client f->ifndx = -1; f->last_used = CCNL_NOW(); DBL_LINKED_LIST_ADD(ccnl->faces, f); TRACEOUT(); return f; }
void ccnl_do_ageing(void *ptr, void *dummy) { struct ccnl_relay_s *relay = (struct ccnl_relay_s*) ptr; struct ccnl_content_s *c = relay->contents; struct ccnl_interest_s *i = relay->pit; struct ccnl_face_s *f = relay->faces; time_t t = CCNL_NOW(); char *bufp = NULL; DEBUGMSG_CORE(INFO, " ICNIoT: ageing t=%d\n", (int)t); while (c) { if ((c->last_used + CCNL_CONTENT_TIMEOUT) <= t && !(c->flags & CCNL_CONTENT_FLAGS_STATIC)){ DEBUGMSG_CORE(INFO, " ICNIoT: AGING: CONTENT REMOVE %p\n", (void*) c); c = ccnl_content_remove(relay, c); } else{ //akhila 29-10-2015 // check if it is the n th time instant. If yes then save the content store if ((((int)t)%CS_SAVE_PERIOD == 0) && !(c->flags & CCNL_CONTENT_FLAGS_STATIC)){ bufp = ccnl_prefix_to_path((c->pkt)->pfx); DEBUGMSG_CORE(INFO, " ICNIoT: ContentStoreItem :%s\n",bufp); ccnl_free(bufp); } c = c->next; } } if (((int)t)%CS_SAVE_PERIOD == 0){ DEBUGMSG_CORE(INFO, " ICNIoT: ContentStoreItem contentCount:%d\n",relay->contentcnt); } while (i) { // CONFORM: "Entries in the PIT MUST timeout rather // than being held indefinitely." if ((i->last_used + CCNL_INTEREST_TIMEOUT) <= t){ // if it has timed out either resend it or remove it based on MAX_RETRIES if(i->retries >= CCNL_MAX_INTEREST_RETRANSMIT){ DEBUGMSG_CORE(INFO, " ICNIoT: AGING: INTEREST REMOVE %p\n", (void*) i); // DEBUGMSG_CORE(DEBUG, " timeout: remove interest 0x%p <%s>\n",(void*)i,ccnl_prefix_to_path(i->pkt->pfx)); i = ccnl_nfn_interest_remove(relay, i); } else { // CONFORM: "A node MUST retransmit Interest Messages // periodically for pending PIT entries." DEBUGMSG_CORE(INFO, " ICNIoT: retransmit %d \n", i->retries); // ccnl_prefix_to_path(i->pkt->pfx)); #ifdef USE_NFN if (i->flags & CCNL_PIT_COREPROPAGATES){ #endif DEBUGMSG_CORE(INFO, " ICNIoT: AGING: PROPAGATING INTEREST %p\n", (void*) i); ccnl_interest_propagate(relay, i); #ifdef USE_NFN } #endif i->retries++; i = i->next; } } else{ // The interest has not timed out yet, so leave it alone ! // DEBUGMSG_CORE(INFO, " ICNIoT: AGING: DO NOTHING %p\n", (void*) i); i = i->next; } } // DEBUGMSG_CORE(INFO, " ICNIoT: PITcount %d\n",relay->pitcnt); while (f) { if (!(f->flags & CCNL_FACE_FLAGS_STATIC) && (f->last_used + CCNL_FACE_TIMEOUT) <= t){ DEBUGMSG_CORE(TRACE, "AGING: FACE REMOVE %p\n", (void*) f); f = ccnl_face_remove(relay, f); } else f = f->next; } }
int drop_this_pkt(struct ccnl_relay_s *relay, struct ccnl_face_s *from){ int drop = 0; #ifdef USE_LOSSY_LINKS int from_nodeID = findIntFromStr(ccnl_addr2ascii(from ? &from->peer : NULL),"/") - 9000; // NULL here means there is something wrong int my_nodeID = relay->nodeID; // DEBUGMSG_CORE(DEBUG, " ICNIoT: pkt received at node %d from node %d\n",my_nodeID, from_nodeID); int* ptr = relay->network_links_ptr; int j=0; int flag = 0; for(j=0;j<relay->num_of_links;j++){ if(((*(ptr + 2*j) == from_nodeID) && (*(ptr + 2*j +1) == my_nodeID)) || ((*(ptr + 2*j) == my_nodeID) && (*(ptr + 2*j +1) == from_nodeID))){// this implies that we are checking bidirectional links flag =1; break; } } if(flag==0){ // DEBUGMSG_CORE(DEBUG, " ICNIoT: This link is NOT a lossy link\n"); return 0; } // DEBUGMSG_CORE(DEBUG, " ICNIoT: This link is a lossy link\n"); double P[2][2]; P[0][0] = (double)1-(double)ALPHA; P[0][1] = (double)ALPHA; P[1][0] = (double)BETA; P[1][1] = (double)1-(double)BETA; // 100 ms is one step double val; int i=0; j=0; // int m=2; int n = (int)(((CCNL_NOW() - relay->last_pkt_recv_time)*(double)STEP_SCALE) + 1); // DEBUGMSG_CORE(DEBUG, " ICNIoT: number of steps passed since last pkt receive is %f - %f = %d\n",CCNL_NOW(),relay->last_pkt_recv_time,n); if (n > 20)// This 20 is because when n is large, due to loss of accuracy the P^n matrix either becomes all 0s or inf n=20; for(i=0;i<n;i++) squareOfMatrix(P); // printf("P^%d is \n",n); // for(i=0;i<m;i++){ // for(j=0;j<m;j++){ // printf("%f ",P[i][j]); // } // printf("\n"); // } val = P[relay->last_state][0]; // DEBUGMSG_CORE(DEBUG, " ICNIoT: current state is %d\n",relay->last_state); double rnd = (double)rand() / (double)((unsigned)RAND_MAX + 1); if(rnd < val) relay->last_state = 0; //update state else relay->last_state = 1; // update state rnd = (double)rand() / (double)((unsigned)RAND_MAX + 1); // DEBUGMSG_CORE(DEBUG, " ICNIoT: Next state is %d, using error rate = %f\n",relay->last_state, relay->linkErrProb[relay->last_state]); if(rnd < relay->linkErrProb[relay->last_state]) drop =1; relay->last_pkt_recv_time = CCNL_NOW(); #endif return drop; }
int ccnl_http_status(struct ccnl_relay_s *ccnl, struct ccnl_http_s *http) { static char txt[64000]; char *hdr = "HTTP/1.1 200 OK\n\r" "Content-Type: text/html; charset=utf-8\n\r" "Connection: close\n\r\n\r", *cp; int len = strlen(hdr), i, j, cnt; time_t t; struct utsname uts; struct ccnl_face_s *f; struct ccnl_forward_s *fwd; struct ccnl_interest_s *ipt; struct ccnl_buf_s *bpt; strcpy(txt, hdr); len += sprintf(txt+len, "<html><head><title>ccn-lite-relay status</title>\n" "<style type=\"text/css\">\n" "body {font-family: sans-serif;}\n" "</style>\n" "</head><body>\n"); len += sprintf(txt+len, "\n<table borders=0>\n<tr><td>" "<a href=\"\">[refresh]</a> <td>" "ccn-lite-relay Status Page "); uname(&uts); len += sprintf(txt+len, "node <strong>%s (%d)</strong>\n", uts.nodename, getpid()); t = time(NULL); cp = ctime(&t); cp[strlen(cp)-1] = 0; len += sprintf(txt+len, "<tr><td><td><font size=-1>%s ", cp); cp = ctime(&ccnl->startup_time); cp[strlen(cp)-1] = 0; len += sprintf(txt+len, " (started %s)</font>\n</table>\n", cp); len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>" "<tr><td><em>Forwarding Table</em></table><ul>\n"); for (fwd = ccnl->fib, cnt = 0; fwd; fwd = fwd->next, cnt++); if (cnt > 0) { struct ccnl_forward_s **fwda; fwda = (struct ccnl_forward_s**) ccnl_malloc(cnt * sizeof(fwd)); for (fwd = ccnl->fib, i = 0; fwd; fwd = fwd->next, i++) fwda[i] = fwd; qsort(fwda, cnt, sizeof(fwd), ccnl_cmpfib); for (i = 0; i < cnt; i++) { char fname[10]; sprintf(fname, "f%d", fwda[i]->face->faceid); len += sprintf(txt+len, "<li>via %4s: <font face=courier>%s</font>\n", fname, ccnl_prefix_to_path(fwda[i]->prefix)); } ccnl_free(fwda); } len += sprintf(txt+len, "</ul>\n"); len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>" "<tr><td><em>Faces</em></table><ul>\n"); for (f = ccnl->faces, cnt = 0; f; f = f->next, cnt++); if (cnt > 0) { struct ccnl_face_s **fa; fa = (struct ccnl_face_s**) ccnl_malloc(cnt * sizeof(f)); for (f = ccnl->faces, i = 0; f; f = f->next, i++) fa[i] = f; qsort(fa, cnt, sizeof(f), ccnl_cmpfaceid); for (i = 0; i < cnt; i++) { len += sprintf(txt+len, "<li><strong>f%d</strong> (via i%d) " "peer=<font face=courier>%s</font> ttl=", fa[i]->faceid, fa[i]->ifndx, ccnl_addr2ascii(&(fa[i]->peer))); if (fa[i]->flags & CCNL_FACE_FLAGS_STATIC) len += sprintf(txt+len, "static"); else len += sprintf(txt+len, "%.1fsec", fa[i]->last_used + CCNL_FACE_TIMEOUT - CCNL_NOW()); for (j = 0, bpt = fa[i]->outq; bpt; bpt = bpt->next, j++); len += sprintf(txt+len, " qlen=%d\n", j); } ccnl_free(fa); } len += sprintf(txt+len, "</ul>\n"); len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>" "<tr><td><em>Interfaces</em></table><ul>\n"); for (i = 0; i < ccnl->ifcount; i++) { len += sprintf(txt+len, "<li><strong>i%d</strong> " "addr=<font face=courier>%s</font> " "qlen=%d/%d\n", i, ccnl_addr2ascii(&ccnl->ifs[i].addr), ccnl->ifs[i].qlen, CCNL_MAX_IF_QLEN); } len += sprintf(txt+len, "</ul>\n"); len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>" "<tr><td><em>Misc stats</em></table><ul>\n"); for (cnt = 0, bpt = ccnl->nonces; bpt; bpt = bpt->next, cnt++); len += sprintf(txt+len, "<li>Nonces: %d\n", cnt); for (cnt = 0, ipt = ccnl->pit; ipt; ipt = ipt->next, cnt++); len += sprintf(txt+len, "<li>Pending interests: %d\n", cnt); len += sprintf(txt+len, "<li>Content chunks: %d (max=%d)\n", ccnl->contentcnt, ccnl->max_cache_entries); len += sprintf(txt+len, "</ul>\n"); len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>" "<tr><td><em>Config</em></table><table borders=0>\n"); len += sprintf(txt+len, "<tr><td>content.timeout:" "<td align=right> %d<td>\n", CCNL_CONTENT_TIMEOUT); len += sprintf(txt+len, "<tr><td>face.timeout:" "<td align=right> %d<td>\n", CCNL_FACE_TIMEOUT); len += sprintf(txt+len, "<tr><td>interest.maxretransmit:" "<td align=right> %d<td>\n", CCNL_MAX_INTEREST_RETRANSMIT); len += sprintf(txt+len, "<tr><td>interest.timeout:" "<td align=right> %d<td>\n", CCNL_INTEREST_TIMEOUT); len += sprintf(txt+len, "<tr><td>nonces.max:" "<td align=right> %d<td>\n", CCNL_MAX_NONCES); len += sprintf(txt+len, "<tr><td>compile.featureset:<td><td> %s\n", compile_string()); len += sprintf(txt+len, "<tr><td>compile.time:" "<td><td>%s %s\n", __DATE__, __TIME__); len += sprintf(txt+len, "<tr><td>compile.ccnl_core_version:" "<td><td>%s\n", CCNL_VERSION); len += sprintf(txt+len, "</table>\n"); len += sprintf(txt+len, "\n<p><hr></body></html>\n"); http->out = (unsigned char*) txt; http->outoffs = 0; http->outlen = len; return 0; }