static void printProfile(Profile *vprofile) { Sdr sdr = getIonsdr(); char buffer[256]; char sdrBuf[SDRSTRING_BUFSZ]; sdr_string_read(sdr, sdrBuf, vprofile->reportToEid); isprintf(buffer, sizeof buffer, "profileID: %u maxRtx: %u lifespan: %u", vprofile->profileID, vprofile->maxRtx, vprofile->lifespan); printText(buffer); isprintf(buffer, sizeof buffer, "aggrSizeLimit: %u, aggTimeLimit: \ %u Priority: %d Custody: %d", vprofile->aggrSizeLimit, vprofile->aggrTimeLimit, vprofile->classOfService, vprofile->custodySwitch); printText(buffer); isprintf(buffer, sizeof buffer, "reportToEid: %s", sdrBuf); printText(buffer); isprintf(buffer, sizeof buffer, "Ordinal: %d Unreliable: %d Critical: \ %d", vprofile->extendedCOS.ordinal, vprofile->extendedCOS.flags & BP_BEST_EFFORT ? 1 : 0, vprofile->extendedCOS.flags & BP_MINIMUM_LATENCY ? 1 : 0); printText(buffer); isprintf(buffer, sizeof buffer, "rcvReport: %d ctReport: %d fwdReport: \ %d dlvReport: %d delReport: %d", vprofile->srrFlags & BP_RECEIVED_RPT ? 1 : 0, vprofile->srrFlags & BP_CUSTODY_RPT? 1 : 0, vprofile->srrFlags & BP_FORWARDED_RPT? 1 : 0, vprofile->srrFlags & BP_DELIVERED_RPT? 1 : 0, vprofile->srrFlags & BP_DELETED_RPT? 1 : 0); printText(buffer); return; }
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; }
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 enqueueBundle(Bundle *bundle, Object bundleObj) { Sdr sdr = getIonsdr(); Object elt; char eidString[SDRSTRING_BUFSZ]; MetaEid metaEid; VScheme *vscheme; PsmAddress vschemeElt; char nodeName[SDRSTRING_BUFSZ]; char demux[SDRSTRING_BUFSZ]; int result; FwdDirective directive; elt = sdr_list_first(sdr, bundle->stations); if (elt == 0) { putErrmsg("Forwarding error; stations stack is empty.", NULL); return -1; } sdr_string_read(sdr, eidString, sdr_list_data(sdr, elt)); if (parseEidString(eidString, &metaEid, &vscheme, &vschemeElt) == 0) { putErrmsg("Can't parse node EID string.", eidString); return bpAbandon(bundleObj, bundle, BP_REASON_NO_ROUTE); } if (strcmp(vscheme->name, "dtn") != 0) { putErrmsg("Forwarding error; EID scheme wrong for dtn2fw.", vscheme->name); return -1; } result = parseDtn2Nss(metaEid.nss, nodeName, demux); restoreEidString(&metaEid); if (result == 0) { putErrmsg("Invalid nss in EID string, cannot forward.", eidString); return bpAbandon(bundleObj, bundle, BP_REASON_NO_ROUTE); } if (dtn2_lookupDirective(nodeName, demux, bundle, &directive) == 0) { putErrmsg("Can't find forwarding directive for EID.", eidString); return bpAbandon(bundleObj, bundle, BP_REASON_NO_ROUTE); } if (directive.action == xmit) { if (bpEnqueue(&directive, bundle, bundleObj, eidString) < 0) { putErrmsg("Can't enqueue bundle.", NULL); return -1; } if (bundle->ductXmitElt) { /* Enqueued. */ return bpAccept(bundleObj, bundle); } else { return bpAbandon(bundleObj, bundle, BP_REASON_NO_ROUTE); } } /* Can't transmit to indicated next node directly, must * forward through some other node. */ sdr_write(sdr, bundleObj, (char *) &bundle, sizeof(Bundle)); sdr_string_read(sdr, eidString, directive.eid); return forwardBundle(bundleObj, bundle, eidString); }
static int enqueueBundle(Bundle *bundle, Object bundleObj) { Sdr sdr = getIonsdr(); Object elt; char eidString[SDRSTRING_BUFSZ]; MetaEid metaEid; VScheme *vscheme; PsmAddress vschemeElt; FwdDirective directive; elt = sdr_list_first(sdr, bundle->stations); if (elt == 0) { putErrmsg("Forwarding error; stations stack is empty.", NULL); return -1; } sdr_string_read(sdr, eidString, sdr_list_data(sdr, elt)); if (parseEidString(eidString, &metaEid, &vscheme, &vschemeElt) == 0) { putErrmsg("Can't parse node EID string.", eidString); return bpAbandon(bundleObj, bundle); } if (strcmp(vscheme->name, "ipn") != 0) { putErrmsg("Forwarding error; EID scheme is not 'ipn'.", vscheme->name); return -1; } if (cgr_forward(bundle, bundleObj, metaEid.nodeNbr, (getIpnConstants())->plans) < 0) { putErrmsg("CGR failed.", NULL); return -1; } /* If dynamic routing succeeded in enqueuing the bundle * to a neighbor, accept the bundle and return. */ if (sdr_list_length(sdr, bundle->xmitRefs) > 0) { /* Enqueued. */ return bpAccept(bundle); } /* No luck using the contact graph to compute a route * to the destination node. So see if destination node * is a neighbor; if so, enqueue for direct transmission. */ if (enqueueToNeighbor(bundle, bundleObj, metaEid.nodeNbr, metaEid.serviceNbr) < 0) { putErrmsg("Can't send bundle to neighbor.", NULL); return -1; } if (sdr_list_length(sdr, bundle->xmitRefs) > 0) { /* Enqueued. */ return bpAccept(bundle); } /* Destination isn't a neighbor either. So look for the * narrowest applicable static route (node range, i.e., * "group") and forward to the prescribed "via" endpoint * for that group. */ if (ipn_lookupGroupDirective(metaEid.nodeNbr, bundle->id.source.c.serviceNbr, bundle->id.source.c.nodeNbr, &directive) == 0) { return bpAbandon(bundleObj, bundle); } /* Found directive; forward via the indicated endpoint. */ sdr_string_read(sdr, eidString, directive.eid); return forwardBundle(bundleObj, bundle, eidString); }