int ccnl_core_RX_datagram(struct ccnl_relay_s *relay, struct ccnl_face_s *from, unsigned char **data, int *datalen) { int rc = 0, num = 0, typ = 0; DEBUGMSG(1, "ccnl_core_RX_datagram: %d bytes from face=%p (id=%d.%d)\n", *datalen, (void *) from, relay->id, from ? from->faceid : -1); while (rc >= 0 && *datalen > 0) { if (dehead(data, datalen, &num, &typ) || typ != CCN_TT_DTAG) { return -1; } switch (num) { case CCN_DTAG_INTEREST: /* no break */ case CCN_DTAG_CONTENTOBJ: rc = ccnl_core_RX_i_or_c(relay, from, data, datalen); continue; #ifdef USE_FRAG case CCNL_DTAG_FRAGMENT2012: rc = ccnl_frag_RX_frag2012(ccnl_core_RX_datagram, relay, from, data, datalen); continue; case CCNL_DTAG_FRAGMENT: rc = ccnl_frag_RX_CCNx2013(ccnl_core_RX_datagram, relay, from, data, datalen); continue; #endif default: DEBUGMSG(15, " unknown datagram type %d\n", num); return -1; } } return rc; }
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(99, "ccnl_frag_RX_CCNx2013 (%d bytes)\n", *datalen); serialFragPDU_init(&s); while (dehead(data, datalen, &num, &typ) == 0) { if (num == 0 && typ == 0) { break; /* end */ } if (typ == CCN_TT_DTAG) { switch (num) { case CCNL_DTAG_FRAG_TYPE: if (hunt_for_end(data, datalen, &pdutype, &pdutypelen) || pdutypelen != 3) { goto Bail; } continue; case CCNL_DTAG_FRAG_SEQNR: getNumField(s.ourseq, s.ourseqwidth, HAS_OSEQ, "ourseq") ; continue; case CCNL_DTAG_FRAG_FLAGS: getNumField(s.flags, s.flagwidth, HAS_FLAGS, "flags") ; continue; case CCN_DTAG_CONTENT: // if (frag) /* error: more than one content entry */ if (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_core_RX_i_or_c(relay, from, data, datalen); if (rc < 0) { return rc; } continue; case CCNL_DTAG_FRAG_OLOSS: getNumField(s.ourloss, s.ourlosswidth, HAS_OLOS, "ourloss") ; continue; case CCNL_DTAG_FRAG_YSEQN: getNumField(s.yourseq, s.yourseqwidth, HAS_YSEQ, "yourseq") ; continue; default: break; } } if (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(1, "* incomplete frag\n"); return 0; } DEBUGMSG(1, "hop-by-hop\n"); 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(1, "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 */ } DEBUGMSG(1, "mid-to-end fragment\n"); return 0; Bail: DEBUGMSG(1, "* frag bailing\n"); return -1; }