Exemplo n.º 1
0
int
ccnl_nfn_thunk_already_computing(struct ccnl_relay_s *ccnl,
                                 struct ccnl_prefix_s *prefix)
{
    int i = 0;
    struct ccnl_prefix_s *copy;

    DEBUGMSG(TRACE, "ccnl_nfn_thunk_already_computing()\n");

    copy = ccnl_prefix_dup(prefix);
    // ccnl_nfn_remove_thunk_from_prefix(copy);
    ccnl_nfnprefix_set(copy, CCNL_PREFIX_NFN | CCNL_PREFIX_THUNK);

    for (i = 0; i < -ccnl->km->configid; ++i) {
        struct configuration_s *config;

        config = ccnl_nfn_findConfig(ccnl->km->configuration_list, -i);
        if (!config)
            continue;
        if (!ccnl_prefix_cmp(config->prefix, NULL, copy, CMP_EXACT)) {
            free_prefix(copy);
            return 1;
        }  
    }
    free_prefix(copy);

    return 0;
}
Exemplo n.º 2
0
void
ccnl_client_TX(char node, char *name, int seqn, int nonce)
{
    char tmp[512];
    struct ccnl_prefix_s *p;
    struct ccnl_buf_s *buf;
    struct ccnl_relay_s *relay = char2relay(node);

    DEBUGMSG(TRACE, "ccnl_client_tx node=%c: request %s #%d\n",
             node, name, seqn);

    if (!relay)
        return;

    sprintf(tmp, "%s/.%d", name, seqn);
    //    p = ccnl_path_to_prefix(tmp);
    //    p->suite = suite;
    p = ccnl_URItoPrefix(tmp, theSuite, NULL, NULL);
    DEBUGMSG(TRACE, "  create interest for %s\n", ccnl_prefix_to_path(p));
    buf = ccnl_mkSimpleInterest(p, &nonce);
    free_prefix(p);

    // inject it into the relay:
    if (buf) {
        ccnl_core_RX(relay, -1, buf->data, buf->datalen, 0, 0);
        ccnl_free(buf);
    }
}
struct ccnl_prefix_s *
ccnl_iottlv_parseHierarchicalName(unsigned char *data, int datalen)
{
    int len = datalen;
    unsigned int typ, len2;
    struct ccnl_prefix_s *p;

    p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s));
    if (!p)
        return NULL;
    p->suite = CCNL_SUITE_IOTTLV;
    p->comp = (unsigned char**) ccnl_malloc(CCNL_MAX_NAME_COMP *
                                           sizeof(unsigned char**));
    p->complen = (int*) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(int));
    if (!p->comp || !p->complen)
        return NULL;

    p->nameptr = data;
    p->namelen = len;
    while (len > 0) {
        if (ccnl_iottlv_dehead(&data, &len, &typ, &len2))
            goto Bail;
        if (typ == IOT_TLV_PN_Component &&
                               p->compcnt < CCNL_MAX_NAME_COMP) {
            p->comp[p->compcnt] = data;
            p->complen[p->compcnt] = len2;
            p->compcnt++;
        }
        data += len2;
        len -= len2;
    }
    datalen -= p->namelen;
#ifdef USE_NFN
            if (p->compcnt > 0 && p->complen[p->compcnt-1] == 3 &&
                    !memcmp(p->comp[p->compcnt-1], "NFN", 3)) {
                p->nfnflags |= CCNL_PREFIX_NFN;
                p->compcnt--;
                if (p->compcnt > 0 && p->complen[p->compcnt-1] == 5 &&
                        !memcmp(p->comp[p->compcnt-1], "THUNK", 5)) {
                    p->nfnflags |= CCNL_PREFIX_THUNK;
                    p->compcnt--;
                }
            }
