Esempio n. 1
0
File: cfdpclock.c Progetto: 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;
				}
			}
		}
	}
Esempio n. 2
0
static int	reforwardStrandedBundles()
{
	Sdr	sdr = getIonsdr();
	BpDB	*bpConstants = getBpConstants();
	Object	elt;
	Object	nextElt;

	CHKERR(sdr_begin_xn(sdr));
	for (elt = sdr_list_first(sdr, bpConstants->limboQueue); elt;
			elt = nextElt)
	{
		nextElt = sdr_list_next(sdr, elt);
		if (releaseFromLimbo(elt, 0) < 0)
		{
			putErrmsg("Failed releasing bundle from limbo.", NULL);
			sdr_cancel_xn(sdr);
			return -1;
		}
	}

	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("brss failed limbo release on client connect.", NULL);
		return -1;
	}

	return 0;
}
Esempio n. 3
0
Object findSdrAcsSignal(Object acsSignals, BpCtReason reasonCode,
                        unsigned char succeeded, Object *signalAddrPtr)
{
    SdrAcsSignal signal;
    Object acsSignalLElt;
    Object acsSignalAddr;

    signal.reasonCode = reasonCode;
    signal.succeeded  = succeeded;

    ASSERT_ACSSDR_XN;

    /* Get the first element of the list. */
    acsSignalLElt = sdr_list_first(acsSdr, acsSignals);
    if (acsSignalLElt == 0)
    {
        ACSLOG_INFO("Couldn't find ACS signal (%s, %d)",
                    succeeded ? "success" : "fail", reasonCode);
        return 0;
    }

    acsSignalLElt = sdr_list_search(acsSdr, acsSignalLElt, 0, cmpSdrAcsSignals, &signal);
    if(acsSignalLElt == 0)
    {
        ACSLOG_INFO("Couldn't find ACS signal (%s, %d)",
                    succeeded ? "success" : "fail", reasonCode);
        return 0;
    }
    acsSignalAddr = sdr_list_data(acsSdr, acsSignalLElt);

    if(signalAddrPtr) *signalAddrPtr = acsSignalAddr;
    return acsSignalLElt;
}
Esempio n. 4
0
int  db_forget(Object *primitiveObj, Object *descObj, Object list)
{
	Sdr sdr = getIonsdr();
	Object elt;

	if((primitiveObj == NULL) || (descObj == NULL) || (list == 0))
	{
		AMP_DEBUG_ERR("db_forget","Bad Params.",NULL);
		return -1;
	}

	CHKERR(sdr_begin_xn(sdr));

	if(*primitiveObj != 0)
	{
	  sdr_free(sdr, *primitiveObj);
	}

	if(*descObj != 0)
	{
	   elt = sdr_list_first(sdr, list);
	   while(elt)
	   {
		   if(sdr_list_data(sdr, elt) == *descObj)
		   {
			   sdr_list_delete(sdr, elt, NULL, NULL);
			   sdr_free(sdr, *descObj);
			   elt = 0;
		   }
		   else
		   {
			   elt = sdr_list_next(sdr, elt);
		   }
	   }
	}

	sdr_end_xn(sdr);

	/* Forget now invalid SDR pointers. */
	*descObj = 0;
	*primitiveObj = 0;

	return 1;
}
Esempio n. 5
0
Object findCustodianByEid(Object custodians, const char *eid)
{
    Object	pendingCustLElt;

    acsSdr = getAcssdr();

    /* Get the first element of the list. */
    pendingCustLElt = sdr_list_first(acsSdr, custodians);
    if (pendingCustLElt == 0)
    {
        return 0;
    }

    pendingCustLElt = sdr_list_search(acsSdr, pendingCustLElt, 0, cmpSdrAcsPendingCust, (void *)(eid));
    if(pendingCustLElt == 0)
    {
        return 0;
    }
    return sdr_list_data(acsSdr, pendingCustLElt);
}
Esempio n. 6
0
void listCustodianInfo(void (*printer)(const char *))
{
    Object custodianLElt;
    Object custodianAddr;
    SdrAcsPendingCust	custodian;
    char buffer[1024];

    CHKVOID(sdr_begin_xn(acsSdr));
    for(custodianLElt = sdr_list_first(acsSdr, acsConstants->pendingCusts);
            custodianLElt;
            custodianLElt = sdr_list_next(acsSdr, custodianLElt))
    {
        custodianAddr = sdr_list_data(acsSdr, custodianLElt);
        sdr_peek(acsSdr, custodian, custodianAddr);

        snprintf(buffer, sizeof(buffer), "%.*s\tDelay: %lu Size: %lu",
                 MAX_EID_LEN, custodian.eid,
                 custodian.acsDelay,
                 custodian.acsSize);
        printer(buffer);
    }
    oK(sdr_end_xn(acsSdr));
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
File: libbp.c Progetto: 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);
	}
}
Esempio n. 9
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;
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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);
}
Esempio n. 12
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;
}
Esempio n. 13
0
File: libbp.c Progetto: 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;
}
Esempio n. 14
0
File: bpclock.c Progetto: 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;
		}
	}
}
Esempio n. 15
0
File: ipnfw.c Progetto: 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);
}
Esempio n. 16
0
int	dtn2fw(int a1, int a2, int a3, int a4, int a5,
		int a6, int a7, int a8, int a9, int a10)
{
#else
int	main(int argc, char *argv[])
{
#endif
	int		running = 1;
	Sdr		sdr;
	VScheme		*vscheme;
	PsmAddress	vschemeElt;
	Scheme		scheme;
	Object		elt;
	Object		bundleAddr;
	Bundle		bundle;

	if (bpAttach() < 0)
	{
		putErrmsg("dtn2fw can't attach to BP.", NULL);
		return 1;
	}

	if (dtn2Init(NULL) < 0)
	{
		putErrmsg("dtn2fw can't load routing database.", NULL);
		return 1;
	}

	sdr = getIonsdr();
	findScheme("dtn", &vscheme, &vschemeElt);
	if (vschemeElt == 0)
	{
		putErrmsg("Scheme name for dtn2 is unknown.", "dtn");
		return 1;
	}

	CHKZERO(sdr_begin_xn(sdr));
	sdr_read(sdr, (char *) &scheme, sdr_list_data(sdr,
			vscheme->schemeElt), sizeof(Scheme));
	sdr_exit_xn(sdr);
	oK(_dtn2fwSemaphore(&vscheme->semaphore));
	isignal(SIGTERM, shutDown);

	/*	Main loop: wait until forwarding queue is non-empty,
	 *	then drain it.						*/

	writeMemo("[i] dtn2fw is running.");
	while (running && !(sm_SemEnded(vscheme->semaphore)))
	{
		/*	We wrap forwarding in an SDR transaction to
		 *	prevent race condition with bpclock (which
		 *	is destroying bundles as their TTLs expire).	*/

		CHKZERO(sdr_begin_xn(sdr));
		elt = sdr_list_first(sdr, scheme.forwardQueue);
		if (elt == 0)	/*	Wait for forwarding notice.	*/
		{
			sdr_exit_xn(sdr);
			if (sm_SemTake(vscheme->semaphore) < 0)
			{
				putErrmsg("Can't take forwarder semaphore.",
						NULL);
				running = 0;
			}

			continue;
		}

		bundleAddr = (Object) sdr_list_data(sdr, elt);
		sdr_stage(sdr, (char *) &bundle, bundleAddr, sizeof(Bundle));
		sdr_list_delete(sdr, elt, NULL, NULL);
		bundle.fwdQueueElt = 0;

		/*	Must rewrite bundle to note removal of
		 *	fwdQueueElt, in case the bundle is abandoned
		 *	and bpDestroyBundle re-reads it from the
		 *	database.					*/

		sdr_write(sdr, bundleAddr, (char *) &bundle, sizeof(Bundle));
		if (enqueueBundle(&bundle, bundleAddr) < 0)
		{
			sdr_cancel_xn(sdr);
			putErrmsg("Can't enqueue bundle.", NULL);
			running = 0;	/*	Terminate loop.		*/
			continue;
		}

		if (sdr_end_xn(sdr) < 0)
		{
			putErrmsg("Can't enqueue bundle.", NULL);
			running = 0;	/*	Terminate loop.		*/
		}

		/*	Make sure other tasks have a chance to run.	*/

		sm_TaskYield();
	}

	writeErrmsgMemos();
	writeMemo("[i] dtn2fw forwarder has ended.");
	ionDetach();
	return 0;
}
Esempio n. 17
0
File: brsscla.c Progetto: 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;
}
Esempio n. 18
0
File: ltpclock.c Progetto: b/ION
static int	dispatchEvents(Sdr sdr, Object events, time_t currentTime)
{
	Object		elt;
	Object		eventObj;
	LtpEvent	event;
	int		result;

	while (1)
	{
		sdr_begin_xn(sdr);
		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);
		sdr_read(sdr, (char *) &event, eventObj, sizeof(LtpEvent));
		if (event.scheduledTime > currentTime)
		{
			/*	This is the first future event.		*/

			sdr_exit_xn(sdr);
			return 0;
		}

		sdr_free(sdr, eventObj);
		sdr_list_delete(sdr, elt, NULL, NULL);
		switch (event.type)
		{
		case LtpResendCheckpoint:
			result = ltpResendCheckpoint(event.refNbr2,
					event.refNbr3);
			break;		/*	Out of switch.		*/

		case LtpResendXmitCancel:
			result = ltpResendXmitCancel(event.refNbr2);
			break;		/*	Out of switch.		*/

		case LtpResendReport:
			result = ltpResendReport(event.refNbr1,
					event.refNbr2, event.refNbr3);
			break;		/*	Out of switch.		*/

		case LtpResendRecvCancel:
			result = ltpResendRecvCancel(event.refNbr1,
					event.refNbr2);
			break;		/*	Out of switch.		*/

		default:		/*	Spurious event.		*/
			result = 0;	/*	Event is ignored.	*/
		}

		if (result < 0)		/*	Dispatching failed.	*/
		{
			sdr_cancel_xn(sdr);
			putErrmsg("failed handing LTP event", NULL);
			return result;
		}

		if (sdr_end_xn(sdr) < 0)
		{
			putErrmsg("failed dispatching LTP event", NULL);
			return -1;
		}
	}
}
Esempio n. 19
0
int	rfx_start()
{
	PsmPartition	ionwm = getIonwm();
	Sdr		sdr = getIonsdr();
	IonVdb		*vdb = getIonVdb();
	Object		iondbObj;
	IonDB		iondb;
	Object		elt;

	iondbObj = getIonDbObject();
	CHKERR(sdr_begin_xn(sdr));	/*	To lock memory.		*/
	sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB));

	/*	Destroy and re-create volatile contact and range
	 *	databases.  This prevents contact/range duplication
	 *	as a result of adds before starting ION.		*/

	sm_rbt_destroy(ionwm, vdb->contactIndex, rfx_erase_data, NULL);
	sm_rbt_destroy(ionwm, vdb->rangeIndex, rfx_erase_data, NULL);
	vdb->contactIndex = sm_rbt_create(ionwm);
	vdb->rangeIndex = sm_rbt_create(ionwm);

	/*	Load range index for all asserted ranges.  In so
	 *	doing, load the nodes for which ranges are known
	 *	and load events for all predicted changes in range.	*/

	for (elt = sdr_list_first(sdr, iondb.ranges); elt;
			elt = sdr_list_next(sdr, elt))
	{
		if (loadRange(elt) < 0)
		{
			putErrmsg("Can't load range.", NULL);
			sdr_exit_xn(sdr);
			return -1;
		}
	}

	/*	Load contact index for all contacts.  In so doing,
	 *	load the nodes for which contacts are planned (as
	 *	necessary) and load events for all planned changes
	 *	in data rate affecting the local node.			*/

	iondbObj = getIonDbObject();
	sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB));
	for (elt = sdr_list_first(sdr, iondb.contacts); elt;
			elt = sdr_list_next(sdr, elt))
	{
		if (loadContact(elt) < 0)
		{
			putErrmsg("Can't load contact.", NULL);
			sdr_exit_xn(sdr);
			return -1;
		}
	}

	/*	Start the rfx clock if necessary.			*/
	/*
	if (vdb->clockPid == ERROR || sm_TaskExists(vdb->clockPid) == 0)
	{
		vdb->clockPid = pseudoshell("rfxclock");
	}
	*/
	sdr_exit_xn(sdr);	/*	Unlock memory.			*/
	return 0;
}