int
ccnl_frag_RX_Sequenced2015(RX_datagram callback, struct ccnl_relay_s *relay,
                           struct ccnl_face_s *from, int mtu,
                           unsigned int bits, unsigned int seqno,
                           unsigned char **data, int *datalen)
{
    struct serialFragPDU_s s;

    DEBUGMSG_EFRA(DEBUG, "ccnl_frag_RX_Sequenced2015 (%d bytes)\n", *datalen);
    serialFragPDU_init(&s);

    s.ourseq = seqno;
    s.flags = bits;
    s.content = *data;
    s.contlen = *datalen;

    if (from) {
        if (!from->frag)
            from->frag = ccnl_frag_new(CCNL_FRAG_SEQUENCED2015, mtu);
        if (from->frag && from->frag->protocol != CCNL_FRAG_SEQUENCED2015) {
            DEBUGMSG_EFRA(WARNING, "WRONG FRAG PROTOCOL\n");
            return 0;
        }
    }
    ccnl_frag_RX_serialfragment(callback, relay, from, &s);

    /*
    *data = s.content;
    *datalen = s.contlen;
    */

    return 1;
}
Beispiel #2
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;
}
Beispiel #3
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;
}
int
ccnl_frag_RX_BeginEnd2015(RX_datagram callback, struct ccnl_relay_s *relay,
                          struct ccnl_face_s *from, int mtu,
                          unsigned int bits, unsigned int seqno,
                          unsigned char **data, int *datalen)
{
    struct ccnl_buf_s *buf = NULL;
    struct ccnl_frag_s *e;

    DEBUGMSG_EFRA(DEBUG, "ccnl_frag_RX_BeginEnd2015 (%d bytes), seqno=%d\n",
                  *datalen, seqno);

    if (!from) {
        DEBUGMSG_EFRA(WARNING, "RX_BeginEnd2015: no from value\n");
        return 0;
    }
    if (!from->frag)
        from->frag = ccnl_frag_new(CCNL_FRAG_BEGINEND2015, mtu);
    if (!from->frag) {
        DEBUGMSG_EFRA(WARNING, "no frag alloc\n");
        return 0;
    }
    if (from->frag->protocol != CCNL_FRAG_BEGINEND2015) {
        DEBUGMSG_EFRA(WARNING, "WRONG FRAG PROTOCOL\n");
        return 0;
    }

    e = from->frag;
    if (e->recvseq != seqno) {
        // should increase error counter here
        DEBUGMSG_EFRA(WARNING, "  >> seqnum mismatch: rcvd %d, expected %d\n",
                      seqno, e->recvseq);
        if (e->defrag) {
            DEBUGMSG_EFRA(WARNING, "  >> had to drop defrag buf\n");
            ccnl_free(e->defrag);
            e->defrag = NULL;
        }
        e->recvseq = seqno;
    }

    switch(bits & (CCNL_BEFRAG_FLAG_MASK)) {
    case CCNL_BEFRAG_FLAG_SINGLE: // single packet
        DEBUGMSG_EFRA(VERBOSE, "  >> single fragment seqno=%d (%d bytes)\n",
                      seqno, *datalen);
        if (e->defrag) {
            DEBUGMSG_EFRA(WARNING, "    had to drop defrag buf\n");
            ccnl_free(e->defrag);
            e->defrag = NULL;
        }
        e->recvseq++;
        // no need to copy the buffer:
        callback(relay, from, data, datalen);
        return 1;
    case CCNL_BEFRAG_FLAG_FIRST: // start of fragment sequence
        DEBUGMSG_EFRA(VERBOSE, "  >> start of fragment series\n");
        if (e->defrag) {
            DEBUGMSG_EFRA(WARNING, "    had to drop defrag buf\n");
            ccnl_free(e->defrag);
        }
        e->defrag = ccnl_buf_new(*data, *datalen);
        break;
    case CCNL_BEFRAG_FLAG_LAST: // end of fragment sequence
        DEBUGMSG_EFRA(VERBOSE, "  >> last fragment of a series\n");
        if (!e->defrag) {
            DEBUGMSG_EFRA(WARNING, "  >> no e->defrag?\n");
            break;
        }
        buf = ccnl_buf_new(NULL, e->defrag->datalen + *datalen);
        if (buf) {
            memcpy(buf->data, e->defrag->data, e->defrag->datalen);
            memcpy(buf->data + e->defrag->datalen, *data, *datalen);
        }
        ccnl_free(e->defrag);
        e->defrag = NULL;
        break;
    case CCNL_BEFRAG_FLAG_MID:  // fragment in the middle of a squence
    default:
        DEBUGMSG_EFRA(VERBOSE, "  >> fragment in the middle of a series\n");
        if (!e->defrag)
            break;
        buf = ccnl_buf_new(NULL, e->defrag->datalen + *datalen);
        if (buf) {
            memcpy(buf->data, e->defrag->data, e->defrag->datalen);
            memcpy(buf->data + e->defrag->datalen, *data, *datalen);
            ccnl_free(e->defrag);
            e->defrag = buf;
            buf = NULL;
        } else {
            ccnl_free(e->defrag);
            e->defrag = NULL;
        }
        break;
    }
    *data += *datalen;
    *datalen = 0;
    e->recvseq++;

    if (buf) {
        unsigned char *frag = buf->data;
        int fraglen = buf->datalen;
        DEBUGMSG_EFRA(DEBUG, "  >> reassembled fragment is %d bytes\n",
                      buf->datalen);
        // FIXME: loop over multiple packets in this reassembled frame?
        callback(relay, from, &frag, &fraglen);
        ccnl_free(buf);
    }

    return 1;
}
int
ccnl_frag_RX_CCNx2013(RX_datagram callback,
                      struct ccnl_relay_s *relay, struct ccnl_face_s *from,
                      unsigned char **data, int *datalen)
{
    int rc, num, typ, pdutypelen;
    unsigned char *pdutype = 0;
    struct serialFragPDU_s s;

    DEBUGMSG_EFRA(TRACE, "ccnl_frag_RX_CCNx2013 (%d bytes)\n", *datalen);
    serialFragPDU_init(&s);
    while (ccnl_ccnb_dehead(data, datalen, &num, &typ) == 0) {
        if (num==0 && typ==0) break; // end
        if (typ == CCN_TT_DTAG) {
            switch (num) {
            case CCNL_DTAG_FRAG2013_TYPE:
                if (ccnl_ccnb_hunt_for_end(data, datalen, &pdutype, &pdutypelen) ||
                        pdutypelen != 3) goto Bail;
                continue;
            case CCNL_DTAG_FRAG2013_SEQNR:
                getNumField(s.ourseq, s.ourseqwidth, HAS_OSEQ, "ourseq");
                continue;
            case CCNL_DTAG_FRAG2013_FLAGS:
                getNumField(s.flags, s.flagwidth, HAS_FLAGS, "flags");
                continue;
            case CCN_DTAG_CONTENT:
//              if (frag) // error: more than one content entry
                if (ccnl_ccnb_consume(typ, num, data, datalen, &s.content,&s.contlen) < 0)
                    goto Bail;
                continue;

            // CCNL extensions:
            case CCN_DTAG_INTEREST:
            case CCN_DTAG_CONTENTOBJ:
//                rc = ccnl_ccnb_forwarder(relay, from, data, datalen);
                rc = callback(relay, from, data, datalen);
                if (rc < 0)
                    return rc;
                continue;
            case CCNL_DTAG_FRAG2013_OLOSS:
                getNumField(s.ourloss, s.ourlosswidth, HAS_OLOS, "ourloss");
                continue;
            case CCNL_DTAG_FRAG2013_YSEQN:
                getNumField(s.yourseq, s.yourseqwidth, HAS_YSEQ, "yourseq");
                continue;
            default:
                break;
            }
        }
        if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0)
            goto Bail;
    }
    if (!pdutype || !s.content ) {
        /* ||
                            (s.HAS&(HAS_FLAGS|HAS_OSEQ)) != (HAS_FLAGS|HAS_OSEQ) ) {
        */
        DEBUGMSG_EFRA(WARNING, "* incomplete frag\n");
        return 0;
    }

    if (memcmp(pdutype, CCNL_FRAG_TYPE_CCNx2013_VAL, 3) == 0) { // hop-by-hop
        if (from) {
            if (!from->frag)
                from->frag = ccnl_frag_new(CCNL_FRAG_CCNx2013,
                                           relay->ifs[from->ifndx].mtu);
            if (from->frag && from->frag->protocol == CCNL_FRAG_CCNx2013)
                ccnl_frag_RX_serialfragment(callback, relay, from, &s);
            else
                DEBUGMSG_EFRA(WARNING, "WRONG FRAG PROTOCOL\n");
        } else
            ccnl_frag_RX_serialfragment(callback, relay, from, &s);
    }

    /*
     * echo "FMTE" | base64 -d | hexdump -v -e '/1 "@x%02x"'| tr @ '\\'; echo
     */
    if (memcmp(pdutype, "\x14\xc4\xc4", 3) == 0) { // mid-to-end fragment
        // not implemented yet
    }

    return 0;