#endif

    return p;
  Bail:
    free_prefix(p);
    return NULL;
}
Exemplo n.º 4
0
void ccnl_populate_cache(struct ccnl_relay_s *ccnl, unsigned char *buf, int datalen)
{
    if (buf[0] == 0x04 && buf[1] == 0x82) {
        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 = buf + 2;
        int contlen;

        datalen -= 2;

        pkt = ccnl_extract_prefix_nonce_ppkd(&data, &datalen, 0, 0,
                                             0, 0, &prefix, &nonce, &ppkd, &content, &contlen);

        if (!pkt) {
            DEBUGMSG(6, "  parsing error\n");
            goto Done;
        }

        if (!prefix) {
            DEBUGMSG(6, "  no prefix error\n");
            goto Done;
        }

        printf("populating: %s\n", ccnl_prefix_to_path(prefix));

        c = ccnl_content_new(ccnl, &pkt, &prefix, &ppkd, content,
                             contlen);

        if (!c) {
            goto Done;
        }

        c->flags |= CCNL_CONTENT_FLAGS_STATIC;
        if (!ccnl_content_add2cache(ccnl, c)) {
            // content store error
            free_content(c);
        }

    Done:
        free_prefix(prefix);
        ccnl_free(pkt);
        ccnl_free(nonce);
        ccnl_free(ppkd);
    }
    else {
        DEBUGMSG(6, "  not a content object\n");
    }
}
Exemplo n.º 5
0
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);

    while (i->pending) {
        struct ccnl_pendint_s *tmp = i->pending->next;
        ccnl_free(i->pending);
        i->pending = tmp;
    }

    i2 = i->next;
    DBL_LINKED_LIST_REMOVE(ccnl->pit, i);
    free_prefix(i->prefix);
    free_3ptr_list(i->ppkd, i->pkt, i);
    return i2;
}
Exemplo n.º 6
0
struct ccnl_prefix_s*
ccnl_prefix_new(int suite, int cnt)
{
    struct ccnl_prefix_s *p;

    p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s));
    if (!p)
        return NULL;
    p->comp = (unsigned char**) ccnl_malloc(cnt * sizeof(unsigned char*));
    p->complen = (int*) ccnl_malloc(cnt * sizeof(int));
    if (!p->comp || !p->complen) {
        free_prefix(p);
        return NULL;
    }
    p->compcnt = cnt;
    p->suite = suite;
    p->chunknum = NULL;

    return p;
}
Exemplo n.º 7
0
struct ccnl_content_s*
ccnl_content_remove(struct ccnl_relay_s *ccnl, struct ccnl_content_s *c)
{
    struct ccnl_content_s *c2;
    c2 = c->next;
    DBL_LINKED_LIST_REMOVE(ccnl->contents, c);

//    free_content(c);
    if (c->pkt) {
        free_prefix(c->pkt->pfx);
        ccnl_free(c->pkt->buf);
        ccnl_free(c->pkt);
    }
    //    free_prefix(c->name);
    ccnl_free(c);

    ccnl->contentcnt--;
    DEBUGMSG_CORE(INFO, " ICNIoT: remove_contentFromCache:%d\n",ccnl->contentcnt);
    return c2;
}
Exemplo n.º 8
0
struct ccnl_content_s*
ccnl_content_remove(struct ccnl_relay_s *ccnl, struct ccnl_content_s *c)
{
    struct ccnl_content_s *c2;
    DEBUGMSG_CORE(TRACE, "ccnl_content_remove\n");

    c2 = c->next;
    DBL_LINKED_LIST_REMOVE(ccnl->contents, c);

//    free_content(c);
    if (c->pkt) {
        free_prefix(c->pkt->pfx);
        ccnl_free(c->pkt->buf);
        ccnl_free(c->pkt);
    }
    //    free_prefix(c->name);
    ccnl_free(c);

    ccnl->contentcnt--;
    return c2;
}
Exemplo n.º 9
0
struct ccnl_prefix_s*
ccnl_prefix_dup(struct ccnl_prefix_s *prefix)
{
    int i = 0, len;
    struct ccnl_prefix_s *p;

    if (!prefix)
        return NULL;
    p = ccnl_prefix_new(prefix->suite, prefix->compcnt);
    if (!p)
        return p;

    p->compcnt = prefix->compcnt;
    p->chunknum = prefix->chunknum;
#ifdef USE_NFN
    p->nfnflags = prefix->nfnflags;
#endif

    for (i = 0, len = 0; i < prefix->compcnt; i++)
        len += prefix->complen[i];
    p->bytes = (unsigned char*) ccnl_malloc(len);
    if (!p->bytes) {
        free_prefix(p);
        return NULL;
    }

    for (i = 0, len = 0; i < prefix->compcnt; i++) {
        p->complen[i] = prefix->complen[i];
        p->comp[i] = p->bytes + len;
        memcpy(p->bytes + len, prefix->comp[i], p->complen[i]);
        len += p->complen[i];
    }

    if (prefix->chunknum) {
        p->chunknum = ccnl_malloc(sizeof(int));
        *p->chunknum = *prefix->chunknum;
    }

    return p;
}
Exemplo n.º 10
0
int _ccnl_fib(int argc, char **argv)
{
    if (argc < 2) {
        ccnl_fib_show(&ccnl_relay);
    }
    else if ((argc == 3) && (strncmp(argv[1], "del", 3) == 0)) {
        int suite = CCNL_SUITE_NDNTLV;
        if (strchr(argv[2], '/')) {
            struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(argv[2], suite, NULL, 0);
            if (!prefix) {
                puts("Error: prefix could not be created!");
                return -1;
            }
            int res = ccnl_fib_rem_entry(&ccnl_relay, prefix, NULL);
            free_prefix(prefix);
            return res;
        }
        else {
            struct ccnl_face_s *face = _intern_face_get(argv[2]);
            if (face == NULL) {
                printf("There is no face for address %s\n", argv[1]);
                return -1;
            }
            int res = ccnl_fib_rem_entry(&ccnl_relay, NULL, face);
            return res;
        }
    }
    else if ((argc == 4) && (strncmp(argv[1], "add", 3) == 0)) {
        if (_intern_fib_add(argv[2], argv[3]) < 0) {
            _ccnl_fib_usage(argv[0]);
            return -1;
        }
    }
    else {
        _ccnl_fib_usage(argv[0]);
        return -1;
    }
    return 0;
}
Exemplo n.º 11
0
struct ccnl_interest_s*
ccnl_nfn_RX_request(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from,
                    int suite, struct ccnl_buf_s **buf,
                    struct ccnl_prefix_s **p, int minsfx, int maxsfx)
{
    struct ccnl_interest_s *i;
    struct ccnl_prefix_s *p2;

    if (ccnl->km->numOfRunningComputations >= NFN_MAX_RUNNING_COMPUTATIONS)
        return 0;

