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 *nextcomp = NULL;
00150 int i;
00151 int n;
00152 int ncomps;
00153 int pubidend;
00154 int pubidstart;
00155 int res;
00156 int rnc;
00157 size_t blob_size = 0;
00158 size_t nextcomp_size = 0;
00159 size_t size;
00160 struct ccn_btree_content_payload *e = NULL;
00161 unsigned char *flatname = NULL;
00162
00163 e = ccn_btree_node_getentry(sizeof(*e), node, ndx);
00164 if (e == NULL || e->magic[0] != CCN_BT_CONTENT_MAGIC)
00165 return(-1);
00166
00167 ncomps = MYFETCH(e, ncomp);
00168 if (ncomps < pi->prefix_comps + pi->min_suffix_comps)
00169 return(0);
00170 if (ncomps > pi->prefix_comps + pi->max_suffix_comps)
00171 return(0);
00172
00173 pubidstart = pi->offset[CCN_PI_B_PublisherID];
00174 pubidend = pi->offset[CCN_PI_E_PublisherID];
00175 if (pubidstart < pubidend) {
00176 blob_size = 0;
00177 ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest,
00178 interest_msg,
00179 pubidstart, pubidend,
00180 &blob, &blob_size);
00181 if (blob_size != sizeof(e->ppkdg))
00182 return(0);
00183 if (0 != memcmp(blob, e->ppkdg, blob_size))
00184 return(0);
00185 }
00186
00187 if (pi->offset[CCN_PI_E_Exclude] > pi->offset[CCN_PI_B_Exclude]) {
00188 res = ccn_btree_key_fetch(scratch, node, ndx);
00189 if (res < 0)
00190 return(-1);
00191 flatname = scratch->buf;
00192 size = scratch->length;
00193 nextcomp = NULL;
00194 nextcomp_size = 0;
00195 for (i = 0, n = 0; i < size; i += CCNFLATSKIP(rnc), n++) {
00196 rnc = ccn_flatname_next_comp(flatname + i, size - i);
00197 if (rnc <= 0)
00198 return(-1);
00199 if (n == pi->prefix_comps) {
00200 nextcomp = flatname + i + CCNFLATDELIMSZ(rnc);
00201 nextcomp_size = CCNFLATDATASZ(rnc);
00202 break;
00203 }
00204 }
00205 if (nextcomp == NULL)
00206 return(0);
00207 if (ccn_excluded(interest_msg + pi->offset[CCN_PI_B_Exclude],
00208 (pi->offset[CCN_PI_E_Exclude] -
00209 pi->offset[CCN_PI_B_Exclude]),
00210 nextcomp,
00211 nextcomp_size))
00212 return(0);
00213 }
00214
00215
00216
00217
00218 return(1);
00219 }
00220
00221
00222
00223
00224
00225
00226 uint_least64_t
00227 ccn_btree_content_cobid(struct ccn_btree_node *node, int ndx)
00228 {
00229 struct ccn_btree_content_payload *e = NULL;
00230 uint_least64_t ans = 0;
00231
00232 e = ccn_btree_node_getentry(sizeof(*e), node, ndx);
00233 if (e != NULL)
00234 ans = MYFETCH64(e, cobid);
00235 return(ans);
00236 }
00237
00238
00239
00240
00241
00242
00243 int
00244 ccn_btree_content_set_cobid(struct ccn_btree_node *node, int ndx,
00245 uint_least64_t cobid)
00246 {
00247 struct ccn_btree_content_payload *e = NULL;
00248 ptrdiff_t dirty;
00249
00250 e = ccn_btree_node_getentry(sizeof(*e), node, ndx);
00251 if (e == NULL)
00252 return(-1);
00253 MYSTORE64(e, cobid, cobid);
00254 dirty = (((unsigned char *)e) - node->buf->buf);
00255 if (dirty >= 0 && dirty < node->clean)
00256 node->clean = dirty;
00257 return(0);
00258 }
00259
00260
00261
00262
00263
00264
00265 int
00266 ccn_btree_content_cobsz(struct ccn_btree_node *node, int ndx)
00267 {
00268 struct ccn_btree_content_payload *e = NULL;
00269
00270 e = ccn_btree_node_getentry(sizeof(*e), node, ndx);
00271 if (e != NULL)
00272 return(MYFETCH(e, cobsz));
00273 return(-1);
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283 int
00284 ccn_flatname_charbuf_compare(struct ccn_charbuf *a, struct ccn_charbuf *b)
00285 {
00286 return(ccn_flatname_compare(a->buf, a->length, b->buf, b->length));
00287 }
00288
00289
00290
00291
00292 int
00293 ccn_flatname_compare(const unsigned char *a, size_t al, const unsigned char *b, size_t bl)
00294 {
00295 int res;
00296
00297 res = memcmp(a, b, al < bl ? al : bl);
00298 if (res != 0)
00299 return(res);
00300 if (al < bl)
00301 return(-9999);
00302 else if (al == bl)
00303 return(0);
00304 else
00305 return(9999);
00306 }
00307
00308
00309
00310
00311
00312
00313
00314 int
00315 ccn_flatname_append_component(struct ccn_charbuf *dst,
00316 const unsigned char *comp, size_t size)
00317 {
00318 int res;
00319 int s;
00320 size_t save;
00321
00322 if (size >= (1 << 21))
00323 return(-1);
00324 save = dst->length;
00325 res = 0;
00326 for (s = 0; size >= (1 << (s + 7)); s += 7)
00327 continue;
00328 for (; s > 0; s -= 7)
00329 res |= ccn_charbuf_append_value(dst, (((size >> s) & 0x7F) | 0x80), 1);
00330 res |= ccn_charbuf_append_value(dst, (size & 0x7F), 1);
00331 res |= ccn_charbuf_append(dst, comp, size);
00332 if (res < 0)
00333 dst->length = save;
00334 return(res);
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 int
00350 ccn_flatname_append_from_ccnb(struct ccn_charbuf *dst,
00351 const unsigned char *ccnb, size_t size,
00352 int skip, int count)
00353 {
00354 int ans = 0;
00355 int ncomp = 0;
00356 const unsigned char *comp = NULL;
00357 size_t compsize = 0;
00358 struct ccn_buf_decoder decoder;
00359 struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, ccnb, size);
00360 int checkclose = 0;
00361 int res;
00362
00363 if (ccn_buf_match_dtag(d, CCN_DTAG_Interest) ||
00364 ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) {
00365 ccn_buf_advance(d);
00366 if (ccn_buf_match_dtag(d, CCN_DTAG_Signature))
00367 ccn_buf_advance_past_element(d);
00368 }
00369 if ((ccn_buf_match_dtag(d, CCN_DTAG_Name) ||
00370 ccn_buf_match_dtag(d, CCN_DTAG_Prefix))) {
00371 checkclose = 1;
00372 ccn_buf_advance(d);
00373 }
00374 else if (count != 0)
00375 count = 1;
00376 while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00377 if (ans == count)
00378 return(ans);
00379 ccn_buf_advance(d);
00380 compsize = 0;
00381 if (ccn_buf_match_blob(d, &comp, &compsize))
00382 ccn_buf_advance(d);
00383 ccn_buf_check_close(d);
00384 if (d->decoder.state < 0)
00385 return(-1);
00386 ncomp += 1;
00387 if (ncomp > skip) {
00388 res = ccn_flatname_append_component(dst, comp, compsize);
00389 if (res < 0)
00390 return(-1);
00391 ans++;
00392 }
00393 }
00394 if (checkclose)
00395 ccn_buf_check_close(d);
00396 if (d->decoder.state < 0)
00397 return (-1);
00398 return(ans);
00399 }
00400
00401
00402
00403
00404
00405 int
00406 ccn_flatname_from_ccnb(struct ccn_charbuf *dst,
00407 const unsigned char *ccnb, size_t size)
00408 {
00409 dst->length = 0;
00410 return(ccn_flatname_append_from_ccnb(dst, ccnb, size, 0, -1));
00411 }
00412
00413
00414
00415
00416
00417
00418
00419 int
00420 ccn_flatname_next_comp(const unsigned char *flatname, size_t size)
00421 {
00422 unsigned i, l, m;
00423
00424 if (size == 0)
00425 return(0);
00426 if (flatname[0] == 0x80)
00427 return(-1);
00428 m = (size < 3) ? size : 3;
00429 for (i = 0, l = 0; i < m && (flatname[i] & 0x80) != 0; i++)
00430 l = (l | (flatname[i] & 0x7F)) << 7;
00431 if (i >= m)
00432 return(-1);
00433 l |= flatname[i++];
00434 if (i + l > size)
00435 return(-1);
00436 return(l * 4 + i);
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 int
00449 ccn_name_append_flatname(struct ccn_charbuf *dst,
00450 const unsigned char *flatname, size_t size,
00451 int skip, int count)
00452 {
00453 int ans;
00454 int compnum;
00455 int i;
00456 int rnc;
00457 int res;
00458 const unsigned char *cp;
00459 size_t cs;
00460
00461 if (skip < 0)
00462 return(-1);
00463 ans = 0;
00464 compnum = 0;
00465 for (i = 0; i < size; i += CCNFLATSKIP(rnc)) {
00466 if (ans == count)
00467 return(ans);
00468 rnc = ccn_flatname_next_comp(flatname + i, size - i);
00469 if (rnc <= 0)
00470 return(-1);
00471 cp = flatname + i + CCNFLATDELIMSZ(rnc);
00472 cs = CCNFLATDATASZ(rnc);
00473 if (compnum >= skip) {
00474 res = ccn_name_append(dst, cp, cs);
00475 if (res < 0)
00476 return(-1);
00477 ans++;
00478 }
00479 compnum++;
00480 }
00481 return(ans);
00482 }
00483
00484
00485
00486
00487 int
00488 ccn_uri_append_flatname(struct ccn_charbuf *uri,
00489 const unsigned char *flatname, size_t size,
00490 int includescheme)
00491 {
00492 struct ccn_charbuf *ccnb = NULL;
00493 int res;
00494
00495 ccnb = ccn_charbuf_create();
00496 if (ccnb == NULL)
00497 return(-1);
00498 res = ccn_name_init(ccnb);
00499 if (res < 0)
00500 goto Bail;
00501 res = ccn_name_append_flatname(ccnb, flatname, size, 0, -1);
00502 if (res < 0)
00503 goto Bail;
00504 res = ccn_uri_append(uri, ccnb->buf, ccnb->length, includescheme);
00505 Bail:
00506 ccn_charbuf_destroy(&ccnb);
00507 return(res);
00508 }
00509
00510
00511
00512
00513
00514
00515 int
00516 ccn_flatname_ncomps(const unsigned char *flatname, size_t size)
00517 {
00518 int ans;
00519 int i;
00520 int rnc;
00521
00522 ans = 0;
00523 for (i = 0; i < size; i += CCNFLATSKIP(rnc)) {
00524 rnc = ccn_flatname_next_comp(flatname + i, size - i);
00525 if (rnc <= 0)
00526 return(-1);
00527 ans++;
00528 }
00529 return(ans);
00530 }