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); }