    p2 = ccnl_prefix_dup(*p);
    i = ccnl_interest_new(ccnl, from, (*p)->suite, buf, p, minsfx, maxsfx);
    i->flags &= ~CCNL_PIT_COREPROPAGATES; // do not forward interests for running computations
    ccnl_interest_append_pending(i, from);
    if (!(i->flags & CCNL_PIT_COREPROPAGATES))
        ccnl_nfn(ccnl, p2, from, NULL, i, suite, 0);
    else {
        free_prefix(p2);
    }
    return i;
}
Exemplo n.º 12
0
static int _debug_cache_date(int argc, char **argv)
{
    if ((argc < 3) || (strlen(argv[1]) > 8) || (strlen(argv[2]) > 8)) {
        puts("Usage: dc <ID> <timestamp>");
        return 1;
    }

    /* get data into cache by sending to loopback */
    LOG_DEBUG("main: put data into cache via loopback\n");
    size_t prefix_len = sizeof(CCNLRIOT_SITE_PREFIX) + sizeof(CCNLRIOT_TYPE_PREFIX) + 9 + 9;
    char pfx[prefix_len];
    snprintf(pfx, prefix_len, "%s%s/%s/%s", CCNLRIOT_SITE_PREFIX, CCNLRIOT_TYPE_PREFIX, argv[1], argv[2]);
    LOG_INFO("main: DEBUG DATA: %s\n", pfx);
    struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(pfx, CCNL_SUITE_NDNTLV, NULL, 0);
    if (prefix == NULL) {
        LOG_ERROR("caching: We're doomed, WE ARE ALL DOOMED!\n");
    }
    else {
        ccnl_helper_create_cont(prefix, (unsigned char*) argv[2], strlen(argv[2]) + 1, true, false);
        free_prefix(prefix);
    }
    return 0;
}
Exemplo n.º 13
0
void
ccnl_core_cleanup(struct ccnl_relay_s *ccnl)
{
    int k;

    DEBUGMSG_CORE(TRACE, "ccnl_core_cleanup %p\n", (void *) ccnl);

    while (ccnl->pit)
        ccnl_interest_remove(ccnl, ccnl->pit);
    while (ccnl->faces)
        ccnl_face_remove(ccnl, ccnl->faces); // removes allmost all FWD entries
    while (ccnl->fib) {
        struct ccnl_forward_s *fwd = ccnl->fib->next;
        free_prefix(ccnl->fib->prefix);
        ccnl_free(ccnl->fib);
        ccnl->fib = fwd;
    }
    while (ccnl->contents)
        ccnl_content_remove(ccnl, ccnl->contents);
    while (ccnl->nonces) {
        struct ccnl_buf_s *tmp = ccnl->nonces->next;
        ccnl_free(ccnl->nonces);
        ccnl->nonces = tmp;
    }
    for (k = 0; k < ccnl->ifcount; k++)
        ccnl_interface_cleanup(ccnl->ifs + k);

    while (bufCleanUpList) {
        struct ccnl_buf_s *tmp = bufCleanUpList->next;
        ccnl_free(bufCleanUpList);
        bufCleanUpList = tmp;
    }

#ifdef USE_NFN
    ccnl_nfn_freeKrivine(ccnl);
#endif
}
Exemplo n.º 14
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 configuration_s *config, struct ccnl_interest_s *interest,
         int suite, int start_locally)
{
    int num_of_required_thunks = 0;
    int thunk_request = 0;
    struct ccnl_buf_s *res = NULL;
    char str[CCNL_MAX_PACKET_SIZE];
    int i, len = 0;

    DEBUGMSG(TRACE, "ccnl_nfn(%p, %s, %p, config=%p)\n",
             (void*)ccnl, ccnl_prefix_to_path(prefix),
             (void*)from, (void*)config);

    //    prefix = ccnl_prefix_dup(prefix);
    DEBUGMSG(DEBUG, "Namecomps: %s \n", ccnl_prefix_to_path(prefix));

    if (config){
        suite = config->suite;
        thunk_request = config->fox_state->thunk_request;
        goto restart; //do not do parsing thunks again
    }

    from->flags = CCNL_FACE_FLAGS_STATIC;

    if (ccnl_nfn_thunk_already_computing(ccnl, prefix)) {
        DEBUGMSG(DEBUG, "Computation for this interest is already running\n");
        return -1;
    }
    if (ccnl_nfnprefix_isTHUNK(prefix))
        thunk_request = 1;


    // Checks first if the interest has a routing hint and then searches for it locally.
    // If it exisits, the computation is started locally,  otherwise it is directly forwarded without entering the AM.
    // Without this mechanism, there will be situations where several nodes "overtake" a computation
    // applying the same strategy and, potentially, all executing it locally (after trying all arguments).
    // TODO: this is not an elegant solution and should be improved on, because the clients cannot send a
    // computation with a routing hint on which the network applies a strategy if the routable name
    // does not exist (because each node will just forward it without ever taking it into an abstract machine).
    // encoding the routing hint more explicitely as well as additonal information (e.g. already tried names) 
    // could solve the problem. More generally speaking, additional state describing the exact situation will be required.
    
    if (interest && interest->prefix->compcnt > 1) { // forward interests with outsourced components
        struct ccnl_prefix_s *copy = ccnl_prefix_dup(prefix);
        copy->compcnt -= (1 + thunk_request);
        DEBUGMSG(DEBUG, "   checking local available of %s\n", ccnl_prefix_to_path(copy));
        ccnl_nfnprefix_clear(copy, CCNL_PREFIX_NFN | CCNL_PREFIX_THUNK); 
        if (!ccnl_nfn_local_content_search(ccnl, NULL, copy)) {
            free_prefix(copy);
            ccnl_interest_propagate(ccnl, interest);
            return 0;
        }
        free_prefix(copy);
        start_locally = 1;
    }
   
    //put packet together
#ifdef USE_SUITE_CCNTLV
    if (prefix->suite == CCNL_SUITE_CCNTLV) {
        len = prefix->complen[prefix->compcnt-1] - 4;
        memcpy(str, prefix->comp[prefix->compcnt-1] + 4, len);
        str[len] = '\0';
    } else
#endif
    {
        len = prefix->complen[prefix->compcnt-1];
        memcpy(str, prefix->comp[prefix->compcnt-1], len);
        str[len] = '\0';
    }
    if (prefix->compcnt > 1)
        len += sprintf(str + len, " ");
    for (i = 0; i < prefix->compcnt-1; i++) {
#ifdef USE_SUITE_CCNTLV
        if (prefix->suite == CCNL_SUITE_CCNTLV)
            len += sprintf(str+len,"/%.*s",prefix->complen[i]-4,prefix->comp[i]+4);
        else
#endif
            len += sprintf(str+len,"/%.*s",prefix->complen[i],prefix->comp[i]);
    }

    DEBUGMSG(DEBUG, "expr is <%s>\n", str);
    //search for result here... if found return...
    if (thunk_request)
        num_of_required_thunks = ccnl_nfn_count_required_thunks(str);
    
    ++ccnl->km->numOfRunningComputations;
restart:
    res = Krivine_reduction(ccnl, str, thunk_request, start_locally,
                            num_of_required_thunks, &config, prefix, suite);

    //stores result if computed      
    if (res) {
        struct ccnl_prefix_s *copy;
        struct ccnl_content_s *c;

        DEBUGMSG(INFO,"Computation finished: res: %.*s size: %d bytes. Running computations: %d\n",
                 res->datalen, res->data, res->datalen, ccnl->km->numOfRunningComputations);
        if (config && config->fox_state->thunk_request) {
            // ccnl_nfn_remove_thunk_from_prefix(config->prefix);
            ccnl_nfnprefix_clear(config->prefix, CCNL_PREFIX_THUNK);
        }
        copy = ccnl_prefix_dup(config->prefix);
        c = ccnl_nfn_result2content(ccnl, &copy, res->data, res->datalen);
        c->flags = CCNL_CONTENT_FLAGS_STATIC;

        set_propagate_of_interests_to_1(ccnl, c->name);
        ccnl_content_serve_pending(ccnl,c);
        ccnl_content_add2cache(ccnl, c);
        --ccnl->km->numOfRunningComputations;

        DBL_LINKED_LIST_REMOVE(ccnl->km->configuration_list, config);
        ccnl_nfn_freeConfiguration(config);
        ccnl_free(res);
    }
#ifdef USE_NACK
    else if(config->local_done){
        struct ccnl_content_s *nack;
        nack = ccnl_nfn_result2content(ccnl, &config->prefix,
                                       (unsigned char*)":NACK", 5);
        ccnl_content_serve_pending(ccnl, nack);

    }
#endif

    return 0;
}
Exemplo n.º 15
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);
		}
	    }
	}
    }
}
Exemplo n.º 16
0
int ccnl_core_RX_i_or_c(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(1, "ccnl_core_RX_i_or_c: (%d bytes left)\n", *datalen);

    buf = ccnl_extract_prefix_nonce_ppkd(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(1, "ccnl_core_RX_i_or_c: interest=<%s>\n", ccnl_prefix_to_path(p));
        from->stat.received_interest++;

        if (p->compcnt > 0 && p->comp[0][0] == (unsigned char) 0xc1) {
            goto Skip;
        }

        if (p->compcnt == 4 && !memcmp(p->comp[0], "ccnx", 4)) {
            DEBUGMSG(1, "it's a mgnt msg!\n");
            rc = ccnl_mgmt(relay, buf, p, from);
            DEBUGMSG(1, "mgnt processing done!\n");
            goto Done;
        }

        // CONFORM: Step 1:
        if (aok & 0x01) { // honor "answer-from-existing-content-store" flag
            for (c = relay->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);
                from->stat.send_content[c->served_cnt % CCNL_MAX_CONTENT_SERVED_STAT]++;
                c->served_cnt++;

                if (from->ifndx >= 0) {
                    ccnl_face_enqueue(relay, from, buf_dup(c->pkt));
                }

                goto Skip;
            }
        }

        // CONFORM: Step 2: check whether interest is already known
        for (i = relay->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))) {
                break;
            }
        }

        if (!i) { // this is a new/unknown I request: create and propagate
            i = ccnl_interest_new(relay, 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);
                }
            }
        }
        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));
        from->stat.received_content++;

        // CONFORM: Step 1:
        for (c = relay->contents; c; c = c->next) {
            if (buf_equal(c->pkt, buf)) {
                DEBUGMSG(1, "content is dup: skip\n");
                goto Skip;
            }
        }

        c = ccnl_content_new(relay, &buf, &p, &ppkd, content, contlen);

        if (c) { // CONFORM: Step 2 (and 3)
            if (!ccnl_content_serve_pending(relay, c, from)) { // unsolicited content
                // CONFORM: "A node MUST NOT forward unsolicited data [...]"
                DEBUGMSG(7, "  removed because no matching interest\n");
                free_content(c);
                goto Skip;
            }
#if CCNL_DYNAMIC_FIB
            else {
                /* content has matched an interest, we consider this name as available on this face */
                ccnl_content_learn_name_route(relay, c->name, from, relay->fib_threshold_prefix, 0);
            }
#endif

            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);
    DEBUGMSG(1, "leaving\n");
    return rc;
}
Exemplo n.º 17
0
struct ccnl_buf_s *
ccnl_extract_prefix_nonce_ppkd(unsigned char **data, int *datalen, int *scope,
                               int *aok, int *min, int *max, struct ccnl_prefix_s **prefix,
                               struct ccnl_buf_s **nonce, struct ccnl_buf_s **ppkd,
                               unsigned char **content, int *contlen)
{
    unsigned char *start = *data - 2, *cp;
    int num, typ, len;
    struct ccnl_prefix_s *p;
    struct ccnl_buf_s *buf, *n = 0, *pub = 0;
    DEBUGMSG(99, "ccnl_extract_prefix\n");

    p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s));

    if (!p) {
        puts("can't get more memory from malloc, dropping ccn msg...");
        return NULL;
    }

    p->comp = (unsigned char **) ccnl_malloc(
                  CCNL_MAX_NAME_COMP * sizeof(unsigned char **));
    p->complen = (int *) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(int));

    if (!p->comp || !p->complen) {
        puts("can't get more memory from malloc, dropping ccn msg...");
        goto Bail;
    }

    while (dehead(data, datalen, &num, &typ) == 0) {
        if (num == 0 && typ == 0) {
            break;    // end
        }

        if (typ == CCN_TT_DTAG) {
            if (num == CCN_DTAG_NAME) {
                while (1) {
                    if (dehead(data, datalen, &num, &typ) != 0) {
                        goto Bail;
                    }

                    if (num == 0 && typ == 0) {
                        break;
                    }

                    if (typ == CCN_TT_DTAG && num == CCN_DTAG_COMPONENT
                        && p->compcnt < CCNL_MAX_NAME_COMP) {
                        if (hunt_for_end(data, datalen, p->comp + p->compcnt,
                                         p->complen + p->compcnt) < 0) {
                            goto Bail;
                        }

                        p->compcnt++;
                    }
                    else {
                        if (consume(typ, num, data, datalen, 0, 0) < 0) {
                            goto Bail;
                        }
                    }
                }

                continue;
            }

            if (num == CCN_DTAG_SCOPE || num == CCN_DTAG_NONCE
                || num == CCN_DTAG_MINSUFFCOMP
                || num == CCN_DTAG_MAXSUFFCOMP
                || num == CCN_DTAG_PUBPUBKDIGEST) {
                if (hunt_for_end(data, datalen, &cp, &len) < 0) {
                    goto Bail;
                }

                if (num == CCN_DTAG_SCOPE && len == 1 && scope) {
                    *scope = isdigit(*cp) && (*cp < '3') ? *cp - '0' : -1;
                }

                if (num == CCN_DTAG_ANSWERORIGKIND && aok) {
                    *aok = data2uint(cp, len);
                }

                if (num == CCN_DTAG_MINSUFFCOMP && min) {
                    *min = data2uint(cp, len);
                }

                if (num == CCN_DTAG_MAXSUFFCOMP && max) {
                    *max = data2uint(cp, len);
                }

                if (num == CCN_DTAG_NONCE && !n) {
                    n = ccnl_buf_new(cp, len);
                }

                if (num == CCN_DTAG_PUBPUBKDIGEST && !pub) {
                    pub = ccnl_buf_new(cp, len);
                }

                if (num == CCN_DTAG_EXCLUDE) {
                    DEBUGMSG(49, "warning: 'exclude' field ignored\n");
                }
                else {
                    continue;
                }
            }

            if (num == CCN_DTAG_CONTENT || num == CCN_DTAG_CONTENTOBJ) {
                if (consume(typ, num, data, datalen, content, contlen) < 0) {
                    goto Bail;
                }

                continue;
            }
        }

        if (consume(typ, num, data, datalen, 0, 0) < 0) {
            goto Bail;
        }
    }

    if (prefix) {
        p->comp[p->compcnt] = NULL;
        *prefix = p;
    }
    else {
        free_prefix(p);
    }

    if (nonce) {
        *nonce = n;
    }
    else {
        ccnl_free(n);
    }

    if (ppkd) {
        *ppkd = pub;
    }
    else {
        ccnl_free(pub);
    }

    buf = ccnl_buf_new(start, *data - start);

    if (!buf) {
        puts("can't get more memory from malloc, dropping ccn msg...");
        goto Bail;
    }

    // carefully rebase ptrs to new buf because of 64bit pointers:
    if (content) {
        *content = buf->data + (*content - start);
    }

    for (num = 0; num < p->compcnt; num++) {
        p->comp[num] = buf->data + (p->comp[num] - start);
    }

    return buf;
