00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "SyncBase.h"
00022 #include "SyncActions.h"
00023 #include "SyncHashCache.h"
00024 #include "SyncNode.h"
00025 #include "SyncRoot.h"
00026 #include "SyncUtil.h"
00027 #include "IndexSorter.h"
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <strings.h>
00031 #include <sys/time.h>
00032 #include <ccnr/ccnr_msg.h>
00033 #include <ccnr/ccnr_sync.h>
00034 #include <ccn/ccn.h>
00035 #include <ccn/charbuf.h>
00036 #include <ccn/coding.h>
00037 #include <ccn/indexbuf.h>
00038 #include <ccn/uri.h>
00039
00040
00041 static int freshLimit = 30;
00042
00043
00044
00045 #define SET_ERR(d) SyncSetDecodeErr(d, -__LINE__)
00046 extern void
00047 SyncNoteErr(const char *msg) {
00048 char *s = getenv("CCNS_NOTE_ERR");
00049 int useStdErr = 0;
00050 if (s != NULL && s[0] != 0)
00051 useStdErr = strtol(s, NULL, 10);
00052 if (useStdErr > 0) {
00053 fprintf(stderr, "**** error in %s\n", msg);
00054 fflush(stderr);
00055 }
00056 }
00057
00058 extern int
00059 SyncSetDecodeErr(struct ccn_buf_decoder *d, int val) {
00060 SyncNoteErr("setErr");
00061 if (d->decoder.state >= 0) d->decoder.state = val;
00062 return val;
00063 }
00064
00065 extern int
00066 SyncCheckDecodeErr(struct ccn_buf_decoder *d) {
00067 return d->decoder.state < 0;
00068 }
00069
00070 extern int64_t
00071 SyncCurrentTime(void) {
00072 const int64_t M = 1000*1000;
00073 struct timeval now = {0};
00074 gettimeofday(&now, 0);
00075 return now.tv_sec*M+now.tv_usec;
00076 }
00077
00078 extern int64_t
00079 SyncDeltaTime(int64_t mt1, int64_t mt2) {
00080 return mt2-mt1;
00081 }
00082
00083 extern struct ccn_buf_decoder *
00084 SyncInitDecoderFromCharbufRange(struct ccn_buf_decoder *d,
00085 const struct ccn_charbuf *cb,
00086 ssize_t start, ssize_t stop) {
00087 if (((size_t) stop) > cb->length) stop = cb->length;
00088 if (start < 0 || start > stop) {
00089 SET_ERR(d);
00090 } else {
00091 ccn_buf_decoder_start(d, cb->buf+start, stop - start);
00092 }
00093 d->decoder.nest = 1;
00094 return d;
00095 }
00096
00097 extern struct ccn_buf_decoder *
00098 SyncInitDecoderFromCharbuf(struct ccn_buf_decoder *d,
00099 const struct ccn_charbuf *cb,
00100 ssize_t start) {
00101 return SyncInitDecoderFromCharbufRange(d, cb, start, cb->length);
00102 }
00103
00104 extern int
00105 SyncDecodeHexDigit(char c) {
00106 if (c >= '0' && c <= '9') return c - '0';
00107 if (c >= 'a' && c <= 'f') return 10 + c - 'a';
00108 if (c >= 'A' && c <= 'F') return 10 + c - 'A';
00109 return -1;
00110 }
00111
00112 extern int
00113 SyncDecodeUriChar(char c) {
00114 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
00115 || (c >= '0' && c <= '9')
00116 || c == '/' || c == '%' || c == ':'
00117 || c == '.' || c == '-' || c == '_' || c == '~') {
00118
00119 return c;
00120 }
00121 return -1;
00122 }
00123
00124 extern char *
00125 SyncHexStr(const unsigned char *cp, size_t sz) {
00126 char *hex = NEW_ANY(sz*2+1, char);
00127 char *hexLit = "0123456789abcdef";
00128 int i = 0;
00129 for (i = 0; i < sz; i++) {
00130 hex[i+i] = hexLit[(cp[i] / 16) & 15];
00131 hex[i+i+1] = hexLit[cp[i] & 15];
00132 }
00133 return hex;
00134 }
00135
00136
00137
00138
00139
00140 extern int
00141 SyncNoteFailed(struct SyncRootStruct *root, char *where, char *why, int line) {
00142 if (root->base->debug >= CCNL_SEVERE)
00143 ccnr_msg(root->base->client_handle, "%s, root#%u, failed, %s, line %d",
00144 where, root->rootId, why, line);
00145 SyncNoteErr("Sync.SyncNoteFailed");
00146 return -line;
00147 }
00148
00149 extern void
00150 SyncNoteSimple(struct SyncRootStruct *root, char *where, char *s1) {
00151 ccnr_msg(root->base->client_handle, "%s, root#%u, %s", where, root->rootId, s1);
00152 }
00153
00154 extern void
00155 SyncNoteSimple2(struct SyncRootStruct *root, char *where, char *s1, char *s2) {
00156 ccnr_msg(root->base->client_handle, "%s, root#%u, %s, %s", where, root->rootId, s1, s2);
00157 }
00158
00159 extern void
00160 SyncNoteSimple3(struct SyncRootStruct *root, char *where, char *s1, char *s2, char *s3) {
00161 ccnr_msg(root->base->client_handle, "%s, root#%u, %s, %s, %s", where, root->rootId, s1, s2, s3);
00162 }
00163
00164 extern void
00165 SyncNoteUri(struct SyncRootStruct *root, char *where, char *why, struct ccn_charbuf *name) {
00166 struct ccn_charbuf *uri = SyncUriForName(name);
00167 char *str = ccn_charbuf_as_string(uri);
00168 ccnr_msg(root->base->client_handle, "%s, root#%u, %s, %s", where, root->rootId, why, str);
00169 ccn_charbuf_destroy(&uri);
00170 }
00171
00172 extern void
00173 SyncNoteUriBase(struct SyncBaseStruct *base, char *where, char *why, struct ccn_charbuf *name) {
00174 struct ccn_charbuf *uri = SyncUriForName(name);
00175 char *str = ccn_charbuf_as_string(uri);
00176 ccnr_msg(base->client_handle, "%s, %s, %s", where, why, str);
00177 ccn_charbuf_destroy(&uri);
00178 }
00179
00180
00181
00182
00183
00184 extern int
00185 SyncCmpNamesInner(struct ccn_buf_decoder *xx, struct ccn_buf_decoder *yy) {
00186
00187 if (ccn_buf_match_dtag(xx, CCN_DTAG_Name))
00188 ccn_buf_advance(xx);
00189 else SET_ERR(xx);
00190 if (ccn_buf_match_dtag(yy, CCN_DTAG_Name))
00191 ccn_buf_advance(yy);
00192 else SET_ERR(yy);
00193 ssize_t cmp = 0;
00194 while (SyncCheckDecodeErr(xx) == 0 && SyncCheckDecodeErr(yy) == 0) {
00195 int more_x = ccn_buf_match_dtag(xx, CCN_DTAG_Component);
00196 int more_y = ccn_buf_match_dtag(yy, CCN_DTAG_Component);
00197 cmp = more_x - more_y;
00198 if (more_x == 0 || cmp != 0)
00199 break;
00200 ccn_buf_advance(xx);
00201 ccn_buf_advance(yy);
00202 size_t xs = 0;
00203 size_t ys = 0;
00204 const unsigned char *xp = NULL;
00205 const unsigned char *yp = NULL;
00206 if (ccn_buf_match_blob(xx, &xp, &xs)) ccn_buf_advance(xx);
00207 if (ccn_buf_match_blob(yy, &yp, &ys)) ccn_buf_advance(yy);
00208 cmp = xs - ys;
00209 if (cmp != 0)
00210 break;
00211 if (xs != 0) {
00212 cmp = memcmp(xp, yp, xs);
00213 if (cmp != 0)
00214 break;
00215 }
00216 ccn_buf_check_close(xx);
00217 ccn_buf_check_close(yy);
00218 }
00219 ccn_buf_check_close(xx);
00220 ccn_buf_check_close(yy);
00221 if (cmp > 0) return 1;
00222 if (cmp < 0) return -1;
00223 return 0;
00224 }
00225
00226 extern int
00227 SyncCmpNames(const struct ccn_charbuf *cbx, const struct ccn_charbuf *cby) {
00228 struct ccn_buf_decoder xds;
00229 struct ccn_buf_decoder *xx = SyncInitDecoderFromCharbuf(&xds, cbx, 0);
00230 struct ccn_buf_decoder yds;
00231 struct ccn_buf_decoder *yy = SyncInitDecoderFromCharbuf(&yds, cby, 0);
00232 int cmp = SyncCmpNamesInner(xx, yy);
00233 if (SyncCheckDecodeErr(xx) || SyncCheckDecodeErr(yy)) return SYNC_BAD_CMP;
00234 return (cmp);
00235 }
00236
00237
00238
00239 extern int
00240 SyncIsName(const struct ccn_charbuf *cb) {
00241 struct ccn_buf_decoder xds;
00242 struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&xds, cb, 0);
00243 if (!SyncCheckDecodeErr(d) && ccn_buf_match_dtag(d, CCN_DTAG_Name))
00244 return 1;
00245 return 0;
00246 }
00247
00248 extern int
00249 SyncComponentCount(const struct ccn_charbuf *name) {
00250 struct ccn_buf_decoder ds;
00251 struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, name, 0);
00252 int count = 0;
00253 if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
00254 ccn_buf_advance(d);
00255 while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00256 const unsigned char *cPtr = NULL;
00257 size_t cSize = 0;
00258 ccn_buf_advance(d);
00259 if (ccn_buf_match_blob(d, &cPtr, &cSize)) ccn_buf_advance(d);
00260 ccn_buf_check_close(d);
00261 count++;
00262 }
00263 ccn_buf_check_close(d);
00264 if (!SyncCheckDecodeErr(d))
00265 return count;
00266 }
00267 return -1;
00268 }
00269
00270 extern int
00271 SyncPatternMatch(const struct ccn_charbuf *pattern,
00272 const struct ccn_charbuf *name,
00273 int start) {
00274 struct ccn_buf_decoder xds;
00275 struct ccn_buf_decoder *xx = SyncInitDecoderFromCharbuf(&xds, pattern, 0);
00276 struct ccn_buf_decoder yds;
00277 struct ccn_buf_decoder *yy = SyncInitDecoderFromCharbuf(&yds, name, 0);
00278 if (!ccn_buf_match_dtag(xx, CCN_DTAG_Name)) return -1;
00279 ccn_buf_advance(xx);
00280 if (!ccn_buf_match_dtag(yy, CCN_DTAG_Name)) return -1;
00281 ccn_buf_advance(yy);
00282 int match = 0;
00283 int index = 0;
00284 while (index < start) {
00285
00286 if (!ccn_buf_match_dtag(yy, CCN_DTAG_Component))
00287 return -1;
00288 ccn_buf_advance(yy);
00289 if (!ccn_buf_match_blob(yy, NULL, NULL))
00290 return -1;
00291 ccn_buf_advance(yy);
00292 ccn_buf_check_close(yy);
00293 index++;
00294 }
00295 while (SyncCheckDecodeErr(xx) == 0 && SyncCheckDecodeErr(yy) == 0) {
00296 int more_x = ccn_buf_match_dtag(xx, CCN_DTAG_Component);
00297 int more_y = ccn_buf_match_dtag(yy, CCN_DTAG_Component);
00298 if (more_x == 0) {
00299
00300 ccn_buf_check_close(xx);
00301 if (!SyncCheckDecodeErr(xx))
00302 return match;
00303 return -1;
00304 }
00305 if (more_y == 0) {
00306
00307 ccn_buf_check_close(yy);
00308 if (!SyncCheckDecodeErr(yy))
00309 return 0;
00310 return -1;
00311 }
00312 ccn_buf_advance(xx);
00313 ccn_buf_advance(yy);
00314 size_t xs = 0;
00315 size_t ys = 0;
00316 const unsigned char *xp = NULL;
00317 const unsigned char *yp = NULL;
00318 if (ccn_buf_match_blob(xx, &xp, &xs)) ccn_buf_advance(xx);
00319 if (ccn_buf_match_blob(yy, &yp, &ys)) ccn_buf_advance(yy);
00320 int star = 0;
00321 if (xs > 0 && (xp[0] == 255)) {
00322
00323
00324 xs--;
00325 xp++;
00326 if (xs == 0) star = 1;
00327 }
00328 if (star) {
00329
00330 } else if (xs != ys) {
00331
00332 return 0;
00333 } else {
00334
00335 ssize_t cmp = memcmp(xp, yp, xs);
00336 if (cmp != 0) return 0;
00337 }
00338 match++;
00339 ccn_buf_check_close(xx);
00340 ccn_buf_check_close(yy);
00341 }
00342 return (-1);
00343 }
00344
00345 extern int
00346 SyncPrefixMatch(const struct ccn_charbuf *prefix,
00347 const struct ccn_charbuf *name,
00348 int start) {
00349 struct ccn_buf_decoder xds;
00350 struct ccn_buf_decoder *xx = SyncInitDecoderFromCharbuf(&xds, prefix, 0);
00351 struct ccn_buf_decoder yds;
00352 struct ccn_buf_decoder *yy = SyncInitDecoderFromCharbuf(&yds, name, 0);
00353 if (!ccn_buf_match_dtag(xx, CCN_DTAG_Name)) return -1;
00354 ccn_buf_advance(xx);
00355 if (!ccn_buf_match_dtag(yy, CCN_DTAG_Name)) return -1;
00356 ccn_buf_advance(yy);
00357 int match = 0;
00358 int index = 0;
00359 while (index < start) {
00360
00361 if (!ccn_buf_match_dtag(yy, CCN_DTAG_Component)) break;
00362 ccn_buf_advance(yy);
00363 if (ccn_buf_match_blob(yy, NULL, NULL)) ccn_buf_advance(yy);
00364 index++;
00365 }
00366 while (SyncCheckDecodeErr(xx) == 0 && SyncCheckDecodeErr(yy) == 0) {
00367 int more_x = ccn_buf_match_dtag(xx, CCN_DTAG_Component);
00368 int more_y = ccn_buf_match_dtag(yy, CCN_DTAG_Component);
00369 if (more_x == 0) {
00370
00371 ccn_buf_check_close(xx);
00372 if (!SyncCheckDecodeErr(xx))
00373 return match;
00374 return -1;
00375 }
00376 if (more_y == 0) {
00377
00378 ccn_buf_check_close(yy);
00379 if (!SyncCheckDecodeErr(yy))
00380 return 0;
00381 return -1;
00382 }
00383 ccn_buf_advance(xx);
00384 ccn_buf_advance(yy);
00385 size_t xs = 0;
00386 size_t ys = 0;
00387 const unsigned char *xp = NULL;
00388 const unsigned char *yp = NULL;
00389 if (ccn_buf_match_blob(xx, &xp, &xs)) ccn_buf_advance(xx);
00390 if (ccn_buf_match_blob(yy, &yp, &ys)) ccn_buf_advance(yy);
00391 if (xs != ys) {
00392
00393 return 0;
00394 } else if (xs > 0) {
00395
00396 ssize_t cmp = memcmp(xp, yp, xs);
00397 if (cmp != 0) return 0;
00398 }
00399 match++;
00400 ccn_buf_check_close(xx);
00401 ccn_buf_check_close(yy);
00402 }
00403 return -1;
00404 }
00405
00406 extern int
00407 SyncComponentMatch(const struct ccn_charbuf *x,
00408 const struct ccn_charbuf *y) {
00409 struct ccn_buf_decoder xds;
00410 struct ccn_buf_decoder *xx = SyncInitDecoderFromCharbuf(&xds, x, 0);
00411 struct ccn_buf_decoder yds;
00412 struct ccn_buf_decoder *yy = SyncInitDecoderFromCharbuf(&yds, y, 0);
00413 if (!ccn_buf_match_dtag(xx, CCN_DTAG_Name)) return -1;
00414 ccn_buf_advance(xx);
00415 if (!ccn_buf_match_dtag(yy, CCN_DTAG_Name)) return -1;
00416 ccn_buf_advance(yy);
00417 int match = 0;
00418 size_t xs = 0;
00419 size_t ys = 0;
00420 const unsigned char *xp = NULL;
00421 const unsigned char *yp = NULL;
00422 for (;;) {
00423 if (!ccn_buf_match_dtag(xx, CCN_DTAG_Component)) break;
00424 if (!ccn_buf_match_dtag(yy, CCN_DTAG_Component)) break;
00425 ccn_buf_advance(xx);
00426 ccn_buf_advance(yy);
00427 if (!ccn_buf_match_blob(xx, &xp, &xs)) return -1;
00428 if (!ccn_buf_match_blob(yy, &yp, &ys)) return -1;
00429 if (xs != ys) break;
00430 ssize_t cmp = memcmp(xp, yp, xs);
00431 if (cmp != 0) break;
00432 ccn_buf_advance(xx);
00433 ccn_buf_advance(yy);
00434 ccn_buf_check_close(xx);
00435 ccn_buf_check_close(yy);
00436 match++;
00437 }
00438 if (SyncCheckDecodeErr(xx)) match = -1;
00439 if (SyncCheckDecodeErr(yy)) match = -1;
00440 return match;
00441 }
00442
00443 extern int
00444 SyncGetComponentPtr(const struct ccn_charbuf *src, int comp,
00445 const unsigned char **xp, ssize_t *xs) {
00446 struct ccn_buf_decoder sbd;
00447 struct ccn_buf_decoder *s = SyncInitDecoderFromCharbuf(&sbd, src, 0);
00448 if (ccn_buf_match_dtag(s, CCN_DTAG_Name) && (xp != NULL) && (xs != NULL)) {
00449 int pos = 0;
00450 ccn_buf_advance(s);
00451 while (pos <= comp) {
00452 if (!ccn_buf_match_dtag(s, CCN_DTAG_Component)) break;
00453 ccn_buf_advance(s);
00454 if (!ccn_buf_match_blob(s, xp, (size_t *) xs)) break;
00455 ccn_buf_advance(s);
00456 ccn_buf_check_close(s);
00457 if (SyncCheckDecodeErr(s)) break;
00458 if (pos == comp)
00459
00460 return 0;
00461 pos++;
00462 }
00463 }
00464 return -1;
00465 }
00466
00467 extern int
00468 SyncAppendAllComponents(struct ccn_charbuf *dst,
00469 const struct ccn_charbuf *src) {
00470 struct ccn_buf_decoder sbd;
00471 struct ccn_buf_decoder *s = SyncInitDecoderFromCharbuf(&sbd, src, 0);
00472 int count = 0;
00473 int pos = 0;
00474 if (!ccn_buf_match_dtag(s, CCN_DTAG_Name))
00475
00476 return -__LINE__;
00477 ccn_buf_advance(s);
00478 for (;;) {
00479 if (!ccn_buf_match_dtag(s, CCN_DTAG_Component)) break;
00480 ccn_buf_advance(s);
00481 const unsigned char *cPtr = NULL;
00482 size_t cSize = 0;
00483 if (ccn_buf_match_blob(s, &cPtr, &cSize)) ccn_buf_advance(s);
00484 if (ccn_name_append(dst, cPtr, cSize) < 0)
00485 return -__LINE__;
00486 count++;
00487 ccn_buf_check_close(s);
00488 if (SyncCheckDecodeErr(s)) return -__LINE__;
00489 pos++;
00490 }
00491 ccn_buf_check_close(s);
00492 if (SyncCheckDecodeErr(s)) return -__LINE__;
00493 return count;
00494 }
00495
00496 extern struct ccn_charbuf *
00497 SyncNameForIndexbuf(const unsigned char *buf, struct ccn_indexbuf *comps) {
00498 struct ccn_charbuf *name = ccn_charbuf_create();
00499 ccn_name_init(name);
00500 int i = 0;
00501 int nComp = comps->n-1;
00502 int res = 0;
00503 for (i = 0; i < nComp; i++) {
00504 const unsigned char *cp = NULL;
00505 size_t sz = 0;
00506 res |= ccn_name_comp_get(buf, comps, i, &cp, &sz);
00507 if (res < 0) break;
00508 res |= ccn_name_append(name, cp, sz);
00509 if (res < 0) break;
00510 }
00511 if (res < 0) {
00512 SyncNoteErr("SyncNameForIndexbuf failed");
00513 ccn_charbuf_destroy(&name);
00514 return NULL;
00515 }
00516 return name;
00517 }
00518
00519 extern struct ccn_charbuf *
00520 SyncUriForName(struct ccn_charbuf *name) {
00521 struct ccn_charbuf *ret = ccn_charbuf_create();
00522 ccn_uri_append(ret, name->buf, name->length, 0);
00523 return ret;
00524 }
00525
00526
00527
00528
00529
00530 extern void
00531 SyncGetHashPtr(const struct ccn_buf_decoder *hd,
00532 const unsigned char ** xp, ssize_t *xs) {
00533 struct ccn_buf_decoder xds = *hd;
00534 struct ccn_buf_decoder *xd = &xds;
00535 size_t us = 0;
00536 if (ccn_buf_match_dtag(xd, CCN_DTAG_SyncContentHash)) {
00537 ccn_buf_advance(xd);
00538 if (ccn_buf_match_blob(xd, xp, &us)) ccn_buf_advance(xd);
00539 ccn_buf_check_close(xd);
00540 } else if (ccn_buf_match_dtag(xd, CCN_DTAG_Component)) {
00541 ccn_buf_advance(xd);
00542 if (ccn_buf_match_blob(xd, xp, &us)) ccn_buf_advance(xd);
00543 ccn_buf_check_close(xd);
00544 } else if (ccn_buf_match_dtag(xd, CCN_DTAG_Name)) {
00545 ccn_buf_advance(xd);
00546 for (;;) {
00547 if (!ccn_buf_match_dtag(xd, CCN_DTAG_Component)) break;
00548 ccn_buf_advance(xd);
00549 if (ccn_buf_match_blob(xd, xp, &us)) ccn_buf_advance(xd);
00550 ccn_buf_check_close(xd);
00551 }
00552 ccn_buf_check_close(xd);
00553 }
00554 xs[0] = (ssize_t) us;
00555 if (SyncCheckDecodeErr(xd)) {
00556
00557 xp[0] = NULL;
00558 xs[0] = 0;
00559 SyncSetDecodeErr(xd, -__LINE__);
00560 }
00561 }
00562
00563 extern ssize_t
00564 SyncCmpHashesRaw(const unsigned char * xp, ssize_t xs,
00565 const unsigned char * yp, ssize_t ys) {
00566 ssize_t cmp = xs - ys;
00567 if (cmp == 0) {
00568 cmp = memcmp(xp, yp, xs);
00569 }
00570 return cmp;
00571 }
00572
00573
00574
00575 extern void
00576 SyncAccumHashRaw(struct SyncLongHashStruct *hp,
00577 const unsigned char * xp, size_t xs) {
00578 unsigned char *ap = hp->bytes;
00579 int as = MAX_HASH_BYTES;
00580 int aLim = hp->pos;
00581 int c = 0;
00582 if (xs < 2)
00583 SyncNoteErr("SyncAccumHashRaw, xs < 2");
00584
00585 while (xs > 0 && as > 0) {
00586 int val = c;
00587 xs--;
00588 as--;
00589 val = val + ap[as] + xp[xs];
00590 c = (val >> 8) & 255;
00591 ap[as] = val & 255;
00592 }
00593
00594 while (c > 0 && as > 0) {
00595 as--;
00596 c = c + ap[as];
00597 ap[as] = c & 255;
00598 c = (c >> 8) & 255;
00599 }
00600
00601 if (as < aLim) hp->pos = as;
00602 }
00603
00604
00605
00606
00607 extern void
00608 SyncAccumHashInner(struct SyncLongHashStruct *hp,
00609 const struct ccn_buf_decoder *d) {
00610 const unsigned char * xp = NULL;
00611 ssize_t xs = -1;
00612 SyncGetHashPtr(d, &xp, &xs);
00613 if (xs >= 0 && xp != NULL)
00614 SyncAccumHashRaw(hp, xp, xs);
00615 }
00616
00617
00618
00619
00620 extern void
00621 SyncAccumHash(struct SyncLongHashStruct *hp, const struct ccn_charbuf *cb) {
00622 struct ccn_buf_decoder ds;
00623 struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, cb, 0);
00624 SyncAccumHashInner(hp, d);
00625 }
00626
00627 extern struct ccn_charbuf *
00628 SyncLongHashToBuf(const struct SyncLongHashStruct *hp) {
00629 struct ccn_charbuf *ret = ccn_charbuf_create();
00630 int pos = hp->pos;
00631 ccn_charbuf_append(ret, hp->bytes+pos, MAX_HASH_BYTES-pos);
00632 return ret;
00633 }
00634
00635
00636
00637 extern uint32_t
00638 SyncSmallHash(const unsigned char * xp, ssize_t xs) {
00639 uint32_t ret = 0;
00640 if (xs > 0 && xp != NULL) {
00641 int i = 0;
00642 while (i < xs && i < ((int) sizeof(ret))) {
00643 ret = (ret << 8) + (xp[i] & 255);
00644 i++;
00645 }
00646 }
00647 return ret;
00648 }
00649
00650
00651
00652
00653
00654
00655
00656 extern int
00657 SyncAppendTaggedNumber(struct ccn_charbuf *cb,
00658 enum ccn_dtag dtag,
00659 unsigned val) {
00660 int res = ccnb_tagged_putf(cb, dtag, "%u", val);
00661 return res;
00662 }
00663
00664
00665 extern int
00666 SyncAppendRandomBytes(struct ccn_charbuf *cb, int n) {
00667 size_t len = cb->length;
00668 ccn_charbuf_reserve(cb, n);
00669 unsigned char *dst = cb->buf + len;
00670 int i = 0;
00671 while (i < n) {
00672 unsigned int r = random();
00673 dst[i] = (unsigned char) (r & 255);
00674 i++;
00675 }
00676 cb->length = len + n;
00677 return 0;
00678 }
00679
00680
00681 extern int
00682 SyncAppendRandomHash(struct ccn_charbuf *cb, int n) {
00683 int res = ccn_charbuf_append_tt(cb, CCN_DTAG_SyncContentHash, CCN_DTAG);
00684 res |= ccn_charbuf_append_tt(cb, n, CCN_BLOB);
00685 res |= SyncAppendRandomBytes(cb, n);
00686 res |= ccn_charbuf_append_closer(cb);
00687 return res;
00688 }
00689
00690
00691 extern int
00692 SyncAppendRandomName(struct ccn_charbuf *cb, int nComp, int maxCompLen) {
00693 struct ccn_charbuf *rb = ccn_charbuf_create();
00694 int res = ccn_charbuf_append_tt(cb, CCN_DTAG_Name, CCN_DTAG);
00695 res |= ccn_charbuf_append_closer(cb);
00696 while (nComp > 0 && res == 0) {
00697 unsigned nb = random();
00698 nb = (nb % (maxCompLen+1));
00699 ccn_charbuf_reset(rb);
00700 SyncAppendRandomBytes(rb, nb);
00701 res |= ccn_name_append(cb, rb->buf, nb);
00702 nComp--;
00703 }
00704
00705 ccn_charbuf_reset(rb);
00706 res |= SyncAppendRandomBytes(rb, DEFAULT_HASH_BYTES);
00707 res |= ccn_name_append(cb, rb->buf, rb->length);
00708
00709 ccn_charbuf_destroy(&rb);
00710
00711 return res;
00712 }
00713
00714
00715
00716
00717
00718 extern int
00719 SyncAppendElementInner(struct ccn_charbuf *cb, struct ccn_buf_decoder *d) {
00720 int res = 0;
00721 int src = 0;
00722 if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
00723 ccn_buf_advance(d);
00724 int res = ccn_charbuf_append_tt(cb, CCN_DTAG_Name, CCN_DTAG);
00725 res |= ccn_charbuf_append_closer(cb);
00726 while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00727 const unsigned char *cPtr = NULL;
00728 size_t cSize = 0;
00729 ccn_buf_advance(d);
00730 if (ccn_buf_match_blob(d, &cPtr, &cSize)) ccn_buf_advance(d);
00731 res |= ccn_name_append(cb, cPtr, cSize);
00732 ccn_buf_check_close(d);
00733 }
00734 ccn_buf_check_close(d);
00735 } else if (ccn_buf_match_dtag(d, CCN_DTAG_SyncContentHash)) {
00736 const unsigned char *cPtr = NULL;
00737 size_t cSize = 0;
00738 ccn_buf_advance(d);
00739 if (ccn_buf_match_blob(d, &cPtr, &cSize)) ccn_buf_advance(d);
00740 res |= ccnb_append_tagged_blob(cb, CCN_DTAG_SyncContentHash, cPtr, cSize);
00741 } else if (ccn_buf_match_dtag(d, CCN_DTAG_BinaryValue)) {
00742 const unsigned char *cPtr = NULL;
00743 size_t cSize = 0;
00744 ccn_buf_advance(d);
00745 if (ccn_buf_match_blob(d, &cPtr, &cSize)) ccn_buf_advance(d);
00746 res |= ccnb_append_tagged_blob(cb, CCN_DTAG_BinaryValue, cPtr, cSize);
00747 } else res = -__LINE__;
00748 if (SyncCheckDecodeErr(d)) src = -__LINE__;
00749 if (res == 0) res = src;
00750 return res;
00751 }
00752
00753
00754
00755
00756 extern int
00757 SyncAppendElement(struct ccn_charbuf *dst, const struct ccn_charbuf *src) {
00758 struct ccn_buf_decoder ds;
00759 struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, src, 0);
00760 int res = SyncAppendElementInner(dst, d);
00761 return res;
00762 }
00763
00764 extern struct ccn_charbuf *
00765 SyncExtractName(struct ccn_buf_decoder *d) {
00766 struct ccn_charbuf *name = NULL;
00767 if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
00768 name = ccn_charbuf_create();
00769 int res = SyncAppendElementInner(name, d);
00770 if (res < 0) {
00771
00772 ccn_charbuf_destroy(&name);
00773 SyncSetDecodeErr(d, -__LINE__);
00774 }
00775 } else
00776 SyncSetDecodeErr(d, -__LINE__);
00777 return name;
00778 }
00779
00780 extern struct ccn_charbuf *
00781 SyncCopyName(const struct ccn_charbuf *name) {
00782 struct ccn_charbuf *ret = ccn_charbuf_create();
00783 ccn_charbuf_append_charbuf(ret, name);
00784 return ret;
00785 }
00786
00787
00788
00789
00790
00791 extern unsigned
00792 SyncParseUnsigned(struct ccn_buf_decoder *d, enum ccn_dtag dtag) {
00793 uintmax_t val = 0;
00794 if (ccn_buf_match_dtag(d, dtag)) {
00795 ccn_buf_advance(d);
00796 if (ccn_parse_uintmax(d, &val) >= 0) {
00797 ccn_buf_check_close(d);
00798 if (SyncCheckDecodeErr(d) == 0)
00799 return val;
00800 }
00801 }
00802 SET_ERR(d);
00803 return val;
00804 }
00805
00806 extern ssize_t
00807 SyncParseHash(struct ccn_buf_decoder *d) {
00808 ssize_t off = d->decoder.token_index;
00809 ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SyncContentHash, 0, MAX_HASH_BYTES);
00810 return off;
00811 }
00812
00813 extern ssize_t
00814 SyncParseName(struct ccn_buf_decoder *d) {
00815 ssize_t off = d->decoder.token_index;
00816 if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
00817 ccn_buf_advance(d);
00818 while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00819 ccn_buf_advance(d);
00820 if (ccn_buf_match_blob(d, NULL, NULL)) ccn_buf_advance(d);
00821 ccn_buf_check_close(d);
00822 }
00823 ccn_buf_check_close(d);
00824 } else SET_ERR(d);
00825 return off;
00826 }
00827
00828
00829
00830
00831
00832 extern struct SyncNameAccum *
00833 SyncAllocNameAccum(int lim) {
00834 struct SyncNameAccum *na = NEW_STRUCT(1, SyncNameAccum);
00835 if (lim < 4) lim = 4;
00836 na->lim = lim;
00837 na->ents = NEW_STRUCT(lim, SyncNameAccumEntry);
00838 return na;
00839 }
00840
00841 extern struct SyncNameAccum *
00842 SyncFreeNameAccum(struct SyncNameAccum *na) {
00843 if (na != NULL) {
00844 if (na->ents != NULL) free(na->ents);
00845 free(na);
00846 }
00847 return NULL;
00848 }
00849
00850 extern struct SyncNameAccum *
00851 SyncFreeNameAccumAndNames(struct SyncNameAccum *na) {
00852 if (na != NULL) {
00853 if (na->ents != NULL) {
00854 int i = 0;
00855 for (i = 0; i < na->len; i++) {
00856 struct ccn_charbuf *name = na->ents[i].name;
00857 if (name != NULL) {
00858 ccn_charbuf_destroy(&name);
00859 na->ents[i].name = NULL;
00860 }
00861 }
00862 free(na->ents);
00863 na->ents = NULL;
00864 }
00865 free(na);
00866 }
00867 return NULL;
00868 }
00869
00870 extern int
00871 SyncNameAccumSorter(IndexSorter_Base base,
00872 IndexSorter_Index x, IndexSorter_Index y) {
00873 struct SyncNameAccum *na = (struct SyncNameAccum *) base->client;
00874 IndexSorter_Index len = na->len;
00875 if (x < len && y < len) {
00876 struct ccn_charbuf *cbx = na->ents[x].name;
00877 struct ccn_charbuf *cby = na->ents[y].name;
00878 int cmp = SyncCmpNames(cbx, cby);
00879 if (cmp != SYNC_BAD_CMP) return cmp;
00880 }
00881 SyncNoteErr("nameAccumSorter");
00882 return 0;
00883 }
00884
00885 extern int
00886 SyncNameAccumAppend(struct SyncNameAccum *na,
00887 struct ccn_charbuf *name,
00888 intmax_t data) {
00889 if (name == NULL || name->length == 0)
00890 SyncNoteErr("SyncNameAccumAppend");
00891
00892 struct SyncNameAccumEntry *ents = na->ents;
00893 int len = na->len;
00894 if (len == na->lim) {
00895
00896 int newLim = na->lim + na->lim/2 + 4;
00897 struct SyncNameAccumEntry *newEnts = NEW_STRUCT(newLim, SyncNameAccumEntry);
00898 memcpy(newEnts, ents, len*sizeof(struct SyncNameAccumEntry));
00899 free(ents);
00900 na->lim = newLim;
00901 ents = newEnts;
00902 na->ents = newEnts;
00903 }
00904 ents[len].name = name;
00905 ents[len].data = data;
00906 na->len = len + 1;
00907 return 1;
00908 }
00909
00910 extern struct ccn_charbuf *
00911 SyncNameAccumCanon(struct SyncNameAccum *na,
00912 const struct ccn_charbuf *name) {
00913 struct ccn_charbuf *found = NULL;
00914 int i = 0;
00915
00916 for (i = 0; i < na->len; i++) {
00917 int cmp = SyncCmpNames(name, na->ents[i].name);
00918 if (cmp == 0) {
00919
00920 found = na->ents[i].name;
00921 na->ents[i].data++;
00922 break;
00923 }
00924 }
00925 if (found == NULL) {
00926
00927 found = ccn_charbuf_create();
00928 ccn_charbuf_append_charbuf(found, name);
00929 SyncNameAccumAppend(na, found, 1);
00930 }
00931 return found;
00932 }
00933
00934 extern struct SyncNodeAccum *
00935 SyncAllocNodeAccum(int lim) {
00936 struct SyncNodeAccum *na = NEW_STRUCT(1, SyncNodeAccum);
00937 if (lim < 4) lim = 4;
00938 na->lim = lim;
00939 na->ents = NEW_ANY(lim, struct SyncNodeComposite *);
00940 return na;
00941 }
00942
00943 extern struct SyncNodeAccum *
00944 SyncFreeNodeAccum(struct SyncNodeAccum *na) {
00945 if (na != NULL) {
00946 if (na->ents != NULL) free(na->ents);
00947 free(na);
00948 }
00949 return NULL;
00950 }
00951
00952 extern void
00953 SyncAccumNode(struct SyncNodeAccum *na, struct SyncNodeComposite *nc) {
00954 struct SyncNodeComposite **ents = na->ents;
00955 int len = na->len;
00956 if (len == na->lim) {
00957
00958 int newLim = na->lim + na->lim/2 + 4;
00959 struct SyncNodeComposite **newEnts = NEW_ANY(newLim,
00960 struct SyncNodeComposite *);
00961 memcpy(newEnts, ents, len*sizeof(struct SyncNodeComposite *));
00962 free(ents);
00963 na->lim = newLim;
00964 ents = newEnts;
00965 na->ents = newEnts;
00966 }
00967 ents[len] = nc;
00968 na->len = len + 1;
00969 }
00970
00971
00972
00973
00974
00975 static int
00976 appendLifetime(struct ccn_charbuf *cb, int lifetime) {
00977 unsigned char buf[sizeof(int32_t)];
00978 int32_t dreck = lifetime << 12;
00979 int pos = sizeof(int32_t);
00980 int res = 0;
00981 while (dreck > 0 && pos > 0) {
00982 pos--;
00983 buf[pos] = dreck & 255;
00984 dreck = dreck >> 8;
00985 }
00986 res |= ccnb_append_tagged_blob(cb, CCN_DTAG_InterestLifetime,
00987 buf+pos, sizeof(buf)-pos);
00988 return res;
00989 }
00990
00991 static int
00992 appendExclusions(struct ccn_charbuf *cb, struct SyncNameAccum *excl) {
00993 if (excl != NULL) {
00994 int i = 0;
00995 ccn_charbuf_append_tt(cb, CCN_DTAG_Exclude, CCN_DTAG);
00996 for (i = 0; i < excl->len; i++) {
00997 struct ccn_charbuf *name = excl->ents[i].name;
00998
00999 struct ccn_buf_decoder ds;
01000 struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, name, 0);
01001 size_t cSize = 0;
01002 if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
01003 ccn_buf_advance(d);
01004 if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
01005 ccn_buf_advance(d);
01006 const unsigned char *cPtr = NULL;
01007 if (ccn_buf_match_blob(d, &cPtr, &cSize)) {
01008 ccn_buf_advance(d);
01009 ccnb_append_tagged_blob(cb, CCN_DTAG_Component, cPtr, cSize);
01010 }
01011 }
01012 }
01013 if (cSize == 0) return -__LINE__;
01014 }
01015 ccn_charbuf_append_closer(cb);
01016 return 1;
01017 }
01018 return 0;
01019 }
01020
01021 extern struct ccn_charbuf *
01022 SyncGenInterest(struct ccn_charbuf *name,
01023 int scope, int lifetime, int maxSuffix, int childPref,
01024 struct SyncNameAccum *excl) {
01025 struct ccn_charbuf *cb = ccn_charbuf_create();
01026 ccn_charbuf_append_tt(cb, CCN_DTAG_Interest, CCN_DTAG);
01027 int res = 0;
01028 if (name == NULL) {
01029 res |= ccn_charbuf_append_tt(cb, CCN_DTAG_Name, CCN_DTAG);
01030 res |= ccn_charbuf_append_closer(cb);
01031 } else {
01032 ccn_charbuf_append_charbuf(cb, name);
01033 }
01034 if (maxSuffix >= 0)
01035 ccnb_tagged_putf(cb, CCN_DTAG_MaxSuffixComponents, "%d", maxSuffix);
01036 res |= appendExclusions(cb, excl);
01037 if (childPref >= 0)
01038
01039 ccnb_tagged_putf(cb, CCN_DTAG_ChildSelector, "%d", childPref);
01040 if (scope >= 0)
01041 ccnb_tagged_putf(cb, CCN_DTAG_Scope, "%d", scope);
01042 if (lifetime > 0)
01043 appendLifetime(cb, lifetime);
01044 ccn_charbuf_append_closer(cb);
01045 if (res < 0) {
01046 ccn_charbuf_destroy(&cb);
01047 }
01048 return cb;
01049 }
01050
01051
01052
01053
01054
01055 #define UseLocalTopoPrefix 1
01056 extern struct ccn_charbuf *
01057 SyncNameForLocalNode(struct SyncRootStruct *root, struct ccn_charbuf *hash) {
01058
01059
01060 struct ccn_charbuf *sh = root->sliceHash;
01061 struct ccn_charbuf *nm = ccn_charbuf_create();
01062 int res = 0;
01063 #ifdef UseLocalTopoPrefix
01064
01065 res |= ccn_charbuf_append_charbuf(nm, root->topoPrefix);
01066 #else
01067
01068 res |= ccn_name_init(nm);
01069 res |= ccn_name_append_str(nm, "\xC1.M.S.localhost");
01070 #endif
01071 res |= ccn_name_append_str(nm, "\xC1.S.nf");
01072 res |= ccn_name_append(nm, sh->buf, sh->length);
01073 res |= ccn_name_append(nm, hash->buf, hash->length);
01074 if (res < 0) ccn_charbuf_destroy(&nm);
01075 return nm;
01076 }
01077
01078 extern int
01079 SyncPointerToContent(struct ccn_charbuf *cb, struct ccn_parsed_ContentObject *pco,
01080 const unsigned char **xp, size_t *xs) {
01081 struct ccn_parsed_ContentObject pcos;
01082 int res = 0;
01083 if (pco == NULL) {
01084
01085 pco = &pcos;
01086 res = ccn_parse_ContentObject(cb->buf, cb->length,
01087 pco, NULL);
01088 }
01089 if (res >= 0)
01090
01091 res = ccn_content_get_value(cb->buf, cb->length, pco, xp, xs);
01092 return res;
01093 }
01094
01095 extern struct ccn_charbuf *
01096 SyncSignBuf(struct SyncBaseStruct *base,
01097 struct ccn_charbuf *cb,
01098 struct ccn_charbuf *name,
01099 long fresh, int flags) {
01100 struct ccn_charbuf *cob = ccn_charbuf_create();
01101 struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
01102
01103 if (cb != NULL) {
01104
01105 sp.type = CCN_CONTENT_DATA;
01106 } else {
01107
01108 cb = ccn_charbuf_create();
01109 sp.type = CCN_CONTENT_GONE;
01110 }
01111 sp.sp_flags |= flags;
01112
01113 if (fresh > 0 && fresh <= freshLimit) {
01114 sp.template_ccnb = ccn_charbuf_create();
01115 ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
01116 ccnb_tagged_putf(sp.template_ccnb, CCN_DTAG_FreshnessSeconds, "%ld", fresh);
01117 sp.sp_flags |= CCN_SP_TEMPL_FRESHNESS;
01118 ccn_charbuf_append_closer(sp.template_ccnb);
01119 }
01120
01121 int res = ccn_sign_content(base->ccn,
01122 cob,
01123 name,
01124 &sp,
01125 cb->buf,
01126 cb->length);
01127
01128 if (sp.template_ccnb != NULL)
01129 ccn_charbuf_destroy(&sp.template_ccnb);
01130 if (sp.type == CCN_CONTENT_GONE)
01131 ccn_charbuf_destroy(&cb);
01132 if (res < 0) {
01133
01134 ccn_charbuf_destroy(&cob);
01135 return NULL;
01136 }
01137 return cob;
01138 }
01139
01140 extern int
01141 SyncLocalRepoStore(struct SyncBaseStruct *base,
01142 struct ccn_charbuf *name,
01143 struct ccn_charbuf *content,
01144 int flags) {
01145 char *here = "Sync.SyncLocalRepoStore";
01146 int res = -__LINE__;
01147 struct ccn_charbuf *cob = SyncSignBuf(base, content, name, -1, flags);
01148 char *why = NULL;
01149 if (cob == NULL)
01150 why = "signing failed";
01151 else {
01152 res = r_sync_local_store(base->client_handle, cob);
01153 if (res < 0) why = "store failed";
01154 ccn_charbuf_destroy(&cob);
01155 }
01156 if (why != NULL)
01157 if (base->debug >= CCNL_ERROR)
01158 SyncNoteUriBase(base, here, why, name);
01159 return res;
01160 }
01161
01162 extern int
01163 SyncLocalRepoFetch(struct SyncBaseStruct *base,
01164 struct ccn_charbuf *name,
01165 struct ccn_charbuf *cb,
01166 struct ccn_parsed_ContentObject *pco) {
01167 char *here = "Sync.SyncLocalRepoFetch";
01168 struct ccnr_handle *ccnr = base->client_handle;
01169 struct ccn_charbuf *interest = SyncGenInterest(name, 1, 1, -1, 1, NULL);
01170 struct ccn_parsed_ContentObject pcos;
01171 if (pco == NULL) pco = &pcos;
01172 if (interest == NULL) return -__LINE__;
01173 int res = r_sync_lookup(ccnr, interest, cb);
01174 char *why = NULL;
01175 ccn_charbuf_destroy(&interest);
01176 if (res < 0) why = "fetch failed";
01177 else {
01178 res = ccn_parse_ContentObject(cb->buf, cb->length, pco, NULL);
01179 if (res < 0) why = "parse failed";
01180 else {
01181 res = ccn_verify_content(base->ccn, cb->buf, pco);
01182 if (res < 0) why = "verify failed";
01183 }
01184 }
01185 if (why != NULL)
01186 if (base->debug >= CCNL_ERROR)
01187 SyncNoteUriBase(base, here, why, name);
01188 return res;
01189 }
01190
01191
01192