00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "SyncMacros.h"
00022 #include "SyncActions.h"
00023 #include "SyncBase.h"
00024 #include "SyncPrivate.h"
00025 #include "SyncUtil.h"
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <string.h>
00029 #include <ccn/uri.h>
00030 #include <ccnr/ccnr_msg.h>
00031 #include <ccnr/ccnr_private.h>
00032 #include <ccnr/ccnr_sync.h>
00033
00034
00035
00036 extern void
00037 SyncSetErrInner(struct SyncBaseStruct *base,
00038 enum SyncErrCode code,
00039 char * file, int line) {
00040 struct SyncErrStruct *err = NEW_STRUCT(1, SyncErrStruct);
00041 err->code = code;
00042 err->file = file;
00043 err->line = line;
00044 struct SyncErrStruct *lag = base->errList;
00045 while (lag != NULL) {
00046 struct SyncErrStruct *next = lag->next;
00047 if (next == NULL) break;
00048 lag = next;
00049 }
00050 if (lag != NULL) lag->next = err;
00051 else base->errList = err;
00052 }
00053
00054 extern void
00055 SyncClearErr(struct SyncBaseStruct *base) {
00056 for (;;) {
00057 struct SyncErrStruct *err = base->errList;
00058 if (err == NULL) break;
00059 base->errList = err->next;
00060 free(err);
00061 }
00062 }
00063
00064
00065
00066
00067
00068 extern struct SyncBaseStruct *
00069 SyncNewBase(struct ccnr_handle *ccnr,
00070 struct ccn *ccn,
00071 struct ccn_schedule *sched) {
00072 int64_t now = SyncCurrentTime();
00073 struct SyncBaseStruct *base = NEW_STRUCT(1, SyncBaseStruct);
00074 base->client_handle = ccnr;
00075 base->ccn = ccn;
00076 base->sched = sched;
00077 struct SyncPrivate *priv = NEW_STRUCT(1, SyncPrivate);
00078 base->priv = priv;
00079 priv->topoAccum = SyncAllocNameAccum(4);
00080 priv->prefixAccum = SyncAllocNameAccum(4);
00081 priv->sliceCmdPrefix = ccn_charbuf_create();
00082 priv->localHostPrefix = ccn_charbuf_create();
00083 priv->comps = ccn_indexbuf_create();
00084 priv->stableTarget = CCNR_NULL_HWM;
00085 priv->stableStored = CCNR_NULL_HWM;
00086 priv->lastStable = now;
00087 priv->lastCacheClean = now;
00088 ccn_name_from_uri(priv->localHostPrefix, "/%C1.M.S.localhost");
00089 ccn_name_from_uri(priv->sliceCmdPrefix, "/%C1.M.S.localhost/%C1.S.cs");
00090 return base;
00091 }
00092
00093 #ifndef SYNCLIBRARY
00094 static int
00095 getEnvLimited(char *key, int lo, int hi, int def) {
00096 char *s = getenv(key);
00097 if (s != NULL && s[0] != 0) {
00098 int x = strtol(s, NULL, 10);
00099 if (x >= lo && x <= hi) return x;
00100 }
00101 return def;
00102 }
00103 extern void
00104 SyncInit(struct SyncBaseStruct *bp) {
00105 if (bp != NULL) {
00106 struct ccnr_handle *ccnr = bp->client_handle;
00107 char *here = "Sync.SyncInit";
00108
00109 if (ccnr != NULL) {
00110
00111
00112 struct SyncPrivate *priv = bp->priv;
00113 bp->debug = ccnr->syncdebug;
00114
00115 int enable = getEnvLimited("CCNS_ENABLE", 0, 1, 1);
00116
00117 if (enable <= 0) return;
00118
00119 char *debugStr = getenv("CCNS_DEBUG");
00120
00121
00122
00123 priv->useRepoStore = getEnvLimited("CCNS_REPO_STORE", 0, 1, 1);
00124
00125
00126
00127 priv->stableEnabled = getEnvLimited("CCNS_STABLE_ENABLED", 0, 1, 1);
00128
00129
00130 priv->fauxErrorTrigger = getEnvLimited("CCNS_FAUX_ERROR",
00131 0, 99, 0);
00132
00133
00134 priv->syncActionsPrivate = getEnvLimited("CCNS_ACTIONS_PRIVATE",
00135 0, 255, 3);
00136
00137
00138 priv->heartbeatMicros = getEnvLimited("CCNS_HEARTBEAT_MICROS",
00139 10000, 10*1000000, 200000);
00140
00141
00142 priv->rootAdviseFresh = getEnvLimited("CCNS_ROOT_ADVISE_FRESH",
00143 1, 30, 4);
00144
00145
00146 priv->rootAdviseLifetime = getEnvLimited("CCNS_ROOT_ADVISE_LIFETIME",
00147 1, 30, 20);
00148
00149
00150 priv->fetchLifetime = getEnvLimited("CCNS_NODE_FETCH_LIFETIME",
00151 1, 30, 4);
00152
00153
00154 priv->maxFetchBusy = getEnvLimited("CCNS_MAX_FETCH_BUSY",
00155 1, 100, 6);
00156
00157
00158 priv->maxComparesBusy = getEnvLimited("CCNS_MAX_COMPARES_BUSY",
00159 1, 100, 4);
00160
00161
00162 priv->deltasLimit = getEnvLimited("CCNS_DELTAS_LIMIT",
00163 0, 8000, 0);
00164
00165
00166 priv->syncScope = getEnvLimited("CCNS_SYNC_SCOPE",
00167 0, 2, 2);
00168
00169
00170 if (bp->debug >= CCNL_INFO) {
00171 char temp[1024];
00172 int pos = 0;
00173 pos += snprintf(temp+pos, sizeof(temp)-pos,
00174 "CCNS_ENABLE=%d",
00175 enable);
00176 pos += snprintf(temp+pos, sizeof(temp)-pos,
00177 ",CCNS_DEBUG=%s",
00178 debugStr);
00179 pos += snprintf(temp+pos, sizeof(temp)-pos,
00180 ",CCNS_REPO_STORE=%d",
00181 priv->useRepoStore);
00182 pos += snprintf(temp+pos, sizeof(temp)-pos,
00183 ",CCNS_STABLE_ENABLED=%d",
00184 priv->stableEnabled);
00185 pos += snprintf(temp+pos, sizeof(temp)-pos,
00186 ",CCNS_FAUX_ERROR=%d",
00187 priv->fauxErrorTrigger);
00188 pos += snprintf(temp+pos, sizeof(temp)-pos,
00189 ",CCNS_ACTIONS_PRIVATE=%d",
00190 priv->syncActionsPrivate);
00191 pos += snprintf(temp+pos, sizeof(temp)-pos,
00192 ",CCNS_HEARTBEAT_MICROS=%d",
00193 priv->heartbeatMicros);
00194 pos += snprintf(temp+pos, sizeof(temp)-pos,
00195 ",CCNS_ROOT_ADVISE_FRESH=%d",
00196 priv->rootAdviseFresh);
00197 pos += snprintf(temp+pos, sizeof(temp)-pos,
00198 ",CCNS_ROOT_ADVISE_LIFETIME=%d",
00199 priv->rootAdviseLifetime);
00200 pos += snprintf(temp+pos, sizeof(temp)-pos,
00201 ",CCNS_NODE_FETCH_LIFETIME=%d",
00202 priv->fetchLifetime);
00203 pos += snprintf(temp+pos, sizeof(temp)-pos,
00204 ",CCNS_MAX_FETCH_BUSY=%d",
00205 priv->maxFetchBusy);
00206 pos += snprintf(temp+pos, sizeof(temp)-pos,
00207 ",CCNS_MAX_COMPARES_BUSY=%d",
00208 priv->maxComparesBusy);
00209 pos += snprintf(temp+pos, sizeof(temp)-pos,
00210 ",CCNS_DELTAS_LIMIT=%d",
00211 priv->deltasLimit);
00212 pos += snprintf(temp+pos, sizeof(temp)-pos,
00213 ",CCNS_SYNC_SCOPE=%d",
00214 priv->syncScope);
00215 pos += snprintf(temp+pos, sizeof(temp)-pos,
00216 ",defer_verification=%d",
00217 ccn_defer_verification(bp->ccn, -1));
00218 ccnr_msg(ccnr, "%s, %s", here, temp);
00219 }
00220
00221 SyncStartHeartbeat(bp);
00222 }
00223 }
00224 }
00225 #endif
00226
00227 extern void
00228 SyncFreeBase(struct SyncBaseStruct **bp) {
00229 if (bp != NULL) {
00230 struct SyncBaseStruct *base = *bp;
00231 *bp = NULL;
00232 if (base != NULL) {
00233 struct SyncPrivate *priv = base->priv;
00234
00235 SyncClearErr(base);
00236
00237 while (priv->rootHead != NULL) {
00238 if (SyncRemRoot(priv->rootHead) != NULL) break;
00239 }
00240
00241 if (priv->topoAccum != NULL)
00242 SyncFreeNameAccumAndNames(priv->topoAccum);
00243 if (priv->prefixAccum != NULL)
00244 SyncFreeNameAccumAndNames(priv->prefixAccum);
00245 if (priv->comps != NULL)
00246 ccn_indexbuf_destroy(&priv->comps);
00247 ccn_charbuf_destroy(&priv->sliceCmdPrefix);
00248 free(priv);
00249 free(base);
00250 }
00251 }
00252 }
00253
00254
00255 extern int
00256 SyncNotifyContent(struct SyncBaseStruct *base,
00257 int enumeration,
00258 ccnr_accession item,
00259 struct ccn_charbuf *name) {
00260
00261
00262 char *here = "Sync.SyncNotifyContent";
00263
00264 if (base != NULL && base->client_handle != NULL) {
00265 struct SyncPrivate *priv = base->priv;
00266 int debug = base->debug;
00267
00268 if (name == NULL) {
00269
00270 if (enumeration == 0) {
00271 if (debug >= CCNL_WARNING)
00272 ccnr_msg(base->client_handle, "%s, end of time-based enum?", here);
00273 } else if (enumeration == priv->sliceEnum) {
00274 priv->sliceEnum = 0;
00275 if (debug >= CCNL_INFO)
00276 ccnr_msg(base->client_handle, "%s, all slice names seen", here);
00277 } else if (enumeration == priv->sliceBusy) {
00278 priv->sliceBusy = 0;
00279 struct SyncRootStruct *root = priv->rootHead;
00280 while (root != NULL) {
00281 struct SyncRootPrivate *rp = root->priv;
00282 if (enumeration == rp->sliceBusy) {
00283 rp->sliceBusy = 0;
00284 if (debug >= CCNL_INFO)
00285 SyncNoteSimple(root, here, "slice enum done");
00286 break;
00287 }
00288 root = root->next;
00289 }
00290
00291 root = priv->rootHead;
00292 while (root != NULL) {
00293 struct SyncRootPrivate *rp = root->priv;
00294 if (rp->sliceBusy < 0) {
00295 SyncStartSliceEnum(root);
00296 break;
00297 }
00298 root = root->next;
00299 }
00300 } else {
00301 if (debug >= CCNL_WARNING)
00302 ccnr_msg(base->client_handle, "%s, end of what enum?", here);
00303 }
00304 return -1;
00305 }
00306
00307 if (debug >= CCNL_FINE) {
00308 struct ccn_charbuf *uri = SyncUriForName(name);
00309 ccnr_msg(base->client_handle,
00310 "%s, enum %d, %s!",
00311 here, enumeration, ccn_charbuf_as_string(uri));
00312 ccn_charbuf_destroy(&uri);
00313 }
00314
00315 struct ccn_indexbuf *comps = priv->comps;
00316 int splitRes = ccn_name_split(name, comps);
00317 if (splitRes < 0) {
00318
00319 if (debug >= CCNL_SEVERE)
00320 ccnr_msg(base->client_handle, "%s, invalid name!", here);
00321 return 0;
00322 }
00323
00324 unsigned char *comp0 = NULL;
00325 size_t size0 = 0;
00326 unsigned char *comp1 = NULL;
00327 size_t size1 = 0;
00328 ccn_name_comp_get(name->buf, comps, 0,
00329 (const unsigned char **) &comp0, &size0);
00330 ccn_name_comp_get(name->buf, comps, 1,
00331 (const unsigned char **) &comp1, &size1);
00332 ccnr_accession mark = item;
00333 if (SyncPrefixMatch(priv->localHostPrefix, name, 0)) {
00334
00335 mark = CCNR_NULL_ACCESSION;
00336 if (SyncPrefixMatch(priv->sliceCmdPrefix, name, 0))
00337
00338 SyncHandleSlice(base, name);
00339 }
00340 if (mark != CCNR_NULL_ACCESSION)
00341 priv->stableTarget = ccnr_hwm_update(base->client_handle, priv->stableTarget, mark);
00342
00343
00344 SyncAddName(base, name, item);
00345 return 0;
00346 }
00347 return -1;
00348 }
00349
00350 extern void
00351 SyncShutdown(struct SyncBaseStruct *bp) {
00352 char *here = "Sync.SyncShutdown";
00353 int debug = bp->debug;
00354 if (debug >= CCNL_INFO)
00355 ccnr_msg(bp->client_handle, "%s", here);
00356
00357
00358 }
00359
00360