Bail:
    free_prefix(p);
    free_2ptr_list(n, pub);
    return NULL;
}
Exemplo n.º 18
0
// turn an URI into an internal prefix (watch out: this modifies the uri string)
struct ccnl_prefix_s *
ccnl_URItoPrefix(char* uri, int suite, char *nfnexpr, unsigned int *chunknum)
{
    struct ccnl_prefix_s *p;
    char *compvect[CCNL_MAX_NAME_COMP];
    unsigned int complens[CCNL_MAX_NAME_COMP];
    int cnt, i, len, tlen;

    DEBUGMSG_CPFX(TRACE, "ccnl_URItoPrefix(suite=%s, uri=%s, nfn=%s)\n",
             ccnl_suite2str(suite), uri, nfnexpr);

    if (strlen(uri))
        cnt = ccnl_URItoComponents(compvect, complens, uri);
    else
        cnt = 0;

    if (nfnexpr && *nfnexpr)
        cnt += 1;

    p = ccnl_prefix_new(suite, cnt);
    if (!p)
        return NULL;

    for (i = 0, len = 0; i < cnt; i++) {
        if (i == (cnt-1) && nfnexpr && *nfnexpr)
            len += strlen(nfnexpr);
        else
            len += complens[i];//strlen(compvect[i]);
    }
#ifdef USE_SUITE_CCNTLV
    if (suite == CCNL_SUITE_CCNTLV)
        len += cnt * 4; // add TL size
#endif
#ifdef USE_SUITE_CISTLV
    if (suite == CCNL_SUITE_CISTLV)
        len += cnt * 4; // add TL size
#endif

    p->bytes = (unsigned char*) ccnl_malloc(len);
    if (!p->bytes) {
        free_prefix(p);
        return NULL;
    }

    for (i = 0, len = 0, tlen = 0; i < cnt; i++) {
        int isnfnfcomp = i == (cnt-1) && nfnexpr && *nfnexpr;
        char *cp = isnfnfcomp ? nfnexpr : (char*) compvect[i];

        if (isnfnfcomp)
            tlen = strlen(nfnexpr);
        else
            tlen = complens[i];

        p->comp[i] = p->bytes + len;
        tlen = ccnl_pkt_mkComponent(suite, p->comp[i], cp, tlen);
        p->complen[i] = tlen;
        len += tlen;
    }

    p->compcnt = cnt;
#ifdef USE_NFN
    if (nfnexpr && *nfnexpr)
        p->nfnflags |= CCNL_PREFIX_NFN;
#endif

    if(chunknum) {
        p->chunknum = ccnl_malloc(sizeof(int));
        *p->chunknum = *chunknum;
    }

    return p;
}
Exemplo n.º 19
0
void free_content(struct ccnl_content_s *c)
{
    free_prefix(c->name);
    free_2ptr_list(c->pkt, c);
}
Exemplo n.º 20
0
struct ccnl_face_s*
ccnl_face_remove(struct ccnl_relay_s *ccnl, struct ccnl_face_s *f)
{
    struct ccnl_face_s *f2;
    struct ccnl_interest_s *pit;
    struct ccnl_forward_s **ppfwd;

    DEBUGMSG_CORE(DEBUG, "face_remove relay=%p face=%p\n",
             (void*)ccnl, (void*)f);

    ccnl_sched_destroy(f->sched);
    ccnl_frag_destroy(f->frag);

    DEBUGMSG_CORE(TRACE, "face_remove: cleaning PIT\n");
    for (pit = ccnl->pit; pit; ) {
        struct ccnl_pendint_s **ppend, *pend;
        if (pit->from == f)
            pit->from = NULL;
        for (ppend = &pit->pending; *ppend;) {
            if ((*ppend)->face == f) {
                pend = *ppend;
                *ppend = pend->next;
                ccnl_free(pend);
            } else
                ppend = &(*ppend)->next;
        }
        if (pit->pending)
            pit = pit->next;
        else {
            DEBUGMSG_CORE(TRACE, "before NFN interest_remove 0x%p\n",
                          (void*)pit);
            pit = ccnl_nfn_interest_remove(ccnl, pit);
        }
    }
    DEBUGMSG_CORE(TRACE, "face_remove: cleaning fwd table\n");
    for (ppfwd = &ccnl->fib; *ppfwd;) {
        if ((*ppfwd)->face == f) {
            struct ccnl_forward_s *pfwd = *ppfwd;
            free_prefix(pfwd->prefix);
            *ppfwd = pfwd->next;
            ccnl_free(pfwd);
        } else
            ppfwd = &(*ppfwd)->next;
    }
    DEBUGMSG_CORE(TRACE, "face_remove: cleaning pkt queue\n");
    while (f->outq) {
        struct ccnl_buf_s *tmp = f->outq->next;
        ccnl_free(f->outq);
        f->outq = tmp;
    }
    DEBUGMSG_CORE(TRACE, "face_remove: unlinking1 %p %p\n",
             (void*)f->next, (void*)f->prev);
    f2 = f->next;
    DEBUGMSG_CORE(TRACE, "face_remove: unlinking2\n");
    DBL_LINKED_LIST_REMOVE(ccnl->faces, f);
    DEBUGMSG_CORE(TRACE, "face_remove: unlinking3\n");
    ccnl_free(f);

    TRACEOUT();
    return f2;
}
Exemplo n.º 21
0
struct ccnl_buf_s*
ccnl_ccnb_extract(unsigned char **data, int *datalen,
		  int *scope, int *aok, int *min, int *max,
		  struct ccnl_prefix_s **prefix,
		  struct ccnl_buf_s **nonce,
		  struct ccnl_buf_s **ppkd,
		  unsigned char **content, int *contlen)
{
    unsigned char *start = *data - 2 /* account for outer TAG hdr */, *cp;
    int num, typ, len;
    struct ccnl_prefix_s *p;
    struct ccnl_buf_s *buf, *n = 0, *pub = 0;
    DEBUGMSG(99, "ccnl_ccnb_extract\n");

    p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s));
    if (!p) return NULL;
    p->comp = (unsigned char**) ccnl_malloc(CCNL_MAX_NAME_COMP *
					   sizeof(unsigned char**));
    p->complen = (int*) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(int));
    if (!p->comp || !p->complen) goto Bail;

    while (ccnl_ccnb_dehead(data, datalen, &num, &typ) == 0) {
	if (num==0 && typ==0) break; // end
	if (typ == CCN_TT_DTAG) {
	    if (num == CCN_DTAG_NAME) {
		for (;;) {
		    if (ccnl_ccnb_dehead(data, datalen, &num, &typ) != 0)
			goto Bail;
		    if (num==0 && typ==0)
			break;
		    if (typ == CCN_TT_DTAG && num == CCN_DTAG_COMPONENT &&
			p->compcnt < CCNL_MAX_NAME_COMP) {
			if (ccnl_ccnb_hunt_for_end(data, datalen, p->comp + p->compcnt,
				p->complen + p->compcnt) < 0) goto Bail;
			p->compcnt++;
		    } else {
			if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0)
			    goto Bail;
		    }
		}
		continue;
	    }
	    if (num == CCN_DTAG_SCOPE || num == CCN_DTAG_NONCE ||
		num == CCN_DTAG_MINSUFFCOMP || num == CCN_DTAG_MAXSUFFCOMP ||
					 num == CCN_DTAG_PUBPUBKDIGEST) {
		if (ccnl_ccnb_hunt_for_end(data, datalen, &cp, &len) < 0) goto Bail;
		if (num == CCN_DTAG_SCOPE && len == 1 && scope)
		    *scope = isdigit(*cp) && (*cp < '3') ? *cp - '0' : -1;
		if (num == CCN_DTAG_ANSWERORIGKIND && aok)
		    *aok = ccnl_ccnb_data2uint(cp, len);
		if (num == CCN_DTAG_MINSUFFCOMP && min)
		    *min = ccnl_ccnb_data2uint(cp, len);
		if (num == CCN_DTAG_MAXSUFFCOMP && max)
		    *max = ccnl_ccnb_data2uint(cp, len);
		if (num == CCN_DTAG_NONCE && !n)
		    n = ccnl_buf_new(cp, len);
		if (num == CCN_DTAG_PUBPUBKDIGEST && !pub)
		    pub = ccnl_buf_new(cp, len);
		if (num == CCN_DTAG_EXCLUDE) {
		    DEBUGMSG(49, "warning: 'exclude' field ignored\n");
		} else
		    continue;
	    }
	    if (num == CCN_DTAG_CONTENT) {
		if (ccnl_ccnb_consume(typ, num, data, datalen, content, contlen) < 0)
		    goto Bail;
		continue;
	    }
	}
	if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0) goto Bail;
    }
    if (prefix)    *prefix = p;    else free_prefix(p);
    if (nonce)     *nonce = n;     else ccnl_free(n);
    if (ppkd)      *ppkd = pub;    else ccnl_free(pub);

    buf = ccnl_buf_new(start, *data - start);
    // carefully rebase ptrs to new buf because of 64bit pointers:
    if (content)
	*content = buf->data + (*content - start);
    for (num = 0; num < p->compcnt; num++)
	    p->comp[num] = buf->data + (p->comp[num] - start);
    return buf;
