示例#1
0
int
ccnl_ccnb_forwarder(struct ccnl_relay_s *relay, 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;
    struct ccnl_buf_s *buf = 0, *nonce=0, *ppkd=0;
    struct ccnl_interest_s *i = 0;
    struct ccnl_content_s *c = 0;
    struct ccnl_prefix_s *p = 0;
    unsigned char *content = 0;
    DEBUGMSG(99, "ccnl/ccnb forwarder (%d bytes left)\n", *datalen);

    buf = ccnl_ccnb_extract(data, datalen, &scope, &aok, &minsfx,
			    &maxsfx, &p, &nonce, &ppkd, &content, &contlen);
    if (!buf) {
	    DEBUGMSG(6, "  parsing error or no prefix\n"); goto Done;
    }
    if (nonce && ccnl_nonce_find_or_append(relay, nonce)) {
	DEBUGMSG(6, "  dropped because of duplicate nonce\n"); 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
	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;
	}
	// CONFORM: Step 1:
	if ( aok & 0x01 ) { // honor "answer-from-existing-content-store" flag
	    for (c = relay->contents; c; c = c->next) {
		if (c->suite != CCNL_SUITE_CCNB) continue;
		if (!ccnl_i_prefixof_c(p, minsfx, maxsfx, c)) continue;
		if (ppkd && !buf_equal(ppkd, c->details.ccnb.ppkd)) 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
		if (from->ifndx >= 0)
		    ccnl_face_enqueue(relay, from, buf_dup(c->pkt));
		else
		    ccnl_app_RX(relay, c);
		goto Skip;
	    }
	}
	// CONFORM: Step 2: check whether interest is already known
	for (i = relay->pit; i; i = i->next) {
	    if (i->suite == CCNL_SUITE_CCNB &&
		!ccnl_prefix_cmp(i->prefix, NULL, p, CMP_EXACT) &&
		i->details.ccnb.minsuffix == minsfx &&
		i->details.ccnb.maxsuffix == maxsfx && 
		((!ppkd && !i->details.ccnb.ppkd) ||
		   buf_equal(ppkd, i->details.ccnb.ppkd)) )
		break;
	}
	if (!i) { // this is a new/unknown I request: create and propagate
	    i = ccnl_interest_new(relay, from, CCNL_SUITE_CCNB,
				  &buf, &p, minsfx, maxsfx);
	    if (ppkd)
		i->details.ccnb.ppkd = ppkd, ppkd = NULL;
	    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);
	    }
	} 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);
	}
	if (i) { // store the I request, for the incoming face (Step 3)
	    DEBUGMSG(7, "  appending interest entry %p\n", (void *) i);
	    ccnl_interest_append_pending(i, from);
	}
    } else { // content
	DEBUGMSG(6, "  content=<%s>\n", ccnl_prefix_to_path(p));
	ccnl_print_stats(relay, 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;
	}
#endif /*USE_SIGNATURES*/
        
        // CONFORM: Step 1:
	for (c = relay->contents; c; c = c->next)
	    if (buf_equal(c->pkt, buf)) goto Skip; // content is dup
	c = ccnl_content_new(relay, CCNL_SUITE_CCNB,
			     &buf, &p, &ppkd, content, contlen);
	if (c) { // CONFORM: Step 2 (and 3)
	    if (!ccnl_content_serve_pending(relay, 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
		DEBUGMSG(7, "  adding content to cache\n");
		ccnl_content_add2cache(relay, c);
	    } else {
		DEBUGMSG(7, "  content not added to cache\n");
		free_content(c);
	    }
	}
    }
Skip:
    rc = 0;
Done:
    free_prefix(p);
    free_3ptr_list(buf, nonce, ppkd);
    return rc;
}
示例#2
0
int
ccnl_mgmt_crypto(struct ccnl_relay_s *ccnl, char *type, unsigned char *buf, int buflen)
{

   struct ccnl_face_s *from;
   DEBUGMSG(DEBUG,"ccnl_crypto type: %s\n", type);

   if(!strcmp(type, "verify")){
      int seqnum = 0;
      int verified = ccnl_crypto_extract_verify_reply(&buf, &buflen, &seqnum);
      unsigned char *msg, *msg2;
      char cmd[500];
      int len = ccnl_crypto_extract_msg(&buf, &buflen, &msg), len2 = 0;
      struct ccnl_face_s *from;
      //DEBUGMSG(DEBUG,"VERIFIED: %d, MSG_LEN: %d\n", verified, len);

      int scope=3, aok=3, minsfx=0, maxsfx=CCNL_MAX_NAME_COMP, contlen;
      struct ccnl_buf_s *buf1 = 0, *nonce=0, *ppkd=0;
      struct ccnl_prefix_s *p = 0;
      struct ccnl_buf_s *msg2_buf;
      unsigned char *content = 0;

      msg2 = (char *) ccnl_malloc(sizeof(char) * len + 200);
      len2 = ccnl_ccnb_mkHeader(msg2,CCN_DTAG_NAME, CCN_TT_DTAG);
      memcpy(msg2+len2, msg, len);
      len2 +=len;
      msg2[len2++] = 0;

      from = ccnl->faces;
      while(from){
          if(from->faceid == seqnum)
              break;
          from = from->next;
      }

      buf1 = ccnl_ccnb_extract(&msg2, &len2, &scope, &aok, &minsfx,
                         &maxsfx, &p, &nonce, &ppkd, &content, &contlen);

      if (p->complen[2] < sizeof(cmd)) {
            memcpy(cmd, p->comp[2], p->complen[2]);
            cmd[p->complen[2]] = '\0';
      } else
            strcpy(cmd, "cmd-is-too-long-to-display");
      msg2_buf = ccnl_buf_new((char *)msg2, len2);
      ccnl_mgmt_handle(ccnl, msg2_buf, p, from, cmd, verified);
      ccnl_free(msg2_buf);
   }else if(!strcmp(type, "sign")){
      char *sig = (char *) ccnl_malloc(sizeof(char)* CCNL_MAX_PACKET_SIZE);
      unsigned char *out;
      unsigned char *msg;
      int siglen = 0, seqnum = 0, len, len1;
      struct ccnl_buf_s *retbuf;

      ccnl_crypto_extract_sign_reply(&buf, &buflen, sig, &siglen, &seqnum);

      len = ccnl_crypto_extract_msg(&buf, &buflen, &msg);
      out = (char *) ccnl_malloc(sizeof(unsigned char)*len + sizeof(unsigned char)*siglen + 4096);

      len1 = ccnl_ccnb_mkHeader(out, CCN_DTAG_CONTENTOBJ, CCN_TT_DTAG);   // content
      if(siglen > 0) len1 += ccnl_crypto_add_signature(out+len1, sig, siglen);

      memcpy(out+len1, msg, len);
      len1 +=len;

      out[len1++] = 0; // end-of-interest
      from = ccnl->faces;
      while(from){
          if(from->faceid == seqnum)
              break;
          from = from->next;
      }

      retbuf = ccnl_buf_new((char *)out, len1);
      if(seqnum >= 0){
          ccnl_face_enqueue(ccnl, from, retbuf);
      }else{
          struct ccnl_prefix_s *prefix_a = 0;
          struct ccnl_content_s *c = 0;
          struct ccnl_buf_s *nonce=0, *ppkd=0, *pkt = 0;
          unsigned char *content = 0;
          char *ht = (char *) ccnl_malloc(sizeof(char)*20);
          int contlen;
          pkt = ccnl_ccnb_extract(&out, &len1, 0, 0, 0, 0,
                                  &prefix_a, &nonce, &ppkd, &content, &contlen);

          if (!pkt) {
               DEBUGMSG(WARNING, " parsing error\n"); goto Done;
          }
          if (prefix_a) {
              //DEBUGMSG(DEBUG, "%s", prefix_a->comp);
              //ccnl_free(prefix_a);
          }
          //prefix_a = (struct ccnl_prefix_s *)ccnl_malloc(sizeof(struct ccnl_prefix_s));
          prefix_a->compcnt = 2;
          prefix_a->comp = (unsigned char **) ccnl_malloc(sizeof(unsigned char*)*2);
          prefix_a->comp[0] = "mgmt";
          sprintf(ht, "seqnum-%d", -seqnum);
          prefix_a->comp[1] = ht;
          prefix_a->complen = (int *) ccnl_malloc(sizeof(int)*2);
          prefix_a->complen[0] = strlen("mgmt");
          prefix_a->complen[1] = strlen(ht);
          c = ccnl_content_new(ccnl, CCNL_SUITE_CCNB, &pkt, &prefix_a, &ppkd,
                                content, contlen);
          if (!c) goto Done;

          ccnl_content_serve_pending(ccnl, c);
          ccnl_content_add2cache(ccnl, c);
      }
      Done:
      ccnl_free(out);
   }
   return 0;
}
示例#3
0
void
ccnl_populate_cache(struct ccnl_relay_s *ccnl, char *path, int suite)
{
    DIR *dir;
    struct dirent *de;
    int datalen;
    char *suffix;

    DEBUGMSG(99, "ccnl_populate_cache %s\n", path);

    switch (suite) {
#ifdef USE_SUITE_CCNB
    case CCNL_SUITE_CCNB:
	suffix = "*.ccnb"; break;
#endif
#ifdef USE_SUITE_NDNTLV
    case CCNL_SUITE_NDNTLV:
	suffix = "*.ndntlv"; break;
#endif
    default:
	fprintf(stderr, "unknown suite and encoding, cannot populate cache.\n");
	return;
    }

    dir = opendir(path);
    if (!dir)
	return;
    while ((de = readdir(dir))) {
	if (!fnmatch(suffix, de->d_name, FNM_NOESCAPE)) {
	    char fname[1000];
	    struct stat s;
	    strcpy(fname, path);
	    strcat(fname, "/");
	    strcat(fname, de->d_name);
	    if (stat(fname, &s)) {
		perror("stat");
	    } else {
		struct ccnl_buf_s *buf = 0;
		int fd;
		DEBUGMSG(6, "loading file %s, %d bytes\n",
			 de->d_name, (int) s.st_size);

		fd = open(fname, O_RDONLY);
		if (!fd) {
		    perror("open");
		    continue;
		}
               
		buf = (struct ccnl_buf_s *) ccnl_malloc(sizeof(*buf) +
							s.st_size);
		datalen = read(fd, buf->data, s.st_size);
		close(fd);
		if (datalen == s.st_size && datalen >= 2) {
		    struct ccnl_prefix_s *prefix = 0;
		    struct ccnl_content_s *c = 0;
		    struct ccnl_buf_s *nonce=0, *ppkd=0, *pkt = 0;
		    unsigned char *content, *data;
		    int contlen, typ, len;

		    buf->datalen = datalen;
		    switch (suite) {
#ifdef USE_SUITE_CCNB
		    case CCNL_SUITE_CCNB:
			if (buf->data[0] != 0x04 || buf->data[1] != 0x82)
			    goto notacontent;
			data = buf->data + 2;
			datalen -= 2;
			pkt = ccnl_ccnb_extract(&data, &datalen, 0, 0, 0, 0,
				&prefix, &nonce, &ppkd, &content, &contlen);
			break;
#endif
#ifdef USE_SUITE_NDNTLV
		    case CCNL_SUITE_NDNTLV:
			data = buf->data;
			if (ccnl_ndntlv_dehead(&data, &datalen, &typ, &len) ||
			    typ != NDN_TLV_Data)
			    goto notacontent;
			pkt = ccnl_ndntlv_extract(data - buf->data,
						  &data, &datalen, 0, 0, 0, 0,
				&prefix, &nonce, &ppkd, &content, &contlen);
			break;
#endif
		    default:
			goto Done;
		    }
		    if (!pkt) {
			DEBUGMSG(6, "  parsing error\n"); goto Done;
		    }
		    if (!prefix) {
			DEBUGMSG(6, "  no prefix error\n"); goto Done;
		    }
		    c = ccnl_content_new(ccnl, suite, &pkt, &prefix,
					 &ppkd, content, contlen);
		    if (!c)
			goto Done;
		    ccnl_content_add2cache(ccnl, c);
		    c->flags |= CCNL_CONTENT_FLAGS_STATIC;
Done:
		    free_prefix(prefix);
		    ccnl_free(buf);
		    ccnl_free(pkt);
		    ccnl_free(nonce);
		    ccnl_free(ppkd);
		} else {
notacontent:
		    DEBUGMSG(6, "  not a content object\n");
		    ccnl_free(buf);
		}
	    }
	}
    }
}