예제 #1
0
struct timeval *
ccnl_run_events(void)
{
    static struct timeval now;
    long usec;

    ccnl_get_timeval(&now);
    //DEBUGMSG(1, "ccnl_run_events now: %ld:%ld\n", now.tv_sec, now.tv_usec);

    while (eventqueue) {
        struct ccnl_timer_s *t = eventqueue;
        usec = timevaldelta(&(t->timeout), &now);

        if (usec >= 0) {
            //DEBUGMSG(1, "ccnl_run_events nothing to do: %ld:%ld\n", now.tv_sec, now.tv_usec);
            now.tv_sec = usec / 1000000;
            now.tv_usec = usec % 1000000;
            return &now;
        }

        //DEBUGMSG(1, "ccnl_run_events run event handler: %ld:%ld\n", now.tv_sec, now.tv_usec);
        if (t->fct) {
            (t->fct)(t->node, t->intarg);
        }
        else if (t->fct2) {
            (t->fct2)(t->aux1, t->aux2);
        }

        eventqueue = t->next;
        ccnl_free(t);
    }

    return NULL;
}
예제 #2
0
/**
 * @brief initializing routing system
 * @param pointer to count transceiver pids
 *
 */
void *ccnl_riot_relay_start(void *arg)
{
    (void) arg;

    theRelay = calloc(1, sizeof(struct ccnl_relay_s));
    ccnl_get_timeval(&theRelay->startup_time);
    theRelay->riot_pid = sched_active_pid;
    mutex_init(&theRelay->global_lock);

    DEBUGMSG(1, "This is ccn-lite-relay, starting at %lu:%lu\n", theRelay->startup_time.tv_sec, theRelay->startup_time.tv_usec);
    DEBUGMSG(1, "  compile time: %s %s\n", __DATE__, __TIME__);
    DEBUGMSG(1, "  max_cache_entries: %d\n", CCNL_DEFAULT_MAX_CACHE_ENTRIES);
    DEBUGMSG(1, "  threshold_prefix: %d\n", CCNL_DEFAULT_THRESHOLD_PREFIX);
    DEBUGMSG(1, "  threshold_aggregate: %d\n", CCNL_DEFAULT_THRESHOLD_AGGREGATE);

    ccnl_relay_config(theRelay, CCNL_DEFAULT_MAX_CACHE_ENTRIES, CCNL_DEFAULT_THRESHOLD_PREFIX, CCNL_DEFAULT_THRESHOLD_AGGREGATE);

    theRelay->riot_helper_pid = riot_start_helper_thread();

    ccnl_io_loop(theRelay);
    DEBUGMSG(1, "ioloop stopped\n");

    while (eventqueue) {
        ccnl_rem_timer(eventqueue);
    }

    ccnl_core_cleanup(theRelay);

    mutex_lock(&theRelay->stop_lock);
    ccnl_free(theRelay);
    return NULL;
}
예제 #3
0
파일: ccnl-core.c 프로젝트: AnonMall/RIOT
struct ccnl_interest_s *
ccnl_interest_new(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from,
                  struct ccnl_buf_s **pkt, struct ccnl_prefix_s **prefix, int minsuffix,
                  int maxsuffix, struct ccnl_buf_s **ppkd)
{
    struct ccnl_interest_s *i = (struct ccnl_interest_s *) ccnl_calloc(1,
                                sizeof(struct ccnl_interest_s));
    DEBUGMSG(99, "ccnl_new_interest\n");

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

    i->from = from;
    i->prefix = *prefix;
    *prefix = 0;
    i->pkt = *pkt;
    *pkt = 0;
    i->ppkd = *ppkd;
    *ppkd = 0;
    i->minsuffix = minsuffix;
    i->maxsuffix = maxsuffix;
    ccnl_get_timeval(&i->last_used);
    DBL_LINKED_LIST_ADD(ccnl->pit, i);
    return i;
}
예제 #4
0
static cf_time ccnl_cf_now()
{
    struct timeval now;

    ccnl_get_timeval(&now);
    return ((cf_time)now.tv_sec) * 1000000000 + now.tv_usec * 1000;
}
예제 #5
0
struct ccnl_sched_s*
ccnl_sched_pktrate_new(void (cts)(void *aux1, void *aux2),
                       struct ccnl_relay_s *ccnl, int inter_packet_interval)
{
    struct ccnl_sched_s *s;

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

