// 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; } }
// 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); }
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); }