Beispiel #1
0
static Object newSdrAcsCustodian(Object custodians, const char *eid)
{
    Object newCustodianAddr;
    SdrAcsPendingCust newCustodian;

    memset(&newCustodian, 0, sizeof(newCustodian));
    strncpy(newCustodian.eid, eid, MAX_EID_LEN);
    newCustodian.eid[MAX_EID_LEN] = '\0';

    /* Set default ACS size and delay. */
    newCustodian.acsDelay = 2;
    newCustodian.acsSize = 300;

    CHKZERO(sdr_begin_xn(acsSdr));
    newCustodianAddr = sdr_malloc(acsSdr, sizeof(newCustodian));
    newCustodian.signals = sdr_list_create(acsSdr);
    sdr_poke(acsSdr, newCustodianAddr, newCustodian);
    sdr_list_insert_last(acsSdr, custodians, newCustodianAddr);
    if(sdr_end_xn(acsSdr) < 0)
    {
        ACSLOG_WARN("Couldn't create new custodian info for %s", eid);
        return 0;
    }
    return newCustodianAddr;
}
Beispiel #2
0
int	ltpei_add_xmit_trailer_extension(LtpXmitSeg *segment, char tag,
		int valueLength, char *value)
{
	Sdr 			sdr = getIonsdr();
	Sdnv			sdnv;
	LtpExtensionOutbound	extension;
	Object			addr;

	CHKERR(segment);
	CHKERR(ionLocked());
	encodeSdnv(&sdnv, valueLength);
	if (segment->pdu.trailerExtensions == 0)
	{
		if ((segment->pdu.trailerExtensions = sdr_list_create(sdr))
				== 0)
		{
			return -1;	/*	No space in SDR heap.	*/
		}
	}

	extension.tag = tag;
	extension.length = valueLength;
	if (valueLength == 0)
	{
		extension.value = 0;
	}
	else
	{
		CHKERR(value);
		extension.value = sdr_insert(sdr, value, valueLength);
		if (extension.value == 0)
		{
			return -1;	/*	No space in SDR heap.	*/
		}
	}

	if ((addr = sdr_insert(sdr, (char *) &extension,
			sizeof(LtpExtensionOutbound))) == 0)
	{
		return -1;		/*	No space in SDR heap.	*/
	}

	if (sdr_list_insert_last(sdr, segment->pdu.trailerExtensions, addr)
			== 0)
	{
		return -1;		/*	No space in SDR heap.	*/
	}

	segment->pdu.trailerExtensionsCount++;
	segment->pdu.trailerLength += (1 + sdnv.length + valueLength);
	return 0;
}
Beispiel #3
0
int	dtn2_addPlan(char *nodeNm, FwdDirective *defaultDir)
{
	Sdr		sdr = getIonsdr();
	char		nodeName[SDRSTRING_BUFSZ];
	Object		nextPlan;
	Dtn2Plan	plan;
	Object		planObj;

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

	CHKERR(sdr_begin_xn(sdr));
	if (locatePlan(nodeName, &nextPlan) != 0)
	{
		sdr_exit_xn(sdr);
		writeMemoNote("[?] Duplicate plan", nodeNm);
		return 0;
	}

	/*	Okay to add this plan to the database.			*/

	plan.nodeName = sdr_string_create(sdr, nodeName);
	memcpy((char *) &plan.defaultDirective, (char *) defaultDir,
			sizeof(FwdDirective));
	plan.rules = sdr_list_create(sdr);
	planObj = sdr_malloc(sdr, sizeof(Dtn2Plan));
	if (planObj)
	{
		if (nextPlan)
		{
			oK(sdr_list_insert_before(sdr, nextPlan, planObj));
		}
		else
		{
			oK(sdr_list_insert_last(sdr,
					(_dtn2Constants())->plans, planObj));
		}

		sdr_write(sdr, planObj, (char *) &plan, sizeof(Dtn2Plan));
	}

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

	return 1;
}
Beispiel #4
0
Datei: libbp.c Projekt: 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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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();
    }
