void*
ccnl_set_absolute_timer(struct timeval abstime, 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;
    t->timeout = abstime;
    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; // ?
}
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;
}
Exemple #3
0
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;
}
Exemple #4
0
int
ccnl_interest_append_pending(struct ccnl_interest_s *i,
                             struct ccnl_face_s *from)
{
    struct ccnl_pendint_s *pi, *last = NULL;
    DEBUGMSG_CORE(TRACE, "ccnl_append_pending\n");

    for (pi = i->pending; pi; pi = pi->next) { // check whether already listed
        if (pi->face == from) {
            DEBUGMSG_CORE(DEBUG, "  we found a matching interest, updating time\n");
            pi->last_used = CCNL_NOW();
            return 0;
        }
        last = pi;
    }
    pi = (struct ccnl_pendint_s *) ccnl_calloc(1,sizeof(struct ccnl_pendint_s));
    if (!pi) {
        DEBUGMSG_CORE(DEBUG, "  no mem\n");
        return -1;
    }
    DEBUGMSG_CORE(DEBUG, "  appending a new pendint entry %p\n", (void *) pi);
    pi->face = from;
    pi->last_used = CCNL_NOW();
    if (last)
        last->next = pi;
    else
        i->pending = pi;
    return 0;
}
Exemple #5
0
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;
}
Exemple #6
0
/* ---------------------------------------------------------------------- */
struct ccnl_frag_s *
ccnl_frag_new(int protocol, int mtu)
{
    struct ccnl_frag_s *e = NULL;

    DEBUGMSG(8, "ccnl_frag_new proto=%d mtu=%d\n", protocol, mtu);

    switch (protocol) {
        case CCNL_FRAG_SEQUENCED2012:
        case CCNL_FRAG_CCNx2013:
            e = (struct ccnl_frag_s *) ccnl_calloc(1, sizeof(struct ccnl_frag_s));

            if (e) {
                e->protocol = protocol;
                e->mtu = mtu;
                e->flagwidth = 1;
                e->sendseqwidth = 4;
                e->losscountwidth = 2;
                e->recvseqwidth = 4;
            }

            break;

        case CCNL_FRAG_NONE:
        default:
            break;
    }

    return e;
}
Exemple #7
0
struct ccnl_http_s*
ccnl_http_new(struct ccnl_relay_s *ccnl, int serverport)
{
    int s, i = 1;
    struct sockaddr_in me;
    struct ccnl_http_s *http;

    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (!s)
        return NULL;
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));

    me.sin_family = AF_INET;
    me.sin_port = htons(serverport);
    me.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(s, (struct sockaddr*) &me, sizeof(me)) < 0) {
        close(s);
        return NULL;
    }
    listen(s, 2);

    http = (struct ccnl_http_s*) ccnl_calloc(1, sizeof(*http));
    if (!http) {
        close(s);
        return NULL;
    }
    http->server = s;

    DEBUGMSG(INFO, "HTTP status server listening at TCP port %d\n", serverport);

    return http;
}
Exemple #8
0
void
ccnl_simu_add2cache(char node, const char *name, int seqn, void *data, int len)
{
    struct ccnl_relay_s *relay;
    char tmp[100];
    int dataoffset;
    struct ccnl_content_s *c;
    struct ccnl_pkt_s *pkt;

    relay = char2relay(node);
    if (!relay)
        return;

    sprintf(tmp, "%s/.%d", name, seqn);
    DEBUGMSG(VERBOSE, "  %s\n", tmp);
    //    p = ccnl_path_to_prefix(tmp);
    //    p->suite = suite;
    pkt = ccnl_calloc(1, sizeof(*pkt));
    pkt->pfx = ccnl_URItoPrefix(tmp, theSuite, NULL, NULL);
    DEBUGMSG(VERBOSE, "  %s\n", ccnl_prefix_to_path(pkt->pfx));
    pkt->buf = ccnl_mkSimpleContent(pkt->pfx, data, len, &dataoffset);
    pkt->content = pkt->buf->data + dataoffset;
    pkt->contlen = len;
    c = ccnl_content_new(relay, &pkt);
    if (c)
        ccnl_content_add2cache(relay, c);
    return;
}
Exemple #9
0
void
ccnl_ll_TX(struct ccnl_relay_s *relay, struct ccnl_if_s *ifc,
           sockunion *dst, struct ccnl_buf_s *buf)
{
    struct ccnl_ethernet_s *p;
    int cnt;

    for (cnt = 0, p = etherqueue; p; p = p->next, cnt++);

    DEBUGMSG(TRACE, "eth(simu)_ll_TX to %s len=%d (qlen=%d) [0x%02x 0x%02x]\n",
             ccnl_addr2ascii(dst), buf->datalen, cnt,
             buf->data[0], buf->data[1]);
    DEBUGMSG(TRACE, "  src=%s\n", ccnl_addr2ascii(&ifc->addr));

    p = ccnl_calloc(1, sizeof(*p) + 2*ETH_ALEN + buf->datalen);
    p->dst = (unsigned char*)p + sizeof(*p);
    p->src = (unsigned char*)p + sizeof(*p) + ETH_ALEN;
    p->data = (unsigned char*)p + sizeof(*p) + 2*ETH_ALEN;
    p->len = buf->datalen;
    memcpy(p->dst, dst->eth.sll_addr, ETH_ALEN);
    p->protocol = dst->eth.sll_protocol;
    memcpy(p->src, ifc->addr.eth.sll_addr, ETH_ALEN);
    memcpy(p->data, buf->data, buf->datalen);

    // prepend
    p->next = etherqueue;
    etherqueue = p;
}
Exemple #10
0
void
ccnl_simu_add_fwd(char node, const char *name, char dstnode)
{
    struct ccnl_relay_s *relay = char2relay(node), *dst = char2relay(dstnode);
    struct ccnl_forward_s *fwd;
    sockunion sun;
    char *cp;

    DEBUGMSG(TRACE, "ccnl_simu_add_fwd\n");

    sun.eth.sll_family = AF_PACKET;
    memcpy(sun.eth.sll_addr, dst->ifs[0].addr.eth.sll_addr, ETH_ALEN);
    fwd = (struct ccnl_forward_s *) ccnl_calloc(1, sizeof(*fwd));
    //    fwd->prefix = ccnl_path_to_prefix(name);
    cp = ccnl_strdup(name);
    fwd->prefix = ccnl_URItoPrefix(cp, theSuite, NULL, NULL);
    ccnl_free(cp);
    fwd->suite = theSuite;
    fwd->face = ccnl_get_face_or_create(relay, 0, &sun.sa, sizeof(sun.eth));
#ifdef USE_FRAG
    //    fwd->face->frag = ccnl_frag_new(CCNL_FRAG_SEQUENCED2012, 1500);
    fwd->face->frag = ccnl_frag_new(CCNL_FRAG_CCNx2013, 1200);
#endif
    fwd->face->flags |= CCNL_FACE_FLAGS_STATIC;
    fwd->next = relay->fib;
    relay->fib = fwd;
}
Exemple #11
0
void
add_route(char *pfx, struct ccnl_face_s *face, int suite, int mtu)
{
    struct ccnl_forward_s *fwd;
    char buf[100];

    fwd = (struct ccnl_forward_s *) ccnl_calloc(1, sizeof(*fwd));
    if (!fwd)
        return;

    DEBUGMSG(INFO, "adding a route for prefix %s (%s)\n",
             pfx, ccnl_suite2str(suite));

    strcpy(buf, pfx);
    fwd->prefix = ccnl_URItoPrefix(buf, suite, NULL, NULL);
    fwd->face = face;
#ifdef USE_FRAG
    if (mtu > 0) {
        fwd->face->frag = ccnl_frag_new(CCNL_FRAG_BEGINEND2015, mtu);
    }
#endif
    fwd->suite = suite;
    fwd->next = theRelay.fib;
    theRelay.fib = fwd;
}
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;
    gettimeofday(&t->timeout, NULL);
    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; // ?
}
Exemple #13
0
static struct ccnl_forward_s *ccnl_forward_new(struct ccnl_prefix_s *p, struct ccnl_face_s *f, int threshold_prefix, int flags)
{
    struct ccnl_forward_s *fwd = ccnl_calloc(1, sizeof(struct ccnl_forward_s));
    fwd->prefix = ccnl_prefix_clone_strip(p, threshold_prefix);
    fwd->face = f;
    fwd->flags = flags;
    return fwd;
}
struct closure_s *
new_closure(char *term, struct environment_s *env)
{
    struct closure_s *ret = ccnl_calloc(1, sizeof(struct closure_s));

    ret->term = term;
    ret->env = env;
    ccnl_nfn_reserveEnvironment(env);

    return ret;
}
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;
}
Exemple #16
0
struct ccnl_sched_s*
ccnl_sched_dummy_new(void (cts)(void *aux1, void *aux2),
                     struct ccnl_relay_s *ccnl)
{
    struct ccnl_sched_s *s;

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

