void dtn2_findPlan(char *nodeNm, Object *planAddr, Object *eltp) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; /* This function finds the Dtn2Plan for the specified * node, if any. */ CHKVOID(ionLocked()); CHKVOID(nodeNm && planAddr && eltp); *eltp = 0; if (filterNodeName(nodeName, nodeNm) < 0) { return; } elt = locatePlan(nodeName, NULL); if (elt == 0) { return; } *planAddr = sdr_list_data(sdr, elt); *eltp = elt; }
int ltpei_add_xmit_trailer_extension(LtpXmitSeg *segment, char tag, int valueLength, char *value) { Sdr sdr = getIonsdr(); Sdnv sdnv; LtpExtensionOutbound extension; Object addr; CHKERR(segment); CHKERR(ionLocked()); encodeSdnv(&sdnv, valueLength); if (segment->pdu.trailerExtensions == 0) { if ((segment->pdu.trailerExtensions = sdr_list_create(sdr)) == 0) { return -1; /* No space in SDR heap. */ } } extension.tag = tag; extension.length = valueLength; if (valueLength == 0) { extension.value = 0; } else { CHKERR(value); extension.value = sdr_insert(sdr, value, valueLength); if (extension.value == 0) { return -1; /* No space in SDR heap. */ } } if ((addr = sdr_insert(sdr, (char *) &extension, sizeof(LtpExtensionOutbound))) == 0) { return -1; /* No space in SDR heap. */ } if (sdr_list_insert_last(sdr, segment->pdu.trailerExtensions, addr) == 0) { return -1; /* No space in SDR heap. */ } segment->pdu.trailerExtensionsCount++; segment->pdu.trailerLength += (1 + sdnv.length + valueLength); return 0; }
void dtn2_findRule(char *nodeNm, char *demux, Dtn2Plan *plan, Object *ruleAddr, Object *eltp) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; OBJ_POINTER(Dtn2Plan, planPtr); /* This function finds the Dtn2Rule for the specified * demux token, for the specified destination node, if * any. */ CHKVOID(ionLocked()); CHKVOID(ruleAddr); CHKVOID(eltp); *eltp = 0; if (plan == NULL) { if (nodeNm == NULL) { return; } if (filterNodeName(nodeName, nodeNm) < 0) { return; } elt = locatePlan(nodeName, NULL); if (elt == 0) { return; } GET_OBJ_POINTER(sdr, Dtn2Plan, planPtr, sdr_list_data(sdr, elt)); plan = planPtr; } elt = locateRule(plan, demux, NULL); if (elt == 0) { return; } *ruleAddr = sdr_list_data(sdr, elt); *eltp = elt; }
void ionVacate(int size) { Sdr ionsdr = _ionsdr(NULL); Object iondbObject = _iondbObject(NULL); IonDB iondbBuf; CHKVOID(ionLocked()); CHKVOID(size >= 0); sdr_stage(ionsdr, (char *) &iondbBuf, iondbObject, sizeof(IonDB)); if (size > iondbBuf.currentOccupancy) /* Underflow. */ { iondbBuf.currentOccupancy = 0; } else { iondbBuf.currentOccupancy -= size; } sdr_write(ionsdr, iondbObject, (char *) &iondbBuf, sizeof(IonDB)); }
void ionOccupy(int size) { Sdr ionsdr = _ionsdr(NULL); Object iondbObject = _iondbObject(NULL); IonDB iondbBuf; CHKVOID(ionLocked()); CHKVOID(size >= 0); sdr_stage(ionsdr, (char *) &iondbBuf, iondbObject, sizeof(IonDB)); if (iondbBuf.currentOccupancy + size < 0)/* Overflow. */ { iondbBuf.currentOccupancy = iondbBuf.occupancyCeiling; } else { iondbBuf.currentOccupancy += size; } sdr_write(ionsdr, iondbObject, (char *) &iondbBuf, sizeof(IonDB)); }
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 dispatchEvents(Sdr sdr, Object events, time_t currentTime) { Object elt; Object eventObj; OBJ_POINTER(BpEvent, event); int result; while (1) { sdr_begin_xn(sdr); CHKERR(ionLocked()); /* In case of killm. */ elt = sdr_list_first(sdr, events); if (elt == 0) /* No more events to dispatch. */ { sdr_exit_xn(sdr); return 0; } eventObj = sdr_list_data(sdr, elt); GET_OBJ_POINTER(sdr, BpEvent, event, eventObj); if (event->time > currentTime) { /* This is the first future event. */ sdr_exit_xn(sdr); return 0; } switch (event->type) { case expiredTTL: result = bpDestroyBundle(event->ref, 1); /* Note that bpDestroyBundle() always * erases the bundle's timeline event, * so we must NOT do so here. */ break; /* Out of switch. */ case xmitOverdue: result = bpReforwardBundle(event->ref); /* Note that bpReforwardBundle() always * erases the bundle's xmitOverdue event, * so we must NOT do so here. */ break; /* Out of switch. */ case ctDue: result = bpReforwardBundle(event->ref); /* Note that bpReforwardBundle() always * erases the bundle's ctDue event, so * we must NOT do so here. */ break; /* Out of switch. */ default: /* Spurious event; erase. */ sdr_free(sdr, eventObj); sdr_list_delete(sdr, elt, NULL, NULL); result = 0; /* Event is ignored. */ } if (result != 0) /* Dispatching failed. */ { sdr_cancel_xn(sdr); putErrmsg("Failed handing BP event.", NULL); return result; } if (sdr_end_xn(sdr) < 0) { putErrmsg("Failed dispatching BP event.", NULL); return -1; } } }