00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "SyncActions.h"
00025 #include "SyncBase.h"
00026 #include "SyncHashCache.h"
00027 #include "SyncNode.h"
00028 #include "SyncPrivate.h"
00029 #include "SyncRoot.h"
00030 #include "SyncUtil.h"
00031 #include "SyncTreeWorker.h"
00032 #include "IndexSorter.h"
00033
00034 #include <errno.h>
00035 #include <stdarg.h>
00036 #include <stdlib.h>
00037 #include <stdio.h>
00038 #include <string.h>
00039 #include <strings.h>
00040 #include <unistd.h>
00041 #include <sys/stat.h>
00042 #include <sys/time.h>
00043
00044 #include <ccn/ccn.h>
00045 #include <ccn/charbuf.h>
00046 #include <ccn/digest.h>
00047 #include <ccn/fetch.h>
00048 #include <ccn/seqwriter.h>
00049 #include <ccn/uri.h>
00050
00051 #define MAX_READ_LEN 1000000
00052 #define DEFAULT_CMD_TIMEOUT 6000
00053
00054 struct SyncTestParms {
00055 struct SyncBaseStruct *base;
00056 struct SyncRootStruct *root;
00057 int mode;
00058 int mark;
00059 int digest;
00060 int scope;
00061 int syncScope;
00062 int life;
00063 int sort;
00064 int bufs;
00065 int verbose;
00066 int resolve;
00067 int segmented;
00068 int noDup;
00069 int noSend;
00070 int blockSize;
00071 char *inputName;
00072 char *target;
00073 int nSplits;
00074 int *splits;
00075 struct timeval startTime;
00076 struct timeval stopTime;
00077 intmax_t fSize;
00078 };
00079
00080
00081
00082
00083
00084 #include <ccnr/ccnr_private.h>
00085
00086 #include <ccnr/ccnr_sync.h>
00087
00088
00089
00090 PUBLIC void
00091 ccnr_msg(struct ccnr_handle *h, const char *fmt, ...)
00092 {
00093 struct timeval t;
00094 va_list ap;
00095 struct ccn_charbuf *b = ccn_charbuf_create();
00096 ccn_charbuf_reserve(b, 1024);
00097 gettimeofday(&t, NULL);
00098 ccn_charbuf_putf(b, "%s\n", fmt);
00099 char *fb = ccn_charbuf_as_string(b);
00100 va_start(ap, fmt);
00101 vfprintf(stdout, fb, ap);
00102 va_end(ap);
00103 fflush(stdout);
00104 ccn_charbuf_destroy(&b);
00105 }
00106
00107 PUBLIC int
00108 ccnr_msg_level_from_string(char *s) {
00109
00110 if (s == NULL)
00111 return -1;
00112 if (strcasecmp(s, "NONE") == 0)
00113 return 0;
00114 if (strcasecmp(s, "SEVERE") == 0)
00115 return 3;
00116 if (strcasecmp(s, "ERROR") == 0)
00117 return 5;
00118 if (strcasecmp(s, "WARNING") == 0)
00119 return 7;
00120 if (strcasecmp(s, "INFO") == 0)
00121 return 9;
00122 if (strcasecmp(s, "FINE") == 0)
00123 return 11;
00124 if (strcasecmp(s, "FINER") == 0)
00125 return 13;
00126 if (strcasecmp(s, "FINEST") == 0)
00127 return 15;
00128 return -1;
00129 }
00130
00131 PUBLIC void
00132 r_sync_notify_after(struct ccnr_handle *ccnr, ccnr_hwm item)
00133 {
00134
00135 ccnr->notify_after = (ccnr_accession) item;
00136 }
00137
00138 PUBLIC int
00139 r_sync_enumerate(struct ccnr_handle *ccnr,
00140 struct ccn_charbuf *interest)
00141 {
00142 int ans = -1;
00143 return(ans);
00144 }
00145
00146
00147 PUBLIC int
00148 r_sync_lookup(struct ccnr_handle *ccnr,
00149 struct ccn_charbuf *interest,
00150 struct ccn_charbuf *content_ccnb)
00151 {
00152 int ans = -1;
00153 return(ans);
00154 }
00155
00156
00157
00158
00159
00160 PUBLIC enum ccn_upcall_res
00161 r_sync_upcall_store(struct ccnr_handle *ccnr,
00162 enum ccn_upcall_kind kind,
00163 struct ccn_upcall_info *info)
00164 {
00165 enum ccn_upcall_res ans = CCN_UPCALL_RESULT_ERR;
00166 return(ans);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175 PUBLIC int
00176 r_sync_local_store(struct ccnr_handle *ccnr,
00177 struct ccn_charbuf *content)
00178 {
00179 int ans = -1;
00180 return(ans);
00181 }
00182
00183 PUBLIC uintmax_t
00184 ccnr_accession_encode(struct ccnr_handle *ccnr, ccnr_accession a)
00185 {
00186 return(a);
00187 }
00188
00189 PUBLIC ccnr_accession
00190 ccnr_accession_decode(struct ccnr_handle *ccnr, uintmax_t encoded)
00191 {
00192 return(encoded);
00193 }
00194
00195 PUBLIC int
00196 ccnr_accession_compare(struct ccnr_handle *ccnr, ccnr_accession x, ccnr_accession y)
00197 {
00198 if (x > y) return 1;
00199 if (x == y) return 0;
00200 if (x < y) return -1;
00201 return CCNR_NOT_COMPARABLE;
00202 }
00203
00204 PUBLIC uintmax_t
00205 ccnr_hwm_encode(struct ccnr_handle *ccnr, ccnr_hwm hwm)
00206 {
00207 return(hwm);
00208 }
00209
00210 PUBLIC ccnr_hwm
00211 ccnr_hwm_decode(struct ccnr_handle *ccnr, uintmax_t encoded)
00212 {
00213 return(encoded);
00214 }
00215
00216 PUBLIC int
00217 ccnr_acc_in_hwm(struct ccnr_handle *ccnr, ccnr_accession a, ccnr_hwm hwm)
00218 {
00219 return(a <= hwm);
00220 }
00221
00222 PUBLIC ccnr_hwm
00223 ccnr_hwm_update(struct ccnr_handle *ccnr, ccnr_hwm hwm, ccnr_accession a)
00224 {
00225 return(a <= hwm ? hwm : a);
00226 }
00227
00228 PUBLIC ccnr_hwm
00229 ccnr_hwm_merge(struct ccnr_handle *ccnr, ccnr_hwm x, ccnr_hwm y)
00230 {
00231 return(x < y ? y : x);
00232 }
00233
00234 PUBLIC int
00235 ccnr_hwm_compare(struct ccnr_handle *ccnr, ccnr_hwm x, ccnr_hwm y)
00236 {
00237 if (x > y) return 1;
00238 if (x == y) return 0;
00239 if (x < y) return -1;
00240 return CCNR_NOT_COMPARABLE;
00241 }
00242
00243
00244
00245
00246
00247
00248 static int
00249 noteErr(const char *fmt, ...) {
00250 struct timeval t;
00251 va_list ap;
00252 struct ccn_charbuf *b = ccn_charbuf_create();
00253 ccn_charbuf_reserve(b, 1024);
00254 gettimeofday(&t, NULL);
00255 ccn_charbuf_putf(b, "** ERROR: %s\n", fmt);
00256 char *fb = ccn_charbuf_as_string(b);
00257 va_start(ap, fmt);
00258 vfprintf(stderr, fb, ap);
00259 va_end(ap);
00260 fflush(stderr);
00261 ccn_charbuf_destroy(&b);
00262 return -1;
00263 }
00264
00265
00266
00267
00268
00269 static int
00270 parseAndAccumName(char *s, struct SyncNameAccum *na) {
00271 int i = 0;
00272 for (;;) {
00273 char c = s[i];
00274 int d = SyncDecodeUriChar(c);
00275 if (d <= 0) break;
00276 i++;
00277 }
00278 char save = s[i];
00279 s[i] = 0;
00280 struct ccn_charbuf *cb = ccn_charbuf_create();
00281 int skip = ccn_name_from_uri(cb, (const char *) s);
00282 s[i] = save;
00283 if (skip <= 0) {
00284
00285 ccn_charbuf_destroy(&cb);
00286 return skip;
00287 }
00288
00289
00290 intmax_t size = 0;
00291 for (;;) {
00292 char c = s[i];
00293 if (c >= '0' && c <= '9') break;
00294 if (c < ' ') break;
00295 i++;
00296 }
00297 for (;;) {
00298 char c = s[i];
00299 if (c < '0' || c > '9') break;
00300 size = size * 10 + SyncDecodeHexDigit(c);
00301 i++;
00302 }
00303
00304 SyncNameAccumAppend(na, cb, size);
00305 return skip;
00306 }
00307
00308 static struct SyncNameAccum *
00309 readAndAccumNames(FILE *input, int rem) {
00310 struct SyncNameAccum *na = SyncAllocNameAccum(4);
00311 static int tempLim = 4*1024;
00312 char *temp = NEW_ANY(tempLim+4, char);
00313 while (rem > 0) {
00314
00315 int len = 0;
00316 while (len < tempLim) {
00317 int c = fgetc(input);
00318 if (c < 0 || c == '\n') break;
00319 temp[len] = c;
00320 len++;
00321 }
00322 temp[len] = 0;
00323 if (len == 0)
00324
00325 break;
00326
00327 int pos = 0;
00328 static char *key = "ccnx:";
00329 int keyLen = strlen(key);
00330 int found = 0;
00331 while (pos < len) {
00332 if (strncasecmp(temp+pos, key, keyLen) == 0) {
00333
00334 parseAndAccumName(temp+pos, na);
00335 found++;
00336 break;
00337 }
00338 pos++;
00339 }
00340 if (found == 0) {
00341
00342 for (pos = 0; pos < len; pos++) {
00343 if (temp[pos]== '/') {
00344 parseAndAccumName(temp+pos, na);
00345 break;
00346 }
00347 }
00348 }
00349 rem--;
00350 }
00351 free(temp);
00352 return na;
00353 }
00354
00355
00356
00357
00358
00359 static void
00360 printTreeInner(struct SyncTreeWorkerHead *head,
00361 struct ccn_charbuf *tmpB,
00362 struct ccn_charbuf *tmpD,
00363 FILE *f) {
00364 int i = 0;
00365 struct SyncTreeWorkerEntry *ent = SyncTreeWorkerTop(head);
00366 struct SyncHashCacheEntry *ce = ent->cacheEntry;
00367 if (ce == NULL) {
00368 fprintf(f, "?? no cacheEntry ??\n");
00369 return;
00370 }
00371 struct SyncNodeComposite *nc = ((head->remote > 0) ? ce->ncR : ce->ncL);
00372 if (nc == NULL) {
00373 fprintf(f, "?? no cacheEntry->nc ??\n");
00374 return;
00375 }
00376 for (i = 1; i < head->level; i++) fprintf(f, " | ");
00377 char *hex = SyncHexStr(nc->hash->buf, nc->hash->length);
00378 fprintf(f, "node, depth = %d, refs = %d, leaves = %d, hash = %s\n",
00379 (int) nc->treeDepth, (int) nc->refLen, (int) nc->leafCount, hex);
00380 free(hex);
00381 ssize_t pos = 0;
00382 while (pos < nc->refLen) {
00383 struct SyncNodeElem *ep = &nc->refs[pos];
00384 ent->pos = pos;
00385 if (ep->kind & SyncElemKind_leaf) {
00386
00387 struct ccn_buf_decoder nameDec;
00388 struct ccn_buf_decoder *nameD = NULL;
00389 nameD = SyncInitDecoderFromOffset(&nameDec, nc, ep->start, ep->stop);
00390 ccn_charbuf_reset(tmpB);
00391 ccn_charbuf_reset(tmpD);
00392 SyncAppendElementInner(tmpB, nameD);
00393 ccn_uri_append(tmpD, tmpB->buf, tmpB->length, 1);
00394 for (i = 0; i < head->level; i++) fprintf(f, " | ");
00395 fprintf(f, "%s\n", ccn_charbuf_as_string(tmpD));
00396 } else {
00397
00398 SyncTreeWorkerPush(head);
00399 printTreeInner(head, tmpB, tmpD, f);
00400 SyncTreeWorkerPop(head);
00401 }
00402 pos++;
00403 }
00404 }
00405
00406 static void
00407 printTree(struct SyncTreeWorkerHead *head, FILE *f) {
00408 struct ccn_charbuf *tmpB = ccn_charbuf_create();
00409 struct ccn_charbuf *tmpD = ccn_charbuf_create();
00410 printTreeInner(head, tmpB, tmpD, f);
00411 ccn_charbuf_destroy(&tmpB);
00412 ccn_charbuf_destroy(&tmpD);
00413 }
00414
00415 static void putMark(FILE *f) {
00416 struct timeval mark;
00417 gettimeofday(&mark, 0);
00418 fprintf(f, "%ju.%06u: ",
00419 (uintmax_t) mark.tv_sec,
00420 (unsigned) mark.tv_usec);
00421 }
00422
00423
00424
00425
00426
00427
00428 static struct SyncNodeComposite *
00429 testGenComposite(struct SyncBaseStruct *base, int nRefs) {
00430 int res = 0;
00431 struct SyncNodeComposite *nc = SyncAllocComposite(base);
00432 struct ccn_charbuf *tmp = ccn_charbuf_create();
00433
00434
00435 while (nRefs > 0 && res == 0) {
00436 ccn_charbuf_reset(tmp);
00437 res |= SyncAppendRandomName(tmp, 5, 12);
00438 SyncNodeAddName(nc, tmp);
00439 nRefs--;
00440 }
00441
00442 SyncEndComposite(nc);
00443 ccn_charbuf_destroy(&tmp);
00444
00445 nc->err = res;
00446 return nc;
00447 }
00448
00449 static int
00450 testEncodeDecode(struct SyncTestParms *parms) {
00451 struct SyncBaseStruct *base = parms->base;
00452 struct ccn_charbuf *cb = ccn_charbuf_create();
00453 cb->length = 0;
00454 ccnb_element_begin(cb, CCN_DTAG_Content);
00455 fwrite(cb->buf, sizeof(unsigned char), cb->length, stdout);
00456
00457 struct SyncNodeComposite *nc = testGenComposite(base, 4);
00458
00459 SyncWriteComposite(nc, stdout);
00460
00461 struct ccn_buf_decoder ds;
00462 struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, nc->cb, 0);
00463 struct SyncNodeComposite *chk = SyncAllocComposite(base);
00464 SyncParseComposite(chk, d);
00465 SyncWriteComposite(chk, stdout);
00466 SyncFreeComposite(chk);
00467
00468 int pos = cb->length;
00469 ccnb_element_end(cb);
00470 fwrite(cb->buf+pos, sizeof(unsigned char), cb->length-pos, stdout);
00471 fflush(stdout);
00472
00473 SyncFreeComposite(nc);
00474
00475 cb->length = 0;
00476 ccn_charbuf_destroy(&cb);
00477
00478 return 0;
00479 }
00480
00481 static int
00482 testReader(struct SyncTestParms *parms) {
00483 char *fn = parms->inputName;
00484 int sort = parms->sort;
00485 FILE *f = fopen(fn, "r");
00486 int res = 0;
00487 if (f != NULL) {
00488 int64_t startTime = SyncCurrentTime();
00489 struct SyncNameAccum *na = readAndAccumNames(f, MAX_READ_LEN);
00490 fclose(f);
00491 struct ccn_charbuf *tmp = ccn_charbuf_create();
00492 int i = 0;
00493 IndexSorter_Base ixBase = NULL;
00494 int accumNameBytes = 0;
00495 int accumContentBytes = 0;
00496 if (sort > 0) {
00497 IndexSorter_Index ixLim = na->len;
00498 ixBase = IndexSorter_New(ixLim, -1);
00499 ixBase->sorter = SyncNameAccumSorter;
00500 ixBase->client = na;
00501 IndexSorter_Index ix = 0;
00502 for (; ix < ixLim; ix++) IndexSorter_Add(ixBase, ix);
00503 }
00504 struct ccn_charbuf *lag = NULL;
00505 for (;i < na->len; i++) {
00506 int j = i;
00507 if (ixBase != NULL) j = IndexSorter_Rem(ixBase);
00508 struct ccn_charbuf *each = na->ents[j].name;
00509 if (sort == 1 && lag != NULL) {
00510 int cmp = SyncCmpNames(each, lag);
00511 if (cmp < 0)
00512 return noteErr("bad sort (order)!");
00513 if (cmp == 0)
00514 return noteErr("bad sort (duplicate)!");
00515 }
00516 struct ccn_charbuf *repl = each;
00517 accumNameBytes = accumNameBytes + repl->length;
00518 ssize_t size = na->ents[j].data;
00519 accumContentBytes = accumContentBytes + size;
00520 ccn_charbuf_reset(tmp);
00521 ccn_uri_append(tmp, repl->buf, repl->length, 1);
00522 if (sort != 2) {
00523 fprintf(stdout, "%4d", i);
00524 if (sort) fprintf(stdout, ", %4d", j);
00525 fprintf(stdout, ", %8zd, ", size);
00526 }
00527 fprintf(stdout, "%s\n", ccn_charbuf_as_string(tmp));
00528 lag = each;
00529 if (repl != each) ccn_charbuf_destroy(&repl);
00530 }
00531 int64_t dt = SyncDeltaTime(startTime, SyncCurrentTime());
00532 dt = (dt + 500)/ 1000;
00533 fprintf(stdout, "-- %d names, %d name bytes, %d content bytes, %d.%03d seconds\n",
00534 na->len, accumNameBytes, accumContentBytes,
00535 (int) (dt / 1000), (int) (dt % 1000));
00536 if (ixBase != NULL) IndexSorter_Free(&ixBase);
00537 ccn_charbuf_destroy(&tmp);
00538 na = SyncFreeNameAccum(na);
00539 } else {
00540 return noteErr("testReader, could not open %s", fn);
00541 }
00542 return res;
00543 }
00544
00545 static int
00546 testReadBuilder(struct SyncTestParms *parms) {
00547 FILE *f = fopen(parms->inputName, "r");
00548 int ns = parms->nSplits;
00549 int res = 0;
00550
00551 if (f != NULL) {
00552 struct SyncRootStruct *root = parms->root;
00553
00554 if (root == NULL) {
00555
00556 struct ccn_charbuf *topo = ccn_charbuf_create();
00557 ccn_name_from_uri(topo, "/ccn/test/sync");
00558
00559 struct ccn_charbuf *prefix = ccn_charbuf_create();
00560 ccn_name_from_uri(prefix, "/ccn/test");
00561
00562 root = SyncAddRoot(parms->base,
00563 parms->syncScope,
00564 topo,
00565 prefix,
00566 NULL);
00567 parms->root = root;
00568 ccn_charbuf_destroy(&topo);
00569 ccn_charbuf_destroy(&prefix);
00570 }
00571
00572 if (root->namesToAdd != NULL)
00573 SyncFreeNameAccum(root->namesToAdd);
00574
00575 struct SyncLongHashStruct longHash;
00576 int split = 0;
00577 memset(&longHash, 0, sizeof(longHash));
00578 longHash.pos = MAX_HASH_BYTES;
00579 for (;;) {
00580 int i = 0;
00581 if (ns == 0) {
00582 root->namesToAdd = readAndAccumNames(f, MAX_READ_LEN);
00583 } else {
00584 int p = 0;
00585 int k = parms->splits[split];
00586 if (split > 0) p = parms->splits[split-1];
00587 if (k <= 0 || k >= ns) {
00588 return noteErr("splits: bad k %d", k);
00589 break;
00590 }
00591 if (p < 0 || p >= k) {
00592 return noteErr("splits: bad p %d", k);
00593 break;
00594 }
00595 root->namesToAdd = readAndAccumNames(f, k-p);
00596 }
00597
00598 if (root->namesToAdd == NULL || root->namesToAdd->len <= 0)
00599
00600 break;
00601
00602 for (i = 0; i < root->namesToAdd->len; i++) {
00603 SyncAccumHash(&longHash, root->namesToAdd->ents[i].name);
00604 }
00605 SyncUpdateRoot(root);
00606
00607 struct ccn_charbuf *hb = SyncLongHashToBuf(&longHash);
00608 struct ccn_charbuf *rb = root->currentHash;
00609 if (rb->length != hb->length
00610 || memcmp(rb->buf, hb->buf, hb->length) != 0) {
00611
00612 char *hexL = SyncHexStr(hb->buf, hb->length);
00613 char *hexR = SyncHexStr(rb->buf, rb->length);
00614 res = noteErr("hexL %s, hexR %s", hexL, hexR);
00615 free(hexL);
00616 free(hexR);
00617 return res;
00618 }
00619 ccn_charbuf_destroy(&hb);
00620
00621 struct SyncHashCacheEntry *ce = SyncRootTopEntry(root);
00622 struct SyncTreeWorkerHead *tw = SyncTreeWorkerCreate(root->ch, ce, 0);
00623 switch (parms->mode) {
00624 case 0: {
00625
00626 break;
00627 }
00628 case 1: {
00629
00630 SyncWriteComposite(ce->ncL, stdout);
00631 break;
00632 }
00633 case 2: {
00634
00635 SyncTreeWorkerInit(tw, ce, 0);
00636 printTree(tw, stdout);
00637 fprintf(stdout, "-----------------------\n");
00638 break;
00639 }
00640 default: {
00641
00642 break;
00643 }
00644 }
00645
00646
00647 tw = SyncTreeWorkerFree(tw);
00648 split++;
00649 if (ns > 0 && split >= ns) break;
00650 }
00651
00652 fclose(f);
00653 return 0;
00654
00655 } else {
00656 return noteErr("testReadBuilder, could not open %s", parms->inputName);
00657 }
00658 }
00659
00660
00661
00662 static struct SyncRootStruct *
00663 genTestRootRouting(struct SyncTestParms *parms) {
00664 struct SyncBaseStruct *base = parms->base;
00665 struct ccn_charbuf *topoPrefix = ccn_charbuf_create();
00666 struct ccn_charbuf *namingPrefix = ccn_charbuf_create();
00667
00668 ccn_name_from_uri(topoPrefix, "/ccn/test/sync");
00669 ccn_name_from_uri(namingPrefix, "/ccn/test/routing");
00670 struct SyncRootStruct *root = SyncAddRoot(base,
00671 parms->syncScope,
00672 topoPrefix,
00673 namingPrefix,
00674 NULL);
00675 ccn_charbuf_destroy(&topoPrefix);
00676 ccn_charbuf_destroy(&namingPrefix);
00677 return root;
00678 }
00679
00680
00681
00682 static struct SyncRootStruct *
00683 genTestRootRepos(struct SyncTestParms *parms) {
00684 struct SyncBaseStruct *base = parms->base;
00685 struct ccn_charbuf *topoPrefix = ccn_charbuf_create();
00686 struct ccn_charbuf *namingPrefix = ccn_charbuf_create();
00687
00688 ccn_name_from_uri(topoPrefix, "/ccn/test/sync");
00689 ccn_name_from_uri(namingPrefix, "/ccn/test/repos");
00690
00691 struct SyncNameAccum *filter = SyncAllocNameAccum(4);
00692 struct ccn_charbuf *clause = ccn_charbuf_create();
00693 ccn_name_from_uri(clause, "/PARC");
00694 SyncNameAccumAppend(filter, clause, 0);
00695
00696 struct SyncRootStruct *root = SyncAddRoot(base,
00697 parms->syncScope,
00698 topoPrefix,
00699 namingPrefix,
00700 filter);
00701 ccn_charbuf_destroy(&topoPrefix);
00702 ccn_charbuf_destroy(&namingPrefix);
00703 ccn_charbuf_destroy(&clause);
00704 SyncFreeNameAccum(filter);
00705
00706 return root;
00707 }
00708
00709 static struct SyncRootStruct *
00710 testRootCoding(struct SyncTestParms *parms, struct SyncRootStruct *root) {
00711 struct SyncBaseStruct *base = parms->base;
00712 struct ccn_charbuf *cb1 = ccn_charbuf_create();
00713 int res = 0;
00714 SyncRootAppendSlice(cb1, root);
00715
00716 SyncRemRoot(root);
00717
00718 struct ccn_buf_decoder ds;
00719 struct ccn_buf_decoder *d = SyncInitDecoderFromCharbuf(&ds, cb1, 0);
00720 root = SyncRootDecodeAndAdd(base, d);
00721 if (root == NULL) {
00722 res = noteErr("SyncRootDecodeAndAdd, failed");
00723 }
00724 if (res ==0) {
00725
00726 struct ccn_charbuf *cb2 = ccn_charbuf_create();
00727 SyncRootAppendSlice(cb2, root);
00728
00729 if (res == 0) {
00730
00731 if (cb1->length == 0 || cb1->length != cb2->length) {
00732 res = noteErr("testRootCoding, bad encoding lengths, %d != %d",
00733 (int) cb1->length, (int) cb2->length);
00734 }
00735 }
00736 if (res == 0) {
00737
00738 ssize_t cmp = memcmp(cb1->buf, cb2->buf, cb1->length);
00739 if (cmp != 0) {
00740 res = noteErr("testRootCoding, bad encoding data",
00741 (int) cb1->length, (int) cb2->length);
00742 res = -1;
00743 }
00744 }
00745 ccn_charbuf_destroy(&cb2);
00746 }
00747 ccn_charbuf_destroy(&cb1);
00748
00749 if (res == 0) return root;
00750
00751 SyncRemRoot(root);
00752 return NULL;
00753
00754 }
00755
00756 static int
00757 testRootLookup (struct SyncTestParms *parms, struct SyncRootStruct *root,
00758 char * goodName, char * badName) {
00759 int res = 0;
00760
00761 struct ccn_charbuf *name = ccn_charbuf_create();
00762 ccn_name_from_uri(name, goodName);
00763 enum SyncRootLookupCode ec = SyncRootLookupName(root, name);
00764 if (ec != SyncRootLookupCode_covered) {
00765 res = noteErr("testRootLookup, good name not covered, %s",
00766 goodName);
00767 }
00768 ccn_charbuf_reset(name);
00769 ccn_name_from_uri(name, badName);
00770 ec = SyncRootLookupName(root, name);
00771 if (ec != SyncRootLookupCode_none) {
00772 res = noteErr("testRootLookup, bad name not rejected, %s",
00773 badName);
00774 }
00775 return res;
00776 }
00777
00778 static int
00779 testRootBasic(struct SyncTestParms *parms) {
00780 int res = 0;
00781 struct SyncRootStruct *root = NULL;
00782
00783 struct ccn_charbuf *cb = ccn_charbuf_create();
00784 uintmax_t val = 37;
00785 res |= SyncAppendTaggedNumber(cb, CCN_DTAG_SyncVersion, val);
00786
00787 if (res == 0) {
00788 struct ccn_buf_decoder ds;
00789 struct ccn_buf_decoder *d = ccn_buf_decoder_start(&ds, cb->buf, cb->length);
00790 if (SyncParseUnsigned(d, CCN_DTAG_SyncVersion) != val
00791 || d->decoder.state < 0)
00792 res = -__LINE__;
00793 }
00794
00795 if (res < 0) {
00796 return noteErr("testRootBasic, basic numbers failed, %d", res);
00797 }
00798
00799
00800 root = genTestRootRouting(parms);
00801 root = testRootCoding(parms, root);
00802 res = testRootLookup(parms, root,
00803 "ccnx:/ccn/test/routing/XXX",
00804 "ccnx:/ccn/test/repos/PARC/XXX");
00805 SyncRemRoot(root);
00806 if (res < 0) return res;
00807
00808
00809 root = genTestRootRepos(parms);
00810 root = testRootCoding(parms, root);
00811 res = testRootLookup(parms, root,
00812 "ccnx:/ccn/test/repos/PARC/XXX",
00813 "ccnx:/ccn/test/routing/XXX");
00814 SyncRemRoot(root);
00815 if (res < 0) {
00816 return noteErr("testRootBasic, failed");
00817 }
00818
00819 return res;
00820 }
00821
00822 static int
00823 localStore(struct SyncTestParms *parms,
00824 struct ccn *ccn, struct ccn_charbuf *nm, struct ccn_charbuf *cb) {
00825 int res = 0;
00826 struct ccn_charbuf *template = SyncGenInterest(NULL,
00827 1,
00828 parms->life,
00829 -1, -1, NULL);
00830 struct ccn_charbuf *tmp = ccn_charbuf_create();
00831 ccn_create_version(ccn, nm, CCN_V_NOW, 0, 0);
00832 ccn_charbuf_append_charbuf(tmp, nm);
00833 ccn_name_from_uri(tmp, "%C1.R.sw");
00834 ccn_name_append_nonce(tmp);
00835 ccn_get(ccn, tmp, NULL, DEFAULT_CMD_TIMEOUT, NULL, NULL, NULL, 0);
00836 ccn_charbuf_destroy(&tmp);
00837 ccn_charbuf_destroy(&template);
00838 if (res < 0) return res;
00839
00840 struct ccn_charbuf *cob = ccn_charbuf_create();
00841 struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
00842 const void *cp = NULL;
00843 size_t cs = 0;
00844 if (cb != NULL) {
00845 sp.type = CCN_CONTENT_DATA;
00846 cp = (const void *) cb->buf;
00847 cs = cb->length;
00848 } else {
00849 sp.type = CCN_CONTENT_GONE;
00850 }
00851 ccn_name_append_numeric(nm, CCN_MARKER_SEQNUM, 0);
00852 sp.sp_flags |= CCN_SP_FINAL_BLOCK;
00853 res |= ccn_sign_content(ccn,
00854 cob,
00855 nm,
00856 &sp,
00857 cp,
00858 cs);
00859 res |= ccn_put(ccn, (const void *) cob->buf, cob->length);
00860
00861 ccn_charbuf_destroy(&cob);
00862 return res;
00863 }
00864
00865 static int
00866 sendSlice(struct SyncTestParms *parms,
00867 char *topo, char *prefix,
00868 int count, char **clauses) {
00869
00870 struct ccn_charbuf *cb = ccn_charbuf_create();
00871 struct ccn_charbuf *hash = ccn_charbuf_create();
00872 struct ccn_charbuf *nm = ccn_charbuf_create();
00873 int i = 0;
00874 int res = 0;
00875 res |= ccnb_element_begin(cb, CCN_DTAG_SyncConfigSlice);
00876 res |= SyncAppendTaggedNumber(cb, CCN_DTAG_SyncVersion, SLICE_VERSION);
00877 res |= ccn_name_from_uri(nm, topo);
00878 res |= ccn_charbuf_append_charbuf(cb, nm);
00879 res |= ccn_name_from_uri(nm, prefix);
00880 res |= ccn_charbuf_append_charbuf(cb, nm);
00881 res |= ccnb_element_begin(cb, CCN_DTAG_SyncConfigSliceList);
00882 for (i = 0; i < count ; i++) {
00883 res |= SyncAppendTaggedNumber(cb, CCN_DTAG_SyncConfigSliceOp, 0);
00884 res |= ccn_name_from_uri(nm, clauses[i]);
00885 res |= ccn_charbuf_append_charbuf(cb, nm);
00886 }
00887 res |= ccnb_element_end(cb);
00888 res |= ccnb_element_end(cb);
00889
00890 if (res >= 0) {
00891
00892 struct ccn *ccn = NULL;
00893 struct ccn_digest *cow = ccn_digest_create(CCN_DIGEST_DEFAULT);
00894 size_t sz = ccn_digest_size(cow);
00895 unsigned char *dst = ccn_charbuf_reserve(hash, sz);
00896 ccn_digest_init(cow);
00897 ccn_digest_update(cow, cb->buf, cb->length);
00898 ccn_digest_final(cow, dst, sz);
00899 hash->length = sz;
00900 ccn_digest_destroy(&cow);
00901
00902
00903 static char *localLit = "\xC1.M.S.localhost";
00904 static char *sliceCmd = "\xC1.S.cs";
00905 res |= ccn_name_init(nm);
00906 res |= ccn_name_append_str(nm, localLit);
00907 res |= ccn_name_append_str(nm, sliceCmd);
00908 res |= ccn_name_append(nm, hash->buf, hash->length);
00909
00910 if (parms->noSend) {
00911
00912 struct ccn_charbuf *hName = ccn_charbuf_create();
00913 ccn_name_init(hName);
00914 ccn_name_append(hName, hash->buf, hash->length);
00915 struct ccn_charbuf *uri = SyncUriForName(hName);
00916 fprintf(stdout, "%s\n", ccn_charbuf_as_string(uri));
00917 ccn_charbuf_destroy(&hName);
00918 ccn_charbuf_destroy(&uri);
00919 return 0;
00920 }
00921
00922 ccn = ccn_create();
00923 if (ccn_connect(ccn, NULL) == -1) {
00924 perror("Could not connect to ccnd");
00925 exit(1);
00926 }
00927 if (res >= 0) res |= localStore(parms, ccn, nm, cb);
00928 if (res < 0) {
00929 res = noteErr("sendSlice, failed");
00930 } else {
00931 if (parms->mode != 0) {
00932 struct ccn_charbuf *uri = SyncUriForName(nm);
00933 if (parms->mark) putMark(stdout);
00934 fprintf(stdout, "sendSlice, sent %s\n",
00935 ccn_charbuf_as_string(uri));
00936 ccn_charbuf_destroy(&uri);
00937 }
00938 }
00939
00940 ccn_destroy(&ccn);
00941 }
00942
00943 ccn_charbuf_destroy(&cb);
00944 ccn_charbuf_destroy(&hash);
00945 ccn_charbuf_destroy(&nm);
00946 if (res > 0) res = 0;
00947 return res;
00948 }
00949
00950 struct storeFileStruct {
00951 struct SyncTestParms *parms;
00952 struct ccn_charbuf *nm;
00953 struct ccn_charbuf *cb;
00954 struct ccn *ccn;
00955 off_t bs;
00956 off_t fSize;
00957 FILE *file;
00958 unsigned char *segData;
00959 int nSegs;
00960 int stored;
00961 struct ccn_charbuf *template;
00962 };
00963
00964 static int64_t
00965 segFromInfo(struct ccn_upcall_info *info) {
00966
00967
00968 if (info == NULL) return -1;
00969 const unsigned char *ccnb = info->content_ccnb;
00970 struct ccn_indexbuf *cc = info->content_comps;
00971 if (cc == NULL || ccnb == NULL) {
00972
00973 cc = info->interest_comps;
00974 ccnb = info->interest_ccnb;
00975 if (cc == NULL || ccnb == NULL) return -1;
00976 }
00977 int ns = cc->n;
00978 if (ns > 2) {
00979
00980 int start = cc->buf[ns - 2];
00981 int stop = cc->buf[ns - 1];
00982 if (start < stop) {
00983 size_t len = 0;
00984 const unsigned char *data = NULL;
00985 ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb, start, stop, &data, &len);
00986 if (len > 0 && data != NULL) {
00987
00988
00989 if (data[0] == CCN_MARKER_SEQNUM) {
00990 int64_t n = 0;
00991 int i = 0;
00992 for (i = 1; i < len; i++) {
00993 n = n * 256 + data[i];
00994 }
00995 return n;
00996 }
00997 }
00998 }
00999 }
01000 return -1;
01001 }
01002
01003 static enum ccn_upcall_res
01004 storeHandler(struct ccn_closure *selfp,
01005 enum ccn_upcall_kind kind,
01006 struct ccn_upcall_info *info) {
01007 struct storeFileStruct *sfd = selfp->data;
01008 enum ccn_upcall_res ret = CCN_UPCALL_RESULT_OK;
01009 switch (kind) {
01010 case CCN_UPCALL_FINAL:
01011 free(selfp);
01012 break;
01013 case CCN_UPCALL_INTEREST: {
01014 int64_t seg = segFromInfo(info);
01015 if (seg < 0) seg = 0;
01016 struct ccn_charbuf *uri = ccn_charbuf_create();
01017 ccn_uri_append(uri, sfd->nm->buf, sfd->nm->length, 0);
01018 char *str = ccn_charbuf_as_string(uri);
01019 ret = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
01020 if (seg >= 0 && seg < sfd->nSegs) {
01021 struct ccn_charbuf *name = SyncCopyName(sfd->nm);
01022 struct ccn_charbuf *cb = ccn_charbuf_create();
01023 struct ccn_charbuf *cob = ccn_charbuf_create();
01024 off_t bs = sfd->bs;
01025 off_t pos = seg * bs;
01026 off_t rs = sfd->fSize - pos;
01027 if (rs > bs) rs = bs;
01028
01029 ccn_charbuf_reserve(cb, rs);
01030 cb->length = rs;
01031 char *cp = ccn_charbuf_as_string(cb);
01032
01033
01034 int res = fseeko(sfd->file, pos, SEEK_SET);
01035 if (res >= 0) {
01036 res = fread(cp, rs, 1, sfd->file);
01037 if (res < 0) {
01038 char *eMess = strerror(errno);
01039 fprintf(stderr, "ERROR in fread, %s, seg %d, %s\n",
01040 eMess, (int) seg, str);
01041 }
01042 } else {
01043 char *eMess = strerror(errno);
01044 fprintf(stderr, "ERROR in fseeko, %s, seg %d, %s\n",
01045 eMess, (int) seg, str);
01046 }
01047
01048 if (res >= 0) {
01049 struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
01050 const void *cp = NULL;
01051 size_t cs = 0;
01052 sp.type = CCN_CONTENT_DATA;
01053 cp = (const void *) cb->buf;
01054 cs = cb->length;
01055 sp.template_ccnb = sfd->template;
01056
01057 if (seg+1 == sfd->nSegs) sp.sp_flags |= CCN_SP_FINAL_BLOCK;
01058 ccn_name_append_numeric(name, CCN_MARKER_SEQNUM, seg);
01059 res |= ccn_sign_content(sfd->ccn,
01060 cob,
01061 name,
01062 &sp,
01063 cp,
01064 rs);
01065 if (sfd->parms->digest) {
01066
01067 struct ccn_parsed_ContentObject pcos;
01068 ccn_parse_ContentObject(cob->buf, cob->length,
01069 &pcos, NULL);
01070 ccn_digest_ContentObject(cob->buf, &pcos);
01071 if (pcos.digest_bytes > 0)
01072 res |= ccn_name_append(name, pcos.digest, pcos.digest_bytes);
01073 }
01074 res |= ccn_put(sfd->ccn, (const void *) cob->buf, cob->length);
01075
01076 if (res < 0) {
01077 return noteErr("seg %d, %s",
01078 (int) seg,
01079 str);
01080 } else if (sfd->parms->verbose) {
01081 if (sfd->parms->mark) putMark(stdout);
01082 struct ccn_charbuf *nameUri = ccn_charbuf_create();
01083 ccn_uri_append(nameUri, name->buf, name->length, 0);
01084 char *nameStr = ccn_charbuf_as_string(nameUri);
01085 fprintf(stdout, "put seg %d, %s\n",
01086 (int) seg,
01087 nameStr);
01088 ccn_charbuf_destroy(&nameUri);
01089 }
01090
01091
01092 unsigned char uc = sfd->segData[seg];
01093 if (uc == 0) {
01094 uc++;
01095 sfd->stored++;
01096 } else {
01097 if (sfd->parms->noDup) {
01098 fprintf(stderr,
01099 "ERROR in storeHandler, duplicate segment request, seg %d, %s\n",
01100 (int) seg, str);
01101 }
01102 if (uc < 255) uc++;
01103 }
01104 sfd->segData[seg] = uc;
01105 }
01106
01107 ccn_charbuf_destroy(&name);
01108 ccn_charbuf_destroy(&cb);
01109 ccn_charbuf_destroy(&cob);
01110
01111 }
01112 ccn_charbuf_destroy(&uri);
01113 break;
01114 }
01115 default:
01116 ret = CCN_UPCALL_RESULT_ERR;
01117 break;
01118 }
01119 return ret;
01120 }
01121
01122 static void
01123 formatStats(struct SyncTestParms *parms) {
01124 int64_t dt = (1000000*(parms->stopTime.tv_sec-parms->startTime.tv_sec)
01125 + parms->stopTime.tv_usec-parms->startTime.tv_usec);
01126 if (dt <= 0) dt = 1;
01127 int64_t rate = 0;
01128
01129 switch (parms->mode) {
01130 case 0: {
01131
01132 break;
01133 }
01134 case 3: {
01135
01136 const char *expid = getenv("CCN_EXPERIMENT_ID");
01137 const char *sep = " ";
01138 if (expid == NULL) {
01139 expid = "";
01140 sep = "";
01141 }
01142 rate = (parms->fSize * 1000000) / dt;
01143 if (parms->mark) putMark(stderr);
01144 fprintf(stderr,
01145 "%ld.%06u SyncTest[%d]: %s%s"
01146 "%jd bytes transferred in %ld.%06u seconds (%ld bytes/sec)"
01147 "\n",
01148 (long) parms->stopTime.tv_sec,
01149 (unsigned) parms->stopTime.tv_usec,
01150 (int)getpid(),
01151 expid,
01152 sep,
01153 (intmax_t) parms->fSize,
01154 (long) (dt / 1000000),
01155 (unsigned) (dt % 1000000),
01156 (long) rate
01157 );
01158 break;
01159 }
01160 default: {
01161
01162 dt = (dt + 500) / 1000;
01163 if (dt <= 0) dt = 1;
01164 rate = parms->fSize / dt;
01165
01166 if (parms->mark) putMark(stdout);
01167 fprintf(stdout, "transferred %jd bytes in %d.%03d seconds = %d.%03d MB/sec\n",
01168 (intmax_t) parms->fSize,
01169 (int) (dt / 1000), (int) dt % 1000,
01170 (int) (rate / 1000), (int) rate % 1000);
01171 break;
01172 }
01173
01174 }
01175 }
01176
01177 static int
01178 getFile(struct SyncTestParms *parms, char *src, char *dst) {
01179
01180
01181 FILE *file = NULL;
01182
01183 if (dst != NULL) {
01184 file = fopen(dst, "w");
01185 if (file == NULL) {
01186 perror("fopen failed");
01187 return -1;
01188 }
01189 }
01190
01191 struct ccn *ccn = NULL;
01192 ccn = ccn_create();
01193
01194 if (dst == NULL)
01195 ccn_defer_verification(ccn, 1);
01196 if (ccn_connect(ccn, NULL) == -1) {
01197 perror("Could not connect to ccnd");
01198 return -1;
01199 }
01200 struct ccn_charbuf *cb = ccn_charbuf_create();
01201 struct ccn_charbuf *nm = ccn_charbuf_create();
01202 int bs = parms->blockSize;
01203
01204 int res = ccn_name_from_uri(nm, src);
01205 if (res < 0) {
01206 perror("ccn_name_from_uri failed");
01207 return -1;
01208 }
01209
01210 if (parms->resolve) {
01211 res = ccn_resolve_version(ccn, nm, CCN_V_HIGH, parms->life*1000);
01212
01213 if (res < 0) {
01214 perror("ccn_resolve_version failed");
01215 return -1;
01216 }
01217 }
01218
01219 struct ccn_fetch *cf = ccn_fetch_new(ccn);
01220 struct ccn_charbuf *template = SyncGenInterest(NULL,
01221 parms->scope,
01222 parms->life,
01223 -1, -1, NULL);
01224
01225 if (parms->verbose) {
01226 ccn_fetch_set_debug(cf, stderr,
01227 ccn_fetch_flags_NoteOpenClose
01228 | ccn_fetch_flags_NoteNeed
01229 | ccn_fetch_flags_NoteFill
01230 | ccn_fetch_flags_NoteTimeout
01231 | ccn_fetch_flags_NoteFinal);
01232 }
01233 gettimeofday(&parms->startTime, 0);
01234
01235 if (parms->segmented == 0) {
01236
01237 struct ccn_parsed_ContentObject pcos;
01238 res = ccn_get(ccn, nm, template,
01239 parms->life*1000,
01240 cb, &pcos, NULL, 0);
01241 ccn_charbuf_destroy(&template);
01242 if (res < 0) {
01243 perror("get failed");
01244 return -1;
01245 }
01246 if (file != NULL) {
01247 size_t nItems = fwrite(ccn_charbuf_as_string(cb), cb->length, 1, file);
01248 if (nItems < 1) {
01249 perror("fwrite failed");
01250 return -1;
01251 }
01252 }
01253 parms->fSize = parms->fSize + cb->length;
01254
01255 } else {
01256
01257 struct ccn_fetch_stream *fs = ccn_fetch_open(cf, nm,
01258 "SyncTest",
01259 template,
01260 parms->bufs,
01261 0, 0);
01262 ccn_charbuf_destroy(&template);
01263 if (fs == NULL) {
01264 perror("ccn_fetch_open failed");
01265 return -1;
01266 }
01267 ccn_charbuf_reserve(cb, bs);
01268 cb->length = bs;
01269 char *cp = ccn_charbuf_as_string(cb);
01270
01271 for (;;) {
01272 intmax_t av = ccn_fetch_avail(fs);
01273 if (av == CCN_FETCH_READ_NONE) {
01274 ccn_run(ccn, 1);
01275 continue;
01276 }
01277 int nb = ccn_fetch_read(fs, cp, bs);
01278 if (nb > 0) {
01279 if (file != NULL) {
01280 size_t nItems = fwrite(cp, nb, 1, file);
01281 if (nItems < 1) {
01282 perror("fwrite failed");
01283 exit(1);
01284 }
01285 }
01286 parms->fSize = parms->fSize + nb;
01287 } else if (nb == CCN_FETCH_READ_NONE) {
01288
01289 ccn_run(ccn, 1);
01290 } else {
01291 if (nb == CCN_FETCH_READ_END) break;
01292 if (nb == CCN_FETCH_READ_TIMEOUT) {
01293 perror("read failed, timeout");
01294 exit(1);
01295 }
01296 char temp[256];
01297 snprintf(temp, sizeof(temp), "ccn_fetch_read failed: %d", nb);
01298 perror(temp);
01299 return -1;
01300 }
01301 }
01302 ccn_fetch_close(fs);
01303 }
01304
01305 gettimeofday(&parms->stopTime, 0);
01306
01307 if (file != NULL)
01308 fclose(file);
01309
01310 ccn_fetch_destroy(cf);
01311
01312 ccn_destroy(&ccn);
01313 ccn_charbuf_destroy(&cb);
01314 ccn_charbuf_destroy(&nm);
01315
01316 formatStats(parms);
01317
01318 if (res > 0) res = 0;
01319 return res;
01320 }
01321
01322 static int
01323 putFile(struct SyncTestParms *parms, char *src, char *dst) {
01324
01325
01326 struct stat myStat;
01327 int res = stat(src, &myStat);
01328 if (res < 0) {
01329 perror("putFile, stat failed");
01330 return -1;
01331 }
01332 off_t fSize = myStat.st_size;
01333
01334 if (fSize == 0) {
01335 return noteErr("putFile, stat failed, empty src");
01336 }
01337 FILE *file = fopen(src, "r");
01338 if (file == NULL) {
01339 perror("putFile, fopen failed");
01340 return -1;
01341 }
01342
01343 struct ccn *ccn = NULL;
01344 ccn = ccn_create();
01345 if (ccn_connect(ccn, NULL) == -1) {
01346 return noteErr("putFile, could not connect to ccnd");
01347 }
01348 struct ccn_charbuf *cb = ccn_charbuf_create();
01349 struct ccn_charbuf *nm = ccn_charbuf_create();
01350 struct ccn_charbuf *cmd = ccn_charbuf_create();
01351 int bs = parms->blockSize;
01352
01353 res = ccn_name_from_uri(nm, dst);
01354 if (res < 0) {
01355 return noteErr("putFile, ccn_name_from_uri failed");
01356 }
01357 ccn_create_version(ccn, nm, CCN_V_NOW, 0, 0);
01358
01359 struct storeFileStruct *sfData = NEW_STRUCT(1, storeFileStruct);
01360 sfData->parms = parms;
01361 sfData->file = file;
01362 sfData->bs = bs;
01363 sfData->nm = nm;
01364 sfData->cb = cb;
01365 sfData->ccn = ccn;
01366 sfData->fSize = fSize;
01367 sfData->nSegs = (fSize + bs -1) / bs;
01368 sfData->segData = NEW_ANY(sfData->nSegs, unsigned char);
01369
01370 {
01371
01372
01373 const unsigned char *vp = NULL;
01374 ssize_t vs;
01375 SyncGetComponentPtr(nm, SyncComponentCount(nm)-1, &vp, &vs);
01376 if (vp != NULL && vs > 0) {
01377 sfData->template = ccn_charbuf_create();
01378 ccnb_element_begin(sfData->template, CCN_DTAG_SignedInfo);
01379 ccnb_append_tagged_blob(sfData->template, CCN_DTAG_Timestamp, vp, vs);
01380 ccnb_element_end(sfData->template);
01381 } else return noteErr("putFile, create store template failed");
01382 }
01383
01384 struct ccn_charbuf *template = SyncGenInterest(NULL,
01385 parms->scope,
01386 parms->life,
01387 -1, -1, NULL);
01388 struct ccn_closure *action = NEW_STRUCT(1, ccn_closure);
01389 action->p = storeHandler;
01390 action->data = sfData;
01391
01392 parms->fSize = fSize;
01393
01394
01395 res = ccn_set_interest_filter(ccn, nm, action);
01396 if (res < 0) {
01397 return noteErr("putFile, ccn_set_interest_filter failed");
01398 }
01399 ccn_run(ccn, 40);
01400
01401
01402 ccn_charbuf_append_charbuf(cmd, nm);
01403 ccn_name_from_uri(cmd, "%C1.R.sw");
01404 ccn_name_append_nonce(cmd);
01405
01406 if (parms->verbose && parms->mode != 0) {
01407 struct ccn_charbuf *uri = SyncUriForName(nm);
01408 if (parms->mark) putMark(stdout);
01409 fprintf(stdout, "put init, %s\n",
01410 ccn_charbuf_as_string(uri));
01411 ccn_charbuf_destroy(&uri);
01412 }
01413 gettimeofday(&parms->startTime, 0);
01414 ccn_get(ccn, cmd, template, DEFAULT_CMD_TIMEOUT, NULL, NULL, NULL, 0);
01415 ccn_charbuf_destroy(&template);
01416 if (res < 0) {
01417 return noteErr("putFile, ccn_get failed");
01418 }
01419
01420
01421 while (sfData->stored < sfData->nSegs) {
01422 ccn_run(ccn, 2);
01423 }
01424
01425 gettimeofday(&parms->stopTime, 0);
01426
01427 res = ccn_set_interest_filter(ccn, nm, NULL);
01428 if (res < 0) {
01429 return noteErr("putFile, ccn_set_interest_filter failed (removal)");
01430 }
01431 ccn_run(ccn, 40);
01432
01433 ccn_charbuf_destroy(&sfData->template);
01434 free(sfData->segData);
01435 free(sfData);
01436 ccn_destroy(&ccn);
01437 fclose(file);
01438 ccn_charbuf_destroy(&cb);
01439 ccn_charbuf_destroy(&cmd);
01440 ccn_charbuf_destroy(&nm);
01441
01442 formatStats(parms);
01443
01444 if (res > 0) res = 0;
01445 return res;
01446 }
01447
01448 extern int
01449 appendComponents(struct ccn_charbuf *dst,
01450 const struct ccn_charbuf *src,
01451 int start, int len) {
01452 struct ccn_buf_decoder sbd;
01453 struct ccn_buf_decoder *s = SyncInitDecoderFromCharbuf(&sbd, src, 0);
01454 int count = 0;
01455 int pos = 0;
01456 if (!ccn_buf_match_dtag(s, CCN_DTAG_Name))
01457
01458 return -__LINE__;
01459 ccn_buf_advance(s);
01460 int lim = start + len;
01461 while (count < lim) {
01462 if (!ccn_buf_match_dtag(s, CCN_DTAG_Component)) {
01463 ccn_buf_check_close(s);
01464 if (SyncCheckDecodeErr(s)) return -__LINE__;
01465 break;
01466 }
01467 ccn_buf_advance(s);
01468 const unsigned char *cPtr = NULL;
01469 size_t cSize = 0;
01470 if (ccn_buf_match_blob(s, &cPtr, &cSize)) ccn_buf_advance(s);
01471 if (cPtr == NULL)
01472 return -__LINE__;
01473 if (count >= start) {
01474 if (ccn_name_append(dst, cPtr, cSize) < 0)
01475 return -__LINE__;
01476 }
01477 count++;
01478 ccn_buf_check_close(s);
01479 if (SyncCheckDecodeErr(s)) return -__LINE__;
01480 pos++;
01481 }
01482 return count;
01483 }
01484
01485 static int
01486 putFileList(struct SyncTestParms *parms, char *listName) {
01487 struct ccn *ccn = NULL;
01488 ccn = ccn_create();
01489 if (ccn_connect(ccn, NULL) == -1) {
01490 return noteErr("putFile, could not connect to ccnd");
01491 }
01492 FILE *listFile = fopen(listName, "r");
01493 if (listFile == NULL) {
01494 return noteErr("putFileList, failed to open list file");
01495 }
01496 int ret = 0;
01497 struct SyncNameAccum *na = readAndAccumNames(listFile, MAX_READ_LEN);
01498 int i = 0;
01499 fclose(listFile);
01500 struct ccn_charbuf *tmp = ccn_charbuf_create();
01501 struct ccn_charbuf *template = SyncGenInterest(NULL,
01502 parms->scope,
01503 parms->life,
01504 -1, -1, NULL);
01505 while (i < na->len) {
01506 tmp->length = 0;
01507 ccn_name_init(tmp);
01508 struct ccn_charbuf *each = na->ents[i].name;
01509 int nc = SyncComponentCount(each);
01510 if (parms->verbose) {
01511 struct ccn_charbuf *uri = SyncUriForName(each);
01512 if (parms->mark) putMark(stdout);
01513 fprintf(stdout, "putFileList %d, %s\n",
01514 i, ccn_charbuf_as_string(uri));
01515 fflush(stdout);
01516 ccn_charbuf_destroy(&uri);
01517 }
01518 if (nc < 3) {
01519 ret = noteErr("putFileList, bad name");
01520 break;
01521 }
01522 const unsigned char *xp = NULL;
01523 ssize_t xs = -1;
01524 SyncGetComponentPtr(each, nc-2, &xp, &xs);
01525 if (xs > 0 && xp[0] == '\000') {
01526
01527 ret |= appendComponents(tmp, each, 0, nc-2);
01528 ret |= ccn_name_append_str(tmp, "\xC1.R.sw-c");
01529 ret |= ccn_name_append_nonce(tmp);
01530 ret |= appendComponents(tmp, each, nc-2, 2);
01531 } else {
01532
01533 ret |= appendComponents(tmp, each, 0, nc);
01534 ret |= ccn_name_append_str(tmp, "\xC1.R.sw-c");
01535 ret |= ccn_name_append_nonce(tmp);
01536 }
01537
01538 if (ret < 0) {
01539 ret = noteErr("putFileList, bad name");
01540 break;
01541 }
01542 ccn_get(ccn, tmp, template, DEFAULT_CMD_TIMEOUT, NULL, NULL, NULL, 0);
01543 ccn_run(ccn, 10);
01544 i++;
01545 }
01546 ccn_charbuf_destroy(&template);
01547 ccn_charbuf_destroy(&tmp);
01548 na = SyncFreeNameAccumAndNames(na);
01549 ccn_destroy(&ccn);
01550 return ret;
01551 }
01552
01553 static int
01554 existingRootOp(struct SyncTestParms *parms,
01555 char *topo, char *prefix,
01556 int delete) {
01557
01558
01559 struct ccn *ccn = NULL;
01560 int res = 0;
01561
01562 ccn = ccn_create();
01563 if (ccn_connect(ccn, NULL) == -1) {
01564 perror("Could not connect to ccnd");
01565 exit(1);
01566 }
01567
01568
01569 static char *cmdLit = "\xC1.S.rs";
01570 struct ccn_charbuf *nm = ccn_charbuf_create();
01571 if (delete) cmdLit = "\xC1.S.cs";
01572
01573 res |= ccn_name_init(nm);
01574 res |= ccn_name_from_uri(nm, topo);
01575 if (prefix != NULL) {
01576 struct ccn_charbuf *pre = ccn_charbuf_create();
01577 res |= ccn_name_from_uri(pre, prefix);
01578 res |= ccn_name_append_str(nm, cmdLit);
01579 res |= SyncAppendAllComponents(nm, pre);
01580 ccn_charbuf_destroy(&pre);
01581 }
01582
01583 struct ccn_charbuf *cb = ccn_charbuf_create();
01584 if (delete) {
01585
01586 res |= localStore(parms, ccn, nm, NULL);
01587 if (res < 0) {
01588 res = noteErr("requestDelete, failed");
01589 } else {
01590
01591 struct ccn_charbuf *uri = SyncUriForName(nm);
01592 if (parms->mark) putMark(stdout);
01593 fprintf(stdout, "requestDelete, sent %s\n",
01594 ccn_charbuf_as_string(uri));
01595 ccn_charbuf_destroy(&uri);
01596 }
01597 } else {
01598
01599 struct ccn_charbuf *tmpl = SyncGenInterest(NULL, 1, 2, -1, 1, NULL);
01600 res |= ccn_get(ccn, nm, tmpl, DEFAULT_CMD_TIMEOUT, cb, NULL, NULL, 0);
01601
01602 const unsigned char *xp = NULL;
01603 size_t xs = 0;
01604 if (res < 0) {
01605 res = noteErr("requestStats, ccn_get failed");
01606 } else {
01607 res |= SyncPointerToContent(cb, NULL, &xp, &xs);
01608
01609 if (res < 0 || xs == 0) {
01610 res = noteErr("requestStats, failed");
01611 } else {
01612 if (parms->mark) putMark(stdout);
01613 fwrite(xp, xs, sizeof(char), stdout);
01614 fprintf(stdout, "\n");
01615 }
01616 }
01617 ccn_charbuf_destroy(&tmpl);
01618 }
01619 ccn_charbuf_destroy(&cb);
01620 ccn_charbuf_destroy(&nm);
01621 ccn_destroy(&ccn);
01622 if (res > 0) res = 0;
01623 return res;
01624 }
01625
01626 int
01627 main(int argc, char **argv) {
01628 int i = 1;
01629 int seen = 0;
01630 int res = 0;
01631 struct SyncTestParms parmStore;
01632 struct SyncTestParms *parms = &parmStore;
01633 struct SyncBaseStruct *base = SyncNewBase(NULL, NULL, NULL);
01634
01635 memset(parms, 0, sizeof(parmStore));
01636
01637 parms->mode = 1;
01638 parms->scope = 1;
01639 parms->syncScope = 2;
01640 parms->life = 4;
01641 parms->bufs = 4;
01642 parms->blockSize = 4096;
01643 parms->base = base;
01644 parms->resolve = 1;
01645 parms->segmented = 1;
01646
01647 while (i < argc && res >= 0) {
01648 char * sw = argv[i];
01649 i++;
01650 char *arg1 = NULL;
01651 char *arg2 = NULL;
01652 if (i < argc) arg1 = argv[i];
01653 if (i+1 < argc) arg2 = argv[i+1];
01654 if (strcasecmp(sw, "-debug") == 0 || strcasecmp(sw, "-d") == 0) {
01655 i++;
01656 base->debug = ccnr_msg_level_from_string(arg1);
01657 if (base->debug < 0) {
01658 res = noteErr("invalid debug level %s", arg1);
01659 }
01660 } else if (strcasecmp(sw, "-v") == 0) {
01661 parms->verbose = 1;
01662 } else if (strcasecmp(sw, "-cat2") == 0) {
01663 parms->mode = 3;
01664 } else if (strcasecmp(sw, "-mark") == 0) {
01665 parms->mark = 1;
01666 } else if (strcasecmp(sw, "-digest") == 0) {
01667 parms->digest = 1;
01668 } else if (strcasecmp(sw, "-null") == 0) {
01669 parms->mode = 0;
01670 } else if (strcasecmp(sw, "-binary") == 0) {
01671 parms->mode = 1;
01672 } else if (strcasecmp(sw, "-ccnb") == 0) {
01673 parms->mode = 1;
01674 } else if (strcasecmp(sw, "-text") == 0) {
01675 parms->mode = 2;
01676 } else if (strcasecmp(sw, "-nodup") == 0) {
01677 parms->noDup = 1;
01678 } else if (strcasecmp(sw, "-nores") == 0) {
01679 parms->resolve = 0;
01680 } else if (strcasecmp(sw, "-noseg") == 0) {
01681 parms->segmented = 0;
01682 } else if (strcasecmp(sw, "-nosend") == 0) {
01683 parms->noSend = 1;
01684 } else if (strcasecmp(sw, "-bs") == 0) {
01685 i++;
01686 if (arg1 != NULL) {
01687 int bs = atoi(arg1);
01688 if (bs <= 0 || bs > 64*1024) {
01689 res = noteErr("invalid block size %s", arg1);
01690 }
01691 parms->blockSize = bs;
01692 } else
01693 res = noteErr("missing block size");
01694 seen++;
01695 } else if (strcasecmp(sw, "-bufs") == 0) {
01696 if (arg1 != NULL) {
01697 i++;
01698 int bufs = atoi(arg1);
01699 if (bufs <= 0 || bufs > 1024) {
01700 res = noteErr("invalid number of buffers %s", arg1);
01701 break;
01702 }
01703 parms->bufs = bufs;
01704 } else
01705 res = noteErr("missing number of buffers");
01706 } else if (strcasecmp(sw, "-scope") == 0) {
01707 if (arg1 != NULL) {
01708 int scope = atoi(arg1);
01709 if (scope < -1 || scope > 2) {
01710 res = noteErr("invalid scope %s", arg1);
01711 break;
01712 }
01713 parms->scope = scope;
01714 i++;
01715 } else
01716 res = noteErr("missing scope");
01717 seen++;
01718 } else if (strcasecmp(sw, "-syncScope") == 0) {
01719 if (arg1 != NULL) {
01720 int scope = atoi(arg1);
01721 if (scope < -1 || scope > 2) {
01722 res = noteErr("invalid scope %s", arg1);
01723 break;
01724 }
01725 parms->syncScope = scope;
01726 i++;
01727 } else
01728 res = noteErr("missing scope");
01729 seen++;
01730 } else if (strcasecmp(sw, "-life") == 0) {
01731 if (arg1 != NULL) {
01732 int life = atoi(arg1);
01733 if (life < -1 || life > 30) {
01734 res = noteErr("invalid interest lifetime %s", arg1);
01735 break;
01736 }
01737 parms->life = life;
01738 i++;
01739 } else
01740 res = noteErr("missing interest lifetime");
01741 seen++;
01742 } else if (strcasecmp(sw, "-basic") == 0) {
01743 res = testRootBasic(parms);
01744 seen++;
01745 } else if (strcasecmp(sw, "-target") == 0) {
01746 if (arg1 != NULL) {
01747 parms->target = arg1;
01748 i++;
01749 } else
01750 res = noteErr("missing target");
01751 seen++;
01752 } else if (strcasecmp(sw, "-build") == 0) {
01753 if (arg1 != NULL) {
01754 i++;
01755 parms->inputName = arg1;
01756 res = testReadBuilder(parms);
01757 } else
01758 res = noteErr("missing file name");
01759 seen++;
01760 } else if (strcasecmp(sw, "-read") == 0) {
01761 if (arg1 != NULL) {
01762 i++;
01763 parms->inputName = arg1;
01764 parms->sort = 0;
01765 res = testReader(parms);
01766 } else
01767 res = noteErr("missing file name");
01768 seen++;
01769 } else if (strcasecmp(sw, "-sort") == 0) {
01770 if (arg1 != NULL) {
01771 i++;
01772 parms->inputName = arg1;
01773 parms->sort = 1;
01774 res = testReader(parms);
01775 } else
01776 res = noteErr("missing file name");
01777 seen++;
01778 } else if (strcasecmp(sw, "-abs") == 0) {
01779 if (arg1 != NULL) {
01780 i++;
01781 parms->inputName = arg1;
01782 parms->sort = 2;
01783 res = testReader(parms);
01784 } else
01785 res = noteErr("missing file name");
01786 seen++;
01787 } else if (strcasecmp(sw, "-splits") == 0) {
01788 int n = 0;
01789 while (i >= argc) {
01790 char *x = argv[i];
01791 char c = x[0];
01792 if (c < '0' || c > '9') break;
01793 n++;
01794 i++;
01795 }
01796 parms->nSplits = n;
01797 if (parms->splits != NULL) free(parms->splits);
01798 parms->splits = NULL;
01799 if (n > 0) {
01800 int j = 0;
01801 parms->splits = NEW_ANY(n, int);
01802 i = i - n;
01803 while (j < n) {
01804 parms->splits[j] = atoi(argv[i]);
01805 i++;
01806 j++;
01807 }
01808 }
01809 seen++;
01810 } else if (strcasecmp(sw, "-encode") == 0) {
01811 res = testEncodeDecode(parms);
01812 seen++;
01813 } else if (strcasecmp(sw, "-slice") == 0) {
01814 char **clauses = NEW_ANY(argc, char *);
01815 int count = 0;
01816 if (arg1 != NULL && arg2 != NULL) {
01817 i++;
01818 i++;
01819 while (i < argc) {
01820 char *clause = argv[i];
01821 if (clause[0] == '-' || clause[0] == 0) break;
01822 i++;
01823 clauses[count] = clause;
01824 count++;
01825 }
01826 res = sendSlice(parms, arg1, arg2, count, clauses);
01827 } else
01828 res = noteErr("missing slice topo or prefix");
01829 seen++;
01830 } else if (strcasecmp(sw, "-get") == 0) {
01831 if (arg1 != NULL) {
01832 i++;
01833 if (arg2 != NULL) {
01834
01835 if (arg2[0] != '-') i++;
01836 else arg2 = NULL;
01837 }
01838 res = getFile(parms, arg1, arg2);
01839 } else {
01840 res = noteErr("missing src file");
01841 }
01842 seen++;
01843 } else if (strcasecmp(sw, "-put") == 0) {
01844 if (arg1 == NULL) {
01845 res = noteErr("missing src file");
01846 } else if (arg2 == NULL) {
01847 res = noteErr("missing dst file");
01848 } else {
01849 i++;
01850 i++;
01851 res = putFile(parms, arg1, arg2);
01852 }
01853 seen++;
01854 } else if (strcasecmp(sw, "-putList") == 0) {
01855 if (arg1 == NULL) {
01856 res = noteErr("missing list file");
01857 } else {
01858 i++;
01859 i++;
01860 res = putFileList(parms, arg1);
01861 }
01862 seen++;
01863 } else if (strcasecmp(sw, "-stats") == 0) {
01864 if (arg1 != NULL && arg2 != NULL) {
01865 i++;
01866 i++;
01867 res = existingRootOp(parms, arg1, arg2, 0);
01868 } else
01869 res = noteErr("missing topo or hash");
01870 seen++;
01871 } else if (strcasecmp(sw, "-delete") == 0) {
01872 if (arg1 != NULL && arg2 != NULL) {
01873 i++;
01874 i++;
01875 res = existingRootOp(parms, arg1, arg2, 1);
01876 } else
01877 res = noteErr("missing topo or hash");
01878 seen++;
01879 } else {
01880
01881 noteErr("invalid switch: %s", sw);
01882 seen = 0;
01883 break;
01884 }
01885 }
01886 if (parms->splits != NULL) free(parms->splits);
01887 if (parms->root != NULL) SyncRemRoot(parms->root);
01888 SyncFreeBase(&base);
01889 if (seen == 0 && res >= 0) {
01890 printf("usage: \n");
01891 printf(" -debug S set debug level {NONE, SEVERE, ERROR, WARNING, INFO, FINE, FINER, FINEST}\n");
01892 printf(" -v verbose\n");
01893 printf(" -null no output\n");
01894 printf(" -ccnb use binary output\n");
01895 printf(" -binary use binary output\n");
01896 printf(" -text use text output\n");
01897 printf(" -cat2 use ccncatchunks2 format\n");
01898 printf(" -mark print a time code prefix\n");
01899 printf(" -digest show the digest when doing a put\n");
01900 printf(" -nodup disallow duplicate segment requests for -put\n");
01901 printf(" -nores avoid resolve version\n");
01902 printf(" -noseg no segments\n");
01903 printf(" -nosend no send of the slice\n");
01904 printf(" -scope N scope=N for repo commands (default 1)\n");
01905 printf(" -life N life=N for interests (default 4)\n");
01906 printf(" -bs N set block size for put (default 4096)\n");
01907 printf(" -bufs N number of buffers for get (default 4)\n");
01908 printf(" -basic some very basic tests\n");
01909 printf(" -read F read names from file F\n");
01910 printf(" -sort F read names from file F, sort them\n");
01911 printf(" -encode simple encode/decode test\n");
01912 printf(" -build F build tree from file F\n");
01913 printf(" -get src [dst] src is uri in repo, dst is file name (optional)\n");
01914 printf(" -put src dst src is file name, dst is uri in repo\n");
01915 printf(" -putList L does checked write of each name, L is file name of name list\n");
01916 printf(" -slice T P C* topo, prefix, clause ... (send slice to repo)\n");
01917 printf(" -delete T H delete root with topo T, hash H from the repo\n");
01918 printf(" -stats T H print statistics for root with topo T, hash H\n");
01919 }
01920 return res;
01921 }