Example #1
0
// Complete receiving management command
void NiFreeAdminAccept(NAT *n)
{
	// Validate arguments
	if (n == NULL)
	{
		return;
	}

	n->Halt = true;
	Disconnect(n->AdminListenSock);
	Set(n->HaltEvent);

	while (true)
	{
		if (WaitThread(n->AdminAcceptThread, 1000) == false)
		{
			Disconnect(n->AdminListenSock);
		}
		else
		{
			break;
		}
	}
	ReleaseThread(n->AdminAcceptThread);

	ReleaseSock(n->AdminListenSock);
}
Example #2
0
// Release
void NullPaFree(SESSION *s)
{
	// Validate arguments
	NULL_LAN *n;
	BLOCK *b;
	if (s == NULL || (n = s->PacketAdapter->Param) == NULL)
	{
		return;
	}

	n->Halt = true;
	Set(n->Event);

	WaitThread(n->PacketGeneratorThread, INFINITE);
	ReleaseThread(n->PacketGeneratorThread);

	LockQueue(n->PacketQueue);
	{
		while (b = GetNext(n->PacketQueue))
		{
			FreeBlock(b);
		}
	}
	UnlockQueue(n->PacketQueue);

	ReleaseQueue(n->PacketQueue);

	ReleaseCancel(n->Cancel);

	ReleaseEvent(n->Event);

	s->PacketAdapter->Param = NULL;
	Free(n);
}
Example #3
0
// Stop the download thread
void ViDownloadThreadStop(VI_INSTALL_DLG *d)
{
	// Validate arguments
	if (d == NULL)
	{
		return;
	}

	if (d->DownloadStarted == false)
	{
		return;
	}

	d->DownloadStarted = false;
	d->Halt = true;

	while (true)
	{
		if (WaitThread(d->DownloadThread, 50))
		{
			break;
		}

		DoEvents(NULL);
	}

	ReleaseThread(d->DownloadThread);
}
Example #4
0
// Stop the Layer-3 switch
void L3SwStop(L3SW *s)
{
	THREAD *t = NULL;
	// Validate arguments
	if (s == NULL)
	{
		return;
	}

	Lock(s->lock);
	{
		if (s->Active == false)
		{
			Unlock(s->lock);
			return;
		}

		s->Halt = true;

		t = s->Thread;

		s->Active = false;
	}
	Unlock(s->lock);

	WaitThread(t, INFINITE);
	ReleaseThread(t);
}
Example #5
0
// Release of the Tick64
void FreeTick64()
{
	UINT i;
	if (tk64 == NULL)
	{
		// Uninitialized
		return;
	}

	// Termination process
	tk64->Halt = true;
	Set(halt_tick_event);
	WaitThread(tk64->Thread, INFINITE);
	ReleaseThread(tk64->Thread);

	// Releasing process
	for (i = 0;i < LIST_NUM(tk64->AdjustTime);i++)
	{
		ADJUST_TIME *t = LIST_DATA(tk64->AdjustTime, i);
		Free(t);
	}
	ReleaseList(tk64->AdjustTime);
	DeleteLock(tk64->TickLock);
	Free(tk64);
	tk64 = NULL;

	ReleaseEvent(halt_tick_event);
	halt_tick_event = NULL;
}
Example #6
0
int GMSynthDLL::Stop()
{
	SeqState wasRunning = seq.GetState();
	//if (wasRunning != seqOff)
		seq.Halt();
	WaitThread();
	seqMode = seqOff;
	return wasRunning != seqOff;
}
Example #7
0
// Release the SSTP server
void FreeSstpServer(SSTP_SERVER *s)
{
	// Validate arguments
	if (s == NULL)
	{
		return;
	}

	TubeDisconnect(s->TubeRecv);
	TubeDisconnect(s->TubeSend);

	WaitThread(s->PPPThread, INFINITE);
	ReleaseThread(s->PPPThread);

	while (true)
	{
		BLOCK *b = GetNext(s->RecvQueue);

		if (b == NULL)
		{
			break;
		}

		FreeBlock(b);
	}

	while (true)
	{
		BLOCK *b = GetNext(s->SendQueue);

		if (b == NULL)
		{
			break;
		}

		FreeBlock(b);
	}

	ReleaseQueue(s->RecvQueue);
	ReleaseQueue(s->SendQueue);

	ReleaseSockEvent(s->SockEvent);

	FreeInterruptManager(s->Interrupt);

	ReleaseCedar(s->Cedar);

	ReleaseTube(s->TubeSend);
	ReleaseTube(s->TubeRecv);

	Free(s);
}
Example #8
0
// Deadlock Detection
void CheckDeadLock(LOCK *lock, UINT timeout, char *name)
{
	DEADCHECK c;
	THREAD *t;
	char msg[MAX_PATH];

	if (lock == NULL)
	{
		return;
	}
	if (name == NULL)
	{
		name = "Unknown";
	}

	Format(msg, sizeof(msg), "error: CheckDeadLock() Failed: %s\n", name);

	Zero(&c, sizeof(c));
	c.Lock = lock;
	c.Timeout = timeout;
	c.Unlocked = false;

	t = NewThread(CheckDeadLockThread, &c);
	WaitThreadInit(t);
	if (WaitThread(t, timeout) == false)
	{
		if (c.Unlocked == false)
		{
			// Deadlock occured
			AbortExitEx(msg);
		}
		else
		{
			WaitThread(t, INFINITE);
		}
	}

	ReleaseThread(t);
}
Example #9
0
	void CXtzThreadPool::DestroyThreadPool( )
	{
		for ( unsigned int i = 0; i < m_threads.size(); ++i )
		{
			CXtzThread* thread = m_threads[i].get();
			if ( thread != nullptr )
			{
				thread->SetEnd( true );
			}
		}

		WaitThread( );
	}