    s = (struct ccnl_sched_s*) ccnl_calloc(1, sizeof(struct ccnl_sched_s));
    if (!s)
        return NULL;
    s->mode = 1;
    s->cts = cts;
    s->ccnl = ccnl;
#ifdef USE_CHEMFLOW
    if (cfnl_sched_create_default_rnet(s, inter_packet_interval)) {
        ccnl_free(s);
        return NULL;
    }
#else
    ccnl_get_timeval(&(s->nextTX));
    s->ipi = inter_packet_interval;
#endif

    return s;
}
예제 #6
0
void *
ccnl_set_timer(int usec, void (*fct)(void *aux1, void *aux2),
               void *aux1, void *aux2)
{
    struct ccnl_timer_s *t, **pp;
    static int handlercnt;

    t = (struct ccnl_timer_s *) ccnl_calloc(1, sizeof(*t));

    if (!t) {
        return 0;
    }

    t->fct2 = fct;
    ccnl_get_timeval(&t->timeout);
    usec += t->timeout.tv_usec;
    t->timeout.tv_sec += usec / 1000000;
    t->timeout.tv_usec = usec % 1000000;
    t->aux1 = aux1;
    t->aux2 = aux2;

    for (pp = &eventqueue; ; pp = &((*pp)->next)) {
        if (!*pp || (*pp)->timeout.tv_sec > t->timeout.tv_sec ||
            ((*pp)->timeout.tv_sec == t->timeout.tv_sec &&
             (*pp)->timeout.tv_usec > t->timeout.tv_usec)) {
            t->next = *pp;
            t->handler = handlercnt++;
            *pp = t;
            return t;
        }
    }

    return NULL; // ?
}
예제 #7
0
파일: ccnl-core.c 프로젝트: AnonMall/RIOT
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;
        }
    }
}
예제 #8
0
파일: ccnl-core.c 프로젝트: AnonMall/RIOT
struct ccnl_content_s *
ccnl_content_new(struct ccnl_relay_s *ccnl, struct ccnl_buf_s **pkt,
                 struct ccnl_prefix_s **prefix, struct ccnl_buf_s **ppkd,
                 unsigned char *content, int contlen)
{

    (void) ccnl; /* unused */

    struct ccnl_content_s *c;
    //    DEBUGMSG(99, "ccnl_content_new <%s>\n",
    //            prefix == NULL ? NULL : ccnl_prefix_to_path(*prefix));

    c = (struct ccnl_content_s *) ccnl_calloc(1, sizeof(struct ccnl_content_s));

    if (!c) {
        return NULL;
    }

    ccnl_get_timeval(&c->last_used);
    c->content = content;
    c->contentlen = contlen;
    c->pkt = *pkt;
    *pkt = NULL;
    c->name = *prefix;
    *prefix = NULL;

    if (ppkd) {
        c->ppkd = *ppkd;
        *ppkd = NULL;
    }

    return c;
}
예제 #9
0
static int
current_time(void)
{
    struct timeval tv;

    ccnl_get_timeval(&tv);
    return tv.tv_sec;
}
예제 #10
0
파일: ccnl-core.c 프로젝트: AnonMall/RIOT
void ccnl_interest_propagate(struct ccnl_relay_s *ccnl,
                             struct ccnl_interest_s *i)
{
    struct ccnl_forward_s *fwd;
    DEBUGMSG(99, "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
    int forward_cnt = 0;
    for (fwd = ccnl->fib; fwd; fwd = fwd->next) {
        int rc = ccnl_prefix_cmp(fwd->prefix, NULL, i->prefix, CMP_LONGEST);
        DEBUGMSG(40, "  ccnl_interest_propagate, rc=%d/%d\n", rc,
                 fwd->prefix->compcnt);

        if (rc < fwd->prefix->compcnt) {
            continue;
        }

        DEBUGMSG(40, "  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)) {

            i->forwarded_over = fwd;
            fwd->face->stat.send_interest[i->retries]++;
            ccnl_get_timeval(&i->last_used);
            ccnl_face_enqueue(ccnl, fwd->face, buf_dup(i->pkt));
            ccnl_get_timeval(&fwd->last_used);
            forward_cnt++;
        }
    }

    if (forward_cnt == 0) {
        DEBUGMSG(40, "  ccnl_interest_propagate: using broadcast face!\n");
        ccnl->ifs[RIOT_TRANS_IDX].broadcast_face->stat.send_interest[i->retries]++;
        ccnl_get_timeval(&i->last_used);
        ccnl_face_enqueue(ccnl, ccnl->ifs[RIOT_TRANS_IDX].broadcast_face, buf_dup(i->pkt));
    }

    return;
}
예제 #11
0
void
ccnl_sched_CTS_done(struct ccnl_sched_s *s, int cnt, int len)
{
#ifdef USE_CHEMFLOW
    cf_time now = ccnl_cf_now();
#else
    struct timeval now;
    long since;
#endif

    if (!s) {
        DEBUGMSG(VERBOSE, "ccnl_sched_CTS_done sched=%p cnt=%d len=%d\n",
             (void*)s, cnt, len);
        return;
    }
    DEBUGMSG(VERBOSE, "ccnl_sched_CTS_done sched=%p/%d cnt=%d len=%d (mycnt=%d)\n",
             (void*)s, s->mode, cnt, len, s->cnt);

    s->cnt -= cnt;
    if (s->cnt <= 0)
        return;

    if (s->mode == 0) {
        s->cts(s->aux1, s->aux2);
        return;
    }

#ifdef USE_CHEMFLOW
    if (CF_OK == cf_queue_dequeue_packet(s->q, 1)) {
        DEBUGMSG(VERBOSE, "  cf_dequeue successful; CTS\n");
        cf_queue_update_concentrations(s->q, now);
        cf_engine_reschedule_and_set_timer(engine, now);
        s->cts(s->aux1, s->aux2);
    }
#else
    ccnl_get_timeval(&now);

    since = timevaldelta(&(s->nextTX), &now);
    if (since <= 0) {
        now.tv_sec += s->ipi / 1000000;
        now.tv_usec += s->ipi % 1000000;
        memcpy(&(s->nextTX), &now, sizeof(now));
        s->cts(s->aux1, s->aux2);
        return;
    }
    DEBUGMSG(VERBOSE, "since=%ld\n", since);
//    ccnl_set_timer(since, (void(*)(void*,int))signal_cts, ccnl, ifndx);
    s->pendingTimer = ccnl_set_timer(since, s->cts, s->aux1, s->aux2);
    s->nextTX.tv_sec += s->ipi / 1000000;;
    s->nextTX.tv_usec += s->ipi % 1000000;;

//    s->cts();
#endif
}
예제 #12
0
파일: ccnl-core.c 프로젝트: AnonMall/RIOT
struct ccnl_nonce_s *ccnl_nonce_new(struct ccnl_buf_s *that)
{
    struct ccnl_nonce_s *n = (struct ccnl_nonce_s *) ccnl_malloc(sizeof(struct ccnl_nonce_s));