Bail:
    DEBUGMSG_EFRA(WARNING, "* frag bailing\n");
    return -1;
}
int
ccnl_frag_RX_frag2012(RX_datagram callback,
                      struct ccnl_relay_s *relay, struct ccnl_face_s *from,
                      unsigned char **data, int *datalen)
{
    int num, typ;
    struct serialFragPDU_s s;
    DEBUGMSG_EFRA(TRACE, "ccnl_frag_RX_frag2012 (%d bytes)\n", *datalen);

    serialFragPDU_init(&s);
    while (ccnl_ccnb_dehead(data, datalen, &num, &typ) == 0) {
        if (num==0 && typ==0)
            break; // end
        if (typ == CCN_TT_DTAG) {
            switch(num) {
            case CCN_DTAG_CONTENT:
                DEBUGMSG_EFRA(TRACE, "  frag content\n");
//              if (s.content) // error: more than one content entry
                if (ccnl_ccnb_consume(typ, num, data, datalen, &s.content,&s.contlen) < 0)
                    goto Bail;
                continue;
            case CCNL_DTAG_FRAG2012_FLAGS:
                getNumField(s.flags, s.flagwidth, HAS_FLAGS, "flags");
                continue;
            case CCNL_DTAG_FRAG2012_SEQNR:
                getNumField(s.ourseq, s.ourseqwidth, HAS_OSEQ, "ourseq");
                continue;
            case CCNL_DTAG_FRAG2012_OLOSS:
                getNumField(s.ourloss, s.ourlosswidth, HAS_OLOS, "ourloss");
                continue;
            case CCNL_DTAG_FRAG2012_YSEQN:
                getNumField(s.yourseq, s.yourseqwidth, HAS_YSEQ, "yourseq");
                continue;
            default:
                break;
            }
        }
        if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0)
            goto Bail;
    }
    if (!s.content || s.HAS != 15) {
        DEBUGMSG_EFRA(WARNING, "* incomplete frag\n");
        return 0;
    }

    if (from) {
        if (!from->frag)
            from->frag = ccnl_frag_new(CCNL_FRAG_SEQUENCED2012,
                                       relay->ifs[from->ifndx].mtu);
        if (from->frag && from->frag->protocol == CCNL_FRAG_SEQUENCED2012)
            ccnl_frag_RX_serialfragment(callback, relay, from, &s);
        else
            DEBUGMSG_EFRA(WARNING, "WRONG FRAG PROTOCOL\n");
    } else
        ccnl_frag_RX_serialfragment(callback, relay, from, &s);

    return 0;
Bail:
    DEBUGMSG_EFRA(WARNING, "* frag bailing\n");
    return -1;
}
Beispiel #7
0
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;
}