Beispiel #7
0
/*
 * This function writes an item and its associated descriptor into the SDR,
 * allocating space for each, and adding the SDR descriptor pointer to a
 * given SDR list.
 *
 * item    : The serialized item to store in the SDR.
 * item_len: The size of the serialized item.
 * *itemObj: The SDR pointer to the serialized item in the SDR.
 * desc    : The item descriptor being written to the SDR.
 * desc_len: The size of the item descriptor.
 * *descObj: The SDR pointer to the item's descriptor object in the SDR.
 * list    : The SDR list holding the item descriptor (at *descrObj).
 */
int  db_persist(uint8_t  *item,
					  uint32_t  item_len,
					  Object   *itemObj,
					  void     *desc,
					  uint32_t  desc_len,
					  Object   *descObj,
					  Object    list)
{

   Sdr sdr = getIonsdr();

   CHKERR(sdr_begin_xn(sdr));


   /* Step 1: Allocate a descriptor object for this item in the SDR. */
   if((*descObj = sdr_malloc(sdr, desc_len)) == 0)
   {
	   sdr_cancel_xn(sdr);

	   AMP_DEBUG_ERR("db_persist",
			   	       "Can't allocate descriptor of size %d.",
			   	       desc_len);
	   return -1;
   }


   /* Step 2: Allocate space for the serialized rule in the SDR. */
   if((*itemObj = sdr_malloc(sdr, item_len)) == 0)
   {
	   sdr_free(sdr, *descObj);

	   sdr_cancel_xn(sdr);
	   *descObj = 0;
	   AMP_DEBUG_ERR("db_persist",
			   	   	   "Unable to allocate Item in SDR. Size %d.",
			           item_len);
	   return -1;
   }

   /* Step 3: Write the item to the SDR. */
   sdr_write(sdr, *itemObj, (char *) item, item_len);

   /* Step 4: Write the item descriptor to the SDR. */
   sdr_write(sdr, *descObj, (char *) desc, desc_len);

   /* Step 5: Save the descriptor in the AgentDB active rules list. */
   if (sdr_list_insert_last(sdr, list, *descObj) == 0)
   {
      sdr_free(sdr, *itemObj);
      sdr_free(sdr, *descObj);

      sdr_cancel_xn(sdr);

      *itemObj = 0;
      *descObj = 0;
      AMP_DEBUG_ERR("db_persist",
				        "Unable to insert item Descr. in SDR.", NULL);
      return -1;
   }

	if(sdr_end_xn(sdr))
	{
		AMP_DEBUG_ERR("db_persist", "Can't create Agent database.", NULL);
		return -1;
	}

   return 1;
}
Beispiel #8
0
PsmAddress	rfx_insert_contact(time_t fromTime, time_t toTime,
			uvast fromNode, uvast toNode, unsigned int xmitRate,
			float prob)
{
	Sdr		sdr = getIonsdr();
	PsmPartition	ionwm = getIonwm();
	IonVdb 		*vdb = getIonVdb();
	IonCXref	arg;
	PsmAddress	cxelt;
	PsmAddress	nextElt;
	PsmAddress	cxaddr;
	IonCXref	*cxref;
	PsmAddress	prevElt;
	char		contactIdString[128];
	IonContact	contact;
	Object		iondbObj;
	IonDB		iondb;
	Object		obj;
	Object		elt;

	CHKZERO(fromTime);
	CHKZERO(toTime > fromTime);
	CHKZERO(fromNode);
	CHKZERO(toNode);
	CHKZERO(prob > 0.0 && prob <= 1.0);
	CHKZERO(sdr_begin_xn(sdr));

	/*	Make sure contact doesn't overlap with any pre-existing
	 *	contacts.						*/

	memset((char *) &arg, 0, sizeof(IonCXref));
	arg.fromNode = fromNode;
	arg.toNode = toNode;
	arg.fromTime = fromTime;
	arg.toTime = toTime;
	arg.xmitRate = xmitRate;
	arg.routingObject = 0;
	cxelt = sm_rbt_search(ionwm, vdb->contactIndex, rfx_order_contacts, &arg, &nextElt);
	//cxelt = 0;
	if (cxelt)	/*	Contact is in database already.		*/
	{
		cxaddr = sm_rbt_data(ionwm, cxelt);
		cxref = (IonCXref *) psp(ionwm, cxaddr);
		if (cxref->xmitRate == xmitRate)
		{
			sdr_exit_xn(sdr);
			return cxaddr;
		}

		isprintf(contactIdString, sizeof contactIdString,
				"at %lu, %llu->%llu", fromTime, fromNode, toNode);
		writeMemoNote("[?] Contact data rate not revised",
				contactIdString);
		sdr_exit_xn(sdr);
		return 0;
	}
	else	/*	Check for overlap, which is not allowed.	*/
	{
		if (nextElt)
		{
			prevElt = sm_rbt_prev(ionwm, nextElt);
			cxref = (IonCXref *)
				psp(ionwm, sm_rbt_data(ionwm, nextElt));
			if (fromNode == cxref->fromNode
			&& toNode == cxref->toNode
			&& toTime > cxref->fromTime)
			{
				writeMemoNote("[?] Overlapping contact",
						utoa(fromNode));
				sdr_exit_xn(sdr);
				return 0;
			}
		}
		else
		{
			prevElt = sm_rbt_last(ionwm, vdb->contactIndex);
		}

		if (prevElt)
		{
			cxref = (IonCXref *)
				psp(ionwm, sm_rbt_data(ionwm, prevElt));
			if (fromNode == cxref->fromNode
			&& toNode == cxref->toNode
			&& fromTime < cxref->toTime)
			{
				writeMemoNote("[?] Overlapping contact",
						utoa(fromNode));
				sdr_exit_xn(sdr);
				return 0;
			}
		}
	}

	/*	Contact isn't already in database; okay to add.		*/

	cxaddr = 0;
	contact.fromTime = fromTime;
	contact.toTime = toTime;
	contact.fromNode = fromNode;
	contact.toNode = toNode;
	contact.xmitRate = xmitRate;
	contact.prob = prob;
	obj = sdr_malloc(sdr, sizeof(IonContact));
	if (obj)
	{
		sdr_write(sdr, obj, (char *) &contact, sizeof(IonContact));
		iondbObj = getIonDbObject();
		sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB));
 		elt = sdr_list_insert_last(sdr, iondb.contacts, obj);
		if (elt)
		{
			arg.contactElt = elt;
			cxaddr = insertCXref(&arg);
			if (cxaddr == 0)
			{
				sdr_cancel_xn(sdr);
			}
		}
	}

	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("Can't insert contact.", NULL);
		return 0;
	}

	return cxaddr;
}
Beispiel #9
0
Object	rfx_insert_range(time_t fromTime, time_t toTime, uvast fromNode,
		uvast toNode, unsigned int owlt)
{
	Sdr		sdr = getIonsdr();
	PsmPartition	ionwm = getIonwm();
	IonVdb		*vdb = getIonVdb();
	IonRXref	arg1;
	PsmAddress	rxelt;
	PsmAddress	nextElt;
	PsmAddress	rxaddr;
	IonRXref	*rxref;
	IonEvent	arg2;
	PsmAddress	prevElt;
	char		rangeIdString[128];
	IonRange	range;
	Object		iondbObj;
	IonDB		iondb;
	Object		obj;
	Object		elt;

	/*	Note that ranges are normally assumed to be symmetrical,
	 *	i.e., the signal propagation time from B to A is normally
	 *	assumed to be the same as the signal propagation time
	 *	from A to B.  For this reason, normally only the A->B
	 *	range (where A is a node number that is less than node
	 *	number B) need be entered; when ranges are applied to
	 *	the IonNeighbor objects in the ION database, the A->B
	 *	range is stored as the OWLT for transmissions from A to
	 *	B and also as the OWLT for transmissions from B to A.
	 *
	 *	However, it is possible to insert asymmetric ranges, as
	 *	would apply when the forward and return traffic between
	 *	some pair of nodes travels by different transmission
	 *	paths that introduce different latencies.  When this is
	 *	the case, both the A->B and B->A ranges must be entered.
	 *	The A->B range is initially processed as a symmetric
	 *	range as described above, but when the B->A range is
	 *	subsequently noted it overrides the default OWLT for
	 *	transmissions from B to A.				*/

	CHKZERO(fromTime);
	CHKZERO(toTime > fromTime);
	CHKZERO(fromNode);
	CHKZERO(toNode);
	CHKZERO(sdr_begin_xn(sdr));

	/*	Make sure range doesn't overlap with any pre-existing
	 *	ranges.							*/

	memset((char *) &arg1, 0, sizeof(IonRXref));
	arg1.fromNode = fromNode;
	arg1.toNode = toNode;
	arg1.fromTime = fromTime;
	arg1.toTime = toTime;
	arg1.owlt = owlt;
	rxelt = sm_rbt_search(ionwm, vdb->rangeIndex, rfx_order_ranges,
			&arg1, &nextElt);
	if (rxelt)	/*	Range is in database already.		*/
	{
		rxaddr = sm_rbt_data(ionwm, rxelt);
		rxref = (IonRXref *) psp(ionwm, rxaddr);
		if (rxref->rangeElt == 0)	/*	Imputed.	*/
		{
			/*	The existing range for the same nodes
			 *	and time is merely an imputed range,
			 *	which is being overridden by a non-
			 *	canonical range assertion indicating
			 *	an override of the normal symmetry in
			 *	the owlt between nodes.  Must delete
			 *	that imputed range, together with the
			 *	associated events, after which there
			 *	is no duplication.			*/

			sm_rbt_delete(ionwm, vdb->rangeIndex, rfx_order_ranges,
					&arg1, rfx_erase_data, NULL);
			arg2.ref = rxaddr;
			arg2.time = rxref->fromTime;
			arg2.type = IonStartImputedRange;
			sm_rbt_delete(ionwm, vdb->timeline, rfx_order_events,
					&arg2, rfx_erase_data, NULL);
			arg2.time = rxref->toTime;
			arg2.type = IonStopImputedRange;
			sm_rbt_delete(ionwm, vdb->timeline, rfx_order_events,
					&arg2, rfx_erase_data, NULL);
		}
		else	/*	Overriding an asserted range.		*/
		{
			/*	This is an attempt to replace an
			 *	existing asserted range with another
			 *	asserted range, which is prohibited.	*/

			if (rxref->owlt == owlt)
			{
				sdr_exit_xn(sdr);
				return rxaddr;	/*	Idempotent.	*/
			}

			isprintf(rangeIdString, sizeof rangeIdString,
					"from %lu, %llu->%llu", fromTime,
					fromNode, toNode);
			writeMemoNote("[?] Range OWLT not revised",
					rangeIdString);
			sdr_exit_xn(sdr);
			return 0;
		}
	}

	/*	Check for overlap, which is not allowed.		*/

	if (nextElt)
	{
		prevElt = sm_rbt_prev(ionwm, nextElt);
		rxref = (IonRXref *)
			psp(ionwm, sm_rbt_data(ionwm, nextElt));
		if (fromNode == rxref->fromNode
		&& toNode == rxref->toNode
		&& toTime > rxref->fromTime)
		{
			writeMemoNote("[?] Overlapping range",
					utoa(fromNode));
			sdr_exit_xn(sdr);
			return 0;
		}
	}
	else
	{
		prevElt = sm_rbt_last(ionwm, vdb->rangeIndex);
	}

	if (prevElt)
	{
		rxref = (IonRXref *)
			psp(ionwm, sm_rbt_data(ionwm, prevElt));
		if (fromNode == rxref->fromNode
		&& toNode == rxref->toNode
		&& fromTime < rxref->toTime)
		{
			writeMemoNote("[?] Overlapping range",
					utoa(fromNode));
			sdr_exit_xn(sdr);
			return 0;
		}
	}

	/*	Range isn't already in database; okay to add.		*/

	rxaddr = 0;
	range.fromTime = fromTime;
	range.toTime = toTime;
	range.fromNode = fromNode;
	range.toNode = toNode;
	range.owlt = owlt;
	obj = sdr_malloc(sdr, sizeof(IonRange));
	if (obj)
	{
		sdr_write(sdr, obj, (char *) &range, sizeof(IonRange));
		iondbObj = getIonDbObject();
		sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB));
		elt = sdr_list_insert_last(sdr, iondb.ranges, obj);
		if (elt)
		{
			arg1.rangeElt = elt;
			rxaddr = insertRXref(&arg1);
			if (rxaddr == 0)
			{
				sdr_cancel_xn(sdr);
			}
		}
	}

	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("Can't insert range.", NULL);
		return 0;
	}

	return rxaddr;
}