コード例 #1
0
ファイル: bpclock.c プロジェクト: b/ION
static int	adjustThrottles()
{
	PsmPartition	ionwm = getIonwm();
	IonVdb		*ionvdb = getIonVdb();
	BpVdb		*bpvdb = getBpVdb();
	PsmAddress	elt;
	VOutduct	*outduct;
	unsigned long	nodeNbr;
	IonNeighbor	*neighbor;
	PsmAddress	nextElt;
	int		delta;
	VInduct		*induct;

	/*	Only the LTP induct and outduct throttles can be
	 *	dynamically adjusted in response to changes in data
	 *	rate between the local node and its neighbors, because
	 *	(currently) there is no mechanism for mapping neighbor
	 *	node number to duct name for any other CL protocol.
	 *	For LTP, duct name is LTP engine number which, by
	 *	convention, is identical to BP node number.  For all
	 *	other CL protocols, duct nominal data rate is initially
	 *	set to the protocol's configured nominal data rate and
	 *	is never subsequently modified.
	 *	
	 *	So, first we find the LTP induct if any.		*/

	for (elt = sm_list_first(ionwm, bpvdb->inducts); elt;
			elt = sm_list_next(ionwm, elt))
	{
		induct = (VInduct *) psp(ionwm, sm_list_data(ionwm, elt));
		if (strcmp(induct->protocolName, "ltp") == 0)
		{
			break;	/*	Found the LTP induct.		*/
		}
	}

	if (elt == 0)		/*	No LTP induct; nothing to do.	*/
	{
		return 0;
	}

	/*	Now update all LTP outducts, and the induct as well,
	 *	inferring the existence of Neighbors in the process.	*/

	for (elt = sm_list_first(ionwm, bpvdb->outducts); elt;
			elt = sm_list_next(ionwm, elt))
	{
		outduct = (VOutduct *) psp(ionwm, sm_list_data(ionwm, elt));
		if (strcmp(outduct->protocolName, "ltp") != 0)
		{
			continue;
		}

		nodeNbr = atol(outduct->ductName);
		neighbor = findNeighbor(ionvdb, nodeNbr, &nextElt);
		if (neighbor == NULL)
		{
			neighbor = addNeighbor(ionvdb, nodeNbr, nextElt);
			if (neighbor == NULL)
			{
				putErrmsg("Can't adjust outduct throttle.",
						NULL);
				return -1;
			}
		}

		if (neighbor->xmitRate != neighbor->prevXmitRate)
		{
#ifndef ION_NOSTATS
			if (neighbor->nodeNbr != getOwnNodeNbr())
			{
			/*	We report and clear transmission
			 *	statistics as necessary.  NOTE that
			 *	this procedure is based on the
			 *	assumption that the local node is
			 *	in LTP transmission contact with
			 *	AT MOST ONE neighbor at any time.
			 *	For more complex topologies it will
			 *	need to be redesigned.			*/

				if (neighbor->xmitRate == 0)
				{
					/*	End of xmit contact.	*/
					reportAllStateStats();
					clearAllStateStats();
				}
				else if (neighbor->prevXmitRate == 0)
				{
					/*	Start of xmit contact.	*/
					reportAllStateStats();
					clearAllStateStats();
				}
			}
#endif
			outduct->xmitThrottle.nominalRate = neighbor->xmitRate;
			neighbor->prevXmitRate = neighbor->xmitRate;
		}

		/*	Note that the LTP induct is aggregate; the
		 *	duct's nominal rate is the sum of the rates
		 *	at which all neighbors are expected to be
		 *	transmitting to the local node at any given
		 *	moment.  So we must add the change in rate
		 *	for each known neighbor to the aggregate
		 *	nominal reception rate for the induct.		*/

		if (neighbor->recvRate != neighbor->prevRecvRate)
		{
#ifndef ION_NOSTATS
			if (neighbor->nodeNbr != getOwnNodeNbr())
			{
			/*	We report and clear reception
			 *	statistics as necessary.  NOTE that
			 *	this procedure is based on the
			 *	assumption that the local node is
			 *	in LTP reception contact with
			 *	AT MOST ONE neighbor at any time.
			 *	For more complex topologies it will
			 *	need to be redesigned.			*/

				if (neighbor->recvRate == 0)
				{
					/*	End of recv contact.	*/
					reportAllStateStats();
					clearAllStateStats();
				}
				else if (neighbor->prevRecvRate == 0)
				{
					/*	Start of recv contact.	*/
					reportAllStateStats();
					clearAllStateStats();
				}
			}
#endif
			delta = neighbor->recvRate - neighbor->prevRecvRate;
			induct->acqThrottle.nominalRate += delta;
			neighbor->prevRecvRate = neighbor->recvRate;
		}
	}

	return 0;
}
コード例 #2
0
ファイル: bputa.c プロジェクト: NASAHackTO/ion-dtn
static void	*receivePdus(void *parm)
{
    RxThreadParms	*parms = (RxThreadParms *) parm;
    char		ownEid[64];
    Sdr		sdr;
    BpDelivery	dlv;
    int		contentLength;
    ZcoReader	reader;
    unsigned char	*buffer;

    buffer = MTAKE(CFDP_MAX_PDU_SIZE);
    if (buffer == NULL)
    {
        putErrmsg("bputa receiver thread can't get buffer.", NULL);
        parms->running = 0;
        return NULL;
    }

    isprintf(ownEid, sizeof ownEid, "ipn:" UVAST_FIELDSPEC ".%u",
             getOwnNodeNbr(), CFDP_RECV_SVC_NBR);
    if (bp_open(ownEid, &(parms->rxSap)) < 0)
    {
        MRELEASE(buffer);
        putErrmsg("CFDP can't open own 'recv' endpoint.", ownEid);
        parms->running = 0;
        return NULL;
    }

    sdr = bp_get_sdr();
    writeMemo("[i] bputa input has started.");
    while (parms->running)
    {
        if (bp_receive(parms->rxSap, &dlv, BP_BLOCKING) < 0)
        {
            putErrmsg("bputa bundle reception failed.", NULL);
            parms->running = 0;
            continue;
        }

        switch (dlv.result)
        {
        case BpEndpointStopped:
            parms->running = 0;
            break;

        case BpPayloadPresent:
            contentLength = zco_source_data_length(sdr, dlv.adu);
            CHKNULL(sdr_begin_xn(sdr));
            zco_start_receiving(dlv.adu, &reader);
            if (zco_receive_source(sdr, &reader, contentLength,
                                   (char *) buffer) < 0)
            {
                sdr_cancel_xn(sdr);
                putErrmsg("bputa can't receive bundle ADU.",
                          itoa(contentLength));
                parms->running = 0;
                continue;
            }

            if (sdr_end_xn(sdr) < 0)
            {
                putErrmsg("bputa can't handle bundle delivery.",
                          NULL);
                parms->running = 0;
                continue;
            }

            if (cfdpHandleInboundPdu(buffer, contentLength) < 0)
            {
                putErrmsg("bputa can't handle inbound PDU.",
                          NULL);
                parms->running = 0;
            }

            break;

        default:
            break;
        }

        bp_release_delivery(&dlv, 1);

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

        sm_TaskYield();
    }

    bp_close(parms->rxSap);
    MRELEASE(buffer);
    writeMemo("[i] bputa input has stopped.");
    return NULL;
}
コード例 #3
0
ファイル: bputa.c プロジェクト: NASAHackTO/ion-dtn
int	bputa(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
    char		ownEid[64];
    BpSAP		txSap;
    RxThreadParms	parms;
    Sdr		sdr;
    pthread_t	rxThread;
    int		haveRxThread = 0;
    Object		pduZco;
    OutFdu		fduBuffer;
    BpUtParms	utParms;
    uvast		destinationNodeNbr;
    char		destEid[64];
    char		reportToEidBuf[64];
    char		*reportToEid;
    Object		newBundle;
    Object		pduElt;

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

    isprintf(ownEid, sizeof ownEid, "ipn:" UVAST_FIELDSPEC ".%u",
             getOwnNodeNbr(), CFDP_SEND_SVC_NBR);
    if (bp_open(ownEid, &txSap) < 0)
    {
        putErrmsg("CFDP can't open own 'send' endpoint.", ownEid);
        return 0;
    }

    if (txSap == NULL)
    {
        putErrmsg("bputa can't get Bundle Protocol SAP.", NULL);
        return 0;
    }

    if (cfdpAttach() < 0)
    {
        bp_close(txSap);
        putErrmsg("bputa can't attach to CFDP.", NULL);
        return 0;
    }

    sdr = bp_get_sdr();
    parms.mainThread = pthread_self();
    parms.running = 1;
    if (pthread_begin(&rxThread, NULL, receivePdus, &parms))
    {
        bp_close(txSap);
        putSysErrmsg("bputa can't create receiver thread", NULL);
        return -1;
    }

    haveRxThread = 1;
    writeMemo("[i] bputa is running.");
    while (parms.running)
    {
        /*	Get an outbound CFDP PDU for transmission.	*/

        if (cfdpDequeueOutboundPdu(&pduZco, &fduBuffer) < 0)
        {
            writeMemo("[?] bputa can't dequeue outbound CFDP PDU; \
terminating.");
            parms.running = 0;
            continue;
        }

        /*	Determine quality of service for transmission.	*/

        if (fduBuffer.utParmsLength == sizeof(BpUtParms))
        {
            memcpy((char *) &utParms, (char *) &fduBuffer.utParms,
                   sizeof(BpUtParms));
        }
        else
        {
            memset((char *) &utParms, 0, sizeof(BpUtParms));
            utParms.reportToNodeNbr = 0;
            utParms.lifespan = 86400;	/*	1 day.	*/
            utParms.classOfService = BP_STD_PRIORITY;
            utParms.custodySwitch = NoCustodyRequested;
            utParms.srrFlags = 0;
            utParms.ackRequested = 0;
            utParms.extendedCOS.flowLabel = 0;
            utParms.extendedCOS.flags = 0;
            utParms.extendedCOS.ordinal = 0;
        }

        cfdp_decompress_number(&destinationNodeNbr,
                               &fduBuffer.destinationEntityNbr);
        if (destinationNodeNbr == 0)
        {
            writeMemo("[?] bputa declining to send to node 0.");
            continue;
        }

        isprintf(destEid, sizeof destEid, "ipn:" UVAST_FIELDSPEC ".%u",
                 destinationNodeNbr, CFDP_RECV_SVC_NBR);
        if (utParms.reportToNodeNbr == 0)
        {
            reportToEid = NULL;
        }
        else
        {
            isprintf(reportToEidBuf, sizeof reportToEidBuf,
                     "ipn:" UVAST_FIELDSPEC ".%u",
                     utParms.reportToNodeNbr,
                     CFDP_RECV_SVC_NBR);
            reportToEid = reportToEidBuf;
        }

        /*	Send PDU in a bundle.				*/

        newBundle = 0;
        if (bp_send(txSap, destEid, reportToEid, utParms.lifespan,
                    utParms.classOfService, utParms.custodySwitch,
                    utParms.srrFlags, utParms.ackRequested,
                    &utParms.extendedCOS, pduZco, &newBundle) <= 0)
        {
            putErrmsg("bputa can't send PDU in bundle; terminated.",
                      NULL);
            parms.running = 0;
        }

        if (newBundle == 0)
        {
            continue;	/*	Must have stopped.	*/
        }

        /*	Enable cancellation of this PDU.		*/

        if (sdr_begin_xn(sdr) == 0)
        {
            parms.running = 0;
            continue;
        }

        pduElt = sdr_list_insert_last(sdr, fduBuffer.extantPdus,
                                      newBundle);
        if (pduElt)
        {
            bp_track(newBundle, pduElt);
        }

        if (sdr_end_xn(sdr) < 0)
        {
            putErrmsg("bputa can't track PDU; terminated.", NULL);
            parms.running = 0;
        }

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

        sm_TaskYield();
    }
コード例 #4
0
ファイル: rfx.c プロジェクト: michirod/cgr-jni
static PsmAddress	insertCXref(IonCXref *cxref)
{
	PsmPartition	ionwm = getIonwm();
	IonVdb 		*vdb = getIonVdb();
	IonNode		*node;
	PsmAddress	nextElt;
	PsmAddress	cxaddr;
	Object		iondbObj;
	IonDB		iondb;
	PsmAddress	cxelt;
	PsmAddress	addr;
	IonEvent	*event;
	time_t		currentTime = getUTCTime();

	/*	Load the affected nodes.				*/

	node = findNode(vdb, cxref->toNode, &nextElt);
	if (node == NULL)
	{
		node = addNode(vdb, cxref->toNode);
		if (node == NULL)
		{
			return 0;
		}
	}

	node = findNode(vdb, cxref->fromNode, &nextElt);
	if (node == NULL)
	{
		node = addNode(vdb, cxref->fromNode);
		if (node == NULL)
		{
			return 0;
		}
	}

	/*	Construct the contact index entry.			*/

	cxaddr = psm_zalloc(ionwm, sizeof(IonCXref));
	if (cxaddr == 0)
	{
		return 0;
	}

	/*	Compute times of relevant events.			*/

	iondbObj = getIonDbObject();
	sdr_read(getIonsdr(), (char *) &iondb, iondbObj, sizeof(IonDB));
	if (cxref->fromNode == getOwnNodeNbr())
	{
		/*	Be a little slow to start transmission, and
		 *	a little quick to stop, to ensure that
		 *	segments arrive only when neighbor is
		 *	expecting them.					*/

		cxref->startXmit = cxref->fromTime + iondb.maxClockError;
		cxref->stopXmit = cxref->toTime - iondb.maxClockError;
	}

	if (cxref->toNode == getOwnNodeNbr())
	{
		/*	Be a little slow to resume timers, and a
		 *	little quick to suspend them, to minimize the
		 *	chance of premature timeout.			*/

		cxref->startFire = cxref->fromTime + iondb.maxClockError;
		cxref->stopFire = cxref->toTime - iondb.maxClockError;
	}
	else	/*	Not a transmission to the local node.		*/
	{
		cxref->purgeTime = cxref->toTime;
	}

	memcpy((char *) psp(ionwm, cxaddr), (char *) cxref, sizeof(IonCXref));
	cxelt = sm_rbt_insert(ionwm, vdb->contactIndex, cxaddr,
			rfx_order_contacts, cxref);
	if (cxelt == 0)
	{
		psm_free(ionwm, cxaddr);
		return 0;
	}

	/*	Insert relevant timeline events.			*/

	if (cxref->startXmit)
	{
		addr = psm_zalloc(ionwm, sizeof(IonEvent));
		if (addr == 0)
		{
			return 0;
		}

		event = (IonEvent *) psp(ionwm, addr);
		event->time = cxref->startXmit;
		event->type = IonStartXmit;
		event->ref = cxaddr;
		if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events,
				event) == 0)
		{
			psm_free(ionwm, addr);
			return 0;
		}
	}

	if (cxref->stopXmit)
	{
		addr = psm_zalloc(ionwm, sizeof(IonEvent));
		if (addr == 0)
		{
			return 0;
		}

		event = (IonEvent *) psp(ionwm, addr);
		event->time = cxref->stopXmit;
		event->type = IonStopXmit;
		event->ref = cxaddr;
		if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events,
				event) == 0)
		{
			psm_free(ionwm, addr);
			return 0;
		}
	}

	if (cxref->startFire)
	{
		addr = psm_zalloc(ionwm, sizeof(IonEvent));
		if (addr == 0)
		{
			return 0;
		}

		event = (IonEvent *) psp(ionwm, addr);
		event->time = cxref->startFire;
		event->type = IonStartFire;
		event->ref = cxaddr;
		if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events,
				event) == 0)
		{
			psm_free(ionwm, addr);
			return 0;
		}
	}

	if (cxref->stopFire)
	{
		addr = psm_zalloc(ionwm, sizeof(IonEvent));
		if (addr == 0)
		{
			return 0;
		}

		event = (IonEvent *) psp(ionwm, addr);
		event->time = cxref->stopFire;
		event->type = IonStopFire;
		event->ref = cxaddr;
		if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events,
				event) == 0)
		{
			psm_free(ionwm, addr);
			return 0;
		}
	}

	if (cxref->purgeTime)
	{
		addr = psm_zalloc(ionwm, sizeof(IonEvent));
		if (addr == 0)
		{
			return 0;
		}

		event = (IonEvent *) psp(ionwm, addr);
		event->time = cxref->purgeTime;
		event->type = IonPurgeContact;
		event->ref = cxaddr;
		if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events,
				event) == 0)
		{
			psm_free(ionwm, addr);
			return 0;
		}
	}

	if (cxref->toTime > currentTime)	/*	Affects routes.	*/
	{
		vdb->lastEditTime = currentTime;
	}

	return cxaddr;
}
コード例 #5
0
ファイル: rfx.c プロジェクト: michirod/cgr-jni
static void	deleteRange(PsmAddress rxaddr, int conditional)
{
	Sdr		sdr = getIonsdr();
	PsmPartition	ionwm = getIonwm();
	IonVdb 		*vdb = getIonVdb();
	time_t		currentTime = getUTCTime();
	IonRXref	*rxref;
	Object		obj;
	IonEvent	event;
	IonNeighbor	*neighbor;
	PsmAddress	nextElt;

	rxref = (IonRXref *) psp(ionwm, rxaddr);

	/*	Delete range from non-volatile database.		*/

	if (rxref->rangeElt)		/*	An asserted range.	*/
	{
		if (conditional)	/*	Delete only if imputed.	*/
		{
			return;		/*	Retain asserted range.	*/
		}

		/*	Unconditional deletion; remove range from DB.	*/

		obj = sdr_list_data(sdr, rxref->rangeElt);
		sdr_free(sdr, obj);
		sdr_list_delete(sdr, rxref->rangeElt, NULL, NULL);
	}

	/*	Delete range events from timeline.			*/

	event.ref = rxaddr;
	event.time = rxref->fromTime;
	if (rxref->rangeElt)
	{
		event.type = IonStartAssertedRange;
	}
	else
	{
		event.type = IonStartImputedRange;
	}

	sm_rbt_delete(ionwm, vdb->timeline, rfx_order_events,
			&event, rfx_erase_data, NULL);
	event.time = rxref->toTime;
	if (rxref->rangeElt)
	{
		event.type = IonStopAssertedRange;
	}
	else
	{
		event.type = IonStopImputedRange;
	}

	sm_rbt_delete(ionwm, vdb->timeline, rfx_order_events,
			&event, rfx_erase_data, NULL);

	/*	Apply to current state as necessary.			*/

	if (currentTime >= rxref->fromTime && currentTime <= rxref->toTime)
	{
		if (rxref->fromNode == getOwnNodeNbr())
		{
			neighbor = findNeighbor(vdb, rxref->toNode, &nextElt);
			if (neighbor)
			{
				neighbor->owltOutbound = 0;
			}
		}

		if (rxref->toNode == getOwnNodeNbr())
		{
			neighbor = findNeighbor(vdb, rxref->fromNode, &nextElt);
			if (neighbor)
			{
				neighbor->owltInbound = 0;
			}
		}
	}

	/*	Delete range from index.				*/

	if (rxref->toTime > currentTime)	/*	Affects routes.	*/
	{
		vdb->lastEditTime = currentTime;
	}

	sm_rbt_delete(ionwm, vdb->rangeIndex, rfx_order_ranges, rxref,
			rfx_erase_data, NULL);
}
コード例 #6
0
ファイル: dtpcd.c プロジェクト: brnrc/ion-dtn
static void	*getBundles(void *parm)
{
	RxThreadParms		*parms = (RxThreadParms *) parm;
	char			ownEid[64];
	Sdr			sdr = getIonsdr();
	BpDelivery		dlv;
	uvast			profNum;
	Scalar			seqNum;
	char			type;
	unsigned int		aduLength;
	int			bytesRemaining;
	ZcoReader		reader;
	unsigned char		*buffer;
	int			bytesToRead;
	int			sdnvLength;
	unsigned char		*cursor;

	isprintf(ownEid, sizeof ownEid, "ipn:" UVAST_FIELDSPEC ".%d",
			getOwnNodeNbr(), DTPC_RECV_SVC_NBR);
	if (bp_open(ownEid, &(parms->rxSap)) < 0)
	{
		putErrmsg("DTPC can't open own 'recv' endpoint.", ownEid);
		parms->running = 0;
		return NULL;
	}

	writeMemo("[i] dtpcd receiver thread has started.");
	while (parms->running)
	{
		if (bp_receive(parms->rxSap, &dlv, BP_BLOCKING) < 0)
		{
			putErrmsg("dtpcd bundle reception failed.", NULL);
			parms->running = 0;
			continue;
		}

		switch (dlv.result)
		{
		case BpEndpointStopped:
			parms->running = 0;
			break;

		case BpPayloadPresent:
			CHKNULL(sdr_begin_xn(sdr));

			/* Since the max length of a Sdnv is 10 bytes,
			 * read 21 bytes to be sure that the Profile
			 * and Sequence number Sdnvs plus the type
			 * were read.					*/

			aduLength = zco_source_data_length(sdr, dlv.adu);
			bytesRemaining = aduLength;
			if (aduLength < 21)	/* Just in case we receive
						 * a very small adu.	*/
			{			
				bytesToRead = aduLength;
			}
			else
			{
				bytesToRead = 21;
			}

			buffer = MTAKE(bytesToRead);
			if (buffer == NULL)
			{
				putErrmsg("Out of memory.",NULL);
				return NULL;
			}

			cursor = buffer;
			zco_start_receiving(dlv.adu, &reader);
			if (zco_receive_headers(sdr, &reader, bytesToRead,
					(char *) buffer) < 0)
			{
				putErrmsg("dtpcd can't receive ADU header.",
						itoa(bytesToRead));
				sdr_cancel_xn(sdr);
				MRELEASE(buffer);
				parms->running = 0;
				continue;
			}

			type = *cursor;		/* Get the type byte.	*/
			cursor++;
			bytesRemaining--;
			sdnvLength = decodeSdnv(&profNum, cursor);
			cursor += sdnvLength;
			bytesRemaining -= sdnvLength;
			sdnvLength = sdnvToScalar(&seqNum, cursor);
			cursor += sdnvLength;
			bytesRemaining -= sdnvLength;

			/*	Mark remaining bytes as source data.	*/

			zco_delimit_source(sdr, dlv.adu, cursor - buffer,
					bytesRemaining);
			zco_strip(sdr, dlv.adu);
			MRELEASE(buffer);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("dtpcd can't handle bundle delivery.",
						NULL);
				parms->running = 0;
				continue;
			}

			switch (type)
			{
			case 0x00:	/*	Received an adu.	*/
				switch (handleInAdu(sdr, &dlv, profNum, seqNum))
				{
				case -1:
					putErrmsg("dtpcd can't handle inbound \
adu.", NULL);
					parms->running = 0;
					continue;

				case 1:
					if (parseInAdus(sdr) < 0)
					{
						putErrmsg("dtpcd can't parse \
							inbound adus.", NULL);
						parms->running = 0;
						continue;
					}

				case 0: 
					/* 	Intentional fall-through to 
					 *	next case. 		*/				
				default:
					if (dlv.ackRequested)
					{
						if (sendAck(parms->txSap,
								profNum, seqNum,
								&dlv) < 0)
						{
							putErrmsg("dtpcd can't \
send ack.", NULL);
							parms->running = 0;
							continue;
						}
					} 
					break;
				}

				break;

			case 0x01:	/*	Received an ACK.	*/
				if (handleAck(sdr, &dlv, profNum, seqNum) < 0)
				{
					putErrmsg("dtpcd can't handle ACK.",
							NULL);
					parms->running = 0;
					continue;
				}

				break;
			default:
				writeMemo("[?] Invalid item type. Corrupted \
item?");
				break;
			}

		default:
			break;
		}