Example #10
0
void Robot::wait(void) {
	WaitThread(THREAD_MAIN);
	WaitThread(THREAD_SENSE);
	WaitThread(THREAD_CONTROL);
	WaitThread(THREAD_SLAM);
	WaitThread(THREAD_CAMERA);
	WaitThread(THREAD_USER);
}
Example #11
0
// Release and stop the IPsec server
void FreeIPsecServer(IPSEC_SERVER *s)
{
	UINT i;
	IPSEC_SERVICES sl;
	// Validate arguments
	if (s == NULL)
	{
		return;
	}

	s->NoMoreChangeSettings = true;

	// Stopp the L2TP server
	StopL2TPServer(s->L2TP, false);

	// Stop the IKE server
	StopIKEServer(s->Ike);

	// Stop all the services explicitly
	Zero(&sl, sizeof(sl));
	IPsecServerSetServices(s, &sl);

	// Releasing process
	FreeUdpListener(s->UdpListener);

	ReleaseCedar(s->Cedar);

	FreeL2TPServer(s->L2TP);

	FreeIKEServer(s->Ike);

	for (i = 0;i < LIST_NUM(s->EtherIPIdList);i++)
	{
		ETHERIP_ID *k = LIST_DATA(s->EtherIPIdList, i);

		Free(k);
	}

	ReleaseList(s->EtherIPIdList);

	// Stop the OS monitoring thread
	s->Halt = true;
	Set(s->OsServiceCheckThreadEvent);
	WaitThread(s->OsServiceCheckThread, INFINITE);
	ReleaseThread(s->OsServiceCheckThread);
	ReleaseEvent(s->OsServiceCheckThreadEvent);

	DeleteLock(s->LockSettings);

	Free(s);
}
Example #12
0
// Release the UDP acceleration function
void FreeUdpAccel(UDP_ACCEL *a)
{
	// Validate arguments
	if (a == NULL)
	{
		return;
	}

	while (true)
	{
		BLOCK *b = GetNext(a->RecvBlockQueue);

		if (b == NULL)
		{
			break;
		}

		FreeBlock(b);
	}

	ReleaseQueue(a->RecvBlockQueue);

	ReleaseSock(a->UdpSock);

	if (a->IsInCedarPortList)
	{
		LockList(a->Cedar->UdpPortList);
		{
			DelInt(a->Cedar->UdpPortList, a->MyPort);
		}
		UnlockList(a->Cedar->UdpPortList);
	}

	// Release of NAT-T related
	a->NatT_Halt = true;
	Set(a->NatT_HaltEvent);

	if (a->NatT_GetIpThread != NULL)
	{
		WaitThread(a->NatT_GetIpThread, INFINITE);
		ReleaseThread(a->NatT_GetIpThread);
	}

	ReleaseEvent(a->NatT_HaltEvent);
	DeleteLock(a->NatT_Lock);

	ReleaseCedar(a->Cedar);

	Free(a);
}
Example #13
0
int main(int argc, char* argv[])
{
    tPvErr errCode;
	
	// initialize the PvAPI
	if((errCode = PvInitialize()) != ePvErrSuccess)
		printf("PvInitialize err: %u\n", errCode);
	else
	{
        //IMPORTANT: Initialize camera structure. See tPvFrame in PvApi.h for more info.
		memset(&GCamera,0,sizeof(tCamera));

        // set the CTRL-C handler
        SetConsoleCtrlHandler(&CtrlCHandler, TRUE);
        
		printf("Waiting for camera discovery...\n");

        // register camera plugged in callback
        if((errCode = PvLinkCallbackRegister(CameraEventCB,ePvLinkAdd,NULL)) != ePvErrSuccess)
			printf("PvLinkCallbackRegister err: %u\n", errCode);

        // register camera unplugged callback
        if((errCode = PvLinkCallbackRegister(CameraEventCB,ePvLinkRemove,NULL)) != ePvErrSuccess)
			printf("PvLinkCallbackRegister err: %u\n", errCode);
		
        // wait until ctrl+c break
		printf("Ctrl+C to break.\n");
		WaitForEver();
        
        CameraStop();
        CameraUnsetup();          
                
        // If thread spawned (see HandleCameraPlugged), wait to finish
        if(GCamera.ThHandle)
            WaitThread(); 
        
        if((errCode = PvLinkCallbackUnRegister(CameraEventCB,ePvLinkAdd)) != ePvErrSuccess)
			printf("PvLinkCallbackUnRegister err: %u\n", errCode);
        if((errCode = PvLinkCallbackUnRegister(CameraEventCB,ePvLinkRemove)) != ePvErrSuccess)
			printf("PvLinkCallbackUnRegister err: %u\n", errCode);       
               
        // uninitialize the API
        PvUnInitialize();
    }

	return 0;
}
Example #14
0
// Listener stop
void ElStopListener(EL *e)
{
	UINT i;
	THREAD **threads;
	SOCK **socks;
	UINT num_threads, num_socks;
	// Validate arguments
	if (e == NULL)
	{
		return;
	}

	StopAllListener(e->Cedar);

	LockList(e->AdminThreadList);
	{
		threads = ToArray(e->AdminThreadList);
		num_threads = LIST_NUM(e->AdminThreadList);
		DeleteAll(e->AdminThreadList);

		socks = ToArray(e->AdminSockList);
		num_socks = LIST_NUM(e->AdminSockList);
		DeleteAll(e->AdminSockList);
	}
	UnlockList(e->AdminThreadList);

	for (i = 0;i < num_socks;i++)
	{
		Disconnect(socks[i]);
		ReleaseSock(socks[i]);
	}

	for (i = 0;i < num_threads;i++)
	{
		WaitThread(threads[i], INFINITE);
		ReleaseThread(threads[i]);
	}

	Free(threads);
	Free(socks);

	ReleaseList(e->AdminSockList);
	ReleaseList(e->AdminThreadList);

	ReleaseListener(e->Listener);
}
Example #15
0
int main (int argc, char **argv) {
    int i;
    uint32_t id[10], ret;

    for (i = 0; i < 10; i++) {
        id[i] = CreateThread(thread_main, NULL);
        printf("created thread %d\n", id[i]);
        Delay(25);
    }

    for (i = 0; i < 10; i++) {
        printf("waiting for thread %d\n", id[i]);
        WaitThread(id[i], (void **) &ret);
        printf("thread %d return %d\n", id[i], ret);
    }

    return 0;
}
Example #16
0
// Stop the iptables tracking
void NsStopIpTablesTracking(NATIVE_STACK *a)
{
	if (a->IpTablesThread == NULL)
	{
		return;
	}

	a->IpTablesHalt = true;
	Set(a->IpTablesHaltEvent);

	WaitThread(a->IpTablesThread, INFINITE);

	ReleaseThread(a->IpTablesThread);
	ReleaseEvent(a->IpTablesHaltEvent);

	a->IpTablesThread = NULL;
	a->IpTablesHaltEvent = NULL;
	a->IpTablesInitOk = false;
	a->IpTablesHalt = false;
}
Example #17
0
// Release the stack
void FreeNativeStack(NATIVE_STACK *a)
{
	// Validate arguments
	if (a == NULL)
	{
		return;
	}

	if (a->Ipc != NULL && IsZero(&a->CurrentDhcpOptionList, sizeof(a->CurrentDhcpOptionList)) == false)
	{
		IP dhcp_server;

		UINTToIP(&dhcp_server, a->CurrentDhcpOptionList.ServerAddress);

		IPCDhcpFreeIP(a->Ipc, &dhcp_server);
		SleepThread(200);
	}

	a->Halt = true;
	Cancel(a->Cancel);
	Disconnect(a->Sock1);
	Disconnect(a->Sock2);

	WaitThread(a->MainThread, INFINITE);

	ReleaseThread(a->MainThread);

	CloseEth(a->Eth);
	FreeIPC(a->Ipc);

	NsStopIpTablesTracking(a);

	ReleaseCancel(a->Cancel);

	ReleaseSock(a->Sock1);
	ReleaseSock(a->Sock2);

	ReleaseCedar(a->Cedar);

	Free(a);
}
Example #18
0
// Free VPN Azure client
void FreeAzureClient(AZURE_CLIENT *ac)
{
	SOCK *disconnect_sock = NULL;
	// Validate arguments
	if (ac == NULL)
	{
		return;
	}

	ac->Halt = true;

	Lock(ac->Lock);
	{
		if (ac->CurrentSock != NULL)
		{
			disconnect_sock = ac->CurrentSock;

			AddRef(disconnect_sock->ref);
		}
	}
	Unlock(ac->Lock);

	if (disconnect_sock != NULL)
	{
		Disconnect(disconnect_sock);
		ReleaseSock(disconnect_sock);
	}

	Set(ac->Event);

	// Stop main thread
	WaitThread(ac->MainThread, INFINITE);
	ReleaseThread(ac->MainThread);

	ReleaseEvent(ac->Event);

	DeleteLock(ac->Lock);

	Free(ac);
}
Example #19
0
// Release of DDNS client
void FreeDDNSClient(DDNS_CLIENT *c)
{
	// Validate arguments
	if (c == NULL)
	{
		return;
	}

	// Stop the thread 
	c->Halt = true;
	Set(c->Event);

	WaitThread(c->Thread, INFINITE);
	ReleaseThread(c->Thread);

	ReleaseEvent(c->Event);

	ReleaseCedar(c->Cedar);
	DeleteLock(c->Lock);

	Free(c);
}
Example #20
0
// Delete the capture device
bool ElDeleteCaptureDevice(EL *e, char *name)
{
	bool ret = false;
	EL_DEVICE *d, t;
	// Validate arguments
	if (e == NULL || name == NULL)
	{
		return false;
	}

	LockList(e->DeviceList);
	{
		Zero(&t, sizeof(t));
		StrCpy(t.DeviceName, sizeof(t.DeviceName), name);

		d = Search(e->DeviceList, &t);

		if (d != NULL)
		{
			// Stop capture
			d->Halt = true;
			Cancel(d->Cancel1);

			// Wait for thread stop
			WaitThread(d->Thread, INFINITE);
			ReleaseThread(d->Thread);

			// Release the memory
			Delete(e->DeviceList, d);
			Free(d);

			ret = true;
		}
	}
	UnlockList(e->DeviceList);

	return ret;
}
Example #21
0
ResultCode AddressArbiter::ArbitrateAddress(SharedPtr<Thread> thread, ArbitrationType type,
                                            VAddr address, s32 value, u64 nanoseconds) {

    auto timeout_callback = [this](ThreadWakeupReason reason, SharedPtr<Thread> thread,
                                   SharedPtr<WaitObject> object) {
        ASSERT(reason == ThreadWakeupReason::Timeout);
        // Remove the newly-awakened thread from the Arbiter's waiting list.
        waiting_threads.erase(std::remove(waiting_threads.begin(), waiting_threads.end(), thread),
                              waiting_threads.end());
    };

    switch (type) {

    // Signal thread(s) waiting for arbitrate address...
    case ArbitrationType::Signal:
        // Negative value means resume all threads
        if (value < 0) {
            ResumeAllThreads(address);
        } else {
            // Resume first N threads
            for (int i = 0; i < value; i++)
                ResumeHighestPriorityThread(address);
        }
        break;

    // Wait current thread (acquire the arbiter)...
    case ArbitrationType::WaitIfLessThan:
        if ((s32)Memory::Read32(address) < value) {
            WaitThread(std::move(thread), address);
        }
        break;
    case ArbitrationType::WaitIfLessThanWithTimeout:
        if ((s32)Memory::Read32(address) < value) {
            thread->wakeup_callback = timeout_callback;
            thread->WakeAfterDelay(nanoseconds);
            WaitThread(std::move(thread), address);
        }
        break;
    case ArbitrationType::DecrementAndWaitIfLessThan: {
        s32 memory_value = Memory::Read32(address);
        if (memory_value < value) {
            // Only change the memory value if the thread should wait
            Memory::Write32(address, (s32)memory_value - 1);
            WaitThread(std::move(thread), address);
        }
        break;
    }
    case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: {
        s32 memory_value = Memory::Read32(address);
        if (memory_value < value) {
            // Only change the memory value if the thread should wait
            Memory::Write32(address, (s32)memory_value - 1);
            thread->wakeup_callback = timeout_callback;
            thread->WakeAfterDelay(nanoseconds);
            WaitThread(std::move(thread), address);
        }
        break;
    }

    default:
        LOG_ERROR(Kernel, "unknown type={}", static_cast<u32>(type));
        return ERR_INVALID_ENUM_VALUE_FND;
    }

    // The calls that use a timeout seem to always return a Timeout error even if they did not put
    // the thread to sleep
    if (type == ArbitrationType::WaitIfLessThanWithTimeout ||
        type == ArbitrationType::DecrementAndWaitIfLessThanWithTimeout) {

        return RESULT_TIMEOUT;
    }
    return RESULT_SUCCESS;
}
Example #22
0
// Close Ethernet adapter
void CloseEth(ETH *e)
{
	// Validate arguments
	if (e == NULL)
	{
		return;
	}

	if (e->Tap != NULL)
	{
#ifndef	NO_VLAN
		FreeTap(e->Tap);
#endif	// NO_VLAN
	}

#ifdef BRIDGE_PCAP
	{
		struct CAPTUREBLOCK *block;
		pcap_breakloop(e->Pcap);
		WaitThread(e->CaptureThread, INFINITE);
		ReleaseThread(e->CaptureThread);
		pcap_close(e->Pcap);
		while (block = GetNext(e->Queue)){
			Free(block->Buf);
			FreeCaptureBlock(block);
		}
		ReleaseQueue(e->Queue);
	}
#endif // BRIDGE_PCAP

#ifdef BRIDGE_BPF
#ifdef BRIDGE_BPF_THREAD
	{
		struct CAPTUREBLOCK *block;
		int fd = e->Socket;
		e->Socket = INVALID_SOCKET;
		WaitThread(e->CaptureThread, INFINITE);
		ReleaseThread(e->CaptureThread);
		e->Socket = fd; // restore to close after
		while (block = GetNext(e->Queue)){
			Free(block->Buf);
			FreeCaptureBlock(block);
		}
		ReleaseQueue(e->Queue);
	}
#else // BRIDGE_BPF_THREAD
	Free(e->Buffer);
#endif // BRIDGE_BPF_THREAD
#endif // BRIDGE_BPF

	ReleaseCancel(e->Cancel);
	Free(e->Name);
	Free(e->Title);

	// Restore MTU value
	EthSetMtu(e, 0);

	if (e->Socket != INVALID_SOCKET)
	{
#if defined(BRIDGE_BPF) || defined(BRIDGE_PCAP) || defined(UNIX_SOLARIS)
		close(e->Socket);
#else // BRIDGE_PCAP
		closesocket(e->Socket);
#endif // BRIDGE_PCAP
#if defined(BRIDGE_BPF) || defined(UNIX_SOLARIS)
		if (e->SocketBsdIf != INVALID_SOCKET)
		{
			close(e->SocketBsdIf);
		}
#endif	// BRIDGE_BPF || UNIX_SOLARIS
	}

	Free(e);
}
Example #23
0
// Shutdown the Listener
void StopListener(LISTENER *r)
{
	UINT port;
	SOCK *s = NULL;
	// Validate arguments
	if (r == NULL)
	{
		return;
	}

	Lock(r->lock);
	if (r->Halt)
	{
		Unlock(r->lock);
		return;
	}

	// Stop flag set
	r->Halt = true;

	if (r->Sock != NULL)
	{
		s = r->Sock;

		AddRef(s->ref);
	}

	Unlock(r->lock);

	port = r->Port;

	if (r->ShadowIPv6 == false && r->Protocol == LISTENER_TCP)
	{
		SLog(r->Cedar, "LS_LISTENER_STOP_1", port);
	}

	// Close the socket
	if (s != NULL)
	{
		Disconnect(s);
		ReleaseSock(s);
		s = NULL;
	}

	// Set the event
	Set(r->Event);

	// Wait for stopping the thread
	WaitThread(r->Thread, INFINITE);

	// Stop the shadow listener
	if (r->ShadowIPv6 == false)
	{
		if (r->ShadowListener != NULL)
		{
			StopListener(r->ShadowListener);

			ReleaseListener(r->ShadowListener);

			r->ShadowListener = NULL;
		}
	}

	if (r->ShadowIPv6 == false && r->Protocol == LISTENER_TCP)
	{
		SLog(r->Cedar, "LS_LISTENER_STOP_2", port);
	}
}
Example #24
0
// Polling process
void UdpAccelPoll(UDP_ACCEL *a)
{
	UCHAR *tmp = a->TmpBuf;
	IP nat_t_ip;
	UINT num_ignore_errors = 0;
	// Validate arguments
	if (a == NULL)
	{
		return;
	}

	Lock(a->NatT_Lock);
	{
		Copy(&nat_t_ip, &a->NatT_IP, sizeof(IP));
	}
	Unlock(a->NatT_Lock);

	if (IsZeroIp(&nat_t_ip) == false)
	{
		// Release the thread which gets the IP address of the NAT-T server because it is no longer needed
		if (a->NatT_GetIpThread != NULL)
		{
			WaitThread(a->NatT_GetIpThread, INFINITE);
			ReleaseThread(a->NatT_GetIpThread);
			a->NatT_GetIpThread = NULL;
		}
	}

	// Receive a new UDP packet
	while (true)
	{
		IP src_ip;
		UINT src_port;
		UINT ret;

		ret = RecvFrom(a->UdpSock, &src_ip, &src_port, tmp, UDP_ACCELERATION_TMP_BUF_SIZE);

		if (ret != 0 && ret != SOCK_LATER)
		{
			if (a->UseUdpIpQuery && a->UdpIpQueryPacketSize >= 8 && CmpIpAddr(&a->UdpIpQueryHost, &src_ip) == 0 &&
				src_port == a->UdpIpQueryPort)
			{
				// Receive a response of the query for IP and port number
				IP my_ip = {0};
				UINT myport = 0;
				BUF *b = MemToBuf(a->UdpIpQueryPacketData, a->UdpIpQueryPacketSize);


				FreeBuf(b);
			}
			else if (IsZeroIp(&nat_t_ip) == false && CmpIpAddr(&nat_t_ip, &src_ip) == 0 &&
				src_port == UDP_NAT_T_PORT)
			{
				// Receive a response from the NAT-T server
				IP my_ip;
				UINT myport;

				if (RUDPParseIPAndPortStr(tmp, ret, &my_ip, &myport))
				{
					if (myport >= 1 && myport <= 65535)
					{
						if (a->MyPortByNatTServer != myport)
						{
							a->MyPortByNatTServer = myport;
							a->MyPortByNatTServerChanged = true;
							a->CommToNatT_NumFail = 0;

							Debug("NAT-T: MyPort = %u\n", myport);
						}
					}
				}
/*
				BUF *b = NewBuf();
				PACK *p;

				WriteBuf(b, tmp, ret);
				SeekBufToBegin(b);

				p = BufToPack(b);
				if (p != NULL)
				{
					if (PackCmpStr(p, "opcode", "query_for_nat_traversal"))
					{
						if (PackGetBool(p, "ok"))
						{
							if (PackGetInt64(p, "tran_id") == a->NatT_TranId)
							{
								UINT myport = PackGetInt(p, "your_port");

								if (myport >= 1 && myport <= 65535)
								{
									if (a->MyPortByNatTServer != myport)
									{
										a->MyPortByNatTServer = myport;
										a->MyPortByNatTServerChanged = true;

										Debug("NAT-T: MyPort = %u\n", myport);
									}
								}
							}
						}
					}

					FreePack(p);
				}

				FreeBuf(b);*/
			}
			else
			{
				BLOCK *b = UdpAccelProcessRecvPacket(a, tmp, ret, &src_ip, src_port);

				//Debug("UDP Recv: %u %u %u\n", ret, (b == NULL ? 0 : b->Size), (b == NULL ? 0 : b->Compressed));

				/*if (b != NULL)
				{
					char tmp[MAX_SIZE * 10];
					BinToStr(tmp, sizeof(tmp), b->Buf, b->Size);
					Debug("Recv Pkt: %s\n", tmp);
				}*/

				if (b != NULL)
				{
					// Receive a packet
					InsertQueue(a->RecvBlockQueue, b);
				}
			}
		}
		else
		{
			if (ret == 0)
			{
				if (a->UdpSock->IgnoreRecvErr == false)
				{
					// Serious UDP reception error occurs
					a->FatalError = true;
					break;
				}

				if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
				{
					a->FatalError = true;
					break;
				}
			}
			else
			{
				// SOCK_LATER
				break;
			}
		}
	}

	// Send a Keep-Alive packet
	if (a->NextSendKeepAlive == 0 || (a->NextSendKeepAlive <= a->Now) || a->YourPortByNatTServerChanged)
	{
		a->YourPortByNatTServerChanged = false;

		if (UdpAccelIsSendReady(a, false))
		{
			UINT rand_interval;

			if (a->FastDetect == false)
			{
				rand_interval = rand() % (UDP_ACCELERATION_KEEPALIVE_INTERVAL_MAX - UDP_ACCELERATION_KEEPALIVE_INTERVAL_MIN) + UDP_ACCELERATION_KEEPALIVE_INTERVAL_MIN;
			}
			else
			{
				rand_interval = rand() % (UDP_ACCELERATION_KEEPALIVE_INTERVAL_MAX_FAST - UDP_ACCELERATION_KEEPALIVE_INTERVAL_MIN_FAST) + UDP_ACCELERATION_KEEPALIVE_INTERVAL_MIN_FAST;
			}

			a->NextSendKeepAlive = a->Now + (UINT64)rand_interval;

			//Debug("UDP KeepAlive\n");

			UdpAccelSend(a, NULL, 0, false, 1000, false);
		}
	}

	// Send a NAT-T request packet (Only if the connection by UDP has not be established yet)
	if (a->NoNatT == false)
	{
		// In the usual case
		if (IsZeroIp(&nat_t_ip) == false)
		{
			if (UdpAccelIsSendReady(a, true) == false)
			{
				if (a->NextPerformNatTTick == 0 || (a->NextPerformNatTTick <= a->Now))
				{
					UINT rand_interval;
					UCHAR c = 'B';

					a->CommToNatT_NumFail++;
					
					rand_interval = UDP_NAT_T_INTERVAL_INITIAL * MIN(a->CommToNatT_NumFail, UDP_NAT_T_INTERVAL_FAIL_MAX);
					//PACK *p = NewPack();
					//BUF *b;

					if (a->MyPortByNatTServer != 0)
					{
						rand_interval = GenRandInterval(UDP_NAT_T_INTERVAL_MIN, UDP_NAT_T_INTERVAL_MAX);
					}

					a->NextPerformNatTTick = a->Now + (UINT64)rand_interval;

					// Generate the request packet
					/*PackAddStr(p, "description", UDP_NAT_T_SIGNATURE);
					PackAddStr(p, "opcode", "query_for_nat_traversal");
					PackAddInt64(p, "tran_id", a->NatT_TranId);
					b = PackToBuf(p);
					FreePack(p);*/

					// Send the request packet
					SendTo(a->UdpSock, &nat_t_ip, UDP_NAT_T_PORT, &c, 1);

					//FreeBuf(b);
				}
			}
			else
			{
				a->NextPerformNatTTick = 0;
				a->CommToNatT_NumFail = 0;
			}
		}
	}
	else
	{
		// NAT_T is disabled, but there is a reference host (such as VGC)
		if (a->UseUdpIpQuery || a->UseSuperRelayQuery)
		{
		}
	}
}
Example #25
0
// Management port Listen thread
void NiListenThread(THREAD *thread, void *param)
{
	NAT *n = (NAT *)param;
	SOCK *a;
	UINT i;
	bool b = false;
	// Validate arguments
	if (thread == NULL || param == NULL)
	{
		return;
	}

	// Initialize the management list
	n->AdminList = NewList(NULL);

	while (true)
	{
		a = Listen(DEFAULT_NAT_ADMIN_PORT);
		if (b == false)
		{
			b = true;
			NoticeThreadInit(thread);
		}
		if (a != NULL)
		{
			break;
		}

		Wait(n->HaltEvent, NAT_ADMIN_PORT_LISTEN_INTERVAL);
		if (n->Halt)
		{
			return;
		}
	}

	n->AdminListenSock = a;
	AddRef(a->ref);

	// Waiting
	while (true)
	{
		SOCK *s = Accept(a);
		THREAD *t;
		NAT_ADMIN *admin;
		if (s == NULL)
		{
			break;
		}
		if (n->Halt)
		{
			ReleaseSock(s);
			break;
		}

		admin = ZeroMalloc(sizeof(NAT_ADMIN));
		admin->Nat = n;
		admin->Sock = s;
		t = NewThread(NiAdminThread, admin);
		WaitThreadInit(t);
		ReleaseThread(t);
	}

	// Disconnect all management connections
	LockList(n->AdminList);
	{
		for (i = 0;i < LIST_NUM(n->AdminList);i++)
		{
			NAT_ADMIN *a = LIST_DATA(n->AdminList, i);
			Disconnect(a->Sock);
			WaitThread(a->Thread, INFINITE);
			ReleaseThread(a->Thread);
			ReleaseSock(a->Sock);
			Free(a);
		}
	}
	UnlockList(n->AdminList);

	ReleaseList(n->AdminList);

	ReleaseSock(a);
}