00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdint.h>
00021 #include <string.h>
00022 #include <ccn/btree.h>
00023 #include <ccn/btree_content.h>
00024 #include <ccn/bloom.h>
00025 #include <ccn/ccn.h>
00026 #include <ccn/uri.h>
00027
00028 #ifndef MYFETCH
00029 #define MYFETCH(p, f) ccn_btree_fetchval(&((p)->f[0]), sizeof((p)->f))
00030 #endif
00031
00032 #ifndef MYSTORE
00033 #define MYSTORE(p, f, v) ccn_btree_storeval(&((p)->f[0]), sizeof((p)->f), (v))
00034 #endif
00035
00036 #ifndef MYFETCH64
00037 #define MYFETCH64(p, f) ccn_btree_fetchval64(&((p)->f[0]), sizeof((p)->f))
00038 #endif
00039 static uint_least64_t
00040 ccn_btree_fetchval64(const unsigned char *p, int size)
00041 {
00042 int i;
00043 uint_least64_t v;
00044
00045 for (v = 0, i = 0; i < size; i++)
00046 v = (v << 8) + p[i];
00047 return(v);
00048 }
00049
00050 #ifndef MYSTORE64
00051 #define MYSTORE64(p, f, v) ccn_btree_storeval64(&((p)->f[0]), sizeof((p)->f), (v))
00052 #endif
00053 static void
00054 ccn_btree_storeval64(unsigned char *p, int size, uint_least64_t v)
00055 {
00056 int i;
00057
00058 for (i = size; i > 0; i--, v >>= 8)
00059 p[i-1] = v;
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 int
00076 ccn_btree_insert_content(struct ccn_btree_node *node, int ndx,
00077 uint_least64_t cobid,
00078 const unsigned char *content_object,
00079 struct ccn_parsed_ContentObject *pc,
00080 struct ccn_charbuf *flatname)
00081 {
00082 struct ccn_btree_content_payload payload;
00083 struct ccn_btree_content_payload *e = &payload;
00084 int ncomp;
00085 int res;
00086 unsigned size;
00087 unsigned flags = 0;
00088 const unsigned char *blob = NULL;
00089 size_t blob_size = 0;
00090
00091 size = pc->offset[CCN_PCO_E];
00092 ncomp = ccn_flatname_ncomps(flatname->buf, flatname->length);
00093 if (ncomp != pc->name_ncomps + 1)
00094 return(-1);
00095 memset(e, 'U', sizeof(*e));
00096 MYSTORE(e, magic, CCN_BT_CONTENT_MAGIC);
00097 MYSTORE(e, ctype, pc->type);
00098 MYSTORE(e, cobsz, size);
00099 MYSTORE(e, ncomp, ncomp);
00100 MYSTORE(e, flags, flags);
00101 MYSTORE(e, ttpad, 0);
00102 MYSTORE(e, timex, 0);
00103 res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, content_object,
00104 pc->offset[CCN_PCO_B_Timestamp],
00105 pc->offset[CCN_PCO_E_Timestamp],
00106 &blob, &blob_size);
00107 if (res < 0 || blob_size > sizeof(e->timex))
00108 return(-1);
00109 memcpy(e->timex + sizeof(e->timex) - blob_size, blob, blob_size);
00110
00111 MYSTORE64(e, cobid, cobid);
00112 res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, content_object,
00113 pc->offset[CCN_PCO_B_PublisherPublicKeyDigest],
00114 pc->offset[CCN_PCO_E_PublisherPublicKeyDigest],
00115 &blob, &blob_size);
00116 if (res < 0 || blob_size != sizeof(e->ppkdg))
00117 return(-1);
00118 memcpy(e->ppkdg, blob, sizeof(e->ppkdg));
00119
00120 res = ccn_btree_insert_entry(node, ndx,
00121 flatname->buf, flatname->length,
00122 e, sizeof(*e));
00123 return(res);
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 int
00143 ccn_btree_match_interest(struct ccn_btree_node *node, int ndx,
00144 const unsigned char *interest_msg,
00145 const struct ccn_parsed_interest *pi,
00146 struct ccn_charbuf *scratch)
00147 {
00148 const unsigned char *blob = NULL;
00149 const unsigned char *bloom = NULL;
00150 const unsigned char *comp = NULL;
00151 const unsigned char *nextcomp = NULL;
00152 int i;
00153 int n;
00154 int ncomps;
00155 int pubidend;
00156 int pubidstart;
00157 int res;
00158 int rnc;
00159 size_t blob_size = 0;
00160 size_t bloom_size = 0;
00161 size_t comp_size = 0;
00162 size_t nextcomp_size = 0;
00163 size_t size;
00164 struct ccn_btree_content_payload *e = NULL;
00165 struct ccn_buf_decoder *d = NULL;
00166 struct ccn_buf_decoder decoder;
00167 unsigned char *flatname = NULL;
00168 unsigned char match_any[2] = "-";
00169
00170 e = ccn_btree_node_getentry(sizeof(*e), node, ndx);
00171 if (e == NULL || e->magic[0] != CCN_BT_CONTENT_MAGIC)
00172 return(-1);
00173
00174 ncomps = MYFETCH(e, ncomp);
00175 if (ncomps < pi->prefix_comps + pi->min_suffix_comps)
00176 return(0);
00177 if (ncomps > pi->prefix_comps + pi->max_suffix_comps)
00178 return(0);
00179
00180 pubidstart = pi->offset[CCN_PI_B_PublisherID];
00181 pubidend = pi->offset[CCN_PI_E_PublisherID];
00182 if (pubidstart < pubidend) {
00183 blob_size = 0;
00184 ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest,
00185 interest_msg,
00186 pubidstart, pubidend,
00187 &blob, &blob_size);
00188 if (blob_size != sizeof(e->ppkdg))
00189 return(0);
00190 if (0 != memcmp(blob, e->ppkdg, blob_size))
00191 return(0);
00192 }
00193
00194 if (pi->offset[CCN_PI_E_Exclude] > pi->offset[CCN_PI_B_Exclude]) {
00195 res = ccn_btree_key_fetch(scratch, node, ndx);
00196 if (res < 0)
00197 return(-1);
00198 flatname = scratch->buf;
00199 size = scratch->length;
00200 nextcomp = NULL;
00201 nextcomp_size = 0;
00202 for (i = 0, n = 0; i < size; i += CCNFLATSKIP(rnc), n++) {
00203 rnc = ccn_flatname_next_comp(flatname + i, size - i);
00204 if (rnc <= 0)
00205 return(-1);
00206 if (n == pi->prefix_comps) {
00207 nextcomp = flatname + i + CCNFLATDELIMSZ(rnc);
00208 nextcomp_size = CCNFLATDATASZ(rnc);
00209 break;
00210 }
00211 }
00212 if (nextcomp == NULL)
00213 return(0);
00214
00215 d = ccn_buf_decoder_start(&decoder,
00216 interest_msg + pi->offset[CCN_PI_B_Exclude],
00217 pi->offset[CCN_PI_E_Exclude] -
00218 pi->offset[CCN_PI_B_Exclude]);
00219 if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude))
00220 return(-1);
00221 ccn_buf_advance(d);
00222 bloom = NULL;
00223 bloom_size = 0;
00224 if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
00225 ccn_buf_advance(d);
00226 bloom = match_any;
00227 ccn_buf_check_close(d);
00228 }
00229 else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) {
00230 ccn_buf_advance(d);
00231 if (ccn_buf_match_blob(d, &bloom, &bloom_size))
00232 ccn_buf_advance(d);
00233 ccn_buf_check_close(d);
00234 }
00235 while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00236 ccn_buf_advance(d);
00237 comp_size = 0;
00238 if (ccn_buf_match_blob(d, &comp, &comp_size))
00239 ccn_buf_advance(d);
00240 ccn_buf_check_close(d);
00241 if (comp_size > nextcomp_size)
00242 break;
00243 if (comp_size == nextcomp_size) {
00244 res = memcmp(comp, nextcomp, comp_size);
00245 if (res == 0)
00246 return(0);
00247 if (res > 0)
00248 break;
00249 }
00250 bloom = NULL;
00251 bloom_size = 0;
00252 if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
00253 ccn_buf_advance(d);
00254 bloom = match_any;
00255 ccn_buf_check_close(d);
00256 }
00257 else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) {
00258 ccn_buf_advance(d);
00259 if (ccn_buf_match_blob(d, &bloom, &bloom_size))
00260 ccn_buf_advance(d);
00261 ccn_buf_check_close(d);
00262 }
00263 }
00264
00265
00266
00267 if (bloom == match_any)
00268 return(0);
00269 else if (bloom_size != 0) {
00270 const struct ccn_bloom_wire *f = ccn_bloom_validate_wire(bloom, bloom_size);
00271
00272 if (f == NULL)
00273 return(0);
00274 if (ccn_bloom_match_wire(f, nextcomp, nextcomp_size))
00275 return(0);
00276 }
00277 }
00278
00279
00280
00281
00282 return(1);
00283 }
00284
00285
00286
00287
00288
00289
00290 uint_least64_t
00291 ccn_btree_content_cobid(struct ccn_btree_node *node, int ndx)
00292 {
00293 struct ccn_btree_content_payload *e = NULL;
00294 uint_least64_t ans = 0;
00295
00296 e = ccn_btree_node_getentry(sizeof(*e), node, ndx);
00297 if (e != NULL)
00298 ans = MYFETCH64(e, cobid);
00299 return(ans);
00300 }
00301
00302
00303
00304
00305
00306
00307 int
00308 ccn_btree_content_set_cobid(struct ccn_btree_node *node, int ndx,
00309 uint_least64_t cobid)
00310 {
00311 struct ccn_btree_content_payload *e = NULL;
00312 ptrdiff_t dirty;
00313
00314 e = ccn_btree_node_getentry(sizeof(*e), node, ndx);
00315 if (e == NULL)
00316 return(-1);
00317 MYSTORE64(e, cobid, cobid);
00318 dirty = (((unsigned char *)e) - node->buf->buf);
00319 if (dirty >= 0 && dirty < node->clean)
00320 node->clean = dirty;
00321 return(0);
00322 }
00323
00324
00325
00326
00327
00328
00329 int
00330 ccn_btree_content_cobsz(struct ccn_btree_node *node, int ndx)
00331 {
00332 struct ccn_btree_content_payload *e = NULL;
00333
00334 e = ccn_btree_node_getentry(sizeof(*e), node, ndx);
00335 if (e != NULL)
00336 return(MYFETCH(e, cobsz));
00337 return(-1);
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347 int
00348 ccn_flatname_charbuf_compare(struct ccn_charbuf *a, struct ccn_charbuf *b)
00349 {
00350 return(ccn_flatname_compare(a->buf, a->length, b->buf, b->length));
00351 }
00352
00353
00354
00355
00356 int
00357 ccn_flatname_compare(const unsigned char *a, size_t al, const unsigned char *b, size_t bl)
00358 {
00359 int res;
00360
00361 res = memcmp(a, b, al < bl ? al : bl);
00362 if (res != 0)
00363 return(res);
00364 if (al < bl)
00365 return(-9999);
00366 else if (al == bl)
00367 return(0);
00368 else
00369 return(9999);
00370 }
00371
00372
00373
00374
00375
00376
00377
00378 int
00379 ccn_flatname_append_component(struct ccn_charbuf *dst,
00380 const unsigned char *comp, size_t size)
00381 {
00382 int res;
00383 int s;
00384 size_t save;
00385
00386 if (size >= (1 << 21))
00387 return(-1);
00388 save = dst->length;
00389 res = 0;
00390 for (s = 0; size >= (1 << (s + 7)); s += 7)
00391 continue;
00392 for (; s > 0; s -= 7)
00393 res |= ccn_charbuf_append_value(dst, (((size >> s) & 0x7F) | 0x80), 1);
00394 res |= ccn_charbuf_append_value(dst, (size & 0x7F), 1);
00395 res |= ccn_charbuf_append(dst, comp, size);
00396 if (res < 0)
00397 dst->length = save;
00398 return(res);
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 int
00414 ccn_flatname_append_from_ccnb(struct ccn_charbuf *dst,
00415 const unsigned char *ccnb, size_t size,
00416 int skip, int count)
00417 {
00418 int ans = 0;
00419 int ncomp = 0;
00420 const unsigned char *comp = NULL;
00421 size_t compsize = 0;
00422 struct ccn_buf_decoder decoder;
00423 struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, ccnb, size);
00424 int checkclose = 0;
00425 int res;
00426
00427 if (ccn_buf_match_dtag(d, CCN_DTAG_Interest) ||
00428 ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) {
00429 ccn_buf_advance(d);
00430 if (ccn_buf_match_dtag(d, CCN_DTAG_Signature))
00431 ccn_buf_advance_past_element(d);
00432 }
00433 if ((ccn_buf_match_dtag(d, CCN_DTAG_Name) ||
00434 ccn_buf_match_dtag(d, CCN_DTAG_Prefix))) {
00435 checkclose = 1;
00436 ccn_buf_advance(d);
00437 }
00438 else if (count != 0)
00439 count = 1;
00440 while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00441 if (ans == count)
00442 return(ans);
00443 ccn_buf_advance(d);
00444 compsize = 0;
00445 if (ccn_buf_match_blob(d, &comp, &compsize))
00446 ccn_buf_advance(d);
00447 ccn_buf_check_close(d);
00448 if (d->decoder.state < 0)
00449 return(-1);
00450 ncomp += 1;
00451 if (ncomp > skip) {
00452 res = ccn_flatname_append_component(dst, comp, compsize);
00453 if (res < 0)
00454 return(-1);
00455 ans++;
00456 }
00457 }
00458 if (checkclose)
00459 ccn_buf_check_close(d);
00460 if (d->decoder.state < 0)
00461 return (-1);
00462 return(ans);
00463 }
00464
00465
00466
00467
00468
00469 int
00470 ccn_flatname_from_ccnb(struct ccn_charbuf *dst,
00471 const unsigned char *ccnb, size_t size)
00472 {
00473 dst->length = 0;
00474 return(ccn_flatname_append_from_ccnb(dst, ccnb, size, 0, -1));
00475 }
00476
00477
00478
00479
00480
00481
00482
00483 int
00484 ccn_flatname_next_comp(const unsigned char *flatname, size_t size)
00485 {
00486 unsigned i, l, m;
00487
00488 if (size == 0)
00489 return(0);
00490 if (flatname[0] == 0x80)
00491 return(-1);
00492 m = (size < 3) ? size : 3;
00493 for (i = 0, l = 0; i < m && (flatname[i] & 0x80) != 0; i++)
00494 l = (l | (flatname[i] & 0x7F)) << 7;
00495 if (i >= m)
00496 return(-1);
00497 l |= flatname[i++];
00498 if (i + l > size)
00499 return(-1);
00500 return(l * 4 + i);
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 int
00513 ccn_name_append_flatname(struct ccn_charbuf *dst,
00514 const unsigned char *flatname, size_t size,
00515 int skip, int count)
00516 {
00517 int ans;
00518 int compnum;
00519 int i;
00520 int rnc;
00521 int res;
00522 const unsigned char *cp;
00523 size_t cs;
00524
00525 if (skip < 0)
00526 return(-1);
00527 ans = 0;
00528 compnum = 0;
00529 for (i = 0; i < size; i += CCNFLATSKIP(rnc)) {
00530 if (ans == count)
00531 return(ans);
00532 rnc = ccn_flatname_next_comp(flatname + i, size - i);
00533 if (rnc <= 0)
00534 return(-1);
00535 cp = flatname + i + CCNFLATDELIMSZ(rnc);
00536 cs = CCNFLATDATASZ(rnc);
00537 if (compnum >= skip) {
00538 res = ccn_name_append(dst, cp, cs);
00539 if (res < 0)
00540 return(-1);
00541 ans++;
00542 }
00543 compnum++;
00544 }
00545 return(ans);
00546 }
00547
00548
00549
00550
00551 int
00552 ccn_uri_append_flatname(struct ccn_charbuf *uri,
00553 const unsigned char *flatname, size_t size,
00554 int includescheme)
00555 {
00556 struct ccn_charbuf *ccnb = NULL;
00557 int res;
00558
00559 ccnb = ccn_charbuf_create();
00560 if (ccnb == NULL)
00561 return(-1);
00562 res = ccn_name_init(ccnb);
00563 if (res < 0)
00564 goto Bail;
00565 res = ccn_name_append_flatname(ccnb, flatname, size, 0, -1);
00566 if (res < 0)
00567 goto Bail;
00568 res = ccn_uri_append(uri, ccnb->buf, ccnb->length, includescheme);
00569 Bail:
00570 ccn_charbuf_destroy(&ccnb);
00571 return(res);
00572 }
00573
00574
00575
00576
00577
00578
00579 int
00580 ccn_flatname_ncomps(const unsigned char *flatname, size_t size)
00581 {
00582 int ans;
00583 int i;
00584 int rnc;
00585
00586 ans = 0;
00587 for (i = 0; i < size; i += CCNFLATSKIP(rnc)) {
00588 rnc = ccn_flatname_next_comp(flatname + i, size - i);
00589 if (rnc <= 0)
00590 return(-1);
00591 ans++;
00592 }
00593 return(ans);
00594 }