Esempio n. 1
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;
        ccnl_prefix_free(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);
}
Esempio n. 2
0
void ccnl_core_cleanup(struct ccnl_relay_s *ccnl)
{
    int k;
    DEBUGMSG(99, "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);    // also removes all FWD entries
    }

    while (ccnl->contents) {
        ccnl_content_remove(ccnl, ccnl->contents);
    }

    while (ccnl->nonces) {
        ccnl_nonce_remove(ccnl, ccnl->nonces);
    }

    for (k = 0; k < ccnl->ifcount; k++) {
        ccnl_interface_cleanup(ccnl->ifs + k);
    }
}
Esempio n. 3
0
void ccnl_do_ageing(void *ptr, void *dummy)
{

    (void) dummy; /* unused */

    struct ccnl_relay_s *relay = (struct ccnl_relay_s *) ptr;
    struct ccnl_interest_s *i = relay->pit;
    struct ccnl_content_s *c = relay->contents;

    struct ccnl_face_s *f = relay->faces;
    struct timeval now;
    ccnl_get_timeval(&now);
    //DEBUGMSG(999, "ccnl_do_ageing %ld:%ld\n", now.tv_sec, now.tv_usec);

    while (i) {
        if (ccnl_is_timed_out(&now, &i->last_used, CCNL_INTEREST_TIMEOUT_SEC,
                CCNL_INTEREST_TIMEOUT_USEC)) {
            if (i->from->ifndx == RIOT_MSG_IDX) {
                /* this interest was requested by an app from this node */
                /* inform this app about this problem */
                riot_send_nack(i->from->faceid);
            }
            i = ccnl_interest_remove(relay, i);
        }
        else {
            i = i->next;
        }
    }

    while (c) {
        if (ccnl_is_timed_out(&now, &c->last_used, CCNL_CONTENT_TIMEOUT_SEC, CCNL_CONTENT_TIMEOUT_USEC)
            && !(c->flags & CCNL_CONTENT_FLAGS_STATIC)) {
            c = ccnl_content_remove(relay, c);
        }
        else {
            c = c->next;
        }
    }

    while (f) {
        if (!(f->flags & CCNL_FACE_FLAGS_STATIC)
            && ccnl_is_timed_out(&now, &f->last_used, CCNL_FACE_TIMEOUT_SEC, CCNL_FACE_TIMEOUT_USEC)) {
            f = ccnl_face_remove(relay, f);
        }
        else {
            f = f->next;
        }
    }

    struct ccnl_forward_s *fwd = relay->fib;
    while (fwd) {
        if (!(fwd->flags & CCNL_FORWARD_FLAGS_STATIC)
            && ccnl_is_timed_out(&now, &fwd->last_used, CCNL_FWD_TIMEOUT_SEC, CCNL_FWD_TIMEOUT_USEC)) {
            fwd = ccnl_forward_remove(relay, fwd);
        }
        else {
            fwd = fwd->next;
        }
    }
}
Esempio n. 4
0
// 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_face_s *from)
{
    struct ccnl_interest_s *i;
    struct ccnl_face_s *f;
    int cnt = 0;
    DEBUGMSG(99, "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 (!ccnl_i_prefixof_c(i->prefix, i->ppkd, i->minsuffix, i->maxsuffix,
                               c)) {
            i = i->next;
            continue;
        }

        // 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;
            }

            if (pi->face == from) {
                // the existing pending interest is from the same face
                // as the newly arrived content is...no need to send content back
                DEBUGMSG(1, "  detected looping content, before loop could happen\n");
                continue;
            }

            pi->face->flags |= CCNL_FACE_FLAGS_SERVED;

            DEBUGMSG(6, "  forwarding content <%s>\n",
                     ccnl_prefix_to_path(c->name));
            pi->face->stat.send_content[c->served_cnt % CCNL_MAX_CONTENT_SERVED_STAT]++;
            ccnl_face_enqueue(ccnl, pi->face, buf_dup(c->pkt));

            c->served_cnt++;
            ccnl_get_timeval(&c->last_used);
            cnt++;
        }

        i = ccnl_interest_remove(ccnl, i);
    }

    return cnt;
}
Esempio n. 5
0
int
ccnl_nfn_RX_result(struct ccnl_relay_s *relay, struct ccnl_face_s *from,
                   struct ccnl_content_s *c)
{
    struct ccnl_interest_s *i_it = NULL;
    int found = 0;