    s = (struct ccnl_sched_s*) ccnl_calloc(1, sizeof(struct ccnl_sched_s));
    if (s) {
    s->cts = cts;
    s->ccnl = ccnl;
    }
    return s;
}
struct ccnl_frag_s*
ccnl_frag_new(int protocol, int mtu)
{
    struct ccnl_frag_s *e = NULL;

    DEBUGMSG_EFRA(TRACE, "ccnl_frag_new proto=%d mtu=%d\n", protocol, mtu);

    switch(protocol) {
#ifdef OBSOLETE_BY_2015_06
    case CCNL_FRAG_SEQUENCED2012:
    case CCNL_FRAG_CCNx2013:
    case CCNL_FRAG_SEQUENCED2015:
        e = (struct ccnl_frag_s*) ccnl_calloc(1, sizeof(struct ccnl_frag_s));
        if (e) {
            e->protocol = protocol;
            e->mtu = mtu;
            e->flagwidth = 1;
            e->sendseqwidth =   4;
            e->losscountwidth = 2;
            e->recvseqwidth =   4;
        }
        break;
#endif
    case CCNL_FRAG_BEGINEND2015:
        e = (struct ccnl_frag_s*) ccnl_calloc(1, sizeof(struct ccnl_frag_s));
        if (e) {
            e->protocol = protocol;
            e->mtu = mtu;
        }
        break;
    case CCNL_FRAG_NONE:
    default:
        break;
    }
    return e;
}
// binds the name to the given fct in ZAM's list of known operations
void
ZAM_registerOp(char *name, BIF fct)
{
    struct builtin_s *b;
    struct ccnl_buf_s *buf;

    buf = ccnl_calloc(1, sizeof(*buf) + sizeof(*b));
    ccnl_core_addToCleanup(buf);

    b = (struct builtin_s*) buf->data;
    b->name = name;
    b->fct = fct;
    b->next = op_extensions;

    op_extensions = b;
}
void
add_to_environment(struct environment_s **env, char *name,
                   struct closure_s *closure)
{
    struct environment_s *e;

