示例#1
0
文件: dtn2fw.c 项目: brnrc/ion-dtn
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);
}
示例#2
0
文件: libbp.c 项目: b/ION
int	bp_open(char *eidString, BpSAP *bpsapPtr)
{
	Sdr		sdr;
	MetaEid		metaEid;
	VScheme		*vscheme;
	PsmAddress	vschemeElt;
	Sap		sap;
	VEndpoint	*vpoint;
	PsmAddress	vpointElt;

	CHKERR(eidString && *eidString && bpsapPtr);
	*bpsapPtr = NULL;	/*	Default, in case of failure.	*/
	sdr = getIonsdr();
	sdr_begin_xn(sdr);	/*	Just to lock memory.		*/

	/*	First validate the endpoint ID.				*/

	if (parseEidString(eidString, &metaEid, &vscheme, &vschemeElt) == 0)
	{
		sdr_exit_xn(sdr);
		putErrmsg("Malformed EID.", eidString);
		return -1;
	}

	if (vschemeElt == 0)
	{
		sdr_exit_xn(sdr);
		putErrmsg("Scheme not known.", metaEid.schemeName);
		restoreEidString(&metaEid);
		return -1;
	}

	findEndpoint(NULL, metaEid.nss, vscheme, &vpoint, &vpointElt);
	if (vpointElt == 0)
	{
		sdr_exit_xn(sdr);
		putErrmsg("Endpoint not known.", metaEid.nss);
		restoreEidString(&metaEid);
		return -1;
	}

	/*	Endpoint exists; make sure it's not already opened
	 *	by some application.					*/

	if (vpoint->appPid > 0)	/*	Endpoint not closed.		*/
	{
		if (sm_TaskExists(vpoint->appPid))
		{
			sdr_exit_xn(sdr);
			if (vpoint->appPid == sm_TaskIdSelf())
			{
				return 0;
			}

			restoreEidString(&metaEid);
			putErrmsg("Endpoint is already open.",
					itoa(vpoint->appPid));
			return -1;
		}

		/*	Application terminated without closing the
		 *	endpoint, so simply close it now.		*/

		vpoint->appPid = -1;
	}

	/*	Construct the service access point.			*/

	sap.vpoint = vpoint;
	memcpy(&sap.endpointMetaEid, &metaEid, sizeof(MetaEid));
	sap.endpointMetaEid.colon = NULL;
	sap.endpointMetaEid.schemeName = MTAKE(metaEid.schemeNameLength + 1);
	if (sap.endpointMetaEid.schemeName == NULL)
	{
		sdr_exit_xn(sdr);
		putErrmsg("Can't create BpSAP.", NULL);
		restoreEidString(&metaEid);
		return -1;
	}

	sap.endpointMetaEid.nss = MTAKE(metaEid.nssLength + 1);
	if (sap.endpointMetaEid.nss == NULL)
	{
		sdr_exit_xn(sdr);
		MRELEASE(sap.endpointMetaEid.schemeName);
		putErrmsg("Can't create BpSAP.", NULL);
		restoreEidString(&metaEid);
		return -1;
	}

	*bpsapPtr = MTAKE(sizeof(Sap));
	if (*bpsapPtr == NULL)
	{
		sdr_exit_xn(sdr);
		MRELEASE(sap.endpointMetaEid.nss);
		MRELEASE(sap.endpointMetaEid.schemeName);
		putErrmsg("Can't create BpSAP.", NULL);
		restoreEidString(&metaEid);
		return -1;
	}

	istrcpy(sap.endpointMetaEid.schemeName, metaEid.schemeName,
			sizeof sap.endpointMetaEid.schemeName);
	istrcpy(sap.endpointMetaEid.nss, metaEid.nss,
			sizeof sap.endpointMetaEid.nss);
	restoreEidString(&metaEid);
	sap.recvSemaphore = vpoint->semaphore;
	memcpy((char *) *bpsapPtr, (char *) &sap, sizeof(Sap));

	/*	Having created the SAP, give its owner exclusive
	 *	access to the endpoint.					*/

	vpoint->appPid = sm_TaskIdSelf();
	sdr_exit_xn(sdr);	/*	Unlock memory.			*/
	return 0;
}
示例#3
0
文件: ipnfw.c 项目: b/ION
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);
}