void ccnl_ll_TX(struct ccnl_relay_s *relay, struct ccnl_if_s *ifc, sockunion *dst, struct ccnl_buf_s *buf) { struct ccnl_ethernet_s *p; int cnt; for (cnt = 0, p = etherqueue; p; p = p->next, cnt++); DEBUGMSG(TRACE, "eth(simu)_ll_TX to %s len=%d (qlen=%d) [0x%02x 0x%02x]\n", ccnl_addr2ascii(dst), buf->datalen, cnt, buf->data[0], buf->data[1]); DEBUGMSG(TRACE, " src=%s\n", ccnl_addr2ascii(&ifc->addr)); p = ccnl_calloc(1, sizeof(*p) + 2*ETH_ALEN + buf->datalen); p->dst = (unsigned char*)p + sizeof(*p); p->src = (unsigned char*)p + sizeof(*p) + ETH_ALEN; p->data = (unsigned char*)p + sizeof(*p) + 2*ETH_ALEN; p->len = buf->datalen; memcpy(p->dst, dst->eth.sll_addr, ETH_ALEN); p->protocol = dst->eth.sll_protocol; memcpy(p->src, ifc->addr.eth.sll_addr, ETH_ALEN); memcpy(p->data, buf->data, buf->datalen); // prepend p->next = etherqueue; etherqueue = p; }
int get_interface_dump(int lev, void *p, int *ifndx, char **addr, long *dev, int *devtype, int *reflect) { struct ccnl_relay_s *top = (struct ccnl_relay_s *) p; int k; for (k = 0; k < top->ifcount; k++) { // INDENT(lev+1); ifndx[k] = k; // sprintf(addr[k], ccnl_addr2ascii(&top->ifs[k].addr)); strcpy(addr[k], ccnl_addr2ascii(&top->ifs[k].addr)); #ifdef CCNL_LINUXKERNEL if (top->ifs[k].addr.sa.sa_family == AF_PACKET) { dev[k] = (long) (void *) top->ifs[k].netdev; //%p devtype[k] = 1; } else { dev[k] = (long) (void *) top->ifs[k].sock; //%p devtype[k] = 2; } #else dev[k] = (long) top->ifs[k].sock; devtype[k] = 3; #endif if (top->ifs[k].reflect) reflect[k] = top->ifs[k].reflect; } return top->ifcount; }
void ccnl_core_RX(struct ccnl_relay_s *relay, int ifndx, unsigned char *data, int datalen, struct sockaddr *sa, int addrlen) { unsigned char *base = data; struct ccnl_face_s *from; int enc, suite = -1, skip; dispatchFct dispatch; (void) base; // silence compiler warning (if USE_DEBUG is not set) DEBUGMSG_CORE(DEBUG, "ccnl_core_RX ifndx=%d, %d bytes\n", ifndx, datalen); // DEBUGMSG_ON(DEBUG, "ccnl_core_RX ifndx=%d, %d bytes\n", ifndx, datalen); #ifdef USE_STATS if (ifndx >= 0) relay->ifs[ifndx].rx_cnt++; #endif from = ccnl_get_face_or_create(relay, ifndx, sa, addrlen); if (!from) { DEBUGMSG_CORE(DEBUG, " no face\n"); return; } else { DEBUGMSG_CORE(DEBUG, " face %d, peer=%s\n", from->faceid, ccnl_addr2ascii(&from->peer)); } // loop through all packets in the received frame (UDP, Ethernet etc) while (datalen > 0) { // work through explicit code switching while (!ccnl_switch_dehead(&data, &datalen, &enc)) suite = ccnl_enc2suite(enc); if (suite == -1) suite = ccnl_pkt2suite(data, datalen, &skip); if (!ccnl_isSuite(suite)) { DEBUGMSG_CORE(WARNING, "?unknown packet format? ccnl_core_RX ifndx=%d, %d bytes starting with 0x%02x at offset %zd\n", ifndx, datalen, *data, data - base); return; } // dispatch = ccnl_core_RX_dispatch[suite]; dispatch = ccnl_core_suites[suite].RX; if (!dispatch) { DEBUGMSG_CORE(ERROR, "Forwarder not initialized or dispatcher " "for suite %s does not exist.\n", ccnl_suite2str(suite)); return; } if (dispatch(relay, from, &data, &datalen) < 0) break; if (datalen > 0) { DEBUGMSG_CORE(WARNING, "ccnl_core_RX: %d bytes left\n", datalen); } } }
int get_faces_dump(int lev, void *p, int *faceid, long *next, long *prev, int *ifndx, int *flags, char **peer, int *type, char **frag) { struct ccnl_relay_s *top = (struct ccnl_relay_s *) p; struct ccnl_face_s *fac = (struct ccnl_face_s *) top->faces; int line = 0; while (fac) { // INDENT(lev); faceid[line] = fac->faceid; next[line] = (long)(void *) fac->next; prev[line] = (long)(void *) fac->prev; ifndx[line] = fac->ifndx; flags[line] = fac->flags; sprintf(peer[line], "%s", ccnl_addr2ascii(&fac->peer)); if (0) {} #ifdef USE_IPV4 if (fac->peer.sa.sa_family == AF_INET) type[line] = AF_INET; #endif #ifdef USE_IPV6 if (fac->peer.sa.sa_family == AF_INET6) type[line] = AF_INET6; #endif #ifdef USE_LINKLAYER else if (fac->peer.sa.sa_family == AF_PACKET) type[line] = AF_PACKET; #endif #ifdef USE_UNIXSOCKET else if (fac->peer.sa.sa_family == AF_UNIX) type[line] = AF_UNIX; #endif else type[line] = 0; #ifdef USE_FRAG if (fac->frag) sprintf(frag[line], "fragproto=%s mtu=%d", frag_protocol(fac->frag->protocol), fac->frag->mtu); else #endif frag[line][0] = '\0'; fac = fac->next; ++line; } return line; }
void ccnl_frag_reset(struct ccnl_frag_s *e, struct ccnl_buf_s *buf, int ifndx, sockunion *dst) { DEBUGMSG_EFRA(VERBOSE, "ccnl_frag_reset if=%d (%d bytes) dst=%s\n", ifndx, buf ? buf->datalen : -1, ccnl_addr2ascii(dst)); if (!e) return; e->ifndx = ifndx; memcpy(&e->dest, dst, sizeof(*dst)); ccnl_free(e->bigpkt); e->bigpkt = buf; if (buf) e->outsuite = ccnl_pkt2suite(buf->data, buf->datalen, 0); e->sendoffs = 0; }
void ccnl_relay_udp(struct ccnl_relay_s *relay, int port) { struct ccnl_if_s *i; if (port < 0) return; i = &relay->ifs[relay->ifcount]; i->sock = ccnl_open_udpdev(port, &i->addr.ip4); if (i->sock <= 0) { DEBUGMSG(WARNING, "sorry, could not open udp device (port %d)\n", port); return; } // i->frag = CCNL_DGRAM_FRAG_NONE; #ifdef USE_SUITE_CCNB if (suite == CCNL_SUITE_CCNB) i->mtu = CCN_DEFAULT_MTU; #endif #ifdef USE_SUITE_CCNTLV if (suite == CCNL_SUITE_CCNTLV) i->mtu = CCN_DEFAULT_MTU; #endif #ifdef USE_SUITE_NDNTLV if (suite == CCNL_SUITE_NDNTLV) i->mtu = NDN_DEFAULT_MTU; #endif i->fwdalli = 1; relay->ifcount++; DEBUGMSG(INFO, "UDP interface (%s) configured\n", ccnl_addr2ascii(&i->addr)); if (relay->defaultInterfaceScheduler) i->sched = relay->defaultInterfaceScheduler(relay, ccnl_interface_CTS); }
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; }
// deliver new content c to all clients with (loosely) matching interest, // but only one copy per face // returns: number of forwards int ccnl_content_serve_pending(struct ccnl_relay_s *ccnl, struct ccnl_content_s *c) { struct ccnl_interest_s *i; struct ccnl_face_s *f; int cnt = 0; DEBUGMSG_CORE(TRACE, "ccnl_content_serve_pending\n"); for (f = ccnl->faces; f; f = f->next){ f->flags &= ~CCNL_FACE_FLAGS_SERVED; // reply on a face only once } for (i = ccnl->pit; i;) { struct ccnl_pendint_s *pi; if (!i->pkt->pfx) continue; switch (i->pkt->pfx->suite) { #ifdef USE_SUITE_CCNB case CCNL_SUITE_CCNB: if (!ccnl_i_prefixof_c(i->pkt->pfx, i->pkt->s.ccnb.minsuffix, i->pkt->s.ccnb.maxsuffix, c)) { // XX must also check i->ppkd i = i->next; continue; } break; #endif #ifdef USE_SUITE_CCNTLV case CCNL_SUITE_CCNTLV: if (ccnl_prefix_cmp(c->pkt->pfx, NULL, i->pkt->pfx, CMP_EXACT)) { // XX must also check keyid i = i->next; continue; } break; #endif #ifdef USE_SUITE_CISTLV case CCNL_SUITE_CISTLV: if (ccnl_prefix_cmp(c->pkt->pfx, NULL, i->pkt->pfx, CMP_EXACT)) { // XX must also check keyid i = i->next; continue; } break; #endif #ifdef USE_SUITE_IOTTLV case CCNL_SUITE_IOTTLV: if (ccnl_prefix_cmp(c->pkt->pfx, NULL, i->pkt->pfx, CMP_EXACT)) { // XX must also check keyid i = i->next; continue; } break; #endif #ifdef USE_SUITE_NDNTLV case CCNL_SUITE_NDNTLV: if (!ccnl_i_prefixof_c(i->pkt->pfx, i->pkt->s.ndntlv.minsuffix, i->pkt->s.ndntlv.maxsuffix, c)) { // XX must also check i->ppkl, i = i->next; continue; } break; #endif default: i = i->next; continue; } //Hook for add content to cache by callback: if(i && ! i->pending){ DEBUGMSG_CORE(WARNING, "releasing interest 0x%p OK?\n", (void*)i); c->flags |= CCNL_CONTENT_FLAGS_STATIC; i = ccnl_interest_remove(ccnl, i); return 1; } // CONFORM: "Data MUST only be transmitted in response to // an Interest that matches the Data." for (pi = i->pending; pi; pi = pi->next) { if (pi->face->flags & CCNL_FACE_FLAGS_SERVED) continue; pi->face->flags |= CCNL_FACE_FLAGS_SERVED; if (pi->face->ifndx >= 0) { DEBUGMSG_CFWD(INFO, " outgoing data=<%s>%s to=%s\n", ccnl_prefix_to_path(i->pkt->pfx), ccnl_suite2str(i->pkt->pfx->suite), ccnl_addr2ascii(&pi->face->peer)); DEBUGMSG_CORE(VERBOSE, " Serve to face: %d (pkt=%p)\n", pi->face->faceid, (void*) c->pkt); ccnl_nfn_monitor(ccnl, pi->face, c->pkt->pfx, c->pkt->content, c->pkt->contlen); ccnl_face_enqueue(ccnl, pi->face, buf_dup(c->pkt->buf)); } else {// upcall to deliver content to local client ccnl_app_RX(ccnl, c); } c->served_cnt++; cnt++; } i = ccnl_interest_remove(ccnl, i); } return cnt; }
void ccnl_interest_propagate(struct ccnl_relay_s *ccnl, struct ccnl_interest_s *i) { struct ccnl_forward_s *fwd; int rc = 0; #ifdef USE_NACK int matching_face = 0; #endif if (!i) return; DEBUGMSG_CORE(DEBUG, "ccnl_interest_propagate\n"); // CONFORM: "A node MUST implement some strategy rule, even if it is only to // transmit an Interest Message on all listed dest faces in sequence." // CCNL strategy: we forward on all FWD entries with a prefix match for (fwd = ccnl->fib; fwd; fwd = fwd->next) { if (!fwd->prefix) continue; //Only for matching suite if (!i->pkt->pfx || fwd->suite != i->pkt->pfx->suite) { DEBUGMSG_CORE(VERBOSE, " not same suite (%d/%d)\n", fwd->suite, i->pkt->pfx ? i->pkt->pfx->suite : -1); continue; } rc = ccnl_prefix_cmp(fwd->prefix, NULL, i->pkt->pfx, CMP_LONGEST); DEBUGMSG_CORE(DEBUG, " ccnl_interest_propagate, rc=%d/%d\n", rc, fwd->prefix->compcnt); if (rc < fwd->prefix->compcnt) continue; DEBUGMSG_CORE(DEBUG, " ccnl_interest_propagate, fwd==%p\n", (void*)fwd); // suppress forwarding to origin of interest, except wireless if (!i->from || fwd->face != i->from || (i->from->flags & CCNL_FACE_FLAGS_REFLECT)) { DEBUGMSG_CFWD(INFO, " outgoing interest=<%s> to=%s\n", ccnl_prefix_to_path(i->pkt->pfx), fwd->face ? ccnl_addr2ascii(&fwd->face->peer) : "<tap>"); ccnl_nfn_monitor(ccnl, fwd->face, i->pkt->pfx, NULL, 0); // DEBUGMSG(DEBUG, "%p %p %p\n", (void*)i, (void*)i->pkt, (void*)i->pkt->buf); if (fwd->tap) (fwd->tap)(ccnl, i->from, i->pkt->pfx, i->pkt->buf); if (fwd->face) ccnl_face_enqueue(ccnl, fwd->face, buf_dup(i->pkt->buf)); #ifdef USE_NACK matching_face = 1; #endif } else { DEBUGMSG_CORE(DEBUG, " not forwarded\n"); } } #ifdef USE_NACK if(!matching_face){ ccnl_nack_reply(ccnl, i->pkt->pfx, i->from, i->pkt->pfx->suite); ccnl_interest_remove(ccnl, i); } #endif return; }
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; }
void ccnl_relay_config(struct ccnl_relay_s *relay, char *ethdev, int udpport, int tcpport, char *uxpath, int max_cache_entries, char *crypto_face_path) { struct ccnl_if_s *i; char h[1024]; DEBUGMSG(99, "ccnl_relay_config\n"); relay->max_cache_entries = max_cache_entries; #ifdef USE_SCHEDULER relay->defaultFaceScheduler = ccnl_relay_defaultFaceScheduler; relay->defaultInterfaceScheduler = ccnl_relay_defaultInterfaceScheduler; #endif #ifdef USE_ETHERNET // add (real) eth0 interface with index 0: if (ethdev) { i = &relay->ifs[relay->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++; DEBUGMSG(99, "new ETH interface (%s %s) configured\n", ethdev, ccnl_addr2ascii(&i->addr)); if (relay->defaultInterfaceScheduler) i->sched = relay->defaultInterfaceScheduler(relay, ccnl_interface_CTS); } else fprintf(stderr, "sorry, could not open eth device\n"); } #endif // USE_ETHERNET if (udpport > 0) { i = &relay->ifs[relay->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++; DEBUGMSG(99, "new UDP interface (ip4 %s) configured\n", ccnl_addr2ascii(&i->addr)); if (relay->defaultInterfaceScheduler) i->sched = relay->defaultInterfaceScheduler(relay, ccnl_interface_CTS); } else fprintf(stderr, "sorry, could not open udp device\n"); } #ifdef USE_HTTP_STATUS if (tcpport) { relay->http = ccnl_http_new(relay, tcpport); } #endif // USE_HTTP_STATUS #ifdef USE_UNIXSOCKET if (uxpath) { i = &relay->ifs[relay->ifcount]; i->sock = ccnl_open_unixpath(uxpath, &i->addr.ux); i->mtu = 4096; if (i->sock >= 0) { relay->ifcount++; DEBUGMSG(99, "new UNIX interface (%s) configured\n", ccnl_addr2ascii(&i->addr)); if (relay->defaultInterfaceScheduler) i->sched = relay->defaultInterfaceScheduler(relay, ccnl_interface_CTS); } else fprintf(stderr, "sorry, could not open unix datagram device\n"); } #ifdef USE_SIGNATURES if(crypto_face_path) { //sending interface + face i = &relay->ifs[relay->ifcount]; i->sock = ccnl_open_unixpath(crypto_face_path, &i->addr.ux); i->mtu = 4096; if (i->sock >= 0) { relay->ifcount++; DEBUGMSG(99, "new UNIX interface (%s) configured\n", ccnl_addr2ascii(&i->addr)); if (relay->defaultInterfaceScheduler) i->sched = relay->defaultInterfaceScheduler(relay, ccnl_interface_CTS); ccnl_crypto_create_ccnl_crypto_face(relay, crypto_face_path); relay->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->sock = ccnl_open_unixpath(h, &i->addr.ux); i->mtu = 4096; if (i->sock >= 0) { relay->ifcount++; DEBUGMSG(99, "new UNIX interface (%s) configured\n", ccnl_addr2ascii(&i->addr)); if (relay->defaultInterfaceScheduler) i->sched = relay->defaultInterfaceScheduler(relay, ccnl_interface_CTS); //create_ccnl_crypto_face(relay, crypto_face_path); } else fprintf(stderr, "sorry, could not open unix datagram device\n"); } #endif //USE_SIGNATURES #endif // USE_UNIXSOCKET ccnl_set_timer(1000000, ccnl_ageing, relay, 0); }
void ccnl_relay_config(struct ccnl_relay_s *relay, char *ethdev, int udpport1, int udpport2, int httpport, char *uxpath, int suite, int max_cache_entries, char *crypto_face_path) { #if defined(USE_LINKLAYER) || defined(USE_UNIXSOCKET) struct ccnl_if_s *i; #endif DEBUGMSG(INFO, "configuring relay\n"); relay->max_cache_entries = max_cache_entries; #ifdef USE_SCHEDULER relay->defaultFaceScheduler = ccnl_relay_defaultFaceScheduler; relay->defaultInterfaceScheduler = ccnl_relay_defaultInterfaceScheduler; #endif #ifdef USE_LINKLAYER // add (real) eth0 interface with index 0: if (ethdev) { i = &relay->ifs[relay->ifcount]; i->sock = ccnl_open_ethdev(ethdev, &i->addr.linklayer, CCNL_ETH_TYPE); i->mtu = 1500; i->reflect = 1; i->fwdalli = 1; if (i->sock >= 0) { relay->ifcount++; DEBUGMSG(INFO, "ETH interface (%s %s) configured\n", ethdev, ccnl_addr2ascii(&i->addr)); if (relay->defaultInterfaceScheduler) i->sched = relay->defaultInterfaceScheduler(relay, ccnl_interface_CTS); } else DEBUGMSG(WARNING, "sorry, could not open eth device\n"); } #endif // USE_LINKLAYER #ifdef USE_IPV4 ccnl_relay_udp(relay, udpport1); ccnl_relay_udp(relay, udpport2); #endif #ifdef USE_HTTP_STATUS if (httpport > 0) { relay->http = ccnl_http_new(relay, httpport); } #endif // USE_HTTP_STATUS #ifdef USE_NFN relay->km = ccnl_calloc(1, sizeof(struct ccnl_krivine_s)); relay->km->configid = -1; #endif #ifdef USE_UNIXSOCKET if (uxpath) { i = &relay->ifs[relay->ifcount]; i->sock = ccnl_open_unixpath(uxpath, &i->addr.ux); i->mtu = 4096; if (i->sock >= 0) { relay->ifcount++; DEBUGMSG(INFO, "UNIX interface (%s) configured\n", ccnl_addr2ascii(&i->addr)); if (relay->defaultInterfaceScheduler) i->sched = relay->defaultInterfaceScheduler(relay, ccnl_interface_CTS); } else DEBUGMSG(WARNING, "sorry, could not open unix datagram device\n"); } #ifdef USE_SIGNATURES if(crypto_face_path) { char h[1024]; //sending interface + face i = &relay->ifs[relay->ifcount]; i->sock = ccnl_open_unixpath(crypto_face_path, &i->addr.ux); i->mtu = 4096; if (i->sock >= 0) { relay->ifcount++; DEBUGMSG(INFO, "new UNIX interface (%s) configured\n", ccnl_addr2ascii(&i->addr)); if (relay->defaultInterfaceScheduler) i->sched = relay->defaultInterfaceScheduler(relay, ccnl_interface_CTS); ccnl_crypto_create_ccnl_crypto_face(relay, crypto_face_path); relay->crypto_path = crypto_face_path; } else DEBUGMSG(WARNING, "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->sock = ccnl_open_unixpath(h, &i->addr.ux); i->mtu = 4096; if (i->sock >= 0) { relay->ifcount++; DEBUGMSG(INFO, "new UNIX interface (%s) configured\n", ccnl_addr2ascii(&i->addr)); if (relay->defaultInterfaceScheduler) i->sched = relay->defaultInterfaceScheduler(relay, ccnl_interface_CTS); //create_ccnl_crypto_face(relay, crypto_face_path); } else DEBUGMSG(WARNING, "sorry, could not open unix datagram device\n"); } #endif //USE_SIGNATURES #endif // USE_UNIXSOCKET ccnl_set_timer(1000000, ccnl_ageing, relay, 0); }
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; }
void ccnl_dump(int lev, int typ, void *p) { struct ccnl_buf_s *buf = (struct ccnl_buf_s *) p; struct ccnl_prefix_s *pre = (struct ccnl_prefix_s *) p; struct ccnl_relay_s *top = (struct ccnl_relay_s *) p; struct ccnl_face_s *fac = (struct ccnl_face_s *) p; #ifdef USE_FRAG struct ccnl_frag_s *frg = (struct ccnl_frag_s *) p; #endif struct ccnl_forward_s *fwd = (struct ccnl_forward_s *) p; struct ccnl_interest_s *itr = (struct ccnl_interest_s *) p; struct ccnl_pendint_s *pir = (struct ccnl_pendint_s *) p; struct ccnl_pkt_s *pkt = (struct ccnl_pkt_s *) p; struct ccnl_content_s *con = (struct ccnl_content_s *) p; int i, k; #define INDENT(lev) for (i = 0; i < lev; i++) CONSOLE(" ") switch(typ) { case CCNL_BUF: while (buf) { INDENT(lev); CONSOLE("%p BUF len=%zd next=%p\n", (void *) buf, buf->datalen, (void *) buf->next); buf = buf->next; } break; case CCNL_PREFIX: INDENT(lev); CONSOLE("%p PREFIX len=%d val=%s\n", (void *) pre, pre->compcnt, ccnl_prefix_to_path(pre)); break; case CCNL_RELAY: INDENT(lev); CONSOLE("%p RELAY\n", (void *) top); lev++; INDENT(lev); CONSOLE("interfaces:\n"); for (k = 0; k < top->ifcount; k++) { INDENT(lev+1); CONSOLE("ifndx=%d addr=%s", k, ccnl_addr2ascii(&top->ifs[k].addr)); #ifdef CCNL_LINUXKERNEL if (top->ifs[k].addr.sa.sa_family == AF_PACKET) CONSOLE(" netdev=%p", top->ifs[k].netdev); else CONSOLE(" sockstruct=%p", top->ifs[k].sock); #elif !defined(CCNL_RIOT) CONSOLE(" sock=%d", top->ifs[k].sock); #endif if (top->ifs[k].reflect) CONSOLE(" reflect=%d", top->ifs[k].reflect); CONSOLE("\n"); } if (top->faces) { INDENT(lev); CONSOLE("faces:\n"); ccnl_dump(lev+1, CCNL_FACE, top->faces); } if (top->fib) { INDENT(lev); CONSOLE("fib:\n"); ccnl_dump(lev+1, CCNL_FWD, top->fib); } if (top->pit) { INDENT(lev); CONSOLE("pit:\n"); ccnl_dump(lev+1, CCNL_INTEREST, top->pit); } if (top->contents) { INDENT(lev); CONSOLE("contents:\n"); ccnl_dump(lev+1, CCNL_CONTENT, top->contents); } break; case CCNL_FACE: while (fac) { INDENT(lev); CONSOLE("%p FACE id=%d next=%p prev=%p ifndx=%d flags=%02x", (void*) fac, fac->faceid, (void *) fac->next, (void *) fac->prev, fac->ifndx, fac->flags); if (0) {} #ifdef USE_IPV4 else if (fac->peer.sa.sa_family == AF_INET) CONSOLE(" ip=%s", ccnl_addr2ascii(&fac->peer)); #endif #ifdef USE_IPV6 else if (fac->peer.sa.sa_family == AF_INET6) CONSOLE(" ip=%s", ccnl_addr2ascii(&fac->peer)); #endif #ifdef USE_LINKLAYER else if (fac->peer.sa.sa_family == AF_PACKET) CONSOLE(" eth=%s", ccnl_addr2ascii(&fac->peer)); #endif #ifdef USE_WPAN else if (fac->peer.sa.sa_family == AF_IEEE802154) CONSOLE(" wpan=%s", ccnl_addr2ascii(&fac->peer)); #endif #ifdef USE_UNIXSOCKET else if (fac->peer.sa.sa_family == AF_UNIX) CONSOLE(" ux=%s", ccnl_addr2ascii(&fac->peer)); #endif else CONSOLE(" peer=?"); if (fac->frag) ccnl_dump(lev+2, CCNL_FRAG, fac->frag); CONSOLE("\n"); if (fac->outq) { INDENT(lev+1); CONSOLE("outq:\n"); ccnl_dump(lev+2, CCNL_BUF, fac->outq); } fac = fac->next; } break; #ifdef USE_FRAG case CCNL_FRAG: CONSOLE(" fragproto=%s mtu=%d", frag_protocol(frg->protocol), frg->mtu); break; #endif case CCNL_FWD: while (fwd) { INDENT(lev); CONSOLE("%p FWD next=%p face=%p (id=%d suite=%s)\n", (void *) fwd, (void *) fwd->next, (void *) fwd->face, fwd->face->faceid, ccnl_suite2str(fwd->suite)); ccnl_dump(lev+1, CCNL_PREFIX, fwd->prefix); fwd = fwd->next; } break; case CCNL_INTEREST: while (itr) { INDENT(lev); CONSOLE("%p INTEREST next=%p prev=%p last=%d retries=%d\n", (void *) itr, (void *) itr->next, (void *) itr->prev, itr->last_used, itr->retries); ccnl_dump(lev+1, CCNL_PACKET, itr->pkt); if (itr->pending) { INDENT(lev+1); CONSOLE("pending:\n"); ccnl_dump(lev+2, CCNL_PENDINT, itr->pending); } itr = itr->next; } break; case CCNL_PENDINT: while (pir) { INDENT(lev); CONSOLE("%p PENDINT next=%p face=%p last=%d\n", (void *) pir, (void *) pir->next, (void *) pir->face, pir->last_used); pir = pir->next; } break; case CCNL_PACKET: INDENT(lev); CONSOLE("%p PACKET %s typ=%d cont=%p contlen=%d finalBI=%d flags=0x%04x\n", (void *) pkt, ccnl_suite2str(pkt->suite), pkt->type, (void*) pkt->content, pkt->contlen, pkt->val.final_block_id, pkt->flags); ccnl_dump(lev+1, CCNL_PREFIX, pkt->pfx); switch(pkt->suite) { #ifdef USE_SUITE_CCNB case CCNL_SUITE_CCNB: INDENT(lev+1); CONSOLE("minsfx=%d maxsfx=%d aok=%d scope=%d", pkt->s.ccnb.minsuffix, pkt->s.ccnb.maxsuffix, pkt->s.ccnb.aok, pkt->s.ccnb.scope); if (pkt->s.ccnb.nonce) { CONSOLE(" nonce="); blob(pkt->s.ccnb.nonce); } CONSOLE("\n"); if (pkt->s.ccnb.ppkd) { INDENT(lev+1); CONSOLE("ppkd="); blob(pkt->s.ccnb.ppkd); CONSOLE("\n"); } break; #endif #ifdef USE_SUITE_CCNTLV case CCNL_SUITE_CCNTLV: if (pkt->s.ccntlv.keyid) { INDENT(lev+1); CONSOLE("keyid="); blob(pkt->s.ccntlv.keyid); CONSOLE("\n"); } break; #endif #ifdef USE_SUITE_IOTTLV case CCNL_SUITE_IOTTLV: INDENT(lev+1); CONSOLE("ttl=%d\n", pkt->s.iottlv.ttl); break; #endif #ifdef USE_SUITE_NDNTLV case CCNL_SUITE_NDNTLV: INDENT(lev+1); CONSOLE("minsfx=%d maxsfx=%d mbf=%d scope=%d", pkt->s.ndntlv.minsuffix, pkt->s.ndntlv.maxsuffix, pkt->s.ndntlv.mbf, pkt->s.ndntlv.scope); if (pkt->s.ndntlv.nonce) { CONSOLE(" nonce="); blob(pkt->s.ndntlv.nonce); } CONSOLE("\n"); if (pkt->s.ndntlv.ppkl) { INDENT(lev+1); CONSOLE("ppkl="); blob(pkt->s.ndntlv.ppkl); CONSOLE("\n"); } break; #endif default: INDENT(lev+1); CONSOLE("... suite-specific packet details here ...\n"); } ccnl_dump(lev+1, CCNL_BUF, pkt->buf); break; case CCNL_CONTENT: while (con) { INDENT(lev); CONSOLE("%p CONTENT next=%p prev=%p last_used=%d served_cnt=%d\n", (void *) con, (void *) con->next, (void *) con->prev, con->last_used, con->served_cnt); // ccnl_dump(lev+1, CCNL_PREFIX, con->pkt->pfx); ccnl_dump(lev+1, CCNL_PACKET, con->pkt); con = con->next; } break; default: INDENT(lev); CONSOLE("unknown data type %d at %p\n", typ, p); } }