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