    if (!env)
        return;

    e = ccnl_calloc(1, sizeof(struct environment_s));
    e->name = name;
    e->closure = closure;
    e->next = *env;
    *env = e;
    ccnl_nfn_reserveEnvironment(*env);
}
void
push_to_stack(struct stack_s **top, void *content, int type)
{
    struct stack_s *h;

    if (!top)
        return;

    h = ccnl_calloc(1, sizeof(struct stack_s));
    if (h) {
        DEBUGMSG(TRACE, "push_to_stack: %p\n", (void*)h);
        h->next = *top;
        h->content = content;
        h->type = type;
        *top = h;
    }
}
Exemple #21
0
struct ccnl_content_s*
ccnl_content_new(struct ccnl_relay_s *ccnl, struct ccnl_pkt_s **pkt)
{
    struct ccnl_content_s *c;

    DEBUGMSG_CORE(TRACE, "ccnl_content_new %p <%s [%d]>\n",
             (void*) *pkt, ccnl_prefix_to_path((*pkt)->pfx), ((*pkt)->pfx->chunknum)? *((*pkt)->pfx->chunknum) : -1);

    c = (struct ccnl_content_s *) ccnl_calloc(1, sizeof(struct ccnl_content_s));
    if (!c)
        return NULL;
    c->pkt = *pkt;
    *pkt = NULL;
    c->last_used = CCNL_NOW();

    return c;
}
struct ccnl_content_s*
ccnl_content_new(struct ccnl_relay_s *ccnl, struct ccnl_pkt_s **pkt)
{
    struct ccnl_content_s *c;

//    DEBUGMSG_CORE(TRACE, "ccnl_content_new %p <%s [%d]>\n",
//             (void*) *pkt, ccnl_prefix_to_path((*pkt)->pfx), ((*pkt)->pfx->chunknum)? *((*pkt)->pfx->chunknum) : -1);

    c = (struct ccnl_content_s *) ccnl_calloc(1, sizeof(struct ccnl_content_s));
    if (!c)
        return NULL;
    c->pkt = *pkt;
    *pkt = NULL;
    c->last_used = CCNL_NOW();
    c->recommended_cache_time = CCNL_NOW() + PUBLISHING_TIMEPERIOD;
    return c;
}
Exemple #23
0
void
ccnl_simu_init_node(char node, const char *addr,
                    int max_cache_entries, int mtu)
{
    struct ccnl_relay_s *relay = char2relay(node);
    struct ccnl_if_s *i;

    DEBUGMSG(TRACE, "ccnl_simu_init_node\n");

    relay->id = relay - relays;
    relay->max_cache_entries = node == 'C' ? -1 : max_cache_entries;

    // add (fake) eth0 interface with index 0:
    i = &relay->ifs[0];
    i->addr.eth.sll_family = AF_PACKET;
    memcpy(i->addr.eth.sll_addr, addr, ETH_ALEN);
    if (mtu)
        i->mtu = mtu;
    else
        i->mtu = 4096;
    i->reflect = 1;
    i->fwdalli = 1;
    relay->ifcount++;

#ifdef USE_SCHEDULER
    i->sched = ccnl_sched_pktrate_new(ccnl_interface_CTS, relay,
                                      inter_packet_interval);
    relay->defaultFaceScheduler = ccnl_simu_defaultFaceScheduler;
#endif

    if (node == 'A' || node == 'B') {

        struct ccnl_client_s *client = ccnl_calloc(1,
                                           sizeof(struct ccnl_client_s));
        client->lastseq = SIMU_NUMBER_OF_CHUNKS-1;
        client->last_received = -1;
        client->name = node == 'A' ?
            "/ccnl/simu/movie1" : "/ccnl/simu/movie2";
        relay->aux = (void *) client;
    }

    ccnl_set_timer(1000000, ccnl_ageing, relay, 0);
}
Exemple #24
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;
}
Exemple #25
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;
}
Exemple #26
0
struct ccnl_interest_s*
ccnl_interest_new(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from,
                  struct ccnl_pkt_s **pkt)
{
    struct ccnl_interest_s *i = (struct ccnl_interest_s *) ccnl_calloc(1,
                                            sizeof(struct ccnl_interest_s));
    DEBUGMSG_CORE(TRACE,
                  "ccnl_new_interest(prefix=%s, suite=%s)\n",
                  ccnl_prefix_to_path((*pkt)->pfx),
                  ccnl_suite2str((*pkt)->pfx->suite));

