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