int main(int argc, char **argv){ unsigned char out[CCNL_MAX_PACKET_SIZE]; int i = 0, len, opt, sock = 0; char *namecomp[CCNL_MAX_NAME_COMP], *cp, *dest, *comp; char *udp = "127.0.0.1/9695", *ux = NULL; float wait = 3.0; int (*sendproc)(int,char*,unsigned char*,int); int print = 0; while ((opt = getopt(argc, argv, "hptu:v:w:x:")) != -1) { switch (opt) { case 'u': udp = optarg; break; case 'w': wait = (float)strtof(optarg, (char**) NULL); break; case 'x': ux = optarg; break; case 'p': print = 1; break; case 'v': #ifdef USE_LOGGING if (isdigit(optarg[0])) debug_level = (int)strtol(optarg, (char **)NULL, 10); else debug_level = ccnl_debug_str2level(optarg); #endif break; case 'h': default: Usage: fprintf(stderr, "usage: %s " "[-u host/port] [-x ux_path_name] [-w timeout] COMPUTATION URI\n" " -p print interest on console and exit\n" " -u a.b.c.d/port UDP destination (default is 127.0.0.1/9695)\n" #ifdef USE_LOGGING " -v DEBUG_LEVEL (fatal, error, warning, info, debug, verbose, trace)\n" #endif " -w timeout in sec (float)\n" " -x ux_path_name UNIX IPC: use this instead of UDP\n", argv[0]); exit(1); } } if (!argv[optind]) goto Usage; comp = argv[optind++]; if (!argv[optind]) goto Usage; struct ccnl_prefix_s *prefix = create_prefix_from_name(argv[optind]); len = mkInterestCompute(prefix->comp, comp, strlen(comp), out); if(print){ fwrite(out, sizeof(char), len, stdout); return 0; } if (ux) { // use UNIX socket dest = ux; sock = ux_open(); sendproc = ux_sendto; } else { // UDP dest = udp; sock = udp_open(); sendproc = udp_sendto; } request_content(sock, sendproc, dest, out, len, wait); return 0; }
int main(int argc, char *argv[]) { unsigned char out[64*1024]; int cnt, len, opt, sock = 0, socksize, suite = CCNL_SUITE_DEFAULT, port; char *addr = NULL, *udp = NULL, *ux = NULL; char *defaultNFNpath = "";//strdup("/ndn/ch/unibas/nfn"); struct sockaddr sa; struct ccnl_prefix_s *prefix; float wait = 3.0; ccnl_mkInterestFunc mkInterest; ccnl_isContentFunc isContent; while ((opt = getopt(argc, argv, "hn:s:u:v:w:x:")) != -1) { switch (opt) { case 'n': defaultNFNpath = optarg; break; case 's': opt = ccnl_str2suite(optarg); if (opt < 0 || opt >= CCNL_SUITE_LAST) goto usage; suite = opt; break; case 'u': udp = optarg; break; case 'v': #ifdef USE_LOGGING if (isdigit(optarg[0])) debug_level = atoi(optarg); else debug_level = ccnl_debug_str2level(optarg); #endif break; case 'w': wait = atof(optarg); break; case 'x': ux = optarg; break; case 'h': default: usage: fprintf(stderr, "usage: %s [options] NFNexpr\n" " -n NFNPATH default prefix towards some NFN node(s)\n" " -s SUITE (ccnb, ccnx2015, cisco2015, iot2014, ndn2013)\n" " -u a.b.c.d/port UDP destination (default is 127.0.0.1/6363)\n" #ifdef USE_LOGGING " -v DEBUG_LEVEL (fatal, error, warning, info, debug, verbose, trace)\n" #endif " -w timeout in sec (float)\n" " -x ux_path_name UNIX IPC: use this instead of UDP\n" "Examples:\n" "%% simplenfn /ndn/edu/wustl/ping\n" "%% simplenfn \"echo hello world\"\n" "%% simplenfn \"translate 'ccnx2014 /ccnx/parc/info.txt\"\n" "%% simplenfn \"add 1 1\"\n", argv[0]); exit(1); } } if (!argv[optind] || argv[optind+1]) goto usage; srandom(time(NULL)); if (ccnl_parseUdp(udp, suite, &addr, &port) != 0) { exit(-1); } DEBUGMSG(TRACE, "using udp address %s/%d\n", addr, port); mkInterest = ccnl_suite2mkInterestFunc(suite); isContent = ccnl_suite2isContentFunc(suite); if (!mkInterest || !isContent) { exit(-1); } if (ux) { // use UNIX socket struct sockaddr_un *su = (struct sockaddr_un*) &sa; su->sun_family = AF_UNIX; strcpy(su->sun_path, ux); sock = ux_open(); } else { // UDP struct sockaddr_in *si = (struct sockaddr_in*) &sa; si->sin_family = PF_INET; si->sin_addr.s_addr = inet_addr(addr); si->sin_port = htons(port); sock = udp_open(); } prefix = exprToNfnPrefix(defaultNFNpath, suite, argv[optind]); if (!prefix) goto done; for (cnt = 0; cnt < 3; cnt++) { int nonce = random(); len = mkInterest(prefix, &nonce, out, sizeof(out)); DEBUGMSG(TRACE, "sending interest(prefix=%s, suite=%s)\n", ccnl_prefix_to_path(prefix), ccnl_suite2str(suite)); if(ux) { socksize = sizeof(struct sockaddr_un); } else { socksize = sizeof(struct sockaddr_in); } if (sendto(sock, out, len, 0,(struct sockaddr *) &sa, socksize) < 0) { perror("sendto"); myexit(1); } for (;;) { // wait for a content pkt (ignore interests) int rc; if (block_on_read(sock, wait) <= 0) // timeout break; len = recv(sock, out, sizeof(out), 0); /* fprintf(stderr, "received %d bytes\n", len); if (len > 0) fprintf(stderr, " suite=%d\n", ccnl_pkt2suite(out, len)); */ rc = isContent(out, len); if (rc < 0) goto done; if (rc == 0) { // it's an interest, ignore it DEBUGMSG(WARNING, "skipping non-data packet\n"); continue; } write(1, out, len); myexit(0); } if (cnt < 2) DEBUGMSG(INFO, "re-sending interest\n"); } DEBUGMSG(ERROR, "timeout\n"); done: close(sock); myexit(-1); return 0; // avoid a compiler warning }
int main(int argc, char *argv[]) { unsigned char out[64*1024]; int len, opt, port, sock = 0, suite = CCNL_SUITE_DEFAULT; char *addr = NULL, *udp = NULL, *ux = NULL; struct sockaddr sa; float wait = 3.0; while ((opt = getopt(argc, argv, "hs:u:v:w:x:")) != -1) { switch (opt) { case 's': suite = ccnl_str2suite(optarg); if (!ccnl_isSuite(suite)) { DEBUGMSG(ERROR, "Unsupported suite %s\n", optarg); goto usage; } break; case 'u': udp = optarg; break; case 'w': wait = atof(optarg); break; case 'v': #ifdef USE_LOGGING if (isdigit(optarg[0])) debug_level = atoi(optarg); else debug_level = ccnl_debug_str2level(optarg); #endif break; case 'x': ux = optarg; break; case 'h': default: usage: fprintf(stderr, "usage: %s [options] URI [NFNexpr]\n" " -s SUITE (ccnb, ccnx2015, cisco2015, iot2014, ndn2013)\n" " -u a.b.c.d/port UDP destination (default is 127.0.0.1/6363)\n" #ifdef USE_LOGGING " -v DEBUG_LEVEL (fatal, error, warning, info, debug, verbose, trace)\n" #endif " -w timeout in sec (float)\n" " -x ux_path_name UNIX IPC: use this instead of UDP\n" "Examples:\n" "%% peek /ndn/edu/wustl/ping (classic lookup)\n" "%% peek /th/ere \"lambda expr\" (lambda expr, in-net)\n" "%% peek \"\" \"add 1 1\" (lambda expr, local)\n" "%% peek /rpc/site \"call 1 /test/data\" (lambda RPC, directed)\n", argv[0]); exit(1); } } if (!argv[optind]) goto usage; srandom(time(NULL)); if (ccnl_parseUdp(udp, suite, &addr, &port) != 0) { exit(-1); } DEBUGMSG(TRACE, "using suite %d:%s\n", suite, ccnl_suite2str(suite)); DEBUGMSG(TRACE, "using udp address %s/%d\n", addr, port); if (ux) { // use UNIX socket struct sockaddr_un *su = (struct sockaddr_un*) &sa; su->sun_family = AF_UNIX; strcpy(su->sun_path, ux); sock = ux_open(); } else { // UDP struct sockaddr_in *si = (struct sockaddr_in*) &sa; si->sin_family = PF_INET; si->sin_addr.s_addr = inet_addr(addr); si->sin_port = htons(port); sock = udp_open(); } char *url = argv[optind]; char *nfnexpr = 0; if (argv[optind+1]) { nfnexpr = argv[optind+1]; } unsigned char *content = 0; int contlen; unsigned int *curchunknum = NULL; // For CCNTLV always start with the first chunk because of exact content match // This means it can only fetch chunked data and not single content-object data if (suite == CCNL_SUITE_CCNTLV || suite == CCNL_SUITE_CISTLV) { curchunknum = ccnl_malloc(sizeof(unsigned int)); *curchunknum = 0; } struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(url, suite, nfnexpr, curchunknum); const int maxretry = 3; int retry = 0; while (retry < maxretry) { if (curchunknum) { if (!prefix->chunknum) { prefix->chunknum = ccnl_malloc(sizeof(unsigned int)); } *(prefix->chunknum) = *curchunknum; DEBUGMSG(INFO, "fetching chunk %d for prefix '%s'\n", *curchunknum, ccnl_prefix_to_path(prefix)); } else { DEBUGMSG(DEBUG, "fetching first chunk...\n"); DEBUGMSG(INFO, "fetching first chunk for prefix '%s'\n", ccnl_prefix_to_path(prefix)); } // Fetch chunk if (ccnl_fetchContentForChunkName(prefix, nfnexpr, curchunknum, suite, out, sizeof(out), &len, wait, sock, sa) < 0) { retry++; DEBUGMSG(WARNING, "timeout\n");//, retry number %d of %d\n", retry, maxretry); } else { unsigned int lastchunknum; unsigned char *t = &out[0]; struct ccnl_prefix_s *nextprefix = 0; // Parse response if (ccnl_extractDataAndChunkInfo(&t, &len, suite, &nextprefix, &lastchunknum, &content, &contlen) < 0) { retry++; DEBUGMSG(WARNING, "Could not extract response or it was an interest\n"); } else { prefix = nextprefix; // Check if the fetched content is a chunk if (!(prefix->chunknum)) { // Response is not chunked, print content and exit write(1, content, contlen); goto Done; } else { int chunknum = *(prefix->chunknum); // allocate curchunknum because it is the first fetched chunk if(!curchunknum) { curchunknum = ccnl_malloc(sizeof(unsigned int)); *curchunknum = 0; } // Remove chunk component from name if (ccnl_prefix_removeChunkNumComponent(suite, prefix) < 0) { retry++; DEBUGMSG(WARNING, "Could not remove chunknum\n"); } // Check if the chunk is the first chunk or the next valid chunk // otherwise discard content and try again (except if it is the first fetched chunk) if (chunknum == 0 || (curchunknum && *curchunknum == chunknum)) { DEBUGMSG(DEBUG, "Found chunk %d with contlen=%d, lastchunk=%d\n", *curchunknum, contlen, lastchunknum); write(1, content, contlen); if (lastchunknum != -1 && lastchunknum == chunknum) { goto Done; } else { *curchunknum += 1; retry = 0; } } else { // retry if the fetched chunk retry++; DEBUGMSG(WARNING, "Could not find chunk %d, extracted chunknum is %d (lastchunk=%d)\n", *curchunknum, chunknum, lastchunknum); } } } } if(retry > 0) { DEBUGMSG(INFO, "Retry %d of %d\n", retry, maxretry); } } close(sock); return 1; Done: DEBUGMSG(DEBUG, "Sucessfully fetched content\n"); close(sock); return 0; }