예제 #1
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;
				}
			}
		}
	}
예제 #2
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;
}
예제 #3
0
파일: libdtn2fw.c 프로젝트: brnrc/ion-dtn
void	dtn2_findPlan(char *nodeNm, Object *planAddr, Object *eltp)
{
	Sdr	sdr = getIonsdr();
	char	nodeName[SDRSTRING_BUFSZ];
	Object	elt;

	/*	This function finds the Dtn2Plan for the specified
	 *	node, if any.						*/

	CHKVOID(ionLocked());
	CHKVOID(nodeNm && planAddr && eltp);
	*eltp = 0;
	if (filterNodeName(nodeName, nodeNm) < 0)
	{
		return;
	}

	elt = locatePlan(nodeName, NULL);
	if (elt == 0)
	{
		return;
	}

	*planAddr = sdr_list_data(sdr, elt);
	*eltp = elt;
}
예제 #4
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;
}
예제 #5
0
파일: rfx.c 프로젝트: michirod/cgr-jni
static int	loadContact(Object elt)
{
	Sdr		sdr = getIonsdr();
	Object		obj;
	IonContact	contact;
	IonCXref	cxref;

	obj = sdr_list_data(sdr, elt);
	sdr_read(sdr, (char *) &contact, obj, sizeof(IonContact));

	/*	Load contact index entry.				*/

	cxref.fromNode = contact.fromNode;
	cxref.toNode = contact.toNode;
	cxref.fromTime = contact.fromTime;
	cxref.toTime = contact.toTime;
	cxref.xmitRate = contact.xmitRate;
	cxref.prob = contact.prob;
	cxref.contactElt = elt;
	cxref.routingObject = 0;
	if (insertCXref(&cxref) == 0)
	{
		return -1;
	}

	return 0;
}
예제 #6
0
파일: rfx.c 프로젝트: michirod/cgr-jni
static int	loadRange(Object elt)
{
	Sdr		sdr = getIonsdr();
	Object		obj;
	IonRange	range;
	IonRXref	rxref;

	obj = sdr_list_data(sdr, elt);
	sdr_read(sdr, (char *) &range, obj, sizeof(IonRange));

	/*	Load range list entry.					*/

	rxref.fromNode = range.fromNode;
	rxref.toNode = range.toNode;
	rxref.fromTime = range.fromTime;
	rxref.toTime = range.toTime;
	rxref.owlt = range.owlt;
	rxref.rangeElt = elt;
	if (insertRXref(&rxref) < 0)
	{
		return -1;
	}

	return 0;
}
예제 #7
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;
}
예제 #8
0
파일: ion.c 프로젝트: b/ION
void	ionProd(unsigned long fromNode, unsigned long toNode,
		unsigned long xmitRate, unsigned int owlt)
{
	Sdr	ionsdr = _ionsdr(NULL);
	time_t	fromTime;
	time_t	toTime;
	Object	elt;
	char	textbuf[RFX_NOTE_LEN];

	if (ionsdr == NULL)
	{
		if (ionAttach() < 0)
		{
			writeMemo("[?] ionProd: node not initialized yet.");
			return;
		}
	}

	fromTime = getUTCTime();	/*	The current time.	*/
	toTime = fromTime + 14400;	/*	Four hours later.	*/
	elt = rfx_insert_range(fromTime, toTime, fromNode, toNode, owlt);
       	if (elt == 0)
	{
		writeMemoNote("[?] ionProd: range insertion failed.",
				utoa(owlt));
		return;
	}

	writeMemo("ionProd: range inserted.");
	writeMemo(rfx_print_range(sdr_list_data(ionsdr, elt), textbuf));
	elt = rfx_insert_contact(fromTime, toTime, fromNode, toNode, xmitRate);
	if (elt == 0)
	{
		writeMemoNote("[?] ionProd: contact insertion failed.",
				utoa(xmitRate));
		return;
	}

	writeMemo("ionProd: contact inserted.");
	writeMemo(rfx_print_contact(sdr_list_data(ionsdr, elt), textbuf));
}
예제 #9
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;
}
예제 #10
0
파일: ltpei.c 프로젝트: brnrc/ion-dtn
void	ltpei_destroy_extension(Sdr sdr, Object elt, void *arg)
{
	Object			addr;
	LtpExtensionOutbound	ext;

	addr = sdr_list_data(sdr, elt);
	sdr_read(sdr, (char *) &ext, addr, sizeof(LtpExtensionOutbound));
	if (ext.value)
	{
		sdr_free(sdr, ext.value);
	}

	sdr_free(sdr, addr);
}
예제 #11
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;
}
예제 #12
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;
}
예제 #13
0
static void releaseSdrAcsSignal(Object signalLElt)
{
    Sdr			bpSdr = getIonsdr();
    Sdr                 acsSdr = getAcssdr();
    Object              signalAddr;
    SdrAcsSignal        signal;
    SdrAcsPendingCust   pendingCust;

    assert(signalLElt != 0);
    ASSERT_ACSSDR_XN;
    ASSERT_BPSDR_XN;

    if (acsSdr == NULL)
    {
        putErrmsg("Can't release ACS, SDR not available.", NULL);
        return;
    }

    signalAddr = sdr_list_data(acsSdr, signalLElt);
    if (signalAddr == 0) {
        ACSLOG_ERROR("Can't derefence ACS signal to release it.");
        return;
    }

    sdr_peek(acsSdr, signal, signalAddr);
    sdr_peek(acsSdr, pendingCust, signal.pendingCustAddr);

    /* Destroy the objects this AcsSignal contains */
    sdr_list_destroy(acsSdr, signal.acsFills, releaseSdrAcsFill, NULL);

    if(signal.acsDue != 0) {
        destroyBpTimelineEvent(signal.acsDue);
    }

    if(signal.serializedZco != 0) {
        zco_destroy(bpSdr, signal.serializedZco);
    }

    /* Destroy this AcsSignal */
    sdr_free(acsSdr, signalAddr);
    sdr_list_delete(acsSdr, signalLElt, NULL, NULL);
}
예제 #14
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);
}
예제 #15
0
파일: libdtn2fw.c 프로젝트: brnrc/ion-dtn
int	dtn2_updatePlan(char *nodeNm, FwdDirective *defaultDir)
{
	Sdr		sdr = getIonsdr();
	char		nodeName[SDRSTRING_BUFSZ];
	Object		elt;
	Object		planObj;
	Dtn2Plan	plan;

	CHKERR(nodeNm && defaultDir);
	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;
	}

	/*	Okay to update this plan.				*/

	planObj = sdr_list_data(sdr, elt);
	sdr_stage(sdr, (char *) &plan, planObj, sizeof(Dtn2Plan));
	dtn2_destroyDirective(&plan.defaultDirective);
	memcpy((char *) &plan.defaultDirective, (char *) defaultDir,
			sizeof(FwdDirective));
	sdr_write(sdr, planObj, (char *) &plan, sizeof(Dtn2Plan));
	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("Can't update plan.", nodeNm);
		return -1;
	}

	return 1;
}
예제 #16
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));
}
예제 #17
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;
}
예제 #18
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;
}
예제 #19
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);
}
예제 #20
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);
	}
}
예제 #21
0
int sendAcs(Object signalLElt)
{
    BpExtendedCOS		ecos = { 0, 0, 255 };
    Object			signalAddr;
    Object			acsBundleObj;	/* Unused write-out of bpSend */
    SdrAcsSignal        	signal;
    SdrAcsPendingCust	pendingCust;
    int			result;
    Sdr			bpSdr = getIonsdr();

    assert(signalLElt != 0);

    if ((acsSdr = getAcssdr()) == NULL)
    {
        putErrmsg("Can't send ACS, SDR not available.", NULL);
        return -1;
    }

    /* To prevent deadlock, we take the BP SDR before the ACS SDR. */
    CHKERR(sdr_begin_xn(bpSdr));
    CHKERR(sdr_begin_xn(acsSdr));

    signalAddr = sdr_list_data(acsSdr, signalLElt);
    if (signalAddr == 0) {
        ACSLOG_ERROR("Can't derefence ACS signal to send it.");
        sdr_cancel_xn(acsSdr);
        sdr_cancel_xn(bpSdr);
        return -1;
    }

    sdr_peek(acsSdr, signal, signalAddr);
    sdr_peek(acsSdr, pendingCust, signal.pendingCustAddr);

    /* Remove ref to this serialized ZCO from signal; also remove the bundle
     * IDs covered by this serialized ZCO. */
    result = bpSend(NULL, pendingCust.eid, NULL, ACS_TTL,
                    BP_EXPEDITED_PRIORITY, NoCustodyRequested, 0, 0, &ecos,
                    signal.serializedZco, &acsBundleObj, BP_CUSTODY_SIGNAL);
    switch (result)
    {
    /* All return codes from bpSend() still cause us to continue processing
     * to free this ACS.  If it was sent successfully, good.  If it wasn't,
     * that's due to a system failure or problem with this ACS, so the best
     * we can do is delete it from our node without sending. */
    case -1:
        ACSLOG_ERROR("Can't send custody transfer signal.");
        zco_destroy(bpSdr, signal.serializedZco);
        break;

    case 0:
        ACSLOG_ERROR("Custody transfer signal not transmitted.");
        zco_destroy(bpSdr, signal.serializedZco);
        break;

    default:
        /* bpSend() gave the serializedZco to a forwarder, so don't
         * zco_destroy(). */
        break;
    }

    if (signal.acsDue != 0)
    {
        destroyBpTimelineEvent(signal.acsDue);
    }

    signal.acsDue = 0;
    signal.serializedZco = 0;
    sdr_poke(acsSdr, signalAddr, signal);

    releaseSdrAcsSignal(signalLElt);

    if (sdr_end_xn(acsSdr) < 0)
    {
        ACSLOG_ERROR("Couldn't mark a serialized ACS as sent.");
        sdr_cancel_xn(bpSdr);
        return -1;
    }

    if(sdr_end_xn(bpSdr) < 0)
    {
        return -1;
    }

    return result > 0 ? 0 : -1;
}
예제 #22
0
static void releaseSdrAcsFill(Sdr sdr, Object elt, void *arg)
{
    sdr_free(sdr, sdr_list_data(sdr, elt));
}
예제 #23
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);
}
예제 #24
0
파일: ltpclock.c 프로젝트: b/ION
static int	manageLinks(Sdr sdr, time_t currentTime)
{
	PsmPartition	ionwm = getIonwm();
	LtpVdb		*ltpvdb = getLtpVdb();
	IonVdb		*ionvdb = getIonVdb();
	PsmAddress	elt;
	LtpVspan	*vspan;
	Object		obj;
	LtpSpan		span;
	IonNeighbor	*neighbor;
	PsmAddress	nextElt;
	unsigned long	priorXmitRate;

	sdr_begin_xn(sdr);
	for (elt = sm_list_first(ionwm, ltpvdb->spans); elt;
			elt = sm_list_next(ionwm, elt))
	{
		vspan = (LtpVspan *) psp(ionwm, sm_list_data(ionwm, elt));

		/*	Finish aggregation as necessary.		*/

		obj = sdr_list_data(sdr, vspan->spanElt);
		sdr_stage(sdr, (char *) &span, obj, sizeof(LtpSpan));
		if (span.lengthOfBufferedBlock > 0)
		{
			span.ageOfBufferedBlock++;
			sdr_write(sdr, obj, (char *) &span, sizeof(LtpSpan));
			if (span.ageOfBufferedBlock >= span.aggrTimeLimit)
			{
				sm_SemGive(vspan->bufFullSemaphore);
			}
		}

		/*	Find Neighbor object encapsulating the current
		 *	known state of this LTP engine.			*/

		neighbor = findNeighbor(ionvdb, vspan->engineId, &nextElt);
		if (neighbor == NULL)
		{
			neighbor = addNeighbor(ionvdb, vspan->engineId,
					nextElt);
			if (neighbor == NULL)
			{
				putErrmsg("Can't update span.", NULL);
				return -1;
			}
		}

		if (neighbor->xmitRate == 0)
		{
			if (vspan->localXmitRate > 0)
			{
				vspan->localXmitRate = 0;
				ltpStopXmit(vspan);
			}
		}
		else
		{
			if (vspan->localXmitRate == 0)
			{
				vspan->localXmitRate = neighbor->xmitRate;
				ltpStartXmit(vspan);
			}
		}

		if (neighbor->fireRate == 0)
		{
			if (vspan->remoteXmitRate > 0)
			{
				priorXmitRate = vspan->remoteXmitRate;
				vspan->remoteXmitRate = 0;
				if (ltpSuspendTimers(vspan, elt, currentTime,
						priorXmitRate))
				{
					putErrmsg("Can't manage links.", NULL);
					return -1;
				}
			}
		}
		else
		{
			if (vspan->remoteXmitRate == 0)
			{
				vspan->remoteXmitRate = neighbor->fireRate;
				if (ltpResumeTimers(vspan, elt, currentTime,
						vspan->remoteXmitRate))
				{
					putErrmsg("Can't manage links.", NULL);
					return -1;
				}
			}
		}

		if (neighbor->recvRate == 0)
		{
			vspan->receptionRate = 0;
		}
		else
		{
			vspan->receptionRate = neighbor->recvRate;
		}

		if (neighbor->owltInbound != vspan->owltInbound)
		{
			vspan->owltInbound = neighbor->owltInbound;
		}

		if (neighbor->owltOutbound != vspan->owltOutbound)
		{
			vspan->owltOutbound = neighbor->owltOutbound;
		}
	}

	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("ltpclock failed managing links.", NULL);
		return -1;
	}

	return 0;
}
예제 #25
0
파일: ltpclock.c 프로젝트: 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;
		}
	}
}
예제 #26
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;
		}
	}
}
예제 #27
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;
}
예제 #28
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;
}
예제 #29
0
파일: tcpclo.c 프로젝트: brnrc/ion-dtn
int	tcpclo(int a1, int a2, int a3, int a4, int a5,
		int a6, int a7, int a8, int a9, int a10)
{
	char	*ductName = (char *) a1;
#else
int	main(int argc, char *argv[])
{
	char	*ductName = (argc > 1 ? argv[1] : NULL);
#endif
	unsigned char		*buffer;
	VOutduct		*vduct;
	PsmAddress		vductElt;
	Sdr			sdr;
	Outduct			duct;
	ClProtocol		protocol;
	Outflow			outflows[3];
	int			i;
	char			*hostName;
	unsigned short		portNbr;
	unsigned int		hostNbr;
	struct sockaddr		socketName;
	struct sockaddr_in	*inetName;
	int			running = 1;
	pthread_mutex_t		mutex;
	KeepaliveThreadParms	parms;
	ReceiveThreadParms	rparms;
	pthread_t		keepaliveThread;
	pthread_t		receiverThread;
	Object			bundleZco;
	BpExtendedCOS		extendedCOS;
	char			destDuctName[MAX_CL_DUCT_NAME_LEN + 1];
	unsigned int		bundleLength;
	int			ductSocket = -1;
	int			bytesSent;
	int 			keepalivePeriod = 0;
	VInduct			*viduct;

	if (ductName == NULL)
	{
		PUTS("Usage: tcpclo <remote host name>[:<port number>]");
		return 0;
	}

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

	buffer = MTAKE(TCPCLA_BUFSZ);
	if (buffer == NULL)
	{
		putErrmsg("No memory for TCP buffer in tcpclo.", NULL);
		return 1;
	}

	findOutduct("tcp", ductName, &vduct, &vductElt);
	if (vductElt == 0)
	{
		putErrmsg("No such tcp duct.", ductName);
		MRELEASE(buffer);
		return 1;
	}

	if (vduct->cloPid != ERROR && vduct->cloPid != sm_TaskIdSelf())
	{
		putErrmsg("CLO task is already started for this duct.",
				itoa(vduct->cloPid));
		MRELEASE(buffer);
		return 1;
	}

	/*	All command-line arguments are now validated.		*/

	sdr = getIonsdr();
	CHKERR(sdr_begin_xn(sdr));
	sdr_read(sdr, (char *) &duct, sdr_list_data(sdr, vduct->outductElt),
			sizeof(Outduct));
	sdr_read(sdr, (char *) &protocol, duct.protocol, sizeof(ClProtocol));
	sdr_exit_xn(sdr);
	if (protocol.nominalRate == 0)
	{
		vduct->xmitThrottle.nominalRate = DEFAULT_TCP_RATE;
	}
	else
	{
		vduct->xmitThrottle.nominalRate = protocol.nominalRate;
	}

	memset((char *) outflows, 0, sizeof outflows);
	outflows[0].outboundBundles = duct.bulkQueue;
	outflows[1].outboundBundles = duct.stdQueue;
	outflows[2].outboundBundles = duct.urgentQueue;
	for (i = 0; i < 3; i++)
	{
		outflows[i].svcFactor = 1 << i;
	}

	hostName = ductName;
	parseSocketSpec(ductName, &portNbr, &hostNbr);
	if (portNbr == 0)
	{
		portNbr = BpTcpDefaultPortNbr;
	}

	portNbr = htons(portNbr);
	if (hostNbr == 0)
	{
		putErrmsg("Can't get IP address for host.", hostName);
		MRELEASE(buffer);
		return 1;
	}

	hostNbr = htonl(hostNbr);
	memset((char *) &socketName, 0, sizeof socketName);
	inetName = (struct sockaddr_in *) &socketName;
	inetName->sin_family = AF_INET;
	inetName->sin_port = portNbr;
	memcpy((char *) &(inetName->sin_addr.s_addr), (char *) &hostNbr, 4);
	if (_tcpOutductId(&socketName, "tcp", ductName) < 0)
	{
		putErrmsg("Can't record TCP Outduct ID for connection.", NULL);
		MRELEASE(buffer);
		return -1;
	}

	/*	Set up signal handling.  SIGTERM is shutdown signal.	*/

	oK(tcpcloSemaphore(&(vduct->semaphore)));
	isignal(SIGTERM, shutDownClo);
#ifndef mingw
	isignal(SIGPIPE, handleConnectionLoss);
#endif

	/*	Start the keepalive thread for the eventual connection.	*/
	
	tcpDesiredKeepAlivePeriod = KEEPALIVE_PERIOD;
	parms.cloRunning = &running;
	pthread_mutex_init(&mutex, NULL);
	parms.mutex = &mutex;
	parms.socketName = &socketName;
	parms.ductSocket = &ductSocket;
	parms.keepalivePeriod = &keepalivePeriod;
	if (pthread_begin(&keepaliveThread, NULL, sendKeepalives, &parms))
	{
		putSysErrmsg("tcpclo can't create keepalive thread", NULL);
		MRELEASE(buffer);
		pthread_mutex_destroy(&mutex);
		return 1;
	}

	// Returns the VInduct Object of first induct with same protocol
	// as the outduct. The VInduct is required to create an acq area.
	// The Acq Area inturn uses the throttle information from VInduct
	// object while receiving bundles. The throttle information 
	// of all inducts of the same induct will be the same, so choosing 
	// any induct will serve the purpose.
	
	findVInduct(&viduct,protocol.name);
	if(viduct == NULL)
	{
		putErrmsg("tcpclo can't get VInduct", NULL);
		MRELEASE(buffer);
		pthread_mutex_destroy(&mutex);
		return 1;
	
	}

	rparms.vduct =  viduct;
	rparms.bundleSocket = &ductSocket;
	rparms.mutex = &mutex;
	rparms.cloRunning = &running;
	if (pthread_begin(&receiverThread, NULL, receiveBundles, &rparms))
	{
		putSysErrmsg("tcpclo can't create receive thread", NULL);
		MRELEASE(buffer);
		pthread_mutex_destroy(&mutex);
		return 1;
	}

	/*	Can now begin transmitting to remote duct.		*/

	{
		char	txt[500];

		isprintf(txt, sizeof(txt),
			"[i] tcpclo is running, spec=[%s:%d].", 
			inet_ntoa(inetName->sin_addr),
			ntohs(inetName->sin_port));
		writeMemo(txt);
	}

	while (running && !(sm_SemEnded(tcpcloSemaphore(NULL))))
	{
		if (bpDequeue(vduct, outflows, &bundleZco, &extendedCOS,
				destDuctName, 0, -1) < 0)
		{
			running = 0;	/*	Terminate CLO.		*/
			continue;
		}

		if (bundleZco == 0)	/*	Interrupted.		*/
		{
			continue;
		}

		CHKZERO(sdr_begin_xn(sdr));
		bundleLength = zco_length(sdr, bundleZco);
		sdr_exit_xn(sdr);
		pthread_mutex_lock(&mutex);
		bytesSent = sendBundleByTCPCL(&socketName, &ductSocket,
			bundleLength, bundleZco, buffer, &keepalivePeriod);
		pthread_mutex_unlock(&mutex);
		if(bytesSent < 0)
		{
			running = 0;	/*	Terminate CLO.		*/
		}

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

		sm_TaskYield();
	}
	writeMemo("[i] tcpclo done sending");

	if (sendShutDownMessage(&ductSocket, SHUT_DN_NO, -1, &socketName) < 0)
	{
		putErrmsg("Sending Shutdown message failed!!",NULL);
	}

	if (ductSocket != -1)
	{
		closesocket(ductSocket);
		ductSocket=-1;
	}

	running = 0;
	pthread_join(keepaliveThread, NULL);
	writeMemo("[i] tcpclo keepalive thread killed");

	pthread_join(receiverThread, NULL);
	writeMemo("[i] tcpclo receiver thread killed");

	writeErrmsgMemos();
	writeMemo("[i] tcpclo duct has ended.");
	oK(_tcpOutductId(&socketName, NULL, NULL));
	MRELEASE(buffer);
	pthread_mutex_destroy(&mutex);
	bp_detach();
	return 0;
}
예제 #30
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;
}