Beispiel #1
0
Datei: pmqlsi.c Projekt: b/ION
static void	*handleMessages(void *parm)
{
	/*	Main loop for message reception and handling.		*/

	ReceiverThreadParms	*rtp = (ReceiverThreadParms *) parm;
	int			segLength;
	char			msgbuf[PMQLSA_MSGSIZE];
	unsigned int		mqp;	/*	Priority of rec'd msg.	*/

	iblock(SIGTERM);
	while (rtp->running)
	{	
		segLength = mq_receive(rtp->mq, msgbuf, sizeof msgbuf, &mqp);
		switch (segLength)
		{
		case 1:				/*	Normal stop.	*/
			continue;

		case -1:
			putSysErrmsg("pmqlsi failed receiving msg", NULL);
			pthread_kill(rtp->mainThread, SIGTERM);
			rtp->running = 0;
			continue;
		}

		if (ltpHandleInboundSegment(msgbuf, segLength) < 0)
		{
			putErrmsg("Can't handle inbound segment.", NULL);
			pthread_kill(rtp->mainThread, SIGTERM);
			rtp->running = 0;
			continue;
		}

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

		sm_TaskYield();
	}

	writeErrmsgMemos();
	writeMemo("[i] pmqlsi receiver thread has ended.");
	return NULL;
}
Beispiel #2
0
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;
}
Beispiel #3
0
static void	*receiveBundles(void *parm)
{
	/*	Main loop for bundle reception thread	*/

	ReceiveThreadParms	*parms = (ReceiveThreadParms *) parm;
	int			threadRunning = 1;
	AcqWorkArea		*work;
	char			*buffer;

	buffer = MTAKE(TCPCLA_BUFSZ);
	if (buffer == NULL)
	{
		putErrmsg("tcpclo receiver can't get TCP buffer", NULL);
		return NULL;
	}

	work = bpGetAcqArea(parms->vduct);
	if (work == NULL)
	{
		putErrmsg("tcpclo receiver can't get acquisition work area",
				NULL);
		MRELEASE(buffer);
		return NULL;
	}

	iblock(SIGTERM);
	while (threadRunning && *(parms->cloRunning))
	{
		if(*(parms->bundleSocket) < 0)
		{
			snooze(1);
			/*Retry later*/
			continue;
		}

		if (bpBeginAcq(work, 0, NULL) < 0)
		{
			putErrmsg("Can't begin acquisition of bundle.", NULL);
			threadRunning = 0;
			continue;
		}
	
		switch (receiveBundleByTcpCL(*(parms->bundleSocket), work,
					buffer))
		{
		case -1:
			putErrmsg("Can't acquire bundle.", NULL);
			pthread_mutex_lock(parms->mutex);
			closesocket(*(parms->bundleSocket));
			*(parms->bundleSocket) = -1;
			pthread_mutex_unlock(parms->mutex);
			continue;

		case 0:			/*	Shutdown message	*/	
			/*	Go back to the start of the while loop	*/
			pthread_mutex_lock(parms->mutex);
			closesocket(*(parms->bundleSocket));
			*(parms->bundleSocket) = -1;
			pthread_mutex_unlock(parms->mutex);			
			continue;

		default:
			break;			/*	Out of switch.	*/
		}

		if (bpEndAcq(work) < 0)
		{
			putErrmsg("Can't end acquisition of bundle.", NULL);
			threadRunning = 0;
		}

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

		sm_TaskYield();
	}

	/*	End of receiver thread; release resources.		*/

	bpReleaseAcqArea(work);
	MRELEASE(buffer);
	return NULL;
}
Beispiel #4
0
static void	*handleDatagrams(void *parm)
{
	/*	Main loop for UDP datagram reception and handling.	*/

	ReceiverThreadParms	*rtp = (ReceiverThreadParms *) parm;
	char			*procName = "udplsi";
	char			*buffer;
	int			segmentLength;
	struct sockaddr_in	fromAddr;
	socklen_t		fromSize;

	snooze(1);	/*	Let main thread become interruptable.	*/
	buffer = MTAKE(UDPLSA_BUFSZ);
	if (buffer == NULL)
	{
		putErrmsg("udplsi can't get UDP buffer.", NULL);
		ionKillMainThread(procName);
		return NULL;
	}

	/*	Can now start receiving bundles.  On failure, take
	 *	down the LSI.						*/

	while (rtp->running)
	{	
		fromSize = sizeof fromAddr;
		segmentLength = irecvfrom(rtp->linkSocket, buffer, UDPLSA_BUFSZ,
				0, (struct sockaddr *) &fromAddr, &fromSize);
		switch (segmentLength)
		{
		case -1:
			putSysErrmsg("Can't acquire segment", NULL);
			ionKillMainThread(procName);

			/*	Intentional fall-through to next case.	*/

		case 1:				/*	Normal stop.	*/
			rtp->running = 0;
			continue;
		}

		if (ltpHandleInboundSegment(buffer, segmentLength) < 0)
		{
			putErrmsg("Can't handle inbound segment.", NULL);
			ionKillMainThread(procName);
			rtp->running = 0;
			continue;
		}

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

		sm_TaskYield();
	}

	writeErrmsgMemos();
	writeMemo("[i] udplsi receiver thread has ended.");

	/*	Free resources.						*/

	MRELEASE(buffer);
	return NULL;
}
Beispiel #5
0
static void	*handleNotices(void *parm)
{
	/*	Main loop for LTP notice reception and handling.	*/

	Sdr			sdr = getIonsdr();
	ReceiverThreadParms	*rtp = (ReceiverThreadParms *) parm;
	char			*procName = "ltpcli";
	AcqWorkArea		*redWork;
	AcqWorkArea		*greenWork;
	LtpNoticeType		type;
	LtpSessionId		sessionId;
	unsigned char		reasonCode;
	unsigned char		endOfBlock;
	unsigned int		dataOffset;
	unsigned int		dataLength;
	Object			data;		/*	ZCO reference.	*/
	unsigned int		greenBuflen = 0;
	char			*greenBuffer = NULL;

	snooze(1);	/*	Let main thread become interruptable.	*/
	if (ltp_open(BpLtpClientId) < 0)
	{
		putErrmsg("ltpcli can't open client access.",
				itoa(BpLtpClientId));
		ionKillMainThread(procName);
		return NULL;
	}

	redWork = bpGetAcqArea(rtp->vduct);
	greenWork = bpGetAcqArea(rtp->vduct);
	if (redWork == NULL || greenWork == NULL)
	{
		ltp_close(BpLtpClientId);
		putErrmsg("ltpcli can't get acquisition work areas", NULL);
		ionKillMainThread(procName);
		return NULL;
	}

	/*	Can now start receiving notices.  On failure, take
	 *	down the CLI.						*/

	while (rtp->running)
	{
		if (ltp_get_notice(BpLtpClientId, &type, &sessionId,
				&reasonCode, &endOfBlock, &dataOffset,
				&dataLength, &data) < 0)
		{
			putErrmsg("Can't get LTP notice.", NULL);
			ionKillMainThread(procName);
			rtp->running = 0;
			continue;
		}

		switch (type)
		{
		case LtpExportSessionComplete:	/*	Xmit success.	*/
			if (data == 0)		/*	Ignore it.	*/
			{
				break;		/*	Out of switch.	*/
			}

			if (bpHandleXmitSuccess(data, 0) < 0)
			{
				putErrmsg("Crashed on xmit success.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
				break;		/*	Out of switch.	*/
			}

			CHKNULL(sdr_begin_xn(sdr));
			zco_destroy(sdr, data);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Crashed on data cleanup.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		case LtpExportSessionCanceled:	/*	Xmit failure.	*/
			if (data == 0)		/*	Ignore it.	*/
			{
				break;		/*	Out of switch.	*/
			}

			if (bpHandleXmitFailure(data) < 0)
			{
				putErrmsg("Crashed on xmit failure.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
				break;		/*	Out of switch.	*/
			}

			CHKNULL(sdr_begin_xn(sdr));
			zco_destroy(sdr, data);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Crashed on data cleanup.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		case LtpImportSessionCanceled:
			/*	None of the red data for the import
			 *	session (if any) have been received
			 *	yet, so nothing to discard.  In case
			 *	part or all of the import session was
			 *	green data, force deletion of retained
			 *	data.					*/

			sessionId.sourceEngineId = 0;
			sessionId.sessionNbr = 0;
			if (handleGreenSegment(greenWork, &sessionId,
					0, 0, 0, 0, NULL, NULL) < 0)
			{
				putErrmsg("Can't cancel green session.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		case LtpRecvRedPart:
			if (!endOfBlock)
			{
				/*	Block is partially red and
				 *	partially green.  Too risky
				 *	to wait for green EOB before
				 *	clearing the work area, so
				 *	just discard the data.		*/

				CHKNULL(sdr_begin_xn(sdr));
				zco_destroy(sdr, data);
				if (sdr_end_xn(sdr) < 0)
				{
					putErrmsg("Crashed: partially red.",
							NULL);
					ionKillMainThread(procName);
					rtp->running = 0;
				}

				break;		/*	Out of switch.	*/
			}

			if (acquireRedBundles(redWork, data,
					sessionId.sourceEngineId) < 0)
			{
				putErrmsg("Can't acquire bundle(s).", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		case LtpRecvGreenSegment:
			if (handleGreenSegment(greenWork, &sessionId,
					endOfBlock, dataOffset, dataLength,
					data, &greenBuflen, &greenBuffer) < 0)
			{
				putErrmsg("Can't handle green segment.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			/*	Discard the ZCO in any case.		*/

			CHKNULL(sdr_begin_xn(sdr));
			zco_destroy(sdr, data);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Crashed: green segment.", NULL);
				ionKillMainThread(procName);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		default:
			break;		/*	Out of switch.		*/
		}

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

		sm_TaskYield();
	}

	writeErrmsgMemos();
	writeMemo("[i] ltpcli receiver thread has ended.");

	/*	Free resources.						*/

	if (greenBuffer)
	{
		MRELEASE(greenBuffer);
	}

	bpReleaseAcqArea(greenWork);
	bpReleaseAcqArea(redWork);
	ltp_close(BpLtpClientId);
	return NULL;
}
Beispiel #6
0
int	dtn2fw(int a1, int a2, int a3, int a4, int a5,
		int a6, int a7, int a8, int a9, int a10)
{
#else
int	main(int argc, char *argv[])
{
#endif
	int		running = 1;
	Sdr		sdr;
	VScheme		*vscheme;
	PsmAddress	vschemeElt;
	Scheme		scheme;
	Object		elt;
	Object		bundleAddr;
	Bundle		bundle;

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

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

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

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

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

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

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

			continue;
		}

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

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

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

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

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

		sm_TaskYield();
	}

	writeErrmsgMemos();
	writeMemo("[i] dtn2fw forwarder has ended.");
	ionDetach();
	return 0;
}
Beispiel #7
0
static void	*receivePdus(void *parm)
{
    RxThreadParms	*parms = (RxThreadParms *) parm;
    char		ownEid[64];
    Sdr		sdr;
    BpDelivery	dlv;
    int		contentLength;
    ZcoReader	reader;
    unsigned char	*buffer;

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

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

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

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

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

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

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

            break;

        default:
            break;
        }

        bp_release_delivery(&dlv, 1);

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

        sm_TaskYield();
    }

    bp_close(parms->rxSap);
    MRELEASE(buffer);
    writeMemo("[i] bputa input has stopped.");
    return NULL;
}
Beispiel #8
0
static void	*sendBundles(void *parm)
{
	/*	Main loop for single bundle transmission thread
	 *	serving all BRS sockets.				*/

	SenderThreadParms	*parms = (SenderThreadParms *) parm;
	char			*procName = "brsscla";
	unsigned char		*buffer;
	Outduct			outduct;
	Sdr			sdr;
	Outflow			outflows[3];
	int			i;
	Object			bundleZco;
	BpExtendedCOS		extendedCOS;
	char			destDuctName[MAX_CL_DUCT_NAME_LEN + 1];
	unsigned int		bundleLength;
	int			ductNbr;
	int			bytesSent;
	Object			bundleAddr;
	Bundle			bundle;

	snooze(1);	/*	Let main thread become interruptable.	*/
	buffer = MTAKE(TCPCLA_BUFSZ);
	if (buffer == NULL)
	{
		putErrmsg("No memory for TCP buffer in brsscla.", NULL);
		ionKillMainThread(procName);
		return terminateSenderThread(parms);
	}

	sdr = getIonsdr();
	CHKNULL(sdr_begin_xn(sdr));
	sdr_read(sdr, (char *) &outduct, sdr_list_data(sdr,
			parms->vduct->outductElt), sizeof(Outduct));
	sdr_exit_xn(sdr);
	memset((char *) outflows, 0, sizeof outflows);
	outflows[0].outboundBundles = outduct.bulkQueue;
	outflows[1].outboundBundles = outduct.stdQueue;
	outflows[2].outboundBundles = outduct.urgentQueue;
	for (i = 0; i < 3; i++)
	{
		outflows[i].svcFactor = 1 << i;
	}

	/*	Can now begin transmitting to clients.			*/

	while (!(sm_SemEnded(parms->vduct->semaphore)))
	{
		if (bpDequeue(parms->vduct, outflows, &bundleZco,
				&extendedCOS, destDuctName, 0, -1) < 0)
		{
			break;
		}

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

		CHKNULL(sdr_begin_xn(sdr));
		bundleLength = zco_length(sdr, bundleZco);
		sdr_exit_xn(sdr);
		ductNbr = atoi(destDuctName);
		if (ductNbr >= parms->baseDuctNbr
		&& ductNbr <= parms->lastDuctNbr
		&& parms->brsSockets[(i = ductNbr - parms->baseDuctNbr)] != -1)
		{
			bytesSent = sendBundleByTCP(NULL, parms->brsSockets + i,
					bundleLength, bundleZco, buffer);

			/*	Note that TCP I/O errors never block
			 *	the brsscla induct's output functions;
			 *	those functions never connect to remote
			 *	sockets and never behave like a TCP
			 *	outduct, so the _tcpOutductId table is
			 *	never populated.			*/

			if (bytesSent < 0)
			{
				putErrmsg("Can't send bundle.", NULL);
				break;
			}
		}
		else	/*	Can't send it; try again later?		*/
		{
			bytesSent = 0;
		}

		if (bytesSent < bundleLength)
		{
			/*	Couldn't send the bundle, so put it
			 *	in limbo so we can try again later
			 *	-- except that if bundle has already
			 *	been destroyed then just lose the ADU.	*/

			CHKNULL(sdr_begin_xn(sdr));
			if (retrieveSerializedBundle(bundleZco, &bundleAddr))
			{
				putErrmsg("Can't locate unsent bundle.", NULL);
				sdr_cancel_xn(sdr);
				break;
			}

			if (bundleAddr == 0)
			{
				/*	Bundle not found, so we can't
				 *	put it in limbo for another
				 *	attempt later; discard the ADU.	*/

				zco_destroy(sdr, bundleZco);
			}
			else
			{
				sdr_stage(sdr, (char *) &bundle, bundleAddr,
						sizeof(Bundle));
				if (bundle.extendedCOS.flags
						& BP_MINIMUM_LATENCY)
				{
					/*	We never put critical
					 *	bundles into limbo.	*/

					zco_destroy(sdr, bundleZco);
				}
				else
				{
					if (enqueueToLimbo(&bundle, bundleAddr)
							< 0)
					{
						putErrmsg("Can't save bundle.",
								NULL);
						sdr_cancel_xn(sdr);
						break;
					}
				}
			}

			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Failed handling brss xmit.", NULL);
				break;
			}
		}

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

		sm_TaskYield();
	}

	ionKillMainThread(procName);
	writeMemo("[i] brsscla outduct has ended.");
	MRELEASE(buffer);
	return terminateSenderThread(parms);
}
Beispiel #9
0
Datei: stcpclo.c Projekt: b/ION
int	stcpclo(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;
	pthread_t		keepaliveThread;
	Object			bundleZco;
	BpExtendedCOS		extendedCOS;
	char			destDuctName[MAX_CL_DUCT_NAME_LEN + 1];
	unsigned int		bundleLength;
	int			ductSocket = -1;
	int			bytesSent;

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

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

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

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

	if (vduct->cloPid > 0 && 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();
	sdr_read(sdr, (char *) &duct, sdr_list_data(sdr, vduct->outductElt),
			sizeof(Outduct));
	sdr_read(sdr, (char *) &protocol, duct.protocol, sizeof(ClProtocol));
	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);

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

	oK(stcpcloSemaphore(&(vduct->semaphore)));
	isignal(SIGTERM, shutDownClo);
	isignal(SIGPIPE, handleConnectionLoss);

	/*	Start the keepalive thread for the eventual connection.	*/

	parms.cloRunning = &running;
	pthread_mutex_init(&mutex, NULL);
	parms.mutex = &mutex;
	parms.socketName = &socketName;
	parms.ductSocket = &ductSocket;
	if (pthread_create(&keepaliveThread, NULL, sendKeepalives, &parms))
	{
		putSysErrmsg("stcpclo can't create keepalive thread", NULL);
		MRELEASE(buffer);
		pthread_mutex_destroy(&mutex);
		return 1;
	}

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

	writeMemo("[i] stcpclo is running.");
	while (!(sm_SemEnded(stcpcloSemaphore(NULL))))
	{
		if (bpDequeue(vduct, outflows, &bundleZco, &extendedCOS,
				destDuctName) < 0)
		{
			sm_SemEnd(stcpcloSemaphore(NULL));/*	Stop.	*/
			continue;
		}

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

		bundleLength = zco_length(sdr, bundleZco);
		pthread_mutex_lock(&mutex);
		bytesSent = sendBundleByTCP(&socketName, &ductSocket,
				bundleLength, bundleZco, buffer);
		pthread_mutex_unlock(&mutex);
		if (bytesSent < bundleLength)
		{
			sm_SemEnd(stcpcloSemaphore(NULL));/*	Stop.	*/
			continue;
		}

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

		sm_TaskYield();
	}

	running = 0;			/*	Terminate keepalive.	*/
	pthread_join(keepaliveThread, NULL);
	if (ductSocket != -1)
	{
		close(ductSocket);
	}

	pthread_mutex_destroy(&mutex);
	writeErrmsgMemos();
	writeMemo("[i] stcpclo duct has ended.");
	MRELEASE(buffer);
	ionDetach();
	return 0;
}
Beispiel #10
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 #11
0
Datei: brsscla.c Projekt: b/ION
static void	*sendBundles(void *parm)
{
	/*	Main loop for single bundle transmission thread
	 *	serving all BRS sockets.				*/

	SenderThreadParms	*parms = (SenderThreadParms *) parm;
	unsigned char		*buffer;
	Outduct			outduct;
	Sdr			sdr;
	Outflow			outflows[3];
	int			i;
	Object			bundleZco;
	BpExtendedCOS		extendedCOS;
	char			destDuctName[MAX_CL_DUCT_NAME_LEN + 1];
	unsigned int		bundleLength;
	int			ductNbr;
	int			bytesSent;
	int			failedTransmissions = 0;

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

	sdr = getIonsdr();
	sdr_read(sdr, (char *) &outduct, sdr_list_data(sdr,
			parms->vduct->outductElt), sizeof(Outduct));
	memset((char *) outflows, 0, sizeof outflows);
	outflows[0].outboundBundles = outduct.bulkQueue;
	outflows[1].outboundBundles = outduct.stdQueue;
	outflows[2].outboundBundles = outduct.urgentQueue;
	for (i = 0; i < 3; i++)
	{
		outflows[i].svcFactor = 1 << i;
	}

	/*	Can now begin transmitting to clients.			*/

	iblock(SIGTERM);
	while (!(sm_SemEnded(parms->vduct->semaphore)))
	{
		if (bpDequeue(parms->vduct, outflows, &bundleZco,
				&extendedCOS, destDuctName) < 0)
		{
			break;
		}

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

		bundleLength = zco_length(sdr, bundleZco);
		ductNbr = atoi(destDuctName);
		if (ductNbr >= parms->baseDuctNbr
		&& ductNbr <= parms->lastDuctNbr
		&& parms->brsSockets[(i = ductNbr - parms->baseDuctNbr)] != -1)
		{
			bytesSent = sendBundleByTCP(NULL, parms->brsSockets + i,
					bundleLength, bundleZco, buffer);
			if (bytesSent < 0)
			{
				putErrmsg("Can't send bundle.", NULL);
				break;
			}

			if (bytesSent < bundleLength)
			{
				failedTransmissions++;
			}
		}
		else	/*	Can't send it; just discard it.		*/
		{
			sdr_begin_xn(sdr);
			zco_destroy_reference(sdr, bundleZco);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Can't destroy ZCO reference.", NULL);
				break;
			}
		}

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

		sm_TaskYield();
	}

	pthread_kill(brssclaMainThread(0), SIGTERM);
	writeMemoNote("[i] brsscla outduct has ended",
			itoa(failedTransmissions));
	MRELEASE(buffer);
	return terminateSenderThread(parms);
}
Beispiel #12
0
int	pmqlso(int a1, int a2, int a3, int a4, int a5,
		int a6, int a7, int a8, int a9, int a10)
{
	char		*mqName = (char *) a1;
	uvast		remoteEngineId = a2 != 0 ? strtouvast((char *) a2) : 0;
#else
int	main(int argc, char *argv[])
{
	char		*mqName = argc > 1 ? argv[1] : NULL;
	uvast		remoteEngineId = argc > 2 ? strtouvast(argv[2]) : 0;
#endif
	Sdr		sdr;
	LtpVspan	*vspan;
	PsmAddress	vspanElt;
	struct mq_attr	mqAttributes = { 0, PMQLSA_MAXMSG, PMQLSA_MSGSIZE, 0 };
	mqd_t		mq;
	int		running;
	int		segmentLength;
	char		*segment;

	if (remoteEngineId == 0 || mqName == NULL)
	{
		puts("Usage: pmqlso <message queue name> <remote engine ID>");
		return 0;
	}

	/*	Note that ltpadmin must be run before the first
	 *	invocation of ltplso, to initialize the LTP database
	 *	(as necessary) and dynamic database.			*/

	if (ltpInit(0) < 0)
	{
		putErrmsg("pmqlso can't initialize LTP.", NULL);
		return 1;
	}

	sdr = getIonsdr();
	CHKERR(sdr_begin_xn(sdr));	/*	Just to lock memory.	*/
	findSpan(remoteEngineId, &vspan, &vspanElt);
	if (vspanElt == 0)
	{
		sdr_exit_xn(sdr);
		putErrmsg("No such engine in database.", itoa(remoteEngineId));
		return 1;
	}

	if (vspan->lsoPid > 0 && vspan->lsoPid != sm_TaskIdSelf())
	{
		sdr_exit_xn(sdr);
		putErrmsg("LSO task is already started for this span.",
				itoa(vspan->lsoPid));
		return 1;
	}

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

	sdr_exit_xn(sdr);
	mq = mq_open(mqName, O_RDWR | O_CREAT, 0777, &mqAttributes);
	if (mq == (mqd_t) -1)
	{
		putSysErrmsg("pmqlso can't open message queue", mqName);
		return 1;
	}

	oK(_pmqlsoSemaphore(&vspan->segSemaphore));
	isignal(SIGTERM, interruptThread);

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

	writeMemo("[i] pmqlso is running.");
	running = 1;
	while (running && !(sm_SemEnded(_pmqlsoSemaphore(NULL))))
	{
		segmentLength = ltpDequeueOutboundSegment(vspan, &segment);
		if (segmentLength < 0)
		{
			running = 0;	/*	Terminate LSO.		*/
			continue;
		}

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

		if (segmentLength > PMQLSA_MSGSIZE)
		{
			putErrmsg("Segment is too big for PMQ LSO.",
					itoa(segmentLength));
			running = 0;	/*	Terminate LSO.		*/
			continue;
		}

		if (sendSegmentByPMQ(mq, segment, segmentLength) < 0)
		{
			putSysErrmsg("pmqlso failed sending segment", mqName);
			running = 0;	/*	Terminate LSO.	*/
			continue;
		}

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

		sm_TaskYield();
	}

	mq_close(mq);
	writeErrmsgMemos();
	writeMemo("[i] pmqlso duct has ended.");
	ionDetach();
	return 0;
}
Beispiel #13
0
int	bsspclo(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
	Sdr		sdr;
	VOutduct	*vduct;
	PsmAddress	vductElt;
	vast		destEngineNbr;
	Outduct		outduct;
	ClProtocol	protocol;
	Outflow		outflows[3];
	int		i;
	int		running = 1;
	Object		bundleZco;
	BpExtendedCOS	extendedCOS;
	char		destDuctName[MAX_CL_DUCT_NAME_LEN + 1];
	BsspSessionId	sessionId;
	unsigned char	*buffer;
	Lyst		streams;
	Bundle		bundleImage;
	char		*dictionary = 0;
	unsigned int	bundleLength;

	if (ductName == NULL)
	{
		PUTS("Usage: bsspclo [-]<destination engine number>");
		return 0;
	}

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

	sdr = getIonsdr();
	findOutduct("bssp", ductName, &vduct, &vductElt);
	if (vductElt == 0)
	{
		putErrmsg("No such bssp duct.", ductName);
		return -1;
	}

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

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

	buffer = (unsigned char *) MTAKE(BP_MAX_BLOCK_SIZE);
	if (buffer == NULL)
	{
		putErrmsg("Can't get buffer for decoding bundle ZCOs.", NULL);
		return -1;
	}

	streams = lyst_create_using(getIonMemoryMgr());
	if (streams == NULL)
	{
		putErrmsg("Can't create lyst of streams.", NULL);
		MRELEASE(buffer);
		return -1;
	}

	lyst_delete_set(streams, eraseStream, NULL);
	CHKERR(sdr_begin_xn(sdr));
	sdr_read(sdr, (char *) &outduct, sdr_list_data(sdr, vduct->outductElt),
			sizeof(Outduct));
	sdr_read(sdr, (char *) &protocol, outduct.protocol, sizeof(ClProtocol));
	sdr_exit_xn(sdr);
	destEngineNbr = strtovast(ductName);

	if (protocol.nominalRate == 0)
	{
		vduct->xmitThrottle.nominalRate = DEFAULT_BSSP_RATE;
	}
	else
	{
		vduct->xmitThrottle.nominalRate = protocol.nominalRate;
	}

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

	if (bssp_attach() < 0)
	{
		putErrmsg("bsspclo can't initialize BSSP.", NULL);
		lyst_destroy(streams);
		MRELEASE(buffer);
		return -1;
	}

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

	oK(bsspcloSemaphore(&(vduct->semaphore)));
	isignal(SIGTERM, shutDownClo);

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

	writeMemo("[i] bsspclo is running.");
	while (running && !(sm_SemEnded(bsspcloSemaphore(NULL))))
	{
		if (bpDequeue(vduct, outflows, &bundleZco, &extendedCOS,
				destDuctName, 0, -1) < 0)
		{
			running = 0;	/*	Terminate CLO.		*/
			continue;
		}

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

		if (decodeBundle(sdr, bundleZco, buffer, &bundleImage,
				&dictionary, &bundleLength) < 0)
		{
			putErrmsg("Can't decode bundle ZCO.", NULL);
			CHKERR(sdr_begin_xn(sdr));
			zco_destroy(sdr, bundleZco);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Failed destroying ZCO.", NULL);
				break;
			}

			continue;
		}

		switch (bssp_send(destEngineNbr, BpBsspClientId, bundleZco,
				isInOrder(streams, &bundleImage), &sessionId))
		{
		case 0:
			putErrmsg("Unable to send this bundle via BSSP.", NULL);
			break;

		case -1:
			putErrmsg("BsspSend failed.", NULL);
			running = 0;	/*	Terminate CLO.		*/
		}

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

		sm_TaskYield();

		/*	Note: bundleZco is destroyed later, when BSSP's
		 *	ExportSession is closed following transmission
		 *	of bundle ZCOs as aggregated into a block.	*/
	}

	writeErrmsgMemos();
	writeMemo("[i] bsspclo duct has ended.");
	lyst_destroy(streams);
	MRELEASE(buffer);
	ionDetach();
	return 0;
}
Beispiel #14
0
Datei: ltpcli.c Projekt: b/ION
static void	*handleNotices(void *parm)
{
	/*	Main loop for LTP notice reception and handling.	*/

	ReceiverThreadParms	*rtp = (ReceiverThreadParms *) parm;
	AcqWorkArea		*work;
	LtpNoticeType		type;
	LtpSessionId		sessionId;
	unsigned char		reasonCode;
	unsigned char		endOfBlock;
	unsigned long		dataOffset;
	unsigned long		dataLength;
	Object			data;		/*	ZCO reference.	*/
	Sdr			sdr;

	snooze(1);	/*	Let main thread become interruptable.	*/
	if (ltp_open(BpLtpClientId) < 0)
	{
		putErrmsg("ltpcli can't open client access.",
				itoa(BpLtpClientId));
		pthread_kill(rtp->mainThread, SIGTERM);
		return NULL;
	}

	work = bpGetAcqArea(rtp->vduct);
	if (work == NULL)
	{
		ltp_close(BpLtpClientId);
		putErrmsg("ltpcli can't get acquisition work area", NULL);
		pthread_kill(rtp->mainThread, SIGTERM);
		return NULL;
	}

	/*	Can now start receiving notices.  On failure, take
	 *	down the CLI.						*/

	while (rtp->running)
	{	
		if (ltp_get_notice(BpLtpClientId, &type, &sessionId,
				&reasonCode, &endOfBlock, &dataOffset,
				&dataLength, &data) < 0)
		{
			putErrmsg("Can't get LTP notice.", NULL);
			pthread_kill(rtp->mainThread, SIGTERM);
			rtp->running = 0;
			continue;
		}

		switch (type)
		{
		case LtpExportSessionCanceled:	/*	Xmit failure.	*/
			if (data == 0)		/*	Ignore it.	*/
			{
				break;		/*	Out of switch.	*/
			}

			if (bpHandleXmitFailure(data) < 0)
			{
				putErrmsg("Crashed on xmit failure.", NULL);
				pthread_kill(rtp->mainThread, SIGTERM);
				rtp->running = 0;
				break;		/*	Out of switch.	*/
			}

			sdr = getIonsdr();
			sdr_begin_xn(sdr);
			zco_destroy_reference(sdr, data);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Crashed on data cleanup.", NULL);
				pthread_kill(rtp->mainThread, SIGTERM);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		case LtpImportSessionCanceled:
			break;		/*	Out of switch.		*/

		case LtpRecvGreenSegment:
		case LtpRecvRedPart:
			if (acquireBundles(work, data,
					sessionId.sourceEngineId) < 0)
			{
				putErrmsg("Can't acquire bundle(s).", NULL);
				pthread_kill(rtp->mainThread, SIGTERM);
				rtp->running = 0;
			}

			break;		/*	Out of switch.		*/

		default:
			break;		/*	Out of switch.		*/
		}

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

		sm_TaskYield();
	}

	writeErrmsgMemos();
	writeMemo("[i] ltpcli receiver thread has ended.");

	/*	Free resources.						*/

	bpReleaseAcqArea(work);
	ltp_close(BpLtpClientId);
	return NULL;
}
Beispiel #15
0
Datei: udpclo.c Projekt: b/ION
int	udpclo(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
	unsigned char		*buffer;
	VOutduct		*vduct;
	PsmAddress		vductElt;
	Sdr			sdr;
	Outduct			outduct;
	ClProtocol		protocol;
	Outflow			outflows[3];
	int			i;
	char			*hostName;
	unsigned short		portNbr;
	unsigned int		hostNbr;
	struct sockaddr		socketName;
	struct sockaddr_in	*inetName;
	Object			bundleZco;
	BpExtendedCOS		extendedCOS;
	char			destDuctName[MAX_CL_DUCT_NAME_LEN + 1];
	unsigned int		bundleLength;
	int			ductSocket = -1;
	int			bytesSent;

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

	buffer = MTAKE(UDPCLA_BUFSZ);
	if (buffer == NULL)
	{
		putErrmsg("No memory for UDP buffer in udpclo.", NULL);
		return -1;
	}

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

	if (vduct->cloPid > 0 && 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();
	sdr_read(sdr, (char *) &outduct, sdr_list_data(sdr, vduct->outductElt),
			sizeof(Outduct));
	sdr_read(sdr, (char *) &protocol, outduct.protocol, sizeof(ClProtocol));
	if (protocol.nominalRate <= 0)
	{
		vduct->xmitThrottle.nominalRate = DEFAULT_UDP_RATE;
	}
	else
	{
		vduct->xmitThrottle.nominalRate = protocol.nominalRate;
	}

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

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

	oK(udpcloSemaphore(&(vduct->semaphore)));
	isignal(SIGTERM, shutDownClo);

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

	writeMemo("[i] udpclo is running.");
	while (!(sm_SemEnded(vduct->semaphore)))
	{
		if (bpDequeue(vduct, outflows, &bundleZco, &extendedCOS,
				destDuctName) < 0)
		{
			sm_SemEnd(udpcloSemaphore(NULL));/*	Stop.	*/
			continue;
		}

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

		hostName = destDuctName;
		parseSocketSpec(destDuctName, &portNbr, &hostNbr);
		if (portNbr == 0)
		{
			portNbr = BpUdpDefaultPortNbr;
		}

		portNbr = htons(portNbr);
		if (hostNbr == 0)
		{
			writeMemoNote("[?] Can't get IP address for host",
					hostName);
		}

		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);
		bundleLength = zco_length(sdr, bundleZco);
		bytesSent = sendBundleByUDP(&socketName, &ductSocket,
				bundleLength, bundleZco, buffer);
		if (bytesSent < bundleLength)
		{
			sm_SemEnd(udpcloSemaphore(NULL));/*	Stop.	*/
			continue;
		}

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

		sm_TaskYield();
	}

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

	writeErrmsgMemos();
	writeMemo("[i] udpclo duct has ended.");
	MRELEASE(buffer);
	ionDetach();
	return 0;
}