    if (!i)
        return NULL;
    i->pkt = *pkt;
    *pkt = NULL;
    i->flags |= CCNL_PIT_COREPROPAGATES;
    i->from = from;
    i->last_used = CCNL_NOW();
    DBL_LINKED_LIST_ADD(ccnl->pit, i);

    return i;
}
struct ccnl_interest_s*
ccnl_interest_new(struct ccnl_relay_s *ccnl, struct ccnl_face_s *from,
                  struct ccnl_pkt_s **pkt)
{
    struct ccnl_interest_s *i = (struct ccnl_interest_s *) ccnl_calloc(1,
                                            sizeof(struct ccnl_interest_s));
    DEBUGMSG_CORE(TRACE, "ccnl_new_interest\n");
             //             ccnl_prefix_to_path((*pkt)->pfx),
             //             ccnl_suite2str((*pkt)->pfx->suite));

    if (!i)
        return NULL;
    i->pkt = *pkt;
    *pkt = NULL;
    i->flags |= CCNL_PIT_COREPROPAGATES;
    i->from = from;
    i->last_used = CCNL_NOW();
    DBL_LINKED_LIST_ADD(ccnl->pit, i);
//akhila 16-10-2015
    ccnl->pitcnt++;
    DEBUGMSG_CORE(TRACE, ": pit_entry_added:%d\n",ccnl->pitcnt);
    return i;
}
Exemple #28
0
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;
}
// We use one extraction procedure for both interest and data pkts.
// This proc assumes that the packet header was already processed and consumed
struct ccnl_pkt_s*
ccnl_ccntlv_bytes2pkt(unsigned char *start, unsigned char **data, int *datalen)
{
    struct ccnl_pkt_s *pkt;
    int i, len;
    unsigned int typ, oldpos;
    struct ccnl_prefix_s *p;
#ifdef USE_HMAC256
    int validAlgoIsHmac256 = 0;
#endif

    DEBUGMSG_PCNX(TRACE, "ccnl_ccntlv_bytes2pkt len=%d\n", *datalen);

    pkt = (struct ccnl_pkt_s*) ccnl_calloc(1, sizeof(*pkt));
    if (!pkt)
        return NULL;

    pkt->pfx = p = ccnl_prefix_new(CCNL_SUITE_CCNTLV, CCNL_MAX_NAME_COMP);
    if (!p) {
        ccnl_free(pkt);
        return NULL;
    }
    p->compcnt = 0;

#ifdef USE_HMAC256
    pkt->hmacStart = *data;
#endif
    // We ignore the TL types of the message for now:
    // content and interests are filled in both cases (and only one exists).
    // Validation info is now collected
    if (ccnl_ccntlv_dehead(data, datalen, &typ, (unsigned int*) &len) || (int) len > *datalen)
        goto Bail;

    pkt->type = typ;
    pkt->suite = CCNL_SUITE_CCNTLV;
    pkt->val.final_block_id = -1;

    // XXX this parsing is not safe for all input data - needs more bound
    // checks, as some packets with wrong L values can bring this to crash
    oldpos = *data - start;
    while (ccnl_ccntlv_dehead(data, datalen, &typ, (unsigned int*) &len) == 0) {
        unsigned char *cp = *data, *cp2;
        int len2 = len;
        int len3;

        if ( (int)len > *datalen)
            goto Bail;
        switch (typ) {
        case CCNX_TLV_M_Name:
            p->nameptr = start + oldpos;
            while (len2 > 0) {
                cp2 = cp;
                if (ccnl_ccntlv_dehead(&cp, &len2, &typ, (unsigned int*) &len3) || (int)len>*datalen)
                    goto Bail;

                switch (typ) {
                case CCNX_TLV_N_Chunk:
                    // We extract the chunknum to the prefix but keep it
                    // in the name component for now. In the future we
                    // possibly want to remove the chunk segment from the
                    // name components and rely on the chunknum field in
                    // the prefix.
                  p->chunknum = (int*) ccnl_malloc(sizeof(int));

                    if (ccnl_ccnltv_extractNetworkVarInt(cp, len3,
                                                         (unsigned int*) p->chunknum) < 0) {
                        DEBUGMSG_PCNX(WARNING, "Error in NetworkVarInt for chunk\n");
                        goto Bail;
                    }
                    if (p->compcnt < CCNL_MAX_NAME_COMP) {
                        p->comp[p->compcnt] = cp2;
                        p->complen[p->compcnt] = cp - cp2 + len3;
                        p->compcnt++;
                    } // else out of name component memory: skip
                    break;
                case CCNX_TLV_N_NameSegment:
                    if (p->compcnt < CCNL_MAX_NAME_COMP) {
                        p->comp[p->compcnt] = cp2;
                        p->complen[p->compcnt] = cp - cp2 + len3;
                        p->compcnt++;
                    } // else out of name component memory: skip
                    break;
                case CCNX_TLV_N_Meta:
                    if (ccnl_ccntlv_dehead(&cp, &len2, &typ, (unsigned int*) &len3) ||
                        (int)len > *datalen) {
                        DEBUGMSG_PCNX(WARNING, "error when extracting CCNX_TLV_M_MetaData\n");
                        goto Bail;
                    }
                    break;
                default:
                    break;
                }
                cp += len3;
                len2 -= len3;
            }
            p->namelen = *data - p->nameptr;
#ifdef USE_NFN
            if (p->compcnt > 0 && p->complen[p->compcnt-1] == 7 &&
                    !memcmp(p->comp[p->compcnt-1], "\x00\x01\x00\x03NFN", 7)) {
                p->nfnflags |= CCNL_PREFIX_NFN;
                p->compcnt--;
            }
#endif
            break;
        case CCNX_TLV_M_ENDChunk:
            if (ccnl_ccnltv_extractNetworkVarInt(cp, len,
                              (unsigned int*) &(pkt->val.final_block_id)) < 0) {
                DEBUGMSG_PCNX(WARNING, "error when extracting CCNX_TLV_M_ENDChunk\n");
                goto Bail;
            }
            break;
        case CCNX_TLV_M_Payload:
            pkt->content = *data;
            pkt->contlen = len;
            break;
#ifdef USE_HMAC256
        case CCNX_TLV_TL_ValidationAlgo:
            cp = *data;
            len2 = len;
            if (ccnl_ccntlv_dehead(&cp, &len2, &typ, (unsigned*) &len3) || len>*datalen)
                goto Bail;
            if (typ == CCNX_VALIDALGO_HMAC_SHA256) {
                // ignore keyId and other algo dependent data ... && len3 == 0)
                validAlgoIsHmac256 = 1;
            }
            break;
        case CCNX_TLV_TL_ValidationPayload:
            if (pkt->hmacStart && validAlgoIsHmac256 && len == 32) {
                pkt->hmacLen = *data - pkt->hmacStart - 4;
                pkt->hmacSignature = *data;
            }
            break;
#endif
        default:
            break;
        }
        *data += len;
        *datalen -= len;
        oldpos = *data - start;
    }
    if (*datalen > 0)
        goto Bail;

    pkt->pfx = p;
    pkt->buf = ccnl_buf_new(start, *data - start);
    if (!pkt->buf)
        goto Bail;
    // carefully rebase ptrs to new buf because of 64bit pointers:
    if (pkt->content)
        pkt->content = pkt->buf->data + (pkt->content - start);
    for (i = 0; i < p->compcnt; i++)
        p->comp[i] = pkt->buf->data + (p->comp[i] - start);
    if (p->nameptr)
        p->nameptr = pkt->buf->data + (p->nameptr - start);
#ifdef USE_HMAC256
    pkt->hmacStart = pkt->buf->data + (pkt->hmacStart - start);
    pkt->hmacSignature = pkt->buf->data + (pkt->hmacSignature - start);
#endif

    return pkt;
Bail:
    free_packet(pkt);
    return NULL;
}
Exemple #30
0
struct ccnl_face_s*
ccnl_get_face_or_create(struct ccnl_relay_s *ccnl, int ifndx,
                       struct sockaddr *sa, int addrlen)
