void free_content(struct ccnl_content_s *c) { free_prefix(c->name); free_2ptr_list(c->pkt, c); }
struct ccnl_buf_s* ccnl_ccnb_extract(unsigned char **data, int *datalen, int *scope, int *aok, int *min, int *max, struct ccnl_prefix_s **prefix, struct ccnl_buf_s **nonce, struct ccnl_buf_s **ppkd, unsigned char **content, int *contlen) { unsigned char *start = *data - 2 /* account for outer TAG hdr */, *cp; int num, typ, len; struct ccnl_prefix_s *p; struct ccnl_buf_s *buf, *n = 0, *pub = 0; DEBUGMSG(99, "ccnl_ccnb_extract\n"); p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s)); if (!p) return NULL; 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) goto Bail; while (ccnl_ccnb_dehead(data, datalen, &num, &typ) == 0) { if (num==0 && typ==0) break; // end if (typ == CCN_TT_DTAG) { if (num == CCN_DTAG_NAME) { for (;;) { if (ccnl_ccnb_dehead(data, datalen, &num, &typ) != 0) goto Bail; if (num==0 && typ==0) break; if (typ == CCN_TT_DTAG && num == CCN_DTAG_COMPONENT && p->compcnt < CCNL_MAX_NAME_COMP) { if (ccnl_ccnb_hunt_for_end(data, datalen, p->comp + p->compcnt, p->complen + p->compcnt) < 0) goto Bail; p->compcnt++; } else { if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0) goto Bail; } } continue; } if (num == CCN_DTAG_SCOPE || num == CCN_DTAG_NONCE || num == CCN_DTAG_MINSUFFCOMP || num == CCN_DTAG_MAXSUFFCOMP || num == CCN_DTAG_PUBPUBKDIGEST) { if (ccnl_ccnb_hunt_for_end(data, datalen, &cp, &len) < 0) goto Bail; if (num == CCN_DTAG_SCOPE && len == 1 && scope) *scope = isdigit(*cp) && (*cp < '3') ? *cp - '0' : -1; if (num == CCN_DTAG_ANSWERORIGKIND && aok) *aok = ccnl_ccnb_data2uint(cp, len); if (num == CCN_DTAG_MINSUFFCOMP && min) *min = ccnl_ccnb_data2uint(cp, len); if (num == CCN_DTAG_MAXSUFFCOMP && max) *max = ccnl_ccnb_data2uint(cp, len); if (num == CCN_DTAG_NONCE && !n) n = ccnl_buf_new(cp, len); if (num == CCN_DTAG_PUBPUBKDIGEST && !pub) pub = ccnl_buf_new(cp, len); if (num == CCN_DTAG_EXCLUDE) { DEBUGMSG(49, "warning: 'exclude' field ignored\n"); } else continue; } if (num == CCN_DTAG_CONTENT) { if (ccnl_ccnb_consume(typ, num, data, datalen, content, contlen) < 0) goto Bail; continue; } } if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0) goto Bail; } if (prefix) *prefix = p; else free_prefix(p); if (nonce) *nonce = n; else ccnl_free(n); if (ppkd) *ppkd = pub; else ccnl_free(pub); buf = ccnl_buf_new(start, *data - start); // carefully rebase ptrs to new buf because of 64bit pointers: if (content) *content = buf->data + (*content - start); for (num = 0; num < p->compcnt; num++) p->comp[num] = buf->data + (p->comp[num] - start); return buf; Bail: free_prefix(p); free_2ptr_list(n, pub); return NULL; }
struct ccnl_buf_s * ccnl_extract_prefix_nonce_ppkd(unsigned char **data, int *datalen, int *scope, int *aok, int *min, int *max, struct ccnl_prefix_s **prefix, struct ccnl_buf_s **nonce, struct ccnl_buf_s **ppkd, unsigned char **content, int *contlen) { unsigned char *start = *data - 2, *cp; int num, typ, len; struct ccnl_prefix_s *p; struct ccnl_buf_s *buf, *n = 0, *pub = 0; DEBUGMSG(99, "ccnl_extract_prefix\n"); p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s)); if (!p) { puts("can't get more memory from malloc, dropping ccn msg..."); return NULL; } 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) { puts("can't get more memory from malloc, dropping ccn msg..."); goto Bail; } while (dehead(data, datalen, &num, &typ) == 0) { if (num == 0 && typ == 0) { break; // end } if (typ == CCN_TT_DTAG) { if (num == CCN_DTAG_NAME) { while (1) { if (dehead(data, datalen, &num, &typ) != 0) { goto Bail; } if (num == 0 && typ == 0) { break; } if (typ == CCN_TT_DTAG && num == CCN_DTAG_COMPONENT && p->compcnt < CCNL_MAX_NAME_COMP) { if (hunt_for_end(data, datalen, p->comp + p->compcnt, p->complen + p->compcnt) < 0) { goto Bail; } p->compcnt++; } else { if (consume(typ, num, data, datalen, 0, 0) < 0) { goto Bail; } } } continue; } if (num == CCN_DTAG_SCOPE || num == CCN_DTAG_NONCE || num == CCN_DTAG_MINSUFFCOMP || num == CCN_DTAG_MAXSUFFCOMP || num == CCN_DTAG_PUBPUBKDIGEST) { if (hunt_for_end(data, datalen, &cp, &len) < 0) { goto Bail; } if (num == CCN_DTAG_SCOPE && len == 1 && scope) { *scope = isdigit(*cp) && (*cp < '3') ? *cp - '0' : -1; } if (num == CCN_DTAG_ANSWERORIGKIND && aok) { *aok = data2uint(cp, len); } if (num == CCN_DTAG_MINSUFFCOMP && min) { *min = data2uint(cp, len); } if (num == CCN_DTAG_MAXSUFFCOMP && max) { *max = data2uint(cp, len); } if (num == CCN_DTAG_NONCE && !n) { n = ccnl_buf_new(cp, len); } if (num == CCN_DTAG_PUBPUBKDIGEST && !pub) { pub = ccnl_buf_new(cp, len); } if (num == CCN_DTAG_EXCLUDE) { DEBUGMSG(49, "warning: 'exclude' field ignored\n"); } else { continue; } } if (num == CCN_DTAG_CONTENT || num == CCN_DTAG_CONTENTOBJ) { if (consume(typ, num, data, datalen, content, contlen) < 0) { goto Bail; } continue; } } if (consume(typ, num, data, datalen, 0, 0) < 0) { goto Bail; } } if (prefix) { p->comp[p->compcnt] = NULL; *prefix = p; } else { free_prefix(p); } if (nonce) { *nonce = n; } else { ccnl_free(n); } if (ppkd) { *ppkd = pub; } else { ccnl_free(pub); } buf = ccnl_buf_new(start, *data - start); if (!buf) { puts("can't get more memory from malloc, dropping ccn msg..."); goto Bail; } // carefully rebase ptrs to new buf because of 64bit pointers: if (content) { *content = buf->data + (*content - start); } for (num = 0; num < p->compcnt; num++) { p->comp[num] = buf->data + (p->comp[num] - start); } return buf; Bail: free_prefix(p); free_2ptr_list(n, pub); return NULL; }