Пример #1
0
// Process the timer interrupt
void SstpProcessInterrupt(SSTP_SERVER *s)
{
	// Validate arguments
	if (s == NULL)
	{
		return;
	}

	s->Now = Tick64();

	s->FlushRecvTube = false;

	// Process the received packet
	while (true)
	{
		BLOCK *b = GetNext(s->RecvQueue);
		SSTP_PACKET *p;

		if (b == NULL)
		{
			break;
		}

		p = SstpParsePacket(b->Buf, b->Size);
		if (p == NULL)
		{
			// Disconnect the SSTP since a bad packet received
			SstpAbort(s);
		}
		else
		{
			// Process the received packet
			SstpProcessPacket(s, p);

			SstpFreePacket(p);
		}

		FreeBlock(b);
	}

	if (s->FlushRecvTube)
	{
		TubeFlush(s->TubeRecv);
	}

	// Transmit a packet that the PPP module is trying to send via the SSTP
	while (true)
	{
		TUBEDATA *d = TubeRecvAsync(s->TubeSend);
		SSTP_PACKET *p;
		if (d == NULL)
		{
			break;
		}

		p = SstpNewDataPacket(d->Data, d->DataSize);

		SstpSendPacket(s, p);

		SstpFreePacket(p);

		FreeTubeData(d);
	}

	if (s->Status == SSTP_SERVER_STATUS_ESTABLISHED)
	{
		if (s->Disconnecting == false && s->Aborting == false)
		{
			// Periodic transmission of Echo Request
			if (s->NextSendEchoRequestTick == 0 || s->NextSendEchoRequestTick <= s->Now)
			{
				UINT64 next_interval = (UINT64)(SSTP_ECHO_SEND_INTERVAL_MIN + Rand32() % (SSTP_ECHO_SEND_INTERVAL_MAX - SSTP_ECHO_SEND_INTERVAL_MIN));
				SSTP_PACKET *p;

				s->NextSendEchoRequestTick = s->Now + next_interval;
				AddInterrupt(s->Interrupt, s->NextSendEchoRequestTick);

				p = SstpNewControlPacket(SSTP_MSG_ECHO_REQUEST);

				SstpSendPacket(s, p);

				SstpFreePacket(p);
			}
		}
	}

	if ((s->LastRecvTick + (UINT64)SSTP_TIMEOUT) <= s->Now)
	{
		// Disconnect the SSTP because a timeout occurred
		SstpAbort(s);
		s->Disconnected = true;
	}

	if (IsTubeConnected(s->TubeRecv) == false || IsTubeConnected(s->TubeSend) == false)
	{
		// Disconnect the SSTP since the PPP module is disconnected
		SstpDisconnect(s);
	}

	if (s->Disconnecting)
	{
		// Normal disconnection process
		if (s->DisconnectSent == false)
		{
			// Send a Disconnect
			SSTP_PACKET *ret = SstpNewControlPacket(s->DisconnectRecved ? SSTP_MSG_CALL_DISCONNECT_ACK : SSTP_MSG_CALL_DISCONNECT);

			SstpSendPacket(s, ret);

			SstpFreePacket(ret);

			s->DisconnectSent = true;
		}
	}

	if (s->Aborting)
	{
		// Abnormal disconnection processing
		if (s->AbortSent == false)
		{
			// Send the Abort
			SSTP_PACKET *ret = SstpNewControlPacket(SSTP_MSG_CALL_ABORT);

			SstpSendPacket(s, ret);

			SstpFreePacket(ret);

			s->AbortSent = true;
		}
	}

	if (s->DisconnectSent && s->DisconnectRecved)
	{
		// Disconnect after exchanging the Disconnect each other
		s->Disconnected = true;
	}

	if (s->AbortSent && s->AbortReceived)
	{
		// Disconnect after exchanging the Abort each other
		s->Disconnected = true;
	}
}
Пример #2
0
// Stack main thread
void NsMainThread(THREAD *thread, void *param)
{
	NATIVE_STACK *a = (NATIVE_STACK *)param;
	// Validate arguments
	if (thread == NULL || param == NULL)
	{
		return;
	}

	while (true)
	{
		SOCKSET set;
		bool err = false;
		bool flush_tube;
		LIST *recv_packets;
		bool state_changed = false;

		InitSockSet(&set);
		AddSockSet(&set, a->Sock1);

		if (a->Halt)
		{
			break;
		}

		// Pass to the IPC by receiving from the bridge
LABEL_RESTART:
		state_changed = false;
		flush_tube = false;
		while (true)
		{
			void *data;
			UINT size;

			size = EthGetPacket(a->Eth, &data);

			if (size == INFINITE)
			{
				// Device error
				err = true;
				break;
			}
			else if (size == 0)
			{
				// Can not get any more
				break;
			}
			else
			{
				// Pass the IPC socket
				TubeSendEx(a->Sock1->SendTube, data, size, NULL, true);
				Free(data);
				flush_tube = true;
				state_changed = true;
			}
		}

		if (flush_tube)
		{
			TubeFlush(a->Sock1->SendTube);
		}

		// Pass to the bridge by receiving from IPC
		recv_packets = NULL;
		while (true)
		{
			TUBEDATA *d = TubeRecvAsync(a->Sock1->RecvTube);

			if (d == NULL)
			{
				break;
			}

			if (recv_packets == NULL)
			{
				recv_packets = NewListFast(NULL);
			}

			Add(recv_packets, d);

			state_changed = true;
		}
		if (recv_packets != NULL)
		{
			UINT i;
			UINT num = LIST_NUM(recv_packets);
			void **data_array;
			UINT *size_array;

			data_array = Malloc(sizeof(void *) * num);
			size_array = Malloc(sizeof(UINT) * num);

			for (i = 0;i < num;i++)
			{
				TUBEDATA *d = LIST_DATA(recv_packets, i);

				data_array[i] = d->Data;
				size_array[i] = d->DataSize;
			}

			EthPutPackets(a->Eth, num, data_array, size_array);

			for (i = 0;i < num;i++)
			{
				TUBEDATA *d = LIST_DATA(recv_packets, i);

				// Because the data buffer has been already released, not to release twice
				d->Data = NULL;

				FreeTubeData(d);
			}

			Free(data_array);
			Free(size_array);

			ReleaseList(recv_packets);
		}

		if (IsTubeConnected(a->Sock1->SendTube) == false || IsTubeConnected(a->Sock1->RecvTube) == false)
		{
			err = true;
		}

		if (err)
		{
			// An error has occured
			Debug("Native Stack: Error !\n");
			a->Halt = true;
			continue;
		}

		if (state_changed)
		{
			goto LABEL_RESTART;
		}

		Select(&set, 1234, a->Cancel, NULL);
	}

	Disconnect(a->Sock1);
	Disconnect(a->Sock2);
}
Пример #3
0
void FilterB(int Tlen_, char *B_, int Qlen_, const FilterParams &FP, int Diameter,
  bool Comp)
	{
	if (Comp)
		Quit("-diameter requires -fwdonly (this needs to be fixed!)");

	SeqQ = B_;
	Tlen = Tlen_;
	Qlen = Qlen_;

	MinMatch = FP.SeedLength;
	MaxError = FP.SeedDiffs;
	TubeOffset = FP.TubeOffset;

	const int Kmask = pow4(k) - 1;

// Ukonnen's Lemma
	MinKmersPerHit = MinMatch + 1 - k*(MaxError + 1);

// Maximum distance between SeqQ positions of two k-mers in a match
// (More stringent bounds may be possible, but not a big problem
// if two adjacent matches get merged).
	MaxKmerDist = MinMatch - k;

	TubeWidth = TubeOffset + MaxError;

	if (TubeOffset < MaxError)
		{
		Log("TubeOffset < MaxError\n");
		exit(1);
		}
	if (MinKmersPerHit <= 0)
		{
		Log("MinKmersPerHit <= 0\n");
		exit(1);
		}

	MaxActiveTubes = (Tlen + TubeWidth - 1)/TubeOffset + 1;
	Tubes = all(TubeState, MaxActiveTubes);
	zero(Tubes, TubeState, MaxActiveTubes);

// Ticker tracks cycling of circular list of active tubes.
	int Ticker = TubeWidth;

// Initialize index to cover first window
	int StartKmerValidPos = 0;
	int EndKmerValidPos = 0;

	AllocateIndex(Diameter, k);
	const int KmerCount = Diameter - k + 1;

	int Start;
	int End;

	for (Start = 0; Start < KmerCount; ++Start)
		{
		int StartKmer = GetKmer(SeqQ, Start);
		AddToIndex(StartKmer, Start);
		}

#if	DEBUG
	ValidateIndex(SeqQ, 0, Diameter - k);
#endif

// Scan entire sequence.
// Start is coordinate of first base in first k-mer in sliding window
// End is coordinate of first base in last k-mer in sliding window
	Start = 0;
	End = Start + Diameter - k;

	int StartKmer = GetKmer(SeqQ, Start);
	if (StartKmer == -1)
		{
		StartKmer = 0;
		StartKmerValidPos = Start + k + 1;
		}
	int EndKmer = GetKmer(SeqQ, End);
	if (EndKmer == -1)
		{
		EndKmer = 0;
		EndKmerValidPos = End + k + 1;
		}
	for (; End < Qlen - k; ++Start, ++End)
		{
#if	DEBUG
		if (Start%10000 == 0)
			fprintf(stderr, "%d\n", Start);
		//if (Start%1000 == 0)
		//	ValidateIndex(SeqQ, Start, End);
#endif
		if (Start >= StartKmerValidPos)
			{
			assert(StartKmer == GetKmer(SeqQ, Start));
			for (DeclareListPtr(p) = GetListPtr(StartKmer); NotEndOfList(p); p = GetListNext(p))
				{
				int HitPos = GetListPos(p);
				CommonKmer(Start, HitPos);
				}
			DeleteFirstInstanceFromIndex(StartKmer, Start);
			}

		if (0 == --Ticker)
			{
			TubeEnd(Start);
			Ticker = TubeOffset;
			}

		{
		char c = SeqQ[Start + k];
		int x = CharToLetter[c];
		if (x < 0)
			{
			StartKmer = 0;
			StartKmerValidPos = Start + k + 1;
			}
		else
			StartKmer = ((StartKmer << 2) | x) & Kmask;
		}

		{
		char c = SeqQ[End + k];
		int x = CharToLetter[c];
		if (x < 0)
			{
			EndKmer = 0;
			EndKmerValidPos = End + k + 1;
			}
		else
			EndKmer = ((EndKmer << 2) | x) & Kmask;

		if (End+1 >= EndKmerValidPos)
			{
			assert(EndKmer == GetKmer(SeqQ, End+1));
			AddToIndex(EndKmer, End+1);
			}
		}
		}

#if	DEBUG
	ValidateIndex(SeqQ, Start, Qlen - k);
#endif

// Special case for end of sequence, don't slide the index
// for the last Diameter bases.
	for (; Start < Qlen - k; ++Start)
		{
		{
		char c = SeqQ[Start + k];
		int x = CharToLetter[c];
		if (x < 0)
			{
			StartKmer = 0;
			StartKmerValidPos = Start + k + 1;
			}
		else
			StartKmer = ((StartKmer << 2) | x) & Kmask;
		}

		if (Start >= StartKmerValidPos)
			{
			for (DeclareListPtr(p) = GetListPtr(StartKmer); NotEndOfList(p); p = GetListNext(p))
				{
				int HitPos = GetListPos(p);
				CommonKmer(Start, HitPos);
				}
			}

		if (0 == --Ticker)
			{
			TubeEnd(Start);
			Ticker = TubeOffset;
			}
		}

	TubeEnd(Qlen - 1);

	int DiagFrom = CalcDiagIndex(Tlen - 1, Qlen - 1) - TubeWidth;
	int DiagTo = CalcDiagIndex(0, Qlen - 1) + TubeWidth;

	int TubeFrom = CalcTubeIndex(DiagFrom);
	if (TubeFrom < 0)
		TubeFrom = 0;

	int TubeTo = CalcTubeIndex(DiagTo);

	for (int TubeIndex = TubeFrom; TubeIndex <= TubeTo; ++TubeIndex)
		TubeFlush(TubeIndex);

	freemem(Tubes);
	}