示例#1
0
int acsAttach()
{
	if (acsConstants)
	{
           return 0;
	}

	if (getAcssdr() == NULL)
	{
		/* ACS can't find ACS SDR. */
		return -1;
	}

	CHKERR(sdr_begin_xn(acsSdr));
	if (acsdbObject == 0)
	{
		acsdbObject = sdr_find(acsSdr, acsDbName, NULL);
		if (acsdbObject == 0)
		{
			sdr_exit_xn(acsSdr);
			return -1;
		}
	}
	acsConstants = &acsConstantsBuf;
	sdr_read(acsSdr, (char *) acsConstants, acsdbObject, sizeof(AcsDB));
	sdr_exit_xn(acsSdr);
	return 0;
}
示例#2
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;
}
示例#3
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;
}
示例#4
0
文件: libdtn2fw.c 项目: brnrc/ion-dtn
static DtnDB	*_dtn2Constants()
{
	static DtnDB	buf;
	static DtnDB	*db = NULL;
	Sdr		sdr;
	Object		dbObject;
	
	if (db == NULL)
	{
		sdr = getIonsdr();
		CHKNULL(sdr);
		dbObject = _dtn2dbObject(NULL);
		if (dbObject)
		{
			if (sdr_heap_is_halted(sdr))
			{
				sdr_read(sdr, (char *) &buf, dbObject,
						sizeof(DtnDB));
			}
			else
			{
				CHKNULL(sdr_begin_xn(sdr));
				sdr_read(sdr, (char *) &buf, dbObject,
						sizeof(DtnDB));
				sdr_exit_xn(sdr);
			}

			db = &buf;
		}
	}
	
	return db;
}
示例#5
0
文件: libdtn2fw.c 项目: brnrc/ion-dtn
int	dtn2_removePlan(char *nodeNm)
{
	Sdr	sdr = getIonsdr();
	char	nodeName[SDRSTRING_BUFSZ];
	Object	elt;
	Object	planObj;
		OBJ_POINTER(Dtn2Plan, plan);

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

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

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

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

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

	return 1;
}
示例#6
0
static void	executeList(int tokenCount, char **tokens)
{
	Sdr		sdr = getIonsdr();
	PsmPartition	ionwm = getIonwm();
	IonVdb		*vdb = getIonVdb();
	PsmAddress	elt;
	PsmAddress	addr;
	char		buffer[RFX_NOTE_LEN];

	if (tokenCount < 2)
	{
		printText("List what?");
		return;
	}

	if (strcmp(tokens[1], "contact") == 0)
	{
		CHKVOID(sdr_begin_xn(sdr));
		for (elt = sm_rbt_first(ionwm, vdb->contactIndex); elt;
				elt = sm_rbt_next(ionwm, elt))
		{
			addr = sm_rbt_data(ionwm, elt);
			rfx_print_contact(addr, buffer);
			printText(buffer);
		}

		sdr_exit_xn(sdr);
		return;
	}

	if (strcmp(tokens[1], "range") == 0)
	{
		CHKVOID(sdr_begin_xn(sdr));
		for (elt = sm_rbt_first(ionwm, vdb->rangeIndex); elt;
				elt = sm_rbt_next(ionwm, elt))
		{
			addr = sm_rbt_data(ionwm, elt);
			rfx_print_range(addr, buffer);
			printText(buffer);
		}

		sdr_exit_xn(sdr);
		return;
	}

	SYNTAX_ERROR;
}
示例#7
0
文件: bpclock.c 项目: b/ION
static void	applyRateControl(Sdr sdr)
{
	BpVdb		*vdb = getBpVdb();
	PsmPartition	ionwm = getIonwm();
	Throttle	*throttle;
	PsmAddress	elt;
	VInduct		*induct;
	VOutduct	*outduct;
	long		capacityLimit;

	sdr_begin_xn(sdr);	/*	Just to lock memory.		*/

	/*	Recalculate limit on local bundle generation.		*/

	manageProductionThrottle(vdb);

	/*	Enable some bundle acquisition.				*/

	for (elt = sm_list_first(ionwm, vdb->inducts); elt;
			elt = sm_list_next(ionwm, elt))
	{
		induct = (VInduct *) psp(ionwm, sm_list_data(ionwm, elt));
		throttle = &(induct->acqThrottle);
		capacityLimit = throttle->nominalRate << 1;
		throttle->capacity += throttle->nominalRate;
		if (throttle->capacity > capacityLimit)
		{
			throttle->capacity = capacityLimit;
		}

		if (throttle->capacity > 0)
		{
			sm_SemGive(throttle->semaphore);
		}
	}

	/*	Enable some bundle transmission.			*/

	for (elt = sm_list_first(ionwm, vdb->outducts); elt;
			elt = sm_list_next(ionwm, elt))
	{
		outduct = (VOutduct *) psp(ionwm, sm_list_data(ionwm, elt));
		throttle = &(outduct->xmitThrottle);
		capacityLimit = throttle->nominalRate << 1;
		throttle->capacity += throttle->nominalRate;
		if (throttle->capacity > capacityLimit)
		{
			throttle->capacity = capacityLimit;
		}

		if (throttle->capacity > 0)
		{
			sm_SemGive(throttle->semaphore);
		}
	}

	sdr_exit_xn(sdr);	/*	Unlock memory.			*/
}
示例#8
0
文件: libdtn2fw.c 项目: brnrc/ion-dtn
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;
}
示例#9
0
文件: libbp.c 项目: b/ION
void	bp_untrack(Object bundleObj, Object trackingElt)
{
	Sdr	sdr = getIonsdr();
		OBJ_POINTER(Bundle, bundle);
	Object	elt;

	CHKVOID(bundleObj && trackingElt);
	sdr_begin_xn(sdr);
	GET_OBJ_POINTER(sdr, Bundle, bundle, bundleObj);
	if (bundle->trackingElts == 0)
	{
		sdr_exit_xn(sdr);
		return;
	}

	for (elt = sdr_list_first(sdr, bundle->trackingElts); elt;
			elt = sdr_list_next(sdr, elt))
	{
		if (sdr_list_data(sdr, elt) == trackingElt)
		{
			break;
		}
	}

	if (elt == 0)		/*	Not found.			*/
	{
		sdr_exit_xn(sdr);
		return;
	}

	sdr_list_delete(sdr, elt, NULL, NULL);
	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("Failed removing bundle tracking elt.", NULL);
	}
}
示例#10
0
static void	executeInfo(int tokenCount, char **tokens)
{
	Sdr	sdr = getIonsdr();
	ImcDB	imcdb;

	if (tokenCount != 2)
	{
		SYNTAX_ERROR;
		return;
	}

	CHKVOID(sdr_begin_xn(sdr));
	sdr_read(getIonsdr(), (char *) &imcdb, getImcDbObject(), sizeof(ImcDB));
	printKin(strtouvast(tokens[1]), imcdb.parent);
	sdr_exit_xn(sdr);
}
示例#11
0
文件: libdtn2fw.c 项目: brnrc/ion-dtn
int	dtn2Init()
{
	Sdr	sdr = getIonsdr();
	Object	dtn2dbObject;
	DtnDB	dtn2dbBuf;

	/*	Recover the DTN database, creating it if necessary.	*/

	CHKERR(sdr_begin_xn(sdr));
	dtn2dbObject = sdr_find(sdr, DTN_DBNAME, NULL);
	switch (dtn2dbObject)
	{
	case -1:		/*	SDR error.			*/
		sdr_cancel_xn(sdr);
		putErrmsg("Failed seeking DTN database in SDR.", NULL);
		return -1;

	case 0:			/*	Not found; must create new DB.	*/
		dtn2dbObject = sdr_malloc(sdr, sizeof(DtnDB));
		if (dtn2dbObject == 0)
		{
			sdr_cancel_xn(sdr);
			putErrmsg("No space for DTN database.", NULL);
			return -1;
		}

		memset((char *) &dtn2dbBuf, 0, sizeof(DtnDB));
		dtn2dbBuf.plans = sdr_list_create(sdr);
		sdr_write(sdr, dtn2dbObject, (char *) &dtn2dbBuf,
				sizeof(DtnDB));
		sdr_catlg(sdr, DTN_DBNAME, 0, dtn2dbObject);
		if (sdr_end_xn(sdr))
		{
			putErrmsg("Can't create DTN database.", NULL);
			return -1;
		}

		break;

	default:		/*	Found DB in the SDR.		*/
		sdr_exit_xn(sdr);
	}

	oK(_dtn2dbObject(&dtn2dbObject));
	oK(_dtn2Constants());
	return 0;
}
示例#12
0
void    sdrnm_state_get(SdrnmState *state)
{
    Sdr		sdr = getIonsdr();
    SdrUsageSummary	usage;

    CHKVOID(state);
    CHKVOID(sdr_begin_xn(sdr));
    sdr_usage(sdr, &usage);
    state->smallPoolSize = usage.smallPoolSize;
    state->smallPoolFree = usage.smallPoolFree;
    state->smallPoolAllocated = usage.smallPoolAllocated;
    state->largePoolSize = usage.largePoolSize;
    state->largePoolFree = usage.largePoolFree;
    state->largePoolAllocated = usage.largePoolAllocated;
    state->unusedSize = usage.unusedSize;
    sdr_exit_xn(sdr);
}
示例#13
0
文件: cfdpadmin.c 项目: b/ION
static void	executeInfo()
{
	Sdr	sdr = getIonsdr();
		OBJ_POINTER(CfdpDB, db);
	char	buffer[256];

	sdr_begin_xn(sdr);	/*	Just to lock memory.		*/
	GET_OBJ_POINTER(sdr, CfdpDB, db, getCfdpDbObject());
	isprintf(buffer, sizeof buffer, "xncount=%lu, maxtrnbr=%lu, \
fillchar=0x%x, discard=%hu, requirecrc=%hu, segsize=%hu, mtusize = %hu, \
inactivity=%u, ckperiod=%u, maxtimeouts=%u", db->transactionCounter,
			db->maxTransactionNbr, db->fillCharacter,
			db->discardIncompleteFile, db->crcRequired,
			db->maxFileDataLength, db->mtuSize,
			db->transactionInactivityLimit, db->checkTimerPeriod,
			db->checkTimeoutLimit);
	sdr_exit_xn(sdr);
	printText(buffer);
}
示例#14
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;
}
示例#15
0
int	acslist(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)
{
	if(argc > 1) {
		if (strcmp(argv[1], "-s") == 0 ||
				strcmp(argv[1], "--stdout") == 0) {
			printToStdout = 1;
			argc--;
			argv++;
		}
	}
#endif
	Sdr acsSdr;

	/* Attach to ACS database. */
	if (acsAttach() < 0)
	{
		putErrmsg("Can't attach to ACS.", NULL);
		return 1;
	}
	acsSdr = getAcssdr();


	/* Lock SDR and check the database. */
	CHKZERO(sdr_begin_xn(acsSdr));
	printAndCheckByCids(acsSdr);
	checkByBids(acsSdr);
	sdr_exit_xn(acsSdr);


	/* Cleanup */
	writeErrmsgMemos();
	acsDetach();
	bp_detach();
	return errors == 0 ? 0 : 1;
}
示例#16
0
static IonDB	*_ionConstants()
{
	static IonDB	buf;
	static IonDB	*db = NULL;
	Sdr		sdr;
	Object		dbObject;

	if (db == NULL)
	{
		/*	Load constants into a conveniently accessed
		 *	structure.  Note that this CANNOT be treated
		 *	as a current database image in later
		 *	processing.					*/

		sdr = _ionsdr(NULL);
		CHKNULL(sdr);
		dbObject = _iondbObject(NULL);
		if (dbObject)
		{
			if (sdr_heap_is_halted(sdr))
			{
				sdr_read(sdr, (char *) &buf, dbObject,
						sizeof(IonDB));
			}
			else
			{
				CHKNULL(sdr_begin_xn(sdr));
				sdr_read(sdr, (char *) &buf, dbObject,
						sizeof(IonDB));
				sdr_exit_xn(sdr);
			}

			db = &buf;
		}
	}

	return db;
}
示例#17
0
文件: libbp.c 项目: b/ION
int	bp_track(Object bundleObj, Object trackingElt)
{
	Sdr	sdr = getIonsdr();
		OBJ_POINTER(Bundle, bundle);

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

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

	return 0;
}
示例#18
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);
}
示例#19
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;
}
示例#20
0
int acsInitialize(long heapWords, int logLevel)
{
    AcsDB	acsdbBuf;
    unsigned long zero = 0;     /* sdr_stow() wants this */

    if (heapWords == 0)
    {
        /* Caller wants us to supply a default. */
        heapWords = ACS_SDR_DEFAULT_HEAPWORDS;
    }

    if (ionAttach() < 0)
    {
        putErrmsg("Can't attach to ION.", NULL);
        return -1;
    }

    {
        Sdr		sdr = getIonsdr();
        IonDB        iondb;
        char         *pathname = iondb.parmcopy.pathName;

        CHKERR(sdr_begin_xn(sdr));
        sdr_read(sdr, (char *) &iondb, getIonDbObject(), sizeof(IonDB));
        sdr_exit_xn(sdr);

#if 0
        {
            char text[100];

            sprintf( text, "ION parms pathname : %s", pathname );

            writeMemo( text );
        }
#endif

        if (sdr_load_profile(acssdrName, SDR_IN_DRAM, heapWords,
                             SM_NO_KEY, pathname, NULL) < 0)
        {
            putErrmsg("Unable to load SDR profile for ACS.", NULL);
            return -1;
        } else {
            writeMemo("ACS SDR profile loaded.");
        }
    }

    acsSdr = sdr_start_using(acssdrName);
    if (acsSdr == NULL)
    {
        putErrmsg("Can't start using SDR for ACS.", NULL);
        return -1;
    }


    if (getAcssdr() < 0)
    {
        putErrmsg("ACS can't find ACS SDR.", NULL);
        return -1;
    }

    CHKERR(sdr_begin_xn(acsSdr));
    acsdbObject = sdr_find(acsSdr, acsDbName, NULL);
    switch (acsdbObject)
    {
    case -1:		/*	SDR error.			*/
        sdr_cancel_xn(acsSdr);
        putErrmsg("Can't seek ACS database in SDR.", NULL);
        return -1;

    case 0:			/*	Not found must create new DB.	*/
        memset((char *) &acsdbBuf, 0, sizeof(AcsDB));
        acsdbBuf.pendingCusts = sdr_list_create(acsSdr);
        acsdbBuf.logLevel = logLevel;
        acsdbBuf.cidHash = sdr_hash_create(acsSdr, sizeof(AcsCustodyId),
                                           ACS_CIDHASH_ROWCOUNT, 1);
        acsdbBuf.bidHash = sdr_hash_create(acsSdr, sizeof(AcsBundleId),
                                           ACS_BIDHASH_ROWCOUNT, 1);
        acsdbBuf.id = sdr_stow(acsSdr, zero);
        acsdbObject = sdr_malloc(acsSdr, sizeof(AcsDB));
        if (acsdbObject == 0)
        {
            sdr_cancel_xn(acsSdr);
            putErrmsg("No space for ACS database.", NULL);
            return -1;
        }

        sdr_write(acsSdr, acsdbObject, (char *) &acsdbBuf, sizeof(AcsDB));
        sdr_catlg(acsSdr, acsDbName, 0, acsdbObject);
        if (sdr_end_xn(acsSdr))
        {
            putErrmsg("Can't create ACS database.", NULL);
            return -1;
        }

        break;

    default:
        sdr_exit_xn(acsSdr);
    }

    acsConstants = &acsConstantsBuf;
    CHKERR(sdr_begin_xn(acsSdr));
    sdr_read(acsSdr, (char *) acsConstants, acsdbObject, sizeof(AcsDB));
    sdr_exit_xn(acsSdr);
    return 0;
}
示例#21
0
int trySendAcs(SdrAcsPendingCust *custodian,
               BpCtReason reasonCode, unsigned char succeeded,
               const CtebScratchpad *cteb)
{
    Object				signalLElt;
    Object				signalAddr;
    SdrAcsSignal        signal;
    BpEvent				timelineEvent;
    Object				newSerializedZco;
    unsigned long		newSerializedLength;
    int					result;
    Sdr					bpSdr = getIonsdr();

    /* To prevent deadlock, take bpSdr before acsSdr. */
    CHKERR(sdr_begin_xn(bpSdr));
    CHKERR(sdr_begin_xn(acsSdr));

    signalLElt = findSdrAcsSignal(custodian->signals, reasonCode, succeeded,
                                  &signalAddr);
    if (signalAddr == 0)
    {
        ACSLOG_ERROR("Can't find ACS signal");
        sdr_exit_xn(acsSdr);
        sdr_exit_xn(bpSdr);
        return -1;
    }
    sdr_peek(acsSdr, signal, signalAddr);


    newSerializedLength = serializeAcs(signalAddr, &newSerializedZco,
                                       signal.serializedZcoLength);
    if (newSerializedLength == 0)
    {
        ACSLOG_ERROR("Can't serialize new ACS (%lu)", signal.serializedZcoLength);
        sdr_cancel_xn(acsSdr);
        sdr_cancel_xn(bpSdr);
        return -1;
    }
    ACSLOG_DEBUG("Serialized a new ACS to %s that is %lu long (old: %lu)",
                 custodian->eid, newSerializedLength, signal.serializedZcoLength);


    /* If serializeAcs() (which serializes an ACS that covers all the "old"
     * custody IDs as well as 1 "new" custody ID that we're trying to append)
     * returned an ACS that's larger than the custodian' preferred size, then:
     *  1) Send the old ACS (the biggest ACS that's smaller than custodian's
     *     preferred size), covering all the old custody IDs but not the new
     *     one.
     *  2) Make a new ACS that includes only the new custody ID.
     */
    if (custodian->acsSize > 0 && newSerializedLength >= custodian->acsSize)
    {
        if(signal.serializedZco == 0)
        {
            /* We don't have an old unserialized ACS to send.  This means the
             * first custody signal appended to this ACS exceeded the acsSize
             * parameter.  The best we can do is send this ACS even though it's
             * bigger than the recommended acsSize. */
            ACSLOG_WARN("Appending first CS to %s was bigger than %lu",
                        custodian->eid, custodian->acsSize);
            signal.serializedZcoLength = newSerializedLength;
            signal.serializedZco = newSerializedZco;
            sdr_poke(acsSdr, signalAddr, signal);
            sendAcs(signalLElt);
            if(sdr_end_xn(acsSdr) < 0)
            {
                ACSLOG_ERROR("Can't serialize ACS bundle.");
                sdr_cancel_xn(bpSdr);
                return -1;
            }
            if (sdr_end_xn(bpSdr) < 0)
            {
                ACSLOG_ERROR("Can't send ACS bundle.");
                return -1;
            }
            return 0;
        }

        /* Calling this invalidates our signalLElt and signalAddr pointers, so
         * we must re-find the signal before using them again. */
        sendAcs(signalLElt);

        /* Add the one that was uncovered by the serialized payload back in */
        result = appendToSdrAcsSignals(custodian->signals,
                                       signal.pendingCustAddr, reasonCode, succeeded,
                                       cteb);
        switch (result)
        {
        case 0:
            /* Success; continue processing. */
            break;
        default:
            ACSLOG_ERROR("Can't carry size-limited ID to new ACS");
            sdr_cancel_xn(acsSdr);
            sdr_cancel_xn(bpSdr);
            return -1;
        }

        /* Find the uncovered one that we just added. */
        signalLElt = findSdrAcsSignal(custodian->signals, reasonCode,
                                      succeeded, &signalAddr);
        if (signalAddr == 0)
        {
            ACSLOG_ERROR("Can't find ACS signal");
            sdr_cancel_xn(acsSdr);
            sdr_cancel_xn(bpSdr);
            return -1;
        }
        sdr_peek(acsSdr, signal, signalAddr);

        /* Serialize the new one */
        newSerializedLength = serializeAcs(signalAddr, &newSerializedZco, 0);
        if (newSerializedLength <= 0)
        {
            ACSLOG_ERROR("Can't serialize new ACS (%lu)", newSerializedLength);
            sdr_cancel_xn(acsSdr);
            sdr_cancel_xn(bpSdr);
            return -1;
        }
    } else {
        if (signal.serializedZco != 0)
        {
            /* Free the old payload zco. */
            zco_destroy(bpSdr, signal.serializedZco);
        }
    }

    /* Store the new ZCO */
    signal.serializedZco = newSerializedZco;
    signal.serializedZcoLength = newSerializedLength;

    /* If there is not an ACS generation countdown timer, create one. */
    if(signal.acsDue == 0)
    {
        timelineEvent.type = csDue;
        if(custodian->acsDelay == 0) {
            timelineEvent.time = getUTCTime() + DEFAULT_ACS_DELAY;
        } else {
            timelineEvent.time = getUTCTime() + custodian->acsDelay;
        }
        timelineEvent.ref  = signalLElt;
        signal.acsDue = insertBpTimelineEvent(&timelineEvent);
        if (signal.acsDue == 0)
        {
            ACSLOG_ERROR("Can't add timeline event to generate ACS");
            sdr_cancel_xn(acsSdr);
            sdr_cancel_xn(bpSdr);
            return -1;
        }
    }
    sdr_poke(acsSdr, signalAddr, signal);
    if(sdr_end_xn(acsSdr) < 0)
    {
        ACSLOG_ERROR("Can't track ACS");
        sdr_cancel_xn(bpSdr);
        return -1;
    }
    if (sdr_end_xn(bpSdr) < 0)
    {
        ACSLOG_ERROR("Can't add timeline event to generate ACS");
        return -1;
    }
    return 0;
}
示例#22
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;
		}
	}
}
示例#23
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;
		}
	}
}
示例#24
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;
}
示例#25
0
文件: libbp.c 项目: b/ION
int	bp_send(BpSAP sap, int mode, char *destEid, char *reportToEid,
		int lifespan, int classOfService, BpCustodySwitch custodySwitch,
		unsigned char srrFlags, int ackRequested, BpExtendedCOS *ecos,
		Object adu, Object *bundleObj)
{
	Sdr		sdr = getIonsdr();
	BpVdb		*vdb = getBpVdb();
	BpExtendedCOS	defaultECOS = { 0, 0, 0 };
	int		aduOccupancy;
	MetaEid		*sourceMetaEid;
	Throttle	*throttle;

	CHKERR(bundleObj);
	*bundleObj = 0;
	CHKERR(adu);
	if (ecos == NULL)
	{
		ecos = &defaultECOS;
	}
	else
	{
		if (ecos->ordinal == 255)	/*	Reserved.	*/
		{
			ecos->ordinal = 254;
		}
	}

	if (sap)
	{
		sourceMetaEid = &(sap->endpointMetaEid);
	}
	else
	{
		sourceMetaEid = NULL;
	}

	/*	Admission control (bundle production throttling)
	 *	happens here.						*/

	throttle = &(vdb->productionThrottle);
	sdr_begin_xn(sdr);	/*	Just to lock memory.		*/
	aduOccupancy = zco_occupancy(sdr, adu);
	while (aduOccupancy > throttle->capacity)
	{
		sdr_exit_xn(sdr);
		if (mode == BP_NONBLOCKING)
		{
			errno = EWOULDBLOCK;
			return 0;
		}

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

		if (sm_SemEnded(throttle->semaphore))
		{
			putErrmsg("Bundle agent has been stopped.", NULL);
			return -1;
		}

		sdr_begin_xn(sdr);
	}

	sdr_exit_xn(sdr);	/*	Release memory.			*/

	/*	Now go ahead and send the bundle.			*/

	return bpSend(sourceMetaEid, destEid, reportToEid, lifespan,
			classOfService, custodySwitch, srrFlags, ackRequested,
			ecos, adu, bundleObj, 0);
}
示例#26
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;
}
示例#27
0
文件: libbp.c 项目: b/ION
int	bp_open(char *eidString, BpSAP *bpsapPtr)
{
	Sdr		sdr;
	MetaEid		metaEid;
	VScheme		*vscheme;
	PsmAddress	vschemeElt;
	Sap		sap;
	VEndpoint	*vpoint;
	PsmAddress	vpointElt;

	CHKERR(eidString && *eidString && bpsapPtr);
	*bpsapPtr = NULL;	/*	Default, in case of failure.	*/
	sdr = getIonsdr();
	sdr_begin_xn(sdr);	/*	Just to lock memory.		*/

	/*	First validate the endpoint ID.				*/

	if (parseEidString(eidString, &metaEid, &vscheme, &vschemeElt) == 0)
	{
		sdr_exit_xn(sdr);
		putErrmsg("Malformed EID.", eidString);
		return -1;
	}

	if (vschemeElt == 0)
	{
		sdr_exit_xn(sdr);
		putErrmsg("Scheme not known.", metaEid.schemeName);
		restoreEidString(&metaEid);
		return -1;
	}

	findEndpoint(NULL, metaEid.nss, vscheme, &vpoint, &vpointElt);
	if (vpointElt == 0)
	{
		sdr_exit_xn(sdr);
		putErrmsg("Endpoint not known.", metaEid.nss);
		restoreEidString(&metaEid);
		return -1;
	}

	/*	Endpoint exists; make sure it's not already opened
	 *	by some application.					*/

	if (vpoint->appPid > 0)	/*	Endpoint not closed.		*/
	{
		if (sm_TaskExists(vpoint->appPid))
		{
			sdr_exit_xn(sdr);
			if (vpoint->appPid == sm_TaskIdSelf())
			{
				return 0;
			}

			restoreEidString(&metaEid);
			putErrmsg("Endpoint is already open.",
					itoa(vpoint->appPid));
			return -1;
		}

		/*	Application terminated without closing the
		 *	endpoint, so simply close it now.		*/

		vpoint->appPid = -1;
	}

	/*	Construct the service access point.			*/

	sap.vpoint = vpoint;
	memcpy(&sap.endpointMetaEid, &metaEid, sizeof(MetaEid));
	sap.endpointMetaEid.colon = NULL;
	sap.endpointMetaEid.schemeName = MTAKE(metaEid.schemeNameLength + 1);
	if (sap.endpointMetaEid.schemeName == NULL)
	{
		sdr_exit_xn(sdr);
		putErrmsg("Can't create BpSAP.", NULL);
		restoreEidString(&metaEid);
		return -1;
	}

	sap.endpointMetaEid.nss = MTAKE(metaEid.nssLength + 1);
	if (sap.endpointMetaEid.nss == NULL)
	{
		sdr_exit_xn(sdr);
		MRELEASE(sap.endpointMetaEid.schemeName);
		putErrmsg("Can't create BpSAP.", NULL);
		restoreEidString(&metaEid);
		return -1;
	}

	*bpsapPtr = MTAKE(sizeof(Sap));
	if (*bpsapPtr == NULL)
	{
		sdr_exit_xn(sdr);
		MRELEASE(sap.endpointMetaEid.nss);
		MRELEASE(sap.endpointMetaEid.schemeName);
		putErrmsg("Can't create BpSAP.", NULL);
		restoreEidString(&metaEid);
		return -1;
	}

	istrcpy(sap.endpointMetaEid.schemeName, metaEid.schemeName,
			sizeof sap.endpointMetaEid.schemeName);
	istrcpy(sap.endpointMetaEid.nss, metaEid.nss,
			sizeof sap.endpointMetaEid.nss);
	restoreEidString(&metaEid);
	sap.recvSemaphore = vpoint->semaphore;
	memcpy((char *) *bpsapPtr, (char *) &sap, sizeof(Sap));

	/*	Having created the SAP, give its owner exclusive
	 *	access to the endpoint.					*/

	vpoint->appPid = sm_TaskIdSelf();
	sdr_exit_xn(sdr);	/*	Unlock memory.			*/
	return 0;
}
示例#28
0
文件: ion.c 项目: b/ION
int	ionAttach()
{
	Sdr		ionsdr = _ionsdr(NULL);
	Object		iondbObject = _iondbObject(NULL);
	PsmPartition	ionwm = _ionwm(NULL);
	IonVdb		*ionvdb = _ionvdb(NULL);
	char		*wdname;
	char		wdnamebuf[256];
	IonParms	parms;
	sm_WmParms	ionwmParms;
	char		*ionvdbName = _ionvdbName();

	if (ionsdr && iondbObject && ionwm && ionvdb)
	{
		return 0;	/*	Already attached.		*/
	}

	if (sdr_initialize(0, NULL, SM_NO_KEY, NULL) < 0)
	{
		putErrmsg("Can't initialize the SDR system.", NULL);
		return -1;
	}

	wdname = getenv("ION_NODE_WDNAME");
	if (wdname == NULL)
	{
		if (igetcwd(wdnamebuf, 256) == NULL)
		{
			putErrmsg("Can't get cwd name.", NULL);
			return -1;
		}

		wdname = wdnamebuf;
	}

	memset((char *) &parms, 0, sizeof parms);
	if (checkNodeListParms(&parms, wdname, 0) < 0)
	{
		putErrmsg("Failed checking node list parms.", NULL);
		return -1;
	}

	if (ionsdr == NULL)
	{
		ionsdr = sdr_start_using(parms.sdrName);
		if (ionsdr == NULL)
		{
			putErrmsg("Can't start using SDR for ION.", NULL);
			return -1;
		}

		oK(_ionsdr(&ionsdr));
	}

	if (iondbObject == 0)
	{
		sdr_begin_xn(ionsdr);	/*	Lock database.		*/
		iondbObject = sdr_find(ionsdr, _iondbName(), NULL);
		sdr_exit_xn(ionsdr);	/*	Unlock database.	*/
		if (iondbObject == 0)
		{
			putErrmsg("ION database not found.", NULL);
			return -1;
		}

		oK(_iondbObject(&iondbObject));
	}

	oK(_ionConstants());

	/*	Open ION shared-memory partition.			*/

	if (ionwm == NULL)
	{
		ionwmParms.wmKey = parms.wmKey;
		ionwmParms.wmSize = 0;
		ionwmParms.wmAddress = NULL;
		ionwmParms.wmName = ION_SM_NAME;
		ionwm = _ionwm(&ionwmParms);
		if (ionwm == NULL)
		{
			putErrmsg("Can't open access to ION memory.", NULL);
			return -1;
		}
	}

	if (ionvdb == NULL)
	{
		if (_ionvdb(&ionvdbName) == NULL)
		{
			putErrmsg("ION volatile database not found.", NULL);
			return -1;
		}
	}

	ionRedirectMemos();
	return 0;
}
示例#29
0
文件: ion.c 项目: b/ION
int	ionInitialize(IonParms *parms, unsigned long ownNodeNbr)
{
	char		wdname[256];
	Sdr		ionsdr;
	Object		iondbObject;
	IonDB		iondbBuf;
	sm_WmParms	ionwmParms;
	char		*ionvdbName = _ionvdbName();

	CHKERR(parms);
	CHKERR(ownNodeNbr);
	if (sdr_initialize(0, NULL, SM_NO_KEY, NULL) < 0)
	{
		putErrmsg("Can't initialize the SDR system.", NULL);
		return -1;
	}

	if (igetcwd(wdname, 256) == NULL)
	{
		putErrmsg("Can't get cwd name.", NULL);
		return -1;
	}

	if (checkNodeListParms(parms, wdname, ownNodeNbr) < 0)
	{
		putErrmsg("Failed checking node list parms.", NULL);
		return -1;
	}

	if (sdr_load_profile(parms->sdrName, parms->configFlags,
			parms->heapWords, parms->heapKey, parms->pathName) < 0)
	{
		putErrmsg("Unable to load SDR profile for ION.", NULL);
		return -1;
	}

	ionsdr = sdr_start_using(parms->sdrName);
	if (ionsdr == NULL)
	{
		putErrmsg("Can't start using SDR for ION.", NULL);
		return -1;
	}

	ionsdr = _ionsdr(&ionsdr);

	/*	Recover the ION database, creating it if necessary.	*/

	sdr_begin_xn(ionsdr);
	iondbObject = sdr_find(ionsdr, _iondbName(), NULL);
	switch (iondbObject)
	{
	case -1:		/*	SDR error.			*/
		sdr_cancel_xn(ionsdr);
		putErrmsg("Can't seek ION database in SDR.", NULL);
		return -1;

	case 0:			/*	Not found; must create new DB.	*/
		if (ownNodeNbr == 0)
		{
			sdr_cancel_xn(ionsdr);
			putErrmsg("Must supply non-zero node number.", NULL);
			return -1;
		}

		memset((char *) &iondbBuf, 0, sizeof(IonDB));
		memcpy(iondbBuf.workingDirectoryName, wdname, 256);
		iondbBuf.ownNodeNbr = ownNodeNbr;
		iondbBuf.occupancyCeiling = ((sdr_heap_size(ionsdr) / 100)
			 	* (100 - ION_SEQUESTERED));
		iondbBuf.receptionSpikeReserve = iondbBuf.occupancyCeiling / 16;
		if (iondbBuf.receptionSpikeReserve < MIN_SPIKE_RSRV)
		{
			iondbBuf.receptionSpikeReserve = MIN_SPIKE_RSRV;
		}

		iondbBuf.contacts = sdr_list_create(ionsdr);
		iondbBuf.ranges = sdr_list_create(ionsdr);
		iondbBuf.maxClockError = 0;
		iondbObject = sdr_malloc(ionsdr, sizeof(IonDB));
		if (iondbObject == 0)
		{
			sdr_cancel_xn(ionsdr);
			putErrmsg("No space for database.", NULL);
			return -1;
		}

		sdr_write(ionsdr, iondbObject, (char *) &iondbBuf,
				sizeof(IonDB));
		sdr_catlg(ionsdr, _iondbName(), 0, iondbObject);
		if (sdr_end_xn(ionsdr))
		{
			putErrmsg("Can't create ION database.", NULL);
			return -1;
		}

		break;

	default:		/*	Found DB in the SDR.		*/
		sdr_exit_xn(ionsdr);
	}

	oK(_iondbObject(&iondbObject));
	oK(_ionConstants());

	/*	Open ION shared-memory partition.			*/

	ionwmParms.wmKey = parms->wmKey;
	ionwmParms.wmSize = parms->wmSize;
	ionwmParms.wmAddress = parms->wmAddress;
	ionwmParms.wmName = ION_SM_NAME;
	if (_ionwm(&ionwmParms) == NULL)
	{
		putErrmsg("ION memory configuration failed.", NULL);
		return -1;
	}

	if (_ionvdb(&ionvdbName) == NULL)
	{
		putErrmsg("ION can't initialize vdb.", NULL);
		return -1;
	}

	ionRedirectMemos();
	return 0;
}
示例#30
0
文件: ion.c 项目: b/ION
static IonVdb	*_ionvdb(char **name)
{
	static IonVdb	*vdb = NULL;
	PsmAddress	vdbAddress;
	PsmAddress	elt;
	Sdr		sdr;
	PsmPartition	ionwm;

	if (name)
	{
		if (*name == NULL)	/*	Terminating.		*/
		{
			vdb = NULL;
			return vdb;
		}

		/*	Attaching to volatile database.			*/

		ionwm = _ionwm(NULL);
		if (psm_locate(ionwm, *name, &vdbAddress, &elt) < 0)
		{
			putErrmsg("Failed searching for vdb.", NULL);
			return vdb;
		}

		if (elt)
		{
			vdb = (IonVdb *) psp(ionwm, vdbAddress);
			return vdb;
		}

		/*	ION volatile database doesn't exist yet.	*/

		sdr = _ionsdr(NULL);
		sdr_begin_xn(sdr);	/*	Just to lock memory.	*/
		vdbAddress = psm_zalloc(ionwm, sizeof(IonVdb));
		if (vdbAddress == 0)
		{
			sdr_exit_xn(sdr);
			putErrmsg("No space for volatile database.", NULL);
			return NULL;
		}

		vdb = (IonVdb *) psp(ionwm, vdbAddress);
		memset((char *) vdb, 0, sizeof(IonVdb));
		if ((vdb->nodes = sm_list_create(ionwm)) == 0
		|| (vdb->neighbors = sm_list_create(ionwm)) == 0
		|| (vdb->probes = sm_list_create(ionwm)) == 0
		|| psm_catlg(ionwm, *name, vdbAddress) < 0)
		{
			sdr_exit_xn(sdr);
			putErrmsg("Can't initialize volatile database.", NULL);
			return NULL;
		}

		vdb->deltaFromUTC = (_ionConstants())->deltaFromUTC;
		sdr_exit_xn(sdr);	/*	Unlock memory.		*/
	}

	return vdb;
}