// sa==NULL means: local(=in memory) client, search for existing ifndx being -1
// sa!=NULL && ifndx==-1: search suitable interface for given sa_family
// sa!=NULL && ifndx!=-1: use this (incoming) interface for outgoing
{
    static int seqno;
    int i;
    struct ccnl_face_s *f;

    DEBUGMSG_CORE(TRACE, "ccnl_get_face_or_create src=%s\n",
             ccnl_addr2ascii((sockunion*)sa));

    for (f = ccnl->faces; f; f = f->next) {
        if (!sa) {
            if (f->ifndx == -1)
                return f;
            continue;
        }
        if (ifndx != -1 && !ccnl_addr_cmp(&f->peer, (sockunion*)sa)) {
            f->last_used = CCNL_NOW();
            return f;
        }
    }

    if (sa && ifndx == -1) {
        for (i = 0; i < ccnl->ifcount; i++) {
            if (sa->sa_family != ccnl->ifs[i].addr.sa.sa_family)
                continue;
            ifndx = i;
            break;
        }
        if (ifndx == -1) // no suitable interface found
            return NULL;
    }
    DEBUGMSG_CORE(VERBOSE, "  found suitable interface %d for %s\n", ifndx,
                ccnl_addr2ascii((sockunion*)sa));

    f = (struct ccnl_face_s *) ccnl_calloc(1, sizeof(struct ccnl_face_s));
    if (!f) {
        DEBUGMSG_CORE(VERBOSE, "  no memory for face\n");
        return NULL;
    }
    f->faceid = ++seqno;
    f->ifndx = ifndx;

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

    if (sa)
        memcpy(&f->peer, sa, addrlen);
    else // local client
        f->ifndx = -1;
    f->last_used = CCNL_NOW();
    DBL_LINKED_LIST_ADD(ccnl->faces, f);

    TRACEOUT();
    return f;
}