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