コード例 #1
0
ファイル: libdtn2fw.c プロジェクト: brnrc/ion-dtn
int	dtn2_removeRule(char *nodeNm, char *demux)
{
	Sdr	sdr = getIonsdr();
	char	nodeName[SDRSTRING_BUFSZ];
	Object	elt;
		OBJ_POINTER(Dtn2Plan, plan);
	Object	ruleAddr;
		OBJ_POINTER(Dtn2Rule, rule);

	CHKERR(nodeNm && demux);
	if (*demux == '\0')
	{
		writeMemo("[?] Zero-length DTN2 rule demux.");
		return 0;
	}

	if (filterNodeName(nodeName, nodeNm) < 0)
	{
		return 0;
	}

	CHKERR(sdr_begin_xn(sdr));
	elt = locatePlan(nodeName, NULL);
	if (elt == 0)
	{
		sdr_exit_xn(sdr);
		writeMemoNote("[?] No plan defined for this node", nodeNm);
		return 0;
	}

	GET_OBJ_POINTER(sdr, Dtn2Plan, plan, sdr_list_data(sdr, elt));
	dtn2_findRule(nodeName, demux, plan, &ruleAddr, &elt);
	if (elt == 0)
	{
		sdr_exit_xn(sdr);
		writeMemoNote("[?] Unknown rule", demux);
		return 0;
	}

	/*	All parameters validated, okay to remove the rule.	*/

	GET_OBJ_POINTER(sdr, Dtn2Rule, rule, ruleAddr);
	dtn2_destroyDirective(&(rule->directive));
	sdr_free(sdr, ruleAddr);
	sdr_list_delete(sdr, elt, NULL, NULL);
	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("Can't remove rule.", NULL);
		return -1;
	}

	return 1;
}
コード例 #2
0
ファイル: cfdpclock.c プロジェクト: b/ION
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;
				}
			}
		}
	}