    n->buf = buf_dup(that);
    ccnl_get_timeval(&n->created);

    n->next = NULL;
    n->prev = NULL;

    return n;
}
예제 #13
0
파일: ccnl-core.c 프로젝트: AnonMall/RIOT
// 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;
}
예제 #14
0
void
ccnl_sched_RTS(struct ccnl_sched_s *s, int cnt, int len,
               void *aux1, void *aux2)
{
#ifdef USE_CHEMFLOW
    cf_time now = ccnl_cf_now();
#else
    struct timeval now;
    long since;
#endif

    if (!s) {
        DEBUGMSG(VERBOSE, "ccnl_sched_RTS sched=%p len=%d aux1=%p aux2=%p\n",
             (void*)s, len, (void*)aux1, (void*)aux2);
        return;
    }
    DEBUGMSG(VERBOSE, "ccnl_sched_RTS sched=%p/%d len=%d aux1=%p aux2=%p\n",
             (void*)s, s->mode, len, (void*)aux1, (void*)aux2);

    s->cnt += cnt;
    s->aux1 = aux1;
    s->aux2 = aux2;

    if (s->mode == 0) {
        s->cts(aux1, aux2);
        return;
    }

#ifdef USE_CHEMFLOW
    for (; cnt; --cnt) {
        DEBUGMSG(VERBOSE, "  cf_enqueuen");
        if (CF_OK == cf_queue_enqueue_packet(s->q, 1)) {
            cf_queue_update_concentrations(s->q, now);
            cf_engine_reschedule_and_set_timer(engine, now);
        }
    }
#else
    ccnl_get_timeval(&now);
    since = timevaldelta(&(s->nextTX), &now);
    if (since <= 0) {
        now.tv_sec += s->ipi / 1000000;
        now.tv_usec += s->ipi % 1000000;
        memcpy(&(s->nextTX), &now, sizeof(now));
        s->cts(aux1, aux2);
        return;
    }
    DEBUGMSG(VERBOSE, "since=%ld\n", since);
//    ccnl_set_timer(since, (void(*)(void*,int))signal_cts, ccnl, ifndx);
    s->pendingTimer = ccnl_set_timer(since, s->cts, aux1, aux2);
    s->nextTX.tv_sec += s->ipi / 1000000;;
    s->nextTX.tv_usec += s->ipi % 1000000;;
#endif
}
예제 #15
0
파일: ccnl-core.c 프로젝트: AnonMall/RIOT
int ccnl_interest_append_pending(struct ccnl_interest_s *i,
                                 struct ccnl_face_s *from)
{
    struct ccnl_pendint_s *pi, *last = NULL;
    DEBUGMSG(99, "ccnl_append_pending\n");

