void dtn2_destroyDirective(FwdDirective *directive) { Sdr sdr = getIonsdr(); CHKVOID(directive); if (directive->action == fwd) { CHKVOID(sdr_begin_xn(sdr)); sdr_free(sdr, directive->eid); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't destroy directive EID.", NULL); } return; } if (directive->action == xmit) { if (directive->destDuctName) { CHKVOID(sdr_begin_xn(sdr)); sdr_free(sdr, directive->destDuctName); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't destroy destDuctName.", NULL); } } } }
static Object newSdrAcsCustodian(Object custodians, const char *eid) { Object newCustodianAddr; SdrAcsPendingCust newCustodian; memset(&newCustodian, 0, sizeof(newCustodian)); strncpy(newCustodian.eid, eid, MAX_EID_LEN); newCustodian.eid[MAX_EID_LEN] = '\0'; /* Set default ACS size and delay. */ newCustodian.acsDelay = 2; newCustodian.acsSize = 300; CHKZERO(sdr_begin_xn(acsSdr)); newCustodianAddr = sdr_malloc(acsSdr, sizeof(newCustodian)); newCustodian.signals = sdr_list_create(acsSdr); sdr_poke(acsSdr, newCustodianAddr, newCustodian); sdr_list_insert_last(acsSdr, custodians, newCustodianAddr); if(sdr_end_xn(acsSdr) < 0) { ACSLOG_WARN("Couldn't create new custodian info for %s", eid); return 0; } return newCustodianAddr; }
static void manageMtusize(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); Object cfdpdbObj = getCfdpDbObject(); CfdpDB cfdpdb; int newMtusize; if (tokenCount != 3) { SYNTAX_ERROR; } newMtusize = atoi(tokens[2]); if (newMtusize < 0) { putErrmsg("mtuSize invalid.", tokens[2]); return; } sdr_begin_xn(sdr); sdr_stage(sdr, (char *) &cfdpdb, cfdpdbObj, sizeof(CfdpDB)); cfdpdb.mtuSize = newMtusize; sdr_write(sdr, cfdpdbObj, (char *) &cfdpdb, sizeof(CfdpDB)); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't change mtuSize.", NULL); } }
static void manageMaxtrnbr(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); Object cfdpdbObj = getCfdpDbObject(); CfdpDB cfdpdb; int newMaxtrnbr; if (tokenCount != 3) { SYNTAX_ERROR; } newMaxtrnbr = atoi(tokens[2]); if (newMaxtrnbr < 0) { putErrmsg("maxTransactionNbr invalid.", tokens[2]); return; } sdr_begin_xn(sdr); sdr_stage(sdr, (char *) &cfdpdb, cfdpdbObj, sizeof(CfdpDB)); cfdpdb.maxTransactionNbr = newMaxtrnbr; sdr_write(sdr, cfdpdbObj, (char *) &cfdpdb, sizeof(CfdpDB)); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't change maxTransactionNbr.", NULL); } }
static void manageMaxtimeouts(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); Object cfdpdbObj = getCfdpDbObject(); CfdpDB cfdpdb; int newMaxtimeouts; if (tokenCount != 3) { SYNTAX_ERROR; } newMaxtimeouts = atoi(tokens[2]); if (newMaxtimeouts < 0) { putErrmsg("checkTimeoutLimit invalid.", tokens[2]); return; } sdr_begin_xn(sdr); sdr_stage(sdr, (char *) &cfdpdb, cfdpdbObj, sizeof(CfdpDB)); cfdpdb.checkTimeoutLimit = newMaxtimeouts; sdr_write(sdr, cfdpdbObj, (char *) &cfdpdb, sizeof(CfdpDB)); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't change checkTimerPeriod.", NULL); } }
static void manageFillchar(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); Object cfdpdbObj = getCfdpDbObject(); CfdpDB cfdpdb; int newFillchar; char *trailing; if (tokenCount != 3) { SYNTAX_ERROR; } newFillchar = strtol(tokens[2], &trailing, 16); if (*trailing != '\0') { putErrmsg("fillCharacter invalid.", tokens[2]); return; } sdr_begin_xn(sdr); sdr_stage(sdr, (char *) &cfdpdb, cfdpdbObj, sizeof(CfdpDB)); cfdpdb.fillCharacter = newFillchar; sdr_write(sdr, cfdpdbObj, (char *) &cfdpdb, sizeof(CfdpDB)); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't change fillCharacter.", NULL); } }
static void manageRequirecrc(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); Object cfdpdbObj = getCfdpDbObject(); CfdpDB cfdpdb; int newRequirecrc; if (tokenCount != 3) { SYNTAX_ERROR; } newRequirecrc = atoi(tokens[2]); if (newRequirecrc != 0 && newRequirecrc != 1) { putErrmsg("crcRequired switch invalid.", tokens[2]); return; } sdr_begin_xn(sdr); sdr_stage(sdr, (char *) &cfdpdb, cfdpdbObj, sizeof(CfdpDB)); cfdpdb.crcRequired = newRequirecrc; sdr_write(sdr, cfdpdbObj, (char *) &cfdpdb, sizeof(CfdpDB)); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't change crcRequired switch.", NULL); } }
static void manageDiscard(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); Object cfdpdbObj = getCfdpDbObject(); CfdpDB cfdpdb; int newDiscard; if (tokenCount != 3) { SYNTAX_ERROR; } newDiscard = atoi(tokens[2]); if (newDiscard != 0 && newDiscard != 1) { putErrmsg("discardIncompleteFile switch invalid.", tokens[2]); return; } sdr_begin_xn(sdr); sdr_stage(sdr, (char *) &cfdpdb, cfdpdbObj, sizeof(CfdpDB)); cfdpdb.discardIncompleteFile = newDiscard; sdr_write(sdr, cfdpdbObj, (char *) &cfdpdb, sizeof(CfdpDB)); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't change discardIncompleteFile switch.", NULL); } }
static int reforwardStrandedBundles() { Sdr sdr = getIonsdr(); BpDB *bpConstants = getBpConstants(); Object elt; Object nextElt; CHKERR(sdr_begin_xn(sdr)); for (elt = sdr_list_first(sdr, bpConstants->limboQueue); elt; elt = nextElt) { nextElt = sdr_list_next(sdr, elt); if (releaseFromLimbo(elt, 0) < 0) { putErrmsg("Failed releasing bundle from limbo.", NULL); sdr_cancel_xn(sdr); return -1; } } if (sdr_end_xn(sdr) < 0) { putErrmsg("brss failed limbo release on client connect.", NULL); return -1; } return 0; }
Object getOrMakeCustodianByEid(Object custodians, const char *eid) { Object custodianAddr; /* Try to find custodian info if it exists. */ CHKZERO(sdr_begin_xn(acsSdr)); custodianAddr = findCustodianByEid(custodians, eid); if(sdr_end_xn(acsSdr) < 0) { putErrmsg("Can't search custodian database", eid); return 0; } /* If no custodian info, make it. */ if(custodianAddr == 0) { custodianAddr = newSdrAcsCustodian(custodians, eid); if(custodianAddr == 0) { ACSLOG_WARN("Couldn't record new custodian info for %s", eid); return 0; } } return custodianAddr; }
void bp_release_delivery(BpDelivery *dlvBuffer, int releasePayload) { Sdr sdr = getIonsdr(); CHKVOID(dlvBuffer); if (dlvBuffer->result == BpPayloadPresent) { if (dlvBuffer->bundleSourceEid) { MRELEASE(dlvBuffer->bundleSourceEid); dlvBuffer->bundleSourceEid = NULL; } if (releasePayload) { if (dlvBuffer->adu) { sdr_begin_xn(sdr); zco_destroy_reference(sdr, dlvBuffer->adu); if (sdr_end_xn(sdr) < 0) { putErrmsg("Failed releasing delivery.", NULL); } dlvBuffer->adu = 0; } } } }
vast ionAppendZcoExtent(Object zco, ZcoMedium source, Object location, vast offset, vast size, int *cancel) { Sdr sdr = getIonsdr(); IonVdb *vdb = _ionvdb(NULL); Object length; int admissionDelayed = 0; CHKZERO(vdb); if (cancel) { *cancel = 0; /* Initialize. */ } CHKZERO(sdr_begin_xn(sdr)); while (1) { length = zco_append_extent(sdr, zco, source, location, offset, size); if (sdr_end_xn(sdr) < 0 || length == ERROR) { putErrmsg("Can't create ZCO.", NULL); return ERROR; } if (length == 0) /* Not enough ZCO space. */ { if (admissionDelayed) { ionReleaseZcoSpace(vdb); } admissionDelayed = 1; if (ionWaitForZcoSpace(vdb) == 1) { if (cancel && *cancel) { return 0; } CHKZERO(sdr_begin_xn(sdr)); continue; } return ERROR; } /* ZCO extent was appended. */ if (admissionDelayed) { ionReleaseZcoSpace(vdb); } return length; } }
Object ionCreateZco(ZcoMedium source, Object location, vast offset, vast size, int *cancel) { Sdr sdr = getIonsdr(); IonVdb *vdb = _ionvdb(NULL); Object zco; int admissionDelayed = 0; CHKZERO(vdb); if (cancel) { *cancel = 0; /* Initialize. */ } CHKZERO(sdr_begin_xn(sdr)); while (1) { zco = zco_create(sdr, source, location, offset, size); if (sdr_end_xn(sdr) < 0 || zco == (Object) ERROR) { putErrmsg("Can't create ZCO.", NULL); return 0; } if (zco == 0) /* Not enough ZCO space. */ { if (admissionDelayed) { ionReleaseZcoSpace(vdb); } admissionDelayed = 1; if (ionWaitForZcoSpace(vdb) == 1) { if (cancel && *cancel) { return 0; } CHKZERO(sdr_begin_xn(sdr)); continue; } return 0; } /* ZCO was created. */ if (admissionDelayed) { ionReleaseZcoSpace(vdb); } return zco; } }
int updateMinimumCustodyId(unsigned int minimumCustodyId) { CHKERR(sdr_begin_xn(acsSdr)); sdr_poke(acsSdr, acsConstants->id, minimumCustodyId); if(sdr_end_xn(acsSdr) < 0) { ACSLOG_ERROR("Couldn't update minimum custody ID to %u", minimumCustodyId); return -1; } return 0; }
int dtn2_updateRule(char *nodeNm, char *demux, FwdDirective *directive) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; OBJ_POINTER(Dtn2Plan, plan); Object ruleAddr; Dtn2Rule ruleBuf; CHKERR(nodeNm && demux && directive); if (*demux == '\0') { writeMemo("[?] Zero-length DTN2 rule demux."); return 0; } if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); elt = locatePlan(nodeName, NULL); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] No plan defined for this node", nodeNm); return 0; } GET_OBJ_POINTER(sdr, Dtn2Plan, plan, sdr_list_data(sdr, elt)); dtn2_findRule(nodeName, demux, plan, &ruleAddr, &elt); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Unknown rule", demux); return 0; } /* All parameters validated, okay to update the rule. */ sdr_stage(sdr, (char *) &ruleBuf, ruleAddr, sizeof(Dtn2Rule)); dtn2_destroyDirective(&ruleBuf.directive); memcpy((char *) &ruleBuf.directive, (char *) directive, sizeof(FwdDirective)); sdr_write(sdr, ruleAddr, (char *) &ruleBuf, sizeof(Dtn2Rule)); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't update rule.", NULL); return -1; } return 1; }
int dtn2_removeRule(char *nodeNm, char *demux) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; OBJ_POINTER(Dtn2Plan, plan); Object ruleAddr; OBJ_POINTER(Dtn2Rule, rule); CHKERR(nodeNm && demux); if (*demux == '\0') { writeMemo("[?] Zero-length DTN2 rule demux."); return 0; } if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); elt = locatePlan(nodeName, NULL); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] No plan defined for this node", nodeNm); return 0; } GET_OBJ_POINTER(sdr, Dtn2Plan, plan, sdr_list_data(sdr, elt)); dtn2_findRule(nodeName, demux, plan, &ruleAddr, &elt); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Unknown rule", demux); return 0; } /* All parameters validated, okay to remove the rule. */ GET_OBJ_POINTER(sdr, Dtn2Rule, rule, ruleAddr); dtn2_destroyDirective(&(rule->directive)); sdr_free(sdr, ruleAddr); sdr_list_delete(sdr, elt, NULL, NULL); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't remove rule.", NULL); return -1; } return 1; }
int dtn2_addPlan(char *nodeNm, FwdDirective *defaultDir) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object nextPlan; Dtn2Plan plan; Object planObj; CHKERR(nodeNm && defaultDir); if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); if (locatePlan(nodeName, &nextPlan) != 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Duplicate plan", nodeNm); return 0; } /* Okay to add this plan to the database. */ plan.nodeName = sdr_string_create(sdr, nodeName); memcpy((char *) &plan.defaultDirective, (char *) defaultDir, sizeof(FwdDirective)); plan.rules = sdr_list_create(sdr); planObj = sdr_malloc(sdr, sizeof(Dtn2Plan)); if (planObj) { if (nextPlan) { oK(sdr_list_insert_before(sdr, nextPlan, planObj)); } else { oK(sdr_list_insert_last(sdr, (_dtn2Constants())->plans, planObj)); } sdr_write(sdr, planObj, (char *) &plan, sizeof(Dtn2Plan)); } if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't add plan.", nodeNm); return -1; } return 1; }
int dtn2Init() { Sdr sdr = getIonsdr(); Object dtn2dbObject; DtnDB dtn2dbBuf; /* Recover the DTN database, creating it if necessary. */ CHKERR(sdr_begin_xn(sdr)); dtn2dbObject = sdr_find(sdr, DTN_DBNAME, NULL); switch (dtn2dbObject) { case -1: /* SDR error. */ sdr_cancel_xn(sdr); putErrmsg("Failed seeking DTN database in SDR.", NULL); return -1; case 0: /* Not found; must create new DB. */ dtn2dbObject = sdr_malloc(sdr, sizeof(DtnDB)); if (dtn2dbObject == 0) { sdr_cancel_xn(sdr); putErrmsg("No space for DTN database.", NULL); return -1; } memset((char *) &dtn2dbBuf, 0, sizeof(DtnDB)); dtn2dbBuf.plans = sdr_list_create(sdr); sdr_write(sdr, dtn2dbObject, (char *) &dtn2dbBuf, sizeof(DtnDB)); sdr_catlg(sdr, DTN_DBNAME, 0, dtn2dbObject); if (sdr_end_xn(sdr)) { putErrmsg("Can't create DTN database.", NULL); return -1; } break; default: /* Found DB in the SDR. */ sdr_exit_xn(sdr); } oK(_dtn2dbObject(&dtn2dbObject)); oK(_dtn2Constants()); return 0; }
int dtn2_removePlan(char *nodeNm) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; Object planObj; OBJ_POINTER(Dtn2Plan, plan); CHKERR(nodeNm); if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); elt = locatePlan(nodeName, NULL); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Unknown plan", nodeNm); return 0; } planObj = sdr_list_data(sdr, elt); GET_OBJ_POINTER(sdr, Dtn2Plan, plan, planObj); if (sdr_list_length(sdr, plan->rules) > 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Can't remove plan; still has rules", nodeNm); return 0; } /* Okay to remove this plan from the database. */ sdr_list_delete(sdr, elt, NULL, NULL); dtn2_destroyDirective(&(plan->defaultDirective)); sdr_list_destroy(sdr, plan->rules, NULL, NULL); sdr_free(sdr, plan->nodeName); sdr_free(sdr, planObj); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't remove plan.", nodeNm); return -1; } return 1; }
int db_forget(Object *primitiveObj, Object *descObj, Object list) { Sdr sdr = getIonsdr(); Object elt; if((primitiveObj == NULL) || (descObj == NULL) || (list == 0)) { AMP_DEBUG_ERR("db_forget","Bad Params.",NULL); return -1; } CHKERR(sdr_begin_xn(sdr)); if(*primitiveObj != 0) { sdr_free(sdr, *primitiveObj); } if(*descObj != 0) { elt = sdr_list_first(sdr, list); while(elt) { if(sdr_list_data(sdr, elt) == *descObj) { sdr_list_delete(sdr, elt, NULL, NULL); sdr_free(sdr, *descObj); elt = 0; } else { elt = sdr_list_next(sdr, elt); } } } sdr_end_xn(sdr); /* Forget now invalid SDR pointers. */ *descObj = 0; *primitiveObj = 0; return 1; }
int setDeltaFromUTC(int newDelta) { Sdr ionsdr = _ionsdr(NULL); Object iondbObject = _iondbObject(NULL); IonDB *ionConstants = _ionConstants(); IonVdb *ionvdb = _ionvdb(NULL); sdr_begin_xn(ionsdr); sdr_stage(ionsdr, (char *) ionConstants, iondbObject, sizeof(IonDB)); ionConstants->deltaFromUTC = newDelta; sdr_write(ionsdr, iondbObject, (char *) ionConstants, sizeof(IonDB)); if (sdr_end_xn(ionsdr) < 0) { putErrmsg("Can't change delta from UTC.", NULL); return -1; } ionvdb->deltaFromUTC = newDelta; return 0; }
int bp_cancel(Object bundleObj) { Sdr sdr = getIonsdr(); sdr_begin_xn(sdr); if (bpDestroyBundle(bundleObj, 1) < 0) { sdr_cancel_xn(sdr); putErrmsg("Can't cancel bundle.", NULL); return -1; } if (sdr_end_xn(sdr) < 0) { putErrmsg("Failure in bundle cancellation.", NULL); return -1; } return 0; }
int dtn2_updatePlan(char *nodeNm, FwdDirective *defaultDir) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; Object planObj; Dtn2Plan plan; CHKERR(nodeNm && defaultDir); if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); elt = locatePlan(nodeName, NULL); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] No plan defined for this node", nodeNm); return 0; } /* Okay to update this plan. */ planObj = sdr_list_data(sdr, elt); sdr_stage(sdr, (char *) &plan, planObj, sizeof(Dtn2Plan)); dtn2_destroyDirective(&plan.defaultDirective); memcpy((char *) &plan.defaultDirective, (char *) defaultDir, sizeof(FwdDirective)); sdr_write(sdr, planObj, (char *) &plan, sizeof(Dtn2Plan)); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't update plan.", nodeNm); return -1; } return 1; }
void listCustodianInfo(void (*printer)(const char *)) { Object custodianLElt; Object custodianAddr; SdrAcsPendingCust custodian; char buffer[1024]; CHKVOID(sdr_begin_xn(acsSdr)); for(custodianLElt = sdr_list_first(acsSdr, acsConstants->pendingCusts); custodianLElt; custodianLElt = sdr_list_next(acsSdr, custodianLElt)) { custodianAddr = sdr_list_data(acsSdr, custodianLElt); sdr_peek(acsSdr, custodian, custodianAddr); snprintf(buffer, sizeof(buffer), "%.*s\tDelay: %lu Size: %lu", MAX_EID_LEN, custodian.eid, custodian.acsDelay, custodian.acsSize); printer(buffer); } oK(sdr_end_xn(acsSdr)); }
int updateCustodianAcsSize(const char *custodianEid, unsigned long acsSize) { Object custodianAddr; SdrAcsPendingCust custodian; custodianAddr = getOrMakeCustodianByEid(acsConstants->pendingCusts, custodianEid); if(custodianAddr == 0) { return -1; } CHKERR(sdr_begin_xn(acsSdr)); sdr_peek(acsSdr, custodian, custodianAddr); custodian.acsSize = acsSize; sdr_poke(acsSdr, custodianAddr, custodian); if(sdr_end_xn(acsSdr) < 0) { ACSLOG_WARN("Couldn't write new custodian info for %s", custodianEid); return -1; } return 0; }
void bp_untrack(Object bundleObj, Object trackingElt) { Sdr sdr = getIonsdr(); OBJ_POINTER(Bundle, bundle); Object elt; CHKVOID(bundleObj && trackingElt); sdr_begin_xn(sdr); GET_OBJ_POINTER(sdr, Bundle, bundle, bundleObj); if (bundle->trackingElts == 0) { sdr_exit_xn(sdr); return; } for (elt = sdr_list_first(sdr, bundle->trackingElts); elt; elt = sdr_list_next(sdr, elt)) { if (sdr_list_data(sdr, elt) == trackingElt) { break; } } if (elt == 0) /* Not found. */ { sdr_exit_xn(sdr); return; } sdr_list_delete(sdr, elt, NULL, NULL); if (sdr_end_xn(sdr) < 0) { putErrmsg("Failed removing bundle tracking elt.", NULL); } }
int bp_track(Object bundleObj, Object trackingElt) { Sdr sdr = getIonsdr(); OBJ_POINTER(Bundle, bundle); CHKERR(bundleObj && trackingElt); sdr_begin_xn(sdr); GET_OBJ_POINTER(sdr, Bundle, bundle, bundleObj); if (bundle->trackingElts == 0) { sdr_exit_xn(sdr); putErrmsg("Corrupt bundle? Has no trackingElts list.", NULL); return -1; } sdr_list_insert_last(sdr, bundle->trackingElts, trackingElt); if (sdr_end_xn(sdr) < 0) { putErrmsg("Failed adding bundle tracking elt.", NULL); return -1; } return 0; }
int acsInitialize(long heapWords, int logLevel) { AcsDB acsdbBuf; unsigned long zero = 0; /* sdr_stow() wants this */ if (heapWords == 0) { /* Caller wants us to supply a default. */ heapWords = ACS_SDR_DEFAULT_HEAPWORDS; } if (ionAttach() < 0) { putErrmsg("Can't attach to ION.", NULL); return -1; } { Sdr sdr = getIonsdr(); IonDB iondb; char *pathname = iondb.parmcopy.pathName; CHKERR(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &iondb, getIonDbObject(), sizeof(IonDB)); sdr_exit_xn(sdr); #if 0 { char text[100]; sprintf( text, "ION parms pathname : %s", pathname ); writeMemo( text ); } #endif if (sdr_load_profile(acssdrName, SDR_IN_DRAM, heapWords, SM_NO_KEY, pathname, NULL) < 0) { putErrmsg("Unable to load SDR profile for ACS.", NULL); return -1; } else { writeMemo("ACS SDR profile loaded."); } } acsSdr = sdr_start_using(acssdrName); if (acsSdr == NULL) { putErrmsg("Can't start using SDR for ACS.", NULL); return -1; } if (getAcssdr() < 0) { putErrmsg("ACS can't find ACS SDR.", NULL); return -1; } CHKERR(sdr_begin_xn(acsSdr)); acsdbObject = sdr_find(acsSdr, acsDbName, NULL); switch (acsdbObject) { case -1: /* SDR error. */ sdr_cancel_xn(acsSdr); putErrmsg("Can't seek ACS database in SDR.", NULL); return -1; case 0: /* Not found must create new DB. */ memset((char *) &acsdbBuf, 0, sizeof(AcsDB)); acsdbBuf.pendingCusts = sdr_list_create(acsSdr); acsdbBuf.logLevel = logLevel; acsdbBuf.cidHash = sdr_hash_create(acsSdr, sizeof(AcsCustodyId), ACS_CIDHASH_ROWCOUNT, 1); acsdbBuf.bidHash = sdr_hash_create(acsSdr, sizeof(AcsBundleId), ACS_BIDHASH_ROWCOUNT, 1); acsdbBuf.id = sdr_stow(acsSdr, zero); acsdbObject = sdr_malloc(acsSdr, sizeof(AcsDB)); if (acsdbObject == 0) { sdr_cancel_xn(acsSdr); putErrmsg("No space for ACS database.", NULL); return -1; } sdr_write(acsSdr, acsdbObject, (char *) &acsdbBuf, sizeof(AcsDB)); sdr_catlg(acsSdr, acsDbName, 0, acsdbObject); if (sdr_end_xn(acsSdr)) { putErrmsg("Can't create ACS database.", NULL); return -1; } break; default: sdr_exit_xn(acsSdr); } acsConstants = &acsConstantsBuf; CHKERR(sdr_begin_xn(acsSdr)); sdr_read(acsSdr, (char *) acsConstants, acsdbObject, sizeof(AcsDB)); sdr_exit_xn(acsSdr); return 0; }
int trySendAcs(SdrAcsPendingCust *custodian, BpCtReason reasonCode, unsigned char succeeded, const CtebScratchpad *cteb) { Object signalLElt; Object signalAddr; SdrAcsSignal signal; BpEvent timelineEvent; Object newSerializedZco; unsigned long newSerializedLength; int result; Sdr bpSdr = getIonsdr(); /* To prevent deadlock, take bpSdr before acsSdr. */ CHKERR(sdr_begin_xn(bpSdr)); CHKERR(sdr_begin_xn(acsSdr)); signalLElt = findSdrAcsSignal(custodian->signals, reasonCode, succeeded, &signalAddr); if (signalAddr == 0) { ACSLOG_ERROR("Can't find ACS signal"); sdr_exit_xn(acsSdr); sdr_exit_xn(bpSdr); return -1; } sdr_peek(acsSdr, signal, signalAddr); newSerializedLength = serializeAcs(signalAddr, &newSerializedZco, signal.serializedZcoLength); if (newSerializedLength == 0) { ACSLOG_ERROR("Can't serialize new ACS (%lu)", signal.serializedZcoLength); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } ACSLOG_DEBUG("Serialized a new ACS to %s that is %lu long (old: %lu)", custodian->eid, newSerializedLength, signal.serializedZcoLength); /* If serializeAcs() (which serializes an ACS that covers all the "old" * custody IDs as well as 1 "new" custody ID that we're trying to append) * returned an ACS that's larger than the custodian' preferred size, then: * 1) Send the old ACS (the biggest ACS that's smaller than custodian's * preferred size), covering all the old custody IDs but not the new * one. * 2) Make a new ACS that includes only the new custody ID. */ if (custodian->acsSize > 0 && newSerializedLength >= custodian->acsSize) { if(signal.serializedZco == 0) { /* We don't have an old unserialized ACS to send. This means the * first custody signal appended to this ACS exceeded the acsSize * parameter. The best we can do is send this ACS even though it's * bigger than the recommended acsSize. */ ACSLOG_WARN("Appending first CS to %s was bigger than %lu", custodian->eid, custodian->acsSize); signal.serializedZcoLength = newSerializedLength; signal.serializedZco = newSerializedZco; sdr_poke(acsSdr, signalAddr, signal); sendAcs(signalLElt); if(sdr_end_xn(acsSdr) < 0) { ACSLOG_ERROR("Can't serialize ACS bundle."); sdr_cancel_xn(bpSdr); return -1; } if (sdr_end_xn(bpSdr) < 0) { ACSLOG_ERROR("Can't send ACS bundle."); return -1; } return 0; } /* Calling this invalidates our signalLElt and signalAddr pointers, so * we must re-find the signal before using them again. */ sendAcs(signalLElt); /* Add the one that was uncovered by the serialized payload back in */ result = appendToSdrAcsSignals(custodian->signals, signal.pendingCustAddr, reasonCode, succeeded, cteb); switch (result) { case 0: /* Success; continue processing. */ break; default: ACSLOG_ERROR("Can't carry size-limited ID to new ACS"); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } /* Find the uncovered one that we just added. */ signalLElt = findSdrAcsSignal(custodian->signals, reasonCode, succeeded, &signalAddr); if (signalAddr == 0) { ACSLOG_ERROR("Can't find ACS signal"); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } sdr_peek(acsSdr, signal, signalAddr); /* Serialize the new one */ newSerializedLength = serializeAcs(signalAddr, &newSerializedZco, 0); if (newSerializedLength <= 0) { ACSLOG_ERROR("Can't serialize new ACS (%lu)", newSerializedLength); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } } else { if (signal.serializedZco != 0) { /* Free the old payload zco. */ zco_destroy(bpSdr, signal.serializedZco); } } /* Store the new ZCO */ signal.serializedZco = newSerializedZco; signal.serializedZcoLength = newSerializedLength; /* If there is not an ACS generation countdown timer, create one. */ if(signal.acsDue == 0) { timelineEvent.type = csDue; if(custodian->acsDelay == 0) { timelineEvent.time = getUTCTime() + DEFAULT_ACS_DELAY; } else { timelineEvent.time = getUTCTime() + custodian->acsDelay; } timelineEvent.ref = signalLElt; signal.acsDue = insertBpTimelineEvent(&timelineEvent); if (signal.acsDue == 0) { ACSLOG_ERROR("Can't add timeline event to generate ACS"); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } } sdr_poke(acsSdr, signalAddr, signal); if(sdr_end_xn(acsSdr) < 0) { ACSLOG_ERROR("Can't track ACS"); sdr_cancel_xn(bpSdr); return -1; } if (sdr_end_xn(bpSdr) < 0) { ACSLOG_ERROR("Can't add timeline event to generate ACS"); return -1; } return 0; }
int sendAcs(Object signalLElt) { BpExtendedCOS ecos = { 0, 0, 255 }; Object signalAddr; Object acsBundleObj; /* Unused write-out of bpSend */ SdrAcsSignal signal; SdrAcsPendingCust pendingCust; int result; Sdr bpSdr = getIonsdr(); assert(signalLElt != 0); if ((acsSdr = getAcssdr()) == NULL) { putErrmsg("Can't send ACS, SDR not available.", NULL); return -1; } /* To prevent deadlock, we take the BP SDR before the ACS SDR. */ CHKERR(sdr_begin_xn(bpSdr)); CHKERR(sdr_begin_xn(acsSdr)); signalAddr = sdr_list_data(acsSdr, signalLElt); if (signalAddr == 0) { ACSLOG_ERROR("Can't derefence ACS signal to send it."); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } sdr_peek(acsSdr, signal, signalAddr); sdr_peek(acsSdr, pendingCust, signal.pendingCustAddr); /* Remove ref to this serialized ZCO from signal; also remove the bundle * IDs covered by this serialized ZCO. */ result = bpSend(NULL, pendingCust.eid, NULL, ACS_TTL, BP_EXPEDITED_PRIORITY, NoCustodyRequested, 0, 0, &ecos, signal.serializedZco, &acsBundleObj, BP_CUSTODY_SIGNAL); switch (result) { /* All return codes from bpSend() still cause us to continue processing * to free this ACS. If it was sent successfully, good. If it wasn't, * that's due to a system failure or problem with this ACS, so the best * we can do is delete it from our node without sending. */ case -1: ACSLOG_ERROR("Can't send custody transfer signal."); zco_destroy(bpSdr, signal.serializedZco); break; case 0: ACSLOG_ERROR("Custody transfer signal not transmitted."); zco_destroy(bpSdr, signal.serializedZco); break; default: /* bpSend() gave the serializedZco to a forwarder, so don't * zco_destroy(). */ break; } if (signal.acsDue != 0) { destroyBpTimelineEvent(signal.acsDue); } signal.acsDue = 0; signal.serializedZco = 0; sdr_poke(acsSdr, signalAddr, signal); releaseSdrAcsSignal(signalLElt); if (sdr_end_xn(acsSdr) < 0) { ACSLOG_ERROR("Couldn't mark a serialized ACS as sent."); sdr_cancel_xn(bpSdr); return -1; } if(sdr_end_xn(bpSdr) < 0) { return -1; } return result > 0 ? 0 : -1; }