コード例 #3
0
ファイル: libdtn2fw.c プロジェクト: brnrc/ion-dtn
int	dtn2_updateRule(char *nodeNm, char *demux, FwdDirective *directive)
{
	Sdr		sdr = getIonsdr();
	char		nodeName[SDRSTRING_BUFSZ];
	Object		elt;
			OBJ_POINTER(Dtn2Plan, plan);
	Object		ruleAddr;
	Dtn2Rule	ruleBuf;

	CHKERR(nodeNm && demux && directive);
	if (*demux == '\0')
	{
		writeMemo("[?] Zero-length DTN2 rule demux.");
		return 0;
	}

	if (filterNodeName(nodeName, nodeNm) < 0)
	{
		return 0;
	}

	CHKERR(sdr_begin_xn(sdr));
	elt = locatePlan(nodeName, NULL);
	if (elt == 0)
	{
		sdr_exit_xn(sdr);
		writeMemoNote("[?] No plan defined for this node", nodeNm);
		return 0;
	}

	GET_OBJ_POINTER(sdr, Dtn2Plan, plan, sdr_list_data(sdr, elt));
	dtn2_findRule(nodeName, demux, plan, &ruleAddr, &elt);
	if (elt == 0)
	{
		sdr_exit_xn(sdr);
		writeMemoNote("[?] Unknown rule", demux);
		return 0;
	}

	/*	All parameters validated, okay to update the rule.	*/

	sdr_stage(sdr, (char *) &ruleBuf, ruleAddr, sizeof(Dtn2Rule));
	dtn2_destroyDirective(&ruleBuf.directive);
	memcpy((char *) &ruleBuf.directive, (char *) directive,
			sizeof(FwdDirective));
	sdr_write(sdr, ruleAddr, (char *) &ruleBuf, sizeof(Dtn2Rule));
	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("Can't update rule.", NULL);
		return -1;
	}

	return 1;
}
コード例 #4
0
ファイル: libdtn2fw.c プロジェクト: brnrc/ion-dtn
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;
}
コード例 #5
0
ファイル: libdtn2fw.c プロジェクト: brnrc/ion-dtn
int	dtn2_removePlan(char *nodeNm)
{
	Sdr	sdr = getIonsdr();
	char	nodeName[SDRSTRING_BUFSZ];
	Object	elt;
	Object	planObj;
		OBJ_POINTER(Dtn2Plan, plan);

	CHKERR(nodeNm);
	if (filterNodeName(nodeName, nodeNm) < 0)
	{
		return 0;
	}

	CHKERR(sdr_begin_xn(sdr));
	elt = locatePlan(nodeName, NULL);
	if (elt == 0)
	{
		sdr_exit_xn(sdr);
		writeMemoNote("[?] Unknown plan", nodeNm);
		return 0;
	}

	planObj = sdr_list_data(sdr, elt);
	GET_OBJ_POINTER(sdr, Dtn2Plan, plan, planObj);
	if (sdr_list_length(sdr, plan->rules) > 0)
	{
		sdr_exit_xn(sdr);
		writeMemoNote("[?] Can't remove plan; still has rules", nodeNm);
		return 0;
	}

	/*	Okay to remove this plan from the database.		*/

	sdr_list_delete(sdr, elt, NULL, NULL);
	dtn2_destroyDirective(&(plan->defaultDirective));
	sdr_list_destroy(sdr, plan->rules, NULL, NULL);
	sdr_free(sdr, plan->nodeName);
	sdr_free(sdr, planObj);
	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("Can't remove plan.", nodeNm);
		return -1;
	}

	return 1;
}
コード例 #6
0
ファイル: cfdpadmin.c プロジェクト: b/ION
static void	executeInfo()
{
	Sdr	sdr = getIonsdr();
		OBJ_POINTER(CfdpDB, db);
	char	buffer[256];

	sdr_begin_xn(sdr);	/*	Just to lock memory.		*/
	GET_OBJ_POINTER(sdr, CfdpDB, db, getCfdpDbObject());
	isprintf(buffer, sizeof buffer, "xncount=%lu, maxtrnbr=%lu, \
fillchar=0x%x, discard=%hu, requirecrc=%hu, segsize=%hu, mtusize = %hu, \
inactivity=%u, ckperiod=%u, maxtimeouts=%u", db->transactionCounter,
			db->maxTransactionNbr, db->fillCharacter,
			db->discardIncompleteFile, db->crcRequired,
			db->maxFileDataLength, db->mtuSize,
			db->transactionInactivityLimit, db->checkTimerPeriod,
			db->checkTimeoutLimit);
	sdr_exit_xn(sdr);
	printText(buffer);
}
コード例 #7
0
ファイル: libdtn2fw.c プロジェクト: brnrc/ion-dtn
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;
}
コード例 #8
0
ファイル: libdtn2fw.c プロジェクト: brnrc/ion-dtn
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;
}
コード例 #9
0
ファイル: libbp.c プロジェクト: b/ION
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);
	}
}
コード例 #10
0
ファイル: libbp.c プロジェクト: b/ION
int	bp_track(Object bundleObj, Object trackingElt)
{
	Sdr	sdr = getIonsdr();
		OBJ_POINTER(Bundle, bundle);

	CHKERR(bundleObj && trackingElt);
	sdr_begin_xn(sdr);
	GET_OBJ_POINTER(sdr, Bundle, bundle, bundleObj);
	if (bundle->trackingElts == 0)
	{
		sdr_exit_xn(sdr);
		putErrmsg("Corrupt bundle?  Has no trackingElts list.", NULL);
		return -1;
	}

	sdr_list_insert_last(sdr, bundle->trackingElts, trackingElt);
	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("Failed adding bundle tracking elt.", NULL);
		return -1;
	}

	return 0;
}
コード例 #11
0
ファイル: imcadmin.c プロジェクト: pantuza/pleiades-DTN
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);
}
コード例 #12
0
ファイル: libdtn2fw.c プロジェクト: brnrc/ion-dtn
int	dtn2_addRule(char *nodeNm, char *demux, FwdDirective *directive)
{
	Sdr		sdr = getIonsdr();
	char		nodeName[SDRSTRING_BUFSZ];
	Object		elt;
			OBJ_POINTER(Dtn2Plan, plan);
	Object		nextRule;
	Dtn2Rule	ruleBuf;
	Object		addr;

	CHKERR(nodeNm && demux && directive);
	if (*demux == '\0')
	{
		writeMemo("[?] Zero-length DTN2 rule demux.");
		return 0;
	}

	if (filterNodeName(nodeName, nodeNm) < 0)
	{
		return 0;
	}

	CHKERR(sdr_begin_xn(sdr));
	elt = locatePlan(nodeName, NULL);
	if (elt == 0)
	{
		sdr_exit_xn(sdr);
		writeMemoNote("[?] No plan defined for this node", nodeNm);
		return 0;
	}

	GET_OBJ_POINTER(sdr, Dtn2Plan, plan, sdr_list_data(sdr, elt));
	if (locateRule(plan, demux, &nextRule) != 0)
	{
		sdr_exit_xn(sdr);
		writeMemoNote("[?] Duplicate rule", demux);
		return 0;
	}

	/*	All parameters validated, okay to add the rule.		*/

	memset((char *) &ruleBuf, 0, sizeof(Dtn2Rule));
	ruleBuf.demux = sdr_string_create(sdr, demux);
	memcpy((char *) &ruleBuf.directive, (char *) directive,
			sizeof(FwdDirective));
	addr = sdr_malloc(sdr, sizeof(Dtn2Rule));
	if (addr)
	{
		if (nextRule)
		{
			elt = sdr_list_insert_before(sdr, nextRule, addr);
		}
		else
		{
			elt = sdr_list_insert_last(sdr, plan->rules, addr);
		}

		sdr_write(sdr, addr, (char *) &ruleBuf, sizeof(Dtn2Rule));
	}

	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("Can't add rule.", NULL);
		return -1;
	}

	return 1;
}
コード例 #13
0
ファイル: libdtn2fw.c プロジェクト: brnrc/ion-dtn
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;
}
コード例 #14
0
ファイル: libbp.c プロジェクト: b/ION
int	bp_receive(BpSAP sap, BpDelivery *dlvBuffer, int timeoutSeconds)
{
	Sdr		sdr = getIonsdr();
	VEndpoint	*vpoint;
			OBJ_POINTER(Endpoint, endpoint);
	Object		dlvElt;
	Object		bundleAddr;
	Bundle		bundle;
	TimerParms	timerParms;
	pthread_t	timerThread;
	int		result;
	char		*dictionary;

	CHKERR(sap && dlvBuffer);
	if (timeoutSeconds < BP_BLOCKING)
	{
		putErrmsg("Illegal timeout interval.", itoa(timeoutSeconds));
		return -1;
	}

	vpoint = sap->vpoint;
	sdr_begin_xn(sdr);
	if (vpoint->appPid != sm_TaskIdSelf())
	{
		sdr_exit_xn(sdr);
		putErrmsg("Can't receive: not owner of endpoint.",
				itoa(vpoint->appPid));
		return -1;
	}

	if (sm_SemEnded(vpoint->semaphore))
	{
		sdr_exit_xn(sdr);
		writeMemo("[?] Endpoint has been stopped.");

		/*	End task, but without error.			*/

		return -1;
	}

	/*	Get oldest bundle in delivery queue, if any; wait
	 *	for one if necessary.					*/

	GET_OBJ_POINTER(sdr, Endpoint, endpoint, sdr_list_data(sdr,
			vpoint->endpointElt));
	dlvElt = sdr_list_first(sdr, endpoint->deliveryQueue);
	if (dlvElt == 0)
	{
		sdr_exit_xn(sdr);
		if (timeoutSeconds == BP_POLL)
		{
			dlvBuffer->result = BpReceptionTimedOut;
			return 0;
		}

		/*	Wait for semaphore to be given, either by the
		 *	deliverBundle() function or by timer thread.	*/

		if (timeoutSeconds == BP_BLOCKING)
		{
			timerParms.interval = -1;
		}
		else	/*	This is a receive() with a deadline.	*/
		{
			timerParms.interval = timeoutSeconds;
			timerParms.semaphore = vpoint->semaphore;
			if (pthread_create(&timerThread, NULL, timerMain,
					&timerParms) < 0)
			{
				putSysErrmsg("Can't enable interval timer",
						NULL);
				return -1;
			}
		}

		/*	Take endpoint semaphore.			*/

		if (sm_SemTake(vpoint->semaphore) < 0)
		{
			putErrmsg("Can't take endpoint semaphore.", NULL);
			return -1;
		}

		if (sm_SemEnded(vpoint->semaphore))
		{
			writeMemo("[i] Endpoint has been stopped.");

			/*	End task, but without error.		*/

			return -1;
		}

		/*	Have taken the semaphore, one way or another.	*/

		sdr_begin_xn(sdr);
		dlvElt = sdr_list_first(sdr, endpoint->deliveryQueue);
		if (dlvElt == 0)	/*	Still nothing.		*/
		{
			/*	Either sm_SemTake() was interrupted
			 *	or else timer thread gave semaphore.	*/

			sdr_exit_xn(sdr);
			if (timerParms.interval == 0)
			{
				/*	Timer expired.			*/

				dlvBuffer->result = BpReceptionTimedOut;
				pthread_join(timerThread, NULL);
			}
			else	/*	Interrupted.			*/
			{
				dlvBuffer->result = BpReceptionInterrupted;
				if (timerParms.interval != -1)
				{
					pthread_cancel(timerThread);
					pthread_join(timerThread, NULL);
				}
			}

			return 0;
		}
		else		/*	Bundle was delivered.		*/
		{
			if (timerParms.interval != -1)
			{
				pthread_cancel(timerThread);
				pthread_join(timerThread, NULL);
			}
		}
	}

	/*	At this point, we have got a dlvElt and are in an SDR
	 *	transaction.						*/

	bundleAddr = sdr_list_data(sdr, dlvElt);
	sdr_stage(sdr, (char *) &bundle, bundleAddr, sizeof(Bundle));
	dictionary = retrieveDictionary(&bundle);
	if (dictionary == (char *) &bundle)
	{
		sdr_cancel_xn(sdr);
		putErrmsg("Can't retrieve dictionary.", NULL);
		return -1;
	}

	/*	Now fill in the data indication structure.		*/

	dlvBuffer->result = BpPayloadPresent;
	if (printEid(&bundle.id.source, dictionary,
			&dlvBuffer->bundleSourceEid) < 0)
	{
		sdr_cancel_xn(sdr);
		putErrmsg("Can't print source EID.", NULL);
		return -1;
	}

	dlvBuffer->bundleCreationTime.seconds = bundle.id.creationTime.seconds;
	dlvBuffer->bundleCreationTime.count = bundle.id.creationTime.count;
	dlvBuffer->adminRecord = bundle.bundleProcFlags & BDL_IS_ADMIN;
	dlvBuffer->adu = zco_add_reference(sdr, bundle.payload.content);
	dlvBuffer->ackRequested = bundle.bundleProcFlags & BDL_APP_ACK_REQUEST;

	/*	Now before returning we send delivery status report
	 *	if it is requested.					*/

	if (SRR_FLAGS(bundle.bundleProcFlags) & BP_DELIVERED_RPT)
	{
		bundle.statusRpt.flags |= BP_DELIVERED_RPT;
		getCurrentDtnTime(&bundle.statusRpt.deliveryTime);
	}

	if (bundle.statusRpt.flags)
	{
		result = sendStatusRpt(&bundle, dictionary);
		if (result < 0)
		{
			sdr_cancel_xn(sdr);
			putErrmsg("Can't send status report.", NULL);
			return -1;
		}
	}

	/*	Finally delete the delivery list element and, if
	 *	possible, destroy the bundle itself.			*/

	if (dictionary)
	{
		MRELEASE(dictionary);
	}

	sdr_list_delete(sdr, dlvElt, (SdrListDeleteFn) NULL, NULL);
	bundle.dlvQueueElt = 0;
	sdr_write(sdr, bundleAddr, (char *) &bundle, sizeof(Bundle));
	if (bpDestroyBundle(bundleAddr, 0) < 0)
	{
		sdr_cancel_xn(sdr);
		putErrmsg("Can't destroy bundle.", NULL);
		return -1;
	}

	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("Failure in bundle reception.", NULL);
		return -1;
	}

	return 0;
}
コード例 #15
0
ファイル: bpclock.c プロジェクト: b/ION
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;
		}
	}
}
コード例 #16
0
ファイル: brsscla.c プロジェクト: b/ION
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;
}