    for (pi = i->pending; pi; pi = pi->next) { // check whether already listed
        if (pi->face == from) {
            DEBUGMSG(40, "  we found a matching interest, updating time\n");
            ccnl_get_timeval(&pi->last_used);
            return 0;
        }

        last = pi;
    }

    pi = (struct ccnl_pendint_s *) ccnl_calloc(1,
            sizeof(struct ccnl_pendint_s));
    DEBUGMSG(40, "  appending a new pendint entry %p\n", (void *) pi);

    if (!pi) {
        return -1;
    }

    pi->face = from;
    ccnl_get_timeval(&pi->last_used);

    if (last) {
        last->next = pi;
    }
    else {
        i->pending = pi;
    }

    return 0;
}
예제 #16
0
double
current_time()
{
    struct timeval tv;
    static time_t start;
    static time_t start_usec;

    ccnl_get_timeval(&tv);

    if (!start) {
	start = tv.tv_sec;
	start_usec = tv.tv_usec;
    }

    return (double)(tv.tv_sec) - start +
		((double)(tv.tv_usec) - start_usec) / 1000000;
}
예제 #17
0
파일: ccnl-core.c 프로젝트: AnonMall/RIOT
void ccnl_do_nonce_timeout(void *ptr, void *dummy)
{
    (void) dummy; /* unused */

    struct ccnl_relay_s *relay = (struct ccnl_relay_s *) ptr;

    struct timeval now;
    ccnl_get_timeval(&now);
    //DEBUGMSG(99, "ccnl_do_nonce_timeout: %lu:%lu\n", now.tv_sec, now.tv_usec);

    for (struct ccnl_nonce_s *n = relay->nonces; n;) {
        if (ccnl_is_timed_out(&now, &n->created, CCNL_NONCE_TIMEOUT_SEC, CCNL_NONCE_TIMEOUT_USEC)) {
            n = ccnl_nonce_remove(relay, n);
        } else {
            n = n->next;
        }
    }
}
예제 #18
0
struct ccnl_sched_s*
ccnl_sched_packetratelimiter_new(int inter_packet_interval,
                                 void (*cts)(void *aux1, void *aux2),
                                 void *aux1, void *aux2)
{
    struct ccnl_sched_s *s;
    DEBUGMSG(TRACE, "ccnl_rate:limiter_new()\n");

    s = (struct ccnl_sched_s*) ccnl_calloc(1, sizeof(struct ccnl_sched_s));
    if (s) {
        s->cts = cts;
        s->aux1 = aux1;
        s->aux2 = aux2;
#ifndef USE_CHEMFLOW
        ccnl_get_timeval(&s->nextTX);
        s->ipi = inter_packet_interval;
#endif
    }
    return s;
}
예제 #19
0
char *
timestamp(void)
{
    static char ts[30], *cp;
    struct timeval now;
    ccnl_get_timeval(&now);

    sprintf(ts, "%.4lu", (time_t) 100000 * now.tv_sec + now.tv_usec);
    cp = strchr(ts, '.');

    if (!cp) {
        strcat(ts, ".0000");
    }
    else if (strlen(cp) > 5) {
        cp[5] = '\0';
    }
    else while (strlen(cp) < 5) {
            strcat(cp, "0");
        }

    return ts;
}
예제 #20
0
파일: ccnl-core.c 프로젝트: AnonMall/RIOT
void ccnl_content_learn_name_route(struct ccnl_relay_s *ccnl, struct ccnl_prefix_s *p, struct ccnl_face_s *f, int threshold_prefix, int flags)
{
    /*
     * we want to insert a new dynamic route in the fib, let's try to aggregate!
     * for aggregation we ask the fib for a prefix match
     */
    int match_len;
    struct ccnl_forward_s *fwd = ccn_forward_find_common_prefix_to_aggregate(ccnl, p, &match_len);
    if (!fwd) {
        /* there was no prefix match with the user defined creteria. */

        /* create a new fib entry */
        fwd = ccnl_forward_new(p, f, threshold_prefix, flags);
        DBL_LINKED_LIST_ADD(ccnl->fib, fwd);
        DEBUGMSG(999, "ccnl_content_learn_name_route: new route '%s' on face %d learned\n", ccnl_prefix_to_path(fwd->prefix), f->faceid);
    }
    else {
        /* there was a prefix match with the user defined creteria. */

        /* if the new entry has shorter prefix */
        if (p->compcnt < fwd->prefix->compcnt) {
            /* we need to aggregate! */
            DBL_LINKED_LIST_REMOVE(ccnl->fib, fwd);

            /* create a new fib entry */
            fwd = ccnl_forward_new(p, f, (p->compcnt - match_len), flags);
            DBL_LINKED_LIST_ADD(ccnl->fib, fwd);
            DEBUGMSG(999, "ccnl_content_learn_name_route: route '%s' on face %d replaced\n", ccnl_prefix_to_path(fwd->prefix), f->faceid);
        }
        else {
            /* we don't need to do an update, because we know a shorter prefix already */
        }
    }

    /* refresh fwd entry */
    DEBUGMSG(999, "ccnl_content_learn_name_route refresh route '%s' on face %d\n", ccnl_prefix_to_path(fwd->prefix), f->faceid);
    ccnl_get_timeval(&fwd->last_used);
}
예제 #21
0
파일: ccnl-core.c 프로젝트: AnonMall/RIOT
struct ccnl_face_s *
ccnl_get_face_or_create(struct ccnl_relay_s *ccnl, int ifndx, uint16_t sender_id)
{
    struct ccnl_face_s *f;

    for (f = ccnl->faces; f; f = f->next) {
        if (ifndx == f->ifndx && (f->faceid == sender_id)) {
            DEBUGMSG(1, "face found! ifidx=%d sender_id=%d faceid=%d\n", ifndx, sender_id, f->faceid);
            ccnl_get_timeval(&f->last_used);
            return f;
        }
    }

    f = (struct ccnl_face_s *) ccnl_calloc(1, sizeof(struct ccnl_face_s));
    if (!f) {
        return NULL;
    }

    f->faceid = sender_id;
    f->ifndx = ifndx;

    if (sender_id == RIOT_BROADCAST) {
        f->flags |= CCNL_FACE_FLAGS_BROADCAST;
    }

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

    f->peer.id = sender_id;

#ifdef USE_FRAG

    if (ifndx == RIOT_TRANS_IDX) {
        // if newly created face, no fragment policy is defined yet
        // turning on fragmentation for riot trans dev based faces
        int flagval = CCNL_FACE_FLAGS_STATIC;
        f->flags = flagval &
                   (CCNL_FACE_FLAGS_STATIC | CCNL_FACE_FLAGS_REFLECT);

        if (f->frag) {
            ccnl_frag_destroy(f->frag);
            f->frag = NULL;
        }

        int mtu = ccnl->ifs[f->ifndx].mtu;
        f->frag = ccnl_frag_new(CCNL_FRAG_CCNx2013, mtu); //TODO
    }

#endif

    ccnl_get_timeval(&f->last_used);
    DBL_LINKED_LIST_ADD(ccnl->faces, f);

    return f;
}