    DEBUGMSG_CFWD(INFO, "data in rx result %.*s\n", c->pkt->contlen, c->pkt->content);
    TRACEIN();
#ifdef USE_NACK
    if (ccnl_nfnprefix_contentIsNACK(c)) {
        ccnl_nfn_nack_local_computation(relay, c->pkt->buf, c->pkt->pfx,
                                        from, c->pkt->pfx->suite);
        return -1;
    }
#endif // USE_NACK
    for (i_it = relay->pit; i_it;/* i_it = i_it->next*/) {
        //Check if prefix match and it is a nfn request
        if (!ccnl_prefix_cmp(c->pkt->pfx, NULL, i_it->pkt->pfx, CMP_EXACT) &&
                                        i_it->from && i_it->from->faceid < 0) {
            struct ccnl_face_s *from = i_it->from;
            int faceid = - from->faceid;

            DEBUGMSG(TRACE, "  interest faceid=%d\n", i_it->from->faceid);

            ccnl_content_add2cache(relay, c);
	    DEBUGMSG_CFWD(INFO, "data in rx resulti after add to cache %.*s\n", c->pkt->contlen, c->pkt->content);
            DEBUGMSG(DEBUG, "Continue configuration for configid: %d with prefix: %s\n",
                  faceid, ccnl_prefix_to_path(c->pkt->pfx));
            i_it->flags |= CCNL_PIT_COREPROPAGATES;
            i_it->from = NULL;
            ccnl_nfn_continue_computation(relay, faceid, 0);
            i_it = ccnl_interest_remove(relay, i_it);
            //ccnl_face_remove(relay, from);
            ++found;
            //goto Done;
        } else
            i_it = i_it->next;
    }
    TRACEOUT();
    return found > 0;
}
Esempio n. 6
0
int
ccnl_nfn_RX_result(struct ccnl_relay_s *relay, struct ccnl_face_s *from,
                   struct ccnl_content_s *c)
{
    struct ccnl_interest_s *i_it = NULL;
    int found = 0;

    DEBUGMSG(TRACE, "ccnl_nfn_RX_result()\n");
#ifdef USE_NACK
    if (ccnl_nfnprefix_contentIsNACK(c)) {
        ccnl_nfn_nack_local_computation(relay, c->pkt, c->name,
                                        from, c->name->suite);
        return -1;
    }
#endif // USE_NACK
    for (i_it = relay->pit; i_it;/* i_it = i_it->next*/) {
        //Check if prefix match and it is a nfn request
        DEBUGMSG(DEBUG, "CMP: %d (match if zero), faceid: %d \n", 
			ccnl_prefix_cmp(c->name, NULL, i_it->prefix, CMP_EXACT),
			i_it->from->faceid);
        if (!ccnl_prefix_cmp(c->name, NULL, i_it->prefix, CMP_EXACT) &&
                                                i_it->from->faceid < 0) {
            int faceid = -i_it->from->faceid;

            ccnl_content_add2cache(relay, c);
	    DEBUGMSG(DEBUG, "Continue configuration for configid: %d with prefix: %s\n",
                     -i_it->from->faceid, ccnl_prefix_to_path(c->name));
            i_it->flags |= CCNL_PIT_COREPROPAGATES;
            i_it = ccnl_interest_remove(relay, i_it);
            ccnl_nfn_continue_computation(relay, faceid, 0);
            ++found;
            //goto Done;
        }
        else
            i_it = i_it->next;
    }
    return found > 0;
}
Esempio n. 7
0
// 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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
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(1, "ccnl_face_remove relay=%p face=%p\n", (void *) ccnl, (void *) f);

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

    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 {
            pit = ccnl_interest_remove(ccnl, pit);
        }
    }

    for (ppfwd = &ccnl->fib; *ppfwd;) {
        if ((*ppfwd)->face == f) {
            struct ccnl_forward_s *pfwd = *ppfwd;
            *ppfwd = pfwd->next;

            ccnl_forward_remove(ccnl, pfwd);
        }
        else {
            ppfwd = &(*ppfwd)->next;
        }
    }

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

#if ENABLE_DEBUG
    ccnl_face_print_stat(f);
#endif

    f2 = f->next;
    DBL_LINKED_LIST_REMOVE(ccnl->faces, f);
    ccnl_free(f);
    return f2;
}