static int scanInFdus(Sdr sdr, time_t currentTime) { CfdpDB *cfdpConstants; Object entityElt; OBJ_POINTER(Entity, entity); Object elt; Object nextElt; Object fduObj; OBJ_POINTER(InFdu, fdu); CfdpHandler handler; cfdpConstants = getCfdpConstants(); sdr_begin_xn(sdr); for (entityElt = sdr_list_first(sdr, cfdpConstants->entities); entityElt; entityElt = sdr_list_next(sdr, entityElt)) { GET_OBJ_POINTER(sdr, Entity, entity, sdr_list_data(sdr, entityElt)); for (elt = sdr_list_first(sdr, entity->inboundFdus); elt; elt = nextElt) { nextElt = sdr_list_next(sdr, elt); fduObj = sdr_list_data(sdr, elt); GET_OBJ_POINTER(sdr, InFdu, fdu, fduObj); if (fdu->eofReceived && fdu->checkTime < currentTime) { sdr_stage(sdr, NULL, fduObj, 0); fdu->checkTimeouts++; fdu->checkTime += cfdpConstants->checkTimerPeriod; sdr_write(sdr, fduObj, (char *) fdu, sizeof(InFdu)); } if (fdu->checkTimeouts > cfdpConstants->checkTimeoutLimit) { if (handleFault(&(fdu->transactionId), CfdpCheckLimitReached, &handler) < 0) { sdr_cancel_xn(sdr); putErrmsg("Can't handle check limit \ reached.", NULL); return -1; } } } }
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; }
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; }
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)); }
static Object locateRule(Dtn2Plan *plan, char *demux, Object *nextRule) { Sdr sdr = getIonsdr(); Object elt; OBJ_POINTER(Dtn2Rule, rule); char nameBuffer[SDRSTRING_BUFSZ]; int result; /* This function locates the Dtn2Rule identified by the * specified demux token, for the specified destination * endpoint, if any; must be an exact match. If * none, notes the location within the rules list at * which such a rule should be inserted. */ if (nextRule) *nextRule = 0; /* Default. */ for (elt = sdr_list_first(sdr, plan->rules); elt; elt = sdr_list_next(sdr, elt)) { GET_OBJ_POINTER(sdr, Dtn2Rule, rule, sdr_list_data(sdr, elt)); sdr_string_read(sdr, nameBuffer, rule->demux); result = strcmp(nameBuffer, demux); if (result < 0) { continue; } if (result > 0) { if (nextRule) *nextRule = elt; break; /* Same as end of list. */ } return elt; } return 0; }
static Object locatePlan(char *nodeName, Object *nextPlan) { Sdr sdr = getIonsdr(); Object elt; OBJ_POINTER(Dtn2Plan, plan); char nameBuffer[SDRSTRING_BUFSZ]; int result; /* This function locates the Dtn2Plan identified by the * specified node name, if any; must be an exact match. * If none, notes the location within the plans list at * which such a plan should be inserted. */ if (nextPlan) *nextPlan = 0; /* Default. */ for (elt = sdr_list_first(sdr, (_dtn2Constants())->plans); elt; elt = sdr_list_next(sdr, elt)) { GET_OBJ_POINTER(sdr, Dtn2Plan, plan, sdr_list_data(sdr, elt)); sdr_string_read(sdr, nameBuffer, plan->nodeName); result = strcmp(nameBuffer, nodeName); if (result < 0) { continue; } if (result > 0) { if (nextPlan) *nextPlan = elt; break; /* Same as end of list. */ } return elt; } 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); } }
static void executeList(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); ImcDB imcdb; Object elt; OBJ_POINTER(NodeId, node); if (tokenCount != 1) { SYNTAX_ERROR; return; } CHKVOID(sdr_begin_xn(sdr)); sdr_read(getIonsdr(), (char *) &imcdb, getImcDbObject(), sizeof(ImcDB)); for (elt = sdr_list_first(sdr, imcdb.kin); elt; elt = sdr_list_next(sdr, elt)) { GET_OBJ_POINTER(sdr, NodeId, node, sdr_list_data(sdr, elt)); printKin(node->nbr, imcdb.parent); } sdr_exit_xn(sdr); }
int dtn2_lookupDirective(char *nodeName, char *demux, Bundle *bundle, FwdDirective *dirbuf) { Sdr sdr = getIonsdr(); int protClassReqd; Object elt; Object addr; OBJ_POINTER(Dtn2Plan, plan); int stringLen; char stringBuffer[SDRSTRING_BUFSZ]; int result; int last; OBJ_POINTER(Dtn2Rule, rule); /* This function determines the relevant FwdDirective for * the specified eid, if any. Wild card match is okay. */ CHKERR(ionLocked()); CHKERR(nodeName && demux && dirbuf); /* Determine constraints on directive usability. */ protClassReqd = bundle->extendedCOS.flags & BP_PROTOCOL_BOTH; if (protClassReqd == 0) /* Don't care. */ { protClassReqd = -1; /* Matches any. */ } else if (protClassReqd == 10) /* Need BSS. */ { protClassReqd = BP_PROTOCOL_STREAMING; } /* Find best matching plan. Universal wild-card match, * if any, is at the end of the list, so there's no way * to terminate the search early. */ for (elt = sdr_list_first(sdr, (_dtn2Constants())->plans); elt; elt = sdr_list_next(sdr, elt)) { addr = sdr_list_data(sdr, elt); GET_OBJ_POINTER(sdr, Dtn2Plan, plan, addr); stringLen = sdr_string_read(sdr, stringBuffer, plan->nodeName); result = strcmp(stringBuffer, nodeName); if (result < 0) { continue; } if (result == 0) /* Exact match. */ { break; /* Stop searching. */ } /* Node name in plan is greater than node name, * but it might still be a wild-card match. */ last = stringLen - 1; if (stringBuffer[last] == '~' /* "all nodes" */ && strncmp(stringBuffer, nodeName, stringLen - 1) == 0) { break; /* Stop searching. */ } } if (elt == 0) { return 0; /* No plan found. */ } /* Find best matching rule. */ for (elt = sdr_list_first(sdr, plan->rules); elt; elt = sdr_list_next(sdr, elt)) { addr = sdr_list_data(sdr, elt); GET_OBJ_POINTER(sdr, Dtn2Rule, rule, addr); if ((rule->directive.protocolClass & protClassReqd) == 0) { continue; /* Can't use this rule. */ } stringLen = sdr_string_read(sdr, stringBuffer, rule->demux); result = strcmp(stringBuffer, demux); if (result < 0) { continue; } if (result == 0) /* Exact match. */ { break; /* Stop searching. */ } /* Demux in rule is greater than demux, but it * might still be a wild-card match. */ last = stringLen - 1; if (stringBuffer[last] == '~' /* "all demuxes" */ && strncmp(stringBuffer, demux, stringLen - 1) == 0) { break; /* Stop searching. */ } } if (elt == 0) /* End of list. */ { if ((plan->defaultDirective.protocolClass & protClassReqd) == 0) { return 0; /* Matching plan unusable. */ } memcpy((char *) dirbuf, (char *) &plan->defaultDirective, sizeof(FwdDirective)); return 1; } /* Found a matching rule. */ memcpy((char *) dirbuf, (char *) &rule->directive, sizeof(FwdDirective)); return 1; }
static int reforwardStrandedBundles(int nodeNbr) { Sdr sdr = getIonsdr(); BpDB *bpConstants = getBpConstants(); Object elt; Object eventObj; OBJ_POINTER(BpEvent, event); OBJ_POINTER(Bundle, bundle); sdr_begin_xn(sdr); for (elt = sdr_list_first(sdr, bpConstants->timeline); elt; elt = sdr_list_next(sdr, elt)) { eventObj = sdr_list_data(sdr, elt); GET_OBJ_POINTER(sdr, BpEvent, event, eventObj); if (event->type != expiredTTL) { continue; } /* Have got a bundle that still exists. */ GET_OBJ_POINTER(sdr, Bundle, bundle, event->ref); if (bundle->dlvQueueElt || bundle->fragmentElt || bundle->fwdQueueElt || bundle->overdueElt || bundle->ctDueElt || bundle->xmitsNeeded > 0) { /* No need to reforward. */ continue; } /* A stranded bundle, awaiting custody acceptance. * Might be for a neighbor other than the one * that just reconnected, but in that case the * bundle will be reforwarded and requeued and * go into the bit bucket again; no harm. Note, * though, that this means that a BRS server * would be a bad candidate for gateway into a * space subnet: due to long OWLTs, there might * be a lot of bundles sent via LTP that are * awaiting custody acceptance, so reconnection * of a BRS client might trigger retransmission * of a lot of bundles on the space link in * addition to the ones to be issued via brss. */ if (bpReforwardBundle(event->ref) < 0) { sdr_cancel_xn(sdr); putErrmsg("brss reforward failed.", NULL); return -1; } } if (sdr_end_xn(sdr) < 0) { putErrmsg("brss reforwarding failed.", NULL); return -1; } return 0; }
int rfx_start() { PsmPartition ionwm = getIonwm(); Sdr sdr = getIonsdr(); IonVdb *vdb = getIonVdb(); Object iondbObj; IonDB iondb; Object elt; iondbObj = getIonDbObject(); CHKERR(sdr_begin_xn(sdr)); /* To lock memory. */ sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB)); /* Destroy and re-create volatile contact and range * databases. This prevents contact/range duplication * as a result of adds before starting ION. */ sm_rbt_destroy(ionwm, vdb->contactIndex, rfx_erase_data, NULL); sm_rbt_destroy(ionwm, vdb->rangeIndex, rfx_erase_data, NULL); vdb->contactIndex = sm_rbt_create(ionwm); vdb->rangeIndex = sm_rbt_create(ionwm); /* Load range index for all asserted ranges. In so * doing, load the nodes for which ranges are known * and load events for all predicted changes in range. */ for (elt = sdr_list_first(sdr, iondb.ranges); elt; elt = sdr_list_next(sdr, elt)) { if (loadRange(elt) < 0) { putErrmsg("Can't load range.", NULL); sdr_exit_xn(sdr); return -1; } } /* Load contact index for all contacts. In so doing, * load the nodes for which contacts are planned (as * necessary) and load events for all planned changes * in data rate affecting the local node. */ iondbObj = getIonDbObject(); sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB)); for (elt = sdr_list_first(sdr, iondb.contacts); elt; elt = sdr_list_next(sdr, elt)) { if (loadContact(elt) < 0) { putErrmsg("Can't load contact.", NULL); sdr_exit_xn(sdr); return -1; } } /* Start the rfx clock if necessary. */ /* if (vdb->clockPid == ERROR || sm_TaskExists(vdb->clockPid) == 0) { vdb->clockPid = pseudoshell("rfxclock"); } */ sdr_exit_xn(sdr); /* Unlock memory. */ return 0; }