Bail:
    free_prefix(p);
    free_2ptr_list(n, pub);
    return NULL;
}
Exemplo n.º 22
0
int ccnl_riot_client_get(kernel_pid_t relay_pid, char *name, char *reply_buf)
{
    char *prefix[CCNL_MAX_NAME_COMP];
    char *cp = strtok(name, "/");
    int i = 0;

    while (i < (CCNL_MAX_NAME_COMP - 1) && cp) {
        prefix[i++] = cp;
        cp = strtok(NULL, "/");
    }

    //prefix[i] = 0; //segment to request
    prefix[i + 1] = 0;

    int content_len = 0;

    for (int segment = 0; ; segment++) {
        char segment_string[16]; //max=999\0
        memset(segment_string, 0, 16);
        snprintf(segment_string, 16, "%d", segment);
        prefix[i] = segment_string;
        unsigned char *interest_pkg = malloc(PAYLOAD_SIZE);
        if (!interest_pkg) {
            puts("ccnl_riot_client_get: malloc failed");
            return 0;
        }
        unsigned int interest_nonce = genrand_uint32();
        int interest_len = mkInterest(prefix, &interest_nonce, interest_pkg);
        DEBUGMSG(1, "relay_pid=%" PRIkernel_pid " interest_len=%d\n", relay_pid, interest_len);

        riot_ccnl_msg_t rmsg;
        rmsg.payload = interest_pkg;
        rmsg.size = interest_len;

        msg_t m, rep;
        m.content.ptr = (char *) &rmsg;
        m.type = CCNL_RIOT_MSG;
        msg_send(&m, relay_pid, 1);

        /* ######################################################################### */

        msg_receive(&rep);
        free(interest_pkg);
        if (rep.type == CCNL_RIOT_NACK) {
            /* network stack was not able to fetch this chunk */
            return 0;
        }

        /* we got a chunk of data from the network stack */
        riot_ccnl_msg_t *rmsg_reply = (riot_ccnl_msg_t *) rep.content.ptr;

        unsigned char *data = rmsg_reply->payload;
        int datalen = (int) rmsg_reply->size;
        DEBUGMSG(1, "%d bytes left; msg from=%" PRIkernel_pid "\n", datalen, rep.sender_pid);

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

        buf = ccnl_extract_prefix_nonce_ppkd(&data, &datalen, &scope, &aok, &minsfx,
                                             &maxsfx, &p, &nonce, &ppkd, &content, &contlen);

        if (!buf) {
            DEBUGMSG(6, "  parsing error or no prefix\n");
            return 0;
        }

        DEBUGMSG(1, "content_len=%d contlen=%d\n", content_len, contlen);
        memcpy(reply_buf + content_len, content, contlen);
        content_len += contlen;

        free_prefix(p);
        free_3ptr_list(buf, nonce, ppkd);
        ccnl_free(rmsg_reply);

        DEBUGMSG(1, "contentlen=%d CCNL_RIOT_CHUNK_SIZE=%d\n", contlen, CCNL_RIOT_CHUNK_SIZE);
        if (contlen < CCNL_RIOT_CHUNK_SIZE || CCNL_RIOT_CHUNK_SIZE < contlen) {
            /* last chunk */
            break;
        }
    }

    return content_len;
}
Exemplo n.º 23
0
void
ccnl_populate_cache(struct ccnl_relay_s *ccnl, char *path)
{
    DIR *dir;
    struct dirent *de;
    int datalen;

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

    dir = opendir(path);
    if (!dir)
	return;
    while ((de = readdir(dir))) {
	if (!fnmatch("*.ccnb", 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 &&
			    buf->data[0] == 0x04 && buf->data[1] == 0x82) {
		    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 = buf->data + 2;
		    int contlen;

		    buf->datalen = datalen;
		    datalen -= 2;
		    pkt = ccnl_extract_prefix_nonce_ppkd(&data, &datalen, 0, 0,
			      0, 0, &prefix, &nonce, &ppkd, &content, &contlen);
		    if (!pkt) {
			DEBUGMSG(6, "  parsing error\n"); goto Done;
		    }
		    if (!prefix) {
			DEBUGMSG(6, "  no prefix error\n"); goto Done;
		    }
		    c = ccnl_content_new(ccnl, &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 {
		    DEBUGMSG(6, "  not a content object\n");
		    ccnl_free(buf);
		}
	    }
	}
    }
}
Exemplo n.º 24
0
void free_forward(struct ccnl_forward_s *fwd)
{
    free_prefix(fwd->prefix);
    ccnl_free(fwd);
}
Exemplo n.º 25
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;
}
Exemplo n.º 26
0
char*
ZAM_fox(struct ccnl_relay_s *ccnl, struct configuration_s *config,
        int *restart, int *halt, char *prog, char *arg, char *contd)
{
    int local_search = 0, i;
    int parameter_number = 0;
    struct ccnl_content_s *c = NULL;
    struct ccnl_prefix_s *pref;
    struct ccnl_interest_s *interest;

    DEBUGMSG(DEBUG, "---to do: FOX <%s>\n", arg);
    ccnl_free(arg);
    if (*restart) {
        *restart = 0;
        local_search = 1;
        goto recontinue;
    }

    {
        struct stack_s *h;
        h = pop_or_resolve_from_result_stack(ccnl, config);
        assert(h);
        //TODO CHECK IF INT
        config->fox_state->num_of_params = *(int*)h->content;
        h->next = NULL;
        ccnl_nfn_freeStack(h);
    }
    DEBUGMSG(DEBUG, "NUM OF PARAMS: %d\n", config->fox_state->num_of_params);

    config->fox_state->params = ccnl_malloc(sizeof(struct ccnl_stack_s *) *
                                            config->fox_state->num_of_params);

    for (i = 0; i < config->fox_state->num_of_params; ++i) {
        //pop parameter from stack
        config->fox_state->params[i] = pop_from_stack(&config->result_stack);
        switch (config->fox_state->params[i]->type) {
        case STACK_TYPE_INT:
            DEBUGMSG(DEBUG, "  info: Parameter %d %d\n", i,
                     *(int *)config->fox_state->params[i]->content);
            break;
        case STACK_TYPE_PREFIX:
            DEBUGMSG(DEBUG, "  info: Parameter %d %s\n", i,
                     ccnl_prefix_to_path((struct ccnl_prefix_s*)
                                      config->fox_state->params[i]->content));
            break;
        default:
            break;
        }
    }
    //as long as there is a routable parameter: try to find a result
    config->fox_state->it_routable_param = 0;

    //check if last result is now available
recontinue: //loop by reentering after timeout of the interest...
    if (local_search) {
        DEBUGMSG(DEBUG, "Checking if result was received\n");
        parameter_number = choose_parameter(config);
        pref = create_namecomps(ccnl, config, parameter_number,
                        config->fox_state->params[parameter_number]->content);
        // search for a result
        c = ccnl_nfn_local_content_search(ccnl, config, pref);
        set_propagate_of_interests_to_1(ccnl, pref);
        free_prefix(pref);
        //TODO Check? //TODO remove interest here?
        if (c) {
	    DEBUGMSG(DEBUG, "Result was found\n");
            DEBUGMSG_CFWD(INFO, "data after result was found %.*s\n", c->pkt->contlen, c->pkt->content);
            goto handlecontent;
	}
    }

    //result was not delivered --> choose next parameter
    ++config->fox_state->it_routable_param;
    parameter_number = choose_parameter(config);
    if (parameter_number < 0)
        //no more parameter --> no result found, can try a local computation
        goto local_compute;
    // create new prefix with name components!!!!
    pref = create_namecomps(ccnl, config, parameter_number,
                        config->fox_state->params[parameter_number]->content);
    c = ccnl_nfn_local_content_search(ccnl, config, pref);
    if (c) {
        free_prefix(pref);
        goto handlecontent;
    }

    // Result not in cache, search over the network
//    pref2 = ccnl_prefix_dup(pref);
    interest = ccnl_nfn_query2interest(ccnl, &pref, config);
    if (pref)
        free_prefix(pref);
    if (interest) {
        ccnl_interest_propagate(ccnl, interest);
        DEBUGMSG(DEBUG, "  new interest's face is %d\n", interest->from->faceid);
    }
    // wait for content, return current program to continue later
    *halt = -1; //set halt to -1 for async computations
    return ccnl_strdup(prog);

local_compute:
    if (config->local_done)
        return NULL;

    config->local_done = 1;
    pref = ccnl_nfnprefix_mkComputePrefix(config, config->suite);
    DEBUGMSG(DEBUG, "Prefix local computation: %s\n",
             ccnl_prefix_to_path(pref));
    interest = ccnl_nfn_query2interest(ccnl, &pref, config);
    if (pref)
        free_prefix(pref);
    if (interest)
        ccnl_interest_propagate(ccnl, interest);

handlecontent: //if result was found ---> handle it
    if (c) {
#ifdef USE_NACK
        if (!strncmp((char*)c->pkt->content, ":NACK", 5)) {
            DEBUGMSG(DEBUG, "NACK RECEIVED, going to next parameter\n");
            ++config->fox_state->it_routable_param;
            return prog ? ccnl_strdup(prog) : NULL;
        }
#endif
        int isANumber = 1, i = 0;
	    for(i = 0; i < c->pkt->contlen; ++i){
	    	if(!isdigit(c->pkt->content[i])){
                isANumber = 0;
                break;
            }
	    }
	    
        if (isANumber){
            int *integer = ccnl_malloc(sizeof(int));
            *integer = strtol((char*)c->pkt->content, 0, 0);
            push_to_stack(&config->result_stack, integer, STACK_TYPE_INT);
        } else {
            struct prefix_mapping_s *mapping;
            struct ccnl_prefix_s *name =
                create_prefix_for_content_on_result_stack(ccnl, config);
            push_to_stack(&config->result_stack, name, STACK_TYPE_PREFIX);
            mapping = ccnl_malloc(sizeof(struct prefix_mapping_s));
            mapping->key = ccnl_prefix_dup(name); //TODO COPY
            mapping->value = ccnl_prefix_dup(c->pkt->pfx);
            DBL_LINKED_LIST_ADD(config->fox_state->prefix_mapping, mapping);
            DEBUGMSG(DEBUG, "Created a mapping %s - %s\n",
                        ccnl_prefix_to_path(mapping->key),
                        ccnl_prefix_to_path(mapping->value));
        }
    }
    
    DEBUGMSG(DEBUG, " FOX continuation: %s\n", contd);
    return ccnl_strdup(contd);
}