예제 #1
0
struct Blocks *InsertBlock(
                           NInt blockpos,
                           NInt num_tracks,
                           int num_lines,
                           const char *name
                           )
{
        R_ASSERT(is_playing()==false);

	struct Tracker_Windows *window=root->song->tracker_windows;
	struct WBlocks *wblock;

	struct Blocks *block;
          
        InsertBlock_IncBlockNums(blockpos);

        block=talloc(sizeof(struct Blocks));
          
        block->l.num=blockpos;
        NewBlock(block,num_tracks,num_lines,name);
        
        while(window!=NULL){
          wblock=talloc(sizeof(struct WBlocks));
          wblock->l.num=blockpos;
            
          NewWBlock(window,wblock,block);
            
          window=NextWindow(window);
        }

        return block;
}
예제 #2
0
// Send a SSTP packet
void SstpSendPacket(SSTP_SERVER *s, SSTP_PACKET *p)
{
	BUF *b;
	BLOCK *block;
	// Validate arguments
	if (s == NULL || p == NULL)
	{
		return;
	}

	if (p->IsControl)
	{
		Debug("SSTP Control Packet Send: Msg = %u, Num = %u\n", p->MessageType, LIST_NUM(p->AttibuteList));
	}
	else
	{
		//Debug("SSTP Data Packet Send: Size=%u\n", p->DataSize);
	}

	b = SstpBuildPacket(p);
	if (b == NULL)
	{
		return;
	}

	block = NewBlock(b->Buf, b->Size, 0);
	block->PriorityQoS = p->IsControl;
	Free(b);

	InsertQueue(s->SendQueue, block);
}
예제 #3
0
// Packet generation thread
void NullPacketGenerateThread(THREAD *t, void *param)
{
	NULL_LAN *n = (NULL_LAN *)param;
	// Validate arguments
	if (t == NULL || param == NULL)
	{
		return;
	}

	while (true)
	{
		Wait(n->Event, Rand32() % NULL_PACKET_GENERATE_INTERVAL);
		if (n->Halt)
		{
			break;
		}

		LockQueue(n->PacketQueue);
		{
			UCHAR *data;
			BLOCK *b;
			UINT size = Rand32() % 1500 + 14;
			data = Malloc(size);
			Copy(data, null_lan_broadcast_address, 6);
			Copy(data + 6, n->MacAddr, 6);
			b = NewBlock(data, size, 0);
			InsertQueue(n->PacketQueue, b);
		}
		UnlockQueue(n->PacketQueue);
		Cancel(n->Cancel);
	}
}
예제 #4
0
void World::Drop(Block * const block_from,
		const ushort x_to, const ushort y_to, const ushort z_to,
		const ushort src, const ushort dest, const ushort num)
{
	Block * block_to=GetBlock(x_to, y_to, z_to);
	if ( AIR==block_to->Sub() ) {
		SetBlock((block_to=NewBlock(PILE, DIFFERENT)),
			x_to, y_to, z_to);
	} else if ( WATER==block_to->Sub() ) {
		Block * const pile = NewBlock(PILE, DIFFERENT);
		SetBlock(pile, x_to, y_to, z_to);
		pile->HasInventory()->Get(block_to);
		block_to = pile;
	}
	Exchange(block_from, block_to, src, dest, num);
	emit Updated(x_to, y_to, z_to);
}
예제 #5
0
void World::Damage(const ushort x, const ushort y, const ushort z,
		const ushort dmg, const int dmg_kind)
{
	Block * temp = GetBlock(x, y, z);
	if ( temp==Normal(temp->Sub()) && AIR!=temp->Sub() ) {
		SetBlock((temp=NewBlock(temp->Kind(), temp->Sub())), x, y, z);
	}
	if ( temp->Damage(dmg, dmg_kind) > 0 ) {
		temp->ReceiveSignal(SOUND_STRINGS[1]); // "Ouch!"
		if ( block_manager.MakeId(BLOCK, STONE)==temp->GetId() &&
				temp->Durability()!=MAX_DURABILITY )
		{ // convert stone into ladder
			DeleteBlock(temp);
			SetBlock(NewBlock(LADDER, STONE), x, y, z);
			emit ReEnlighten(x, y, z);
		} else {
			SetBlock(ReplaceWithNormal(temp), x, y, z);
		}
	}
}
	void* MemoryArenaAllocator::Alloc(size_t size) {
		size_t rounded = Round(size);
		// If there isn't enough space on this block, we need to
		// allocate a new one.
		if (m_current_block_pos + rounded > m_block_size) {
			NewBlock(rounded);
			m_current_block_pos = 0;
		}
		void* r = m_current_block + m_current_block_pos;
		m_current_block_pos += rounded;
		return r;
	}
예제 #7
0
// Packet generation thread
void NullPacketGenerateThread(THREAD *t, void *param)
{
	NULL_LAN *n = (NULL_LAN *)param;
	UINT64 end_tick = Tick64() + (UINT64)(60 * 1000);
	UINT seq = 0;
	// Validate arguments
	if (t == NULL || param == NULL)
	{
		return;
	}

	while (true)
	{
		/*if (Tick64() >= end_tick)
		{
			break;
		}*/

		Wait(n->Event, Rand32() % 1500);
		if (n->Halt)
		{
			break;
		}

		LockQueue(n->PacketQueue);
		{
			UCHAR *data;
			BLOCK *b;
			UINT size = Rand32() % 1500 + 14;
			UCHAR dst_mac[6];

			NullGenerateMacAddress(n->MacAddr, n->Id, seq);

			//NullGenerateMacAddress(dst_mac, n->Id + 1, 0);
			//StrToMac(dst_mac, "00-1B-21-A9-47-E6");
			StrToMac(dst_mac, "00-AC-7A-EF-83-FD");

			data = Malloc(size);
			Copy(data, null_lan_broadcast_address, 6);
			//Copy(data, dst_mac, 6);
			Copy(data + 6, n->MacAddr, 6);
			b = NewBlock(data, size, 0);
			InsertQueue(n->PacketQueue, b);
		}
		UnlockQueue(n->PacketQueue);
		Cancel(n->Cancel);

		//seq++;
	}
}
예제 #8
0
bool World::Inscribe(const ushort x, const ushort y, const ushort z) {
	Block * block=GetBlock(x, y, z);
	if ( LIQUID==block->Kind() || AIR==block->Sub() ) {
		return false;
	}
	if ( block==Normal(block->Sub()) ) {
		SetBlock(block=NewBlock(block->Kind(), block->Sub()), x, y, z);
	}
	QString str=tr("No note received.");
	emit GetString(str);
	if ( block->Inscribe(str) ) {
		return true;
	} else {
		SetBlock(ReplaceWithNormal(block), x, y, z);
		return false;
	}
}
예제 #9
0
T * CTMemory<T>::Allocate(void) {     

    m_IrlMutex.StartReading();
    // find a block of the right size with at least one free element
    // _L_DEBUG(1, cout << "CTMemory :: looking up a block of " << sizeof(T) << endl);
    bool bNewBlock = true;  
    int nAcquiredBit = -1;
    CIterator Iterator;
    CABlock<T>  * CurrentBlock = (CABlock<T>  *) m_vBlocks.GetLast(Iterator);
    while (CurrentBlock) {
        nAcquiredBit = CurrentBlock->AcquireFree();
        if (nAcquiredBit != -1) {
            bNewBlock = false;
            break;
        }
		CurrentBlock = (CABlock<T>  *) m_vBlocks.GetPrev(Iterator);
    }
    m_IrlMutex.StopReading();    
	
    if (bNewBlock) {    
        // add a new clean one
        // _L_DEBUG(1, cout << "CTMemory :: adding a block of " << sizeof(T) << endl);
        CABlock<T>  NewBlock(sizeof(T));
        m_IrlMutex.StartWriting();
        m_vBlocks += NewBlock;
        CurrentBlock = (CABlock<T>  *) m_vBlocks.GetLast(Iterator);
		
        CurrentBlock->Initialize(m_PageSize);
		
        nAcquiredBit = CurrentBlock->AcquireFree();
        // assert(nAcquiredBit != -1);
        m_IrlMutex.StopWriting();
        // printf("CTMemory :: new file size: %ld bytes.\n", m_TailOffset);
    }
	
    // add a new element to the block
    T * pMem = CurrentBlock->Allocate(nAcquiredBit);    
    // assert(pMem);
    
    // _L_DEBUG(1, cout << "CTMemory :: allocated pointer: " << (long) pMem << endl);
    
    // printf("[+%d]", CurrentBlock->m_nElSize);
    return pMem;
}
예제 #10
0
파일: Link.c 프로젝트: falcon8823/utvpn
// 受信したパケットを書き込み
bool LinkPaPutPacket(SESSION *s, void *data, UINT size)
{
	LINK *k;
	BLOCK *block;
	SESSION *server_session;
	CONNECTION *server_connection;
	// 引数チェック
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return false;
	}

	server_session = k->ServerSession;
	server_connection = server_session->Connection;

	// ここにはリンク接続先の HUB から届いたパケットが来るので
	// サーバーセッションの ReceivedBlocks に届けてあげる
	if (data != NULL)
	{
		block = NewBlock(data, size, 0);

		LockQueue(server_connection->ReceivedBlocks);
		{
			InsertQueue(server_connection->ReceivedBlocks, block);
		}
		UnlockQueue(server_connection->ReceivedBlocks);
	}
	else
	{
		// data == NULL のとき、すべてのパケットを格納し終わったので
		// Cancel を発行する
		Cancel(server_session->Cancel1);

		if (k->Hub != NULL && k->Hub->Option != NULL && k->Hub->Option->YieldAfterStorePacket)
		{
			YieldCpu();
		}
	}

	return true;
}
예제 #11
0
// Write the received packet
bool LinkPaPutPacket(SESSION *s, void *data, UINT size)
{
	LINK *k;
	BLOCK *block;
	SESSION *server_session;
	CONNECTION *server_connection;
	// Validate arguments
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return false;
	}

	server_session = k->ServerSession;
	server_connection = server_session->Connection;

	// Since the packet arrives from the HUB of the link destination,
	// deliver it to the ReceivedBlocks of the server session
	if (data != NULL)
	{
		block = NewBlock(data, size, 0);

		LockQueue(server_connection->ReceivedBlocks);
		{
			InsertQueue(server_connection->ReceivedBlocks, block);
		}
		UnlockQueue(server_connection->ReceivedBlocks);
	}
	else
	{
		// Issue the Cancel, since finished store all packets when the data == NULL
		Cancel(server_session->Cancel1);

		if (k->Hub != NULL && k->Hub->Option != NULL && k->Hub->Option->YieldAfterStorePacket)
		{
			YieldCpu();
		}
	}

	return true;
}
예제 #12
0
 void Interpreter::Interpret(ILineReader & reader, bool showResult)
 {
     Ref<Expr> expr = Parse(reader);
     
     // Bail if we failed to parse.
     if (expr.IsNull()) return;
     
     // Create a starting fiber for the expression.
     Ref<Block> block = Compiler::CompileTopLevel(*this, *expr);
     Value blockObj = NewBlock(block, mNil);
     Value fiber = NewFiber(blockObj);
     
     // Run the interpreter.
     Value result = fiber.AsFiber()->GetFiber().Execute();
     
     if (showResult)
     {
         std::stringstream text;
         text << result << std::endl;
         mHost.Output(String(text.str().c_str()));
     }
 }
예제 #13
0
void World::DestroyAndReplace(const ushort x, const ushort y, const ushort z) {
	Block * const temp = GetBlock(x, y, z);
	if ( temp->Durability() > 0 ) {
		return;
	}
	Block * const dropped = temp->DropAfterDamage();
	Shred * const shred = GetShred(x, y);
	const ushort x_in_shred = Shred::CoordInShred(x);
	const ushort y_in_shred = Shred::CoordInShred(y);
	if ( PILE!=temp->Kind() && (temp->HasInventory() || dropped) ) {
		Block * const new_pile=( ( dropped && PILE==dropped->Kind() ) ?
			dropped : NewBlock(PILE, DIFFERENT) );
		shred->SetBlock(new_pile, x_in_shred, y_in_shred, z);
		Inventory * const inv = temp->HasInventory();
		Inventory * const new_pile_inv = new_pile->HasInventory();
		if ( inv ) {
			new_pile_inv->GetAll(inv);
		}
		if ( dropped && PILE!=dropped->Kind() &&
				!new_pile_inv->Get(dropped) )
		{
			DeleteBlock(dropped);
		}
		shred->AddFalling(x_in_shred, y_in_shred, z);
	} else {
		PutBlock(Normal(AIR), x, y, z);
	}
	const int old_transparency = temp->Transparent();
	const uchar old_light = temp->LightRadius();
	DeleteBlock(temp);
	shred->AddFalling(x_in_shred, y_in_shred, z+1);
	if ( old_transparency != INVISIBLE ) {
		ReEnlightenBlockRemove(x, y, z);
	}
	if ( old_light ) {
		RemoveFireLight(x, y, z);
	}
} // void World::DestroyAndReplace(ushort x, y, z)
예제 #14
0
// Write the received packet
bool LinkPaPutPacket(SESSION *s, void *data, UINT size)
{
	LINK *k;
	BLOCK *block = NULL;
	SESSION *server_session;
	CONNECTION *server_connection;
	bool ret = true;
	bool halting = false;
	// Validate arguments
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return false;
	}

	halting = (k->Halting || (*k->StopAllLinkFlag));

	server_session = k->ServerSession;
	server_connection = server_session->Connection;

	k->Flag1++;
	if ((k->Flag1 % 32) == 0)
	{
		// Ommit for performance
		UINT current_num;
		int diff;

		current_num = GetQueueNum(server_connection->ReceivedBlocks);

		diff = (int)current_num - (int)k->LastServerConnectionReceivedBlocksNum;

		k->LastServerConnectionReceivedBlocksNum = current_num;

		CedarAddQueueBudget(k->Cedar, diff);
	}

	// Since the packet arrives from the HUB of the link destination,
	// deliver it to the ReceivedBlocks of the server session
	if (data != NULL)
	{
		if (halting == false)
		{
			block = NewBlock(data, size, 0);
		}

		if (k->LockFlag == false)
		{
			UINT current_num;
			int diff;

			k->LockFlag = true;
			LockQueue(server_connection->ReceivedBlocks);

			current_num = GetQueueNum(server_connection->ReceivedBlocks);

			diff = (int)current_num - (int)k->LastServerConnectionReceivedBlocksNum;

			k->LastServerConnectionReceivedBlocksNum = current_num;

			CedarAddQueueBudget(k->Cedar, diff);
		}

		if (halting == false)
		{
			if (CedarGetFifoBudgetBalance(k->Cedar) == 0)
			{
				FreeBlock(block);
			}
			else
			{
				InsertReveicedBlockToQueue(server_connection, block, true);
			}
		}
	}
	else
	{
		UINT current_num;
		int diff;

		current_num = GetQueueNum(server_connection->ReceivedBlocks);

		diff = (int)current_num - (int)k->LastServerConnectionReceivedBlocksNum;

		k->LastServerConnectionReceivedBlocksNum = current_num;

		CedarAddQueueBudget(k->Cedar, diff);

		if (k->LockFlag)
		{
			k->LockFlag = false;
			UnlockQueue(server_connection->ReceivedBlocks);
		}

		// Issue the Cancel, since finished store all packets when the data == NULL
		Cancel(server_session->Cancel1);

		if (k->Hub != NULL && k->Hub->Option != NULL && k->Hub->Option->YieldAfterStorePacket)
		{
			YieldCpu();
		}
	}

	if (halting)
	{
		ret = false;
	}

	return ret;
}
예제 #15
0
// Read next packet
UINT EthGetPacket(ETH *e, void **data)
{
	BLOCK *b;
	bool flag = false;
	// Validate arguments
	if (e == NULL || data == NULL)
	{
		return INFINITE;
	}
	if (e->HasFatalError)
	{
		return INFINITE;
	}

	if (e->SuAdapter != NULL)
	{
		// Read packet with SeLow
		UINT size;
		if (SuGetNextPacket(e->SuAdapter, data, &size) == false)
		{
			// Error occurred
			e->HasFatalError = true;
			return INFINITE;
		}

		return size;
	}

RETRY:
	// Check the presence of the packet in queue
	b = GetNext(e->PacketQueue);
	if (b != NULL)
	{
		UINT size;
		size = b->Size;
		*data = b->Buf;
		Free(b);

		if (e->PacketQueue->num_item == 0)
		{
			e->Empty = true;
		}

		return size;
	}

	if (e->Empty)
	{
		e->Empty = false;
		return 0;
	}

	if (flag == false)
	{
		// Try to get next packet
		PROBE_STR("EthGetPacket: PacketInitPacket");
		wp->PacketInitPacket(e->Packet, e->Buffer, e->BufferSize);
		PROBE_STR("EthGetPacket: PacketReceivePacket");
		if (wp->PacketReceivePacket(e->Adapter, e->Packet, false) == false)
		{
			// Failed
			return INFINITE;
		}
		else
		{
			UCHAR *buf;
			UINT total;
			UINT offset;

			buf = (UCHAR *)e->Packet->Buffer;
			total = e->Packet->ulBytesReceived;
			offset = 0;

			while (offset < total)
			{
				struct bpf_hdr *header;
				UINT packet_size;
				UCHAR *packet_data;

				header = (struct bpf_hdr *)(buf + offset);
				packet_size = header->bh_caplen;
				offset += header->bh_hdrlen;
				packet_data = buf + offset;
				offset = Packet_WORDALIGN(offset + packet_size);

				if (packet_size >= 14)
				{
					UCHAR *tmp;
					BLOCK *b;

					PROBE_DATA2("EthGetPacket: NewBlock", packet_data, packet_size);
					
					tmp = MallocFast(packet_size);

					Copy(tmp, packet_data, packet_size);
					b = NewBlock(tmp, packet_size, 0);
					InsertQueue(e->PacketQueue, b);
				}
			}

			flag = true;
			goto RETRY;
		}
	}

	// No more packet
	return 0;
}
예제 #16
0
void * CVMemory::VAllocate(size_t DesiredBytes) { 
    // make Bytes a multiple of 32 nomatter what in order not to have too much fragmentation
    size_t Bytes = 8;
    while (Bytes < DesiredBytes)
        Bytes <<= 1;
    
    m_IrlMutex.StartReading();
    // find a block of the right size with at least one free element
    // _L_DEBUG(1, cout << "CVMemory :: looking up a block of " << Bytes << endl);
    bool bNewBlock = true;  
    int nAcquiredBit = -1;

    // look inside the pool of cached blocks for each multiple of 32 bytes
    short int nCachedIndex = (Bytes / 32) % V_MAX_CACHE;

    CIterator Iterator;
    CABlock<char> * CurrentBlock = m_CacheBlocks[nCachedIndex];

    if ((CurrentBlock) &&
        (((CTBlock<char> *) CurrentBlock)->GetElSize() == Bytes) &&
        ((nAcquiredBit = ((CTBlock<char> *) CurrentBlock)->AcquireFree()) != -1)) {
            bNewBlock = false;
    } else if (Bytes <= (unsigned long) m_LastMultiple) {        
        CurrentBlock = (CABlock<char> *) m_vBlocks.GetLast(Iterator);
        while (CurrentBlock) {
            if (((CTBlock<char> *) CurrentBlock)->GetElSize() == Bytes) {
                nAcquiredBit = ((CTBlock<char> *) CurrentBlock)->AcquireFree();
                if (nAcquiredBit != -1) {
                    bNewBlock = false;
                    break;
                }
            }
            CurrentBlock = (CABlock<char> *) m_vBlocks.GetPrev(Iterator);
        }
    } else {
       m_LastMultiple = Bytes;       
    }
    m_IrlMutex.StopReading();    

    
    // find a multiple of page size - this is the block that we will in fact allocate
    size_t MappedRegionSize = m_PageSize;
    while ((Bytes > MappedRegionSize) || (MappedRegionSize < 64 * KBYTE))
        MappedRegionSize <<= 1;
        
    if (bNewBlock) {    
        // add a new clean one
        // _L_DEBUG(1, cout << "CVMemory :: adding a block of " << Bytes << endl);
        CABlock<char> NewBlock(Bytes);
        m_IrlMutex.StartWriting();
        m_vBlocks += NewBlock;    
        CurrentBlock = (CABlock<char> *) m_vBlocks.GetLast(Iterator);
        
        ((CABlock<char> *) CurrentBlock)->Initialize(MappedRegionSize);
        
        nAcquiredBit = ((CTBlock<char> *) CurrentBlock)->AcquireFree();
        // assert(nAcquiredBit != -1);
        m_IrlMutex.StopWriting();
        // printf("CVMemory :: new file size: %ld bytes.\n", m_TailOffset);
    }

    m_IrlMutex.StartWriting();
    m_CacheBlocks[nCachedIndex] = CurrentBlock;
    m_IrlMutex.StopWriting();
    
    // add a new element to the block
    void * pMem = (void *) ((CTBlock<char> *) CurrentBlock)->Allocate(nAcquiredBit);  
    
    // assert(pMem);
    
    // _L_DEBUG(1, cout << "CVMemory :: allocated pointer: " << (long) pMem << endl);
    
    // printf("[+%d]", CurrentBlock->m_nElSize);
    return pMem;
}
예제 #17
0
// Handle the communication of SSTP protocol
bool ProcessSstpHttps(CEDAR *cedar, SOCK *s, SOCK_EVENT *se)
{
	UINT tmp_size = 65536;
	UCHAR *tmp_buf;
	FIFO *recv_fifo;
	FIFO *send_fifo;
	SSTP_SERVER *sstp;
	bool ret = false;
	// Validate arguments
	if (cedar == NULL || s == NULL || se == NULL)
	{
		return false;
	}

	tmp_buf = Malloc(tmp_size);
	recv_fifo = NewFifo();
	send_fifo = NewFifo();

	sstp = NewSstpServer(cedar, &s->RemoteIP, s->RemotePort, &s->LocalIP, s->LocalPort, se,
		s->RemoteHostname, s->CipherName);

	while (true)
	{
		UINT r;
		bool is_disconnected = false;
		bool state_changed = false;

		// Receive data over SSL
		while (true)
		{
			r = Recv(s, tmp_buf, tmp_size, true);
			if (r == 0)
			{
				// SSL is disconnected
				is_disconnected = true;
				break;
			}
			else if (r == SOCK_LATER)
			{
				// Data is not received any more
				break;
			}
			else
			{
				// Queue the received data
				WriteFifo(recv_fifo, tmp_buf, r);
				state_changed = true;
			}
		}

		while (recv_fifo->size >= 4)
		{
			UCHAR *first4;
			UINT read_size = 0;
			bool ok = false;
			// Read 4 bytes from the beginning of the receive queue
			first4 = ((UCHAR *)recv_fifo->p) + recv_fifo->pos;
			if (first4[0] == SSTP_VERSION_1)
			{
				USHORT len = READ_USHORT(first4 + 2) & 0xFFF;
				if (len >= 4)
				{
					ok = true;

					if (recv_fifo->size >= len)
					{
						UCHAR *data;
						BLOCK *b;

						read_size = len;
						data = Malloc(read_size);

						ReadFifo(recv_fifo, data, read_size);

						b = NewBlock(data, read_size, 0);

						InsertQueue(sstp->RecvQueue, b);
					}
				}
			}

			if (read_size == 0)
			{
				break;
			}

			if (ok == false)
			{
				// Disconnect the connection since a bad packet received
				is_disconnected = true;
				break;
			}
		}

		// Process the timer interrupt
		SstpProcessInterrupt(sstp);

		if (sstp->Disconnected)
		{
			is_disconnected = true;
		}

		// Put the transmission data that SSTP module has generated into the transmission queue
		while (true)
		{
			BLOCK *b = GetNext(sstp->SendQueue);

			if (b == NULL)
			{
				break;
			}

			// When transmit a data packet, If there are packets of more than about
			// 2.5 MB in the transmission queue of the TCP, discard without transmission
			if (b->PriorityQoS || (send_fifo->size <= MAX_BUFFERING_PACKET_SIZE))
			{
				WriteFifo(send_fifo, b->Buf, b->Size);
			}

			FreeBlock(b);
		}

		// Data is transmitted over SSL
		while (send_fifo->size != 0)
		{
			r = Send(s, ((UCHAR *)send_fifo->p) + send_fifo->pos, send_fifo->size, true);
			if (r == 0)
			{
				// SSL is disconnected
				is_disconnected = true;
				break;
			}
			else if (r == SOCK_LATER)
			{
				// Can not send any more
				break;
			}
			else
			{
				// Advance the transmission queue by the amount of the transmitted
				ReadFifo(send_fifo, NULL, r);
				state_changed = true;
			}
		}

		if (is_disconnected)
		{
			// Disconnected
			break;
		}

		// Wait for the next state change
		if (state_changed == false)
		{
			UINT select_time = SELECT_TIME;
			UINT r = GetNextIntervalForInterrupt(sstp->Interrupt);
			WaitSockEvent(se, MIN(r, select_time));
		}
	}

	if (sstp != NULL && sstp->EstablishedCount >= 1)
	{
		ret = true;
	}

	FreeSstpServer(sstp);

	ReleaseFifo(recv_fifo);
	ReleaseFifo(send_fifo);
	Free(tmp_buf);

	YieldCpu();
	Disconnect(s);

	return ret;
}
예제 #18
0
extern  bool            CreateBreak( void )
/*****************************************/
{
    block       *blk;
    block       *break_blk;
    block       *back_break_blk;
    block       *exit_blk;
    block_edge  *edge;
    block_edge  *next_edge;
    block_num   targets;
    int         pending;
    edge_list   *exit_edge;

    if( HeadBlock == NULL ) {
        return( false );
    }
    if( _IsntModel( FORTRAN_ALIASING ) ) {
        return( false );
    }
    if( !FixReturns() ) {
        return( false );
    }
    FixEdges();

/*
    Run through the blocks and find a place (break_blk) where no previous
    blocks are branched to from later blocks. IE: there are no backward branches
    around break_blk.
*/
    _MarkBlkAllUnVisited();
    break_blk = NULL;
    back_break_blk = NULL;
    pending = 0;
    BranchOuts = NULL;
    for( blk = HeadBlock; blk != NULL; blk = blk->next_block ) {
        if( AskIfReachedLabel( blk->label ) && blk != HeadBlock )
            break;
        if( (blk->edge[0].flags & BLOCK_LABEL_DIES) == 0 && blk != HeadBlock ) {
            _MarkBlkVisited( blk );
            ++pending;
        } else if( pending == 0 ) {
            break_blk = blk;
        }
        edge = &blk->edge[0];
        for( targets = blk->targets; targets > 0; --targets ) {
            if( edge->flags & DEST_IS_BLOCK ) {
                if( edge->flags & DEST_LABEL_DIES ) {
                    if( _IsBlkVisited( edge->destination.u.blk ) ) {
                        _MarkBlkUnVisited( edge->destination.u.blk );
                        if( --pending == 0 ) {
                            back_break_blk = blk->next_block;
                        }
                    }
                }
            }
            ++edge;
        }
    }
    /* clean up the BLOCK_VISITED flags */
    _MarkBlkAllUnVisited();
    if( back_break_blk != NULL ) {
        break_blk = back_break_blk; /* always better to break on a back edge */
    }
    if( break_blk == NULL ) {
        break_blk = HeadBlock;
    }
    if( break_blk == HeadBlock ) {
        break_blk = break_blk->next_block;
    }
    if( break_blk == NULL ) {
        UnFixEdges();
        return( false );
    }

/*
    create a new block and link it after break_blk. Point Break to the rest
    of the blocks and unhook them from the block list.
*/
    Break = break_blk;
    Curr = CurrBlock;
    Tail = BlockList;
    exit_blk = NewBlock( NULL, false );
    exit_blk->gen_id = BlockList->gen_id + 1;
    exit_blk->id = BlockList->id + 1;
    exit_blk->ins.hd.line_num = 0;
    BlockList = exit_blk;
    exit_blk->prev_block = break_blk->prev_block;
    exit_blk->next_block = NULL;
    _SetBlkAttr( exit_blk, BLK_UNKNOWN_DESTINATION );
    break_blk->prev_block->next_block = exit_blk;
    break_blk->prev_block = NULL;

/*
    run throuch all the blocks before break_blk, and create a 'BranchOut' for
    and edge that goes to a block after break_blk
*/
    for( blk = HeadBlock; blk != NULL; blk = blk->next_block ) {
        edge = &blk->edge[0];
        for( targets = blk->targets; targets > 0; --targets ) {
            if( (edge->flags & DEST_IS_BLOCK) == 0 || edge->destination.u.blk->gen_id >= break_blk->gen_id ) {
                exit_edge = CGAlloc( sizeof( edge_list ) );
                exit_edge->edge = edge;
                exit_edge->next = BranchOuts;
                exit_edge->gen_id = blk->gen_id;
                BranchOuts = exit_edge;
            }
            ++edge;
        }
    }

/*
    now, point all 'BranchOuts' at the new 'exit' block, saving their original
    labels in the 'lbl' field of the exit_list
*/

    for( exit_edge = BranchOuts; exit_edge != NULL; exit_edge = exit_edge->next ) {
        edge = exit_edge->edge;
        if( edge->flags & DEST_IS_BLOCK ) {
            exit_edge->lbl = edge->destination.u.blk->label;
            RemoveInputEdge( edge );
        } else {
            exit_edge->lbl = edge->destination.u.lbl;
        }
        edge->destination.u.blk = exit_blk;
        edge->flags |= DEST_IS_BLOCK;
        edge->next_source = exit_blk->input_edges;
        exit_blk->input_edges = edge;
        exit_blk->inputs++;
    }

    if( exit_blk->inputs == 0 ) {
        BlockList = exit_blk->prev_block;
        BlockList->next_block = NULL;
        exit_blk->prev_block = NULL;
        FreeABlock( exit_blk );
    }

    _MarkBlkAttr( HeadBlock, BLK_BIG_LABEL );
    HaveBreak = true;
/*
    change any branches to HeadBlock from a block after break_blk into
    a label (~DEST_IS_BLOCK) branch.
*/
    for( edge = HeadBlock->input_edges; edge != NULL; edge = next_edge ) {
        next_edge = edge->next_source;
        if( edge->source->gen_id >= break_blk->gen_id ) {
            RemoveInputEdge( edge );
            edge->destination.u.lbl = edge->destination.u.blk->label;
            edge->flags &= ~DEST_IS_BLOCK;
        }
    }
/*
    Now, set up a new HeadBlock, and redirect all unknowns branches to it.
    Known branches may still go to the old HeadBlock. This is so that
    HeadBlock will not be a loop header. The loop optimizer will
    screw up if it is.
*/
    blk = NewBlock( NULL, false );
    blk->input_edges = NULL;
    blk->inputs = 0;
    blk->label = HeadBlock->label;
    blk->ins.hd.line_num = HeadBlock->ins.hd.line_num;
    HeadBlock->ins.hd.line_num = 0;
    blk->gen_id = 0;
    blk->id = 0;
    HeadBlock->label = AskForNewLabel();
    blk->targets = 1;
    _SetBlkAttr( blk, BLK_BIG_LABEL | BLK_JUMP );
    _MarkBlkAttrNot( HeadBlock, BLK_BIG_LABEL );
    edge = &blk->edge[0];
    edge->flags = DEST_IS_BLOCK;
    edge->destination.u.blk = HeadBlock;
    edge->source = blk;
    edge->next_source = HeadBlock->input_edges;
    HeadBlock->input_edges = edge;
    HeadBlock->inputs++;
    HeadBlock->prev_block = blk;
    blk->prev_block = NULL;
    blk->next_block = HeadBlock;
    HeadBlock = blk;
    return( true );
}
예제 #19
0
// Process the received packet
BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port)
{
	UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE];
	UCHAR *iv;
	CRYPT *c;
	UINT64 my_tick, your_tick;
	UINT inner_size;
	UCHAR *inner_data = NULL;
	UINT pad_size;
	UCHAR *verify;
	bool compress_flag;
	BLOCK *b = NULL;
	UINT cookie;
	// Validate arguments
	if (a == NULL || buf == NULL || size == 0 || src_ip == NULL)
	{
		return NULL;
	}

	if (a->PlainTextMode == false)
	{
		// IV
		if (size < UDP_ACCELERATION_PACKET_IV_SIZE)
		{
			return NULL;
		}
		iv = buf;
		buf += UDP_ACCELERATION_PACKET_IV_SIZE;
		size -= UDP_ACCELERATION_PACKET_IV_SIZE;

		// Calculate the key
		UdpAccelCalcKey(key, a->YourKey, iv);

		if (false)
		{
			char tmp1[256];
			char tmp2[256];
			char tmp3[256];
			BinToStr(tmp1, sizeof(tmp1), a->YourKey, sizeof(a->YourKey));
			BinToStr(tmp2, sizeof(tmp2), iv, UDP_ACCELERATION_PACKET_IV_SIZE);
			BinToStr(tmp3, sizeof(tmp3), key, sizeof(key));
			Debug("Your Key: %s\n"
				  "IV      : %s\n"
				  "Comm Key: %s\n",
				tmp1, tmp2, tmp3);
		}

		// Decryption
		c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE);
		Encrypt(c, buf, buf, size);
		FreeCrypt(c);
	}

	// Cookie
	if (size < sizeof(UINT))
	{
		return NULL;
	}
	cookie = READ_UINT(buf);
	buf += sizeof(UINT);
	size -= sizeof(UINT);

	if (cookie != a->MyCookie)
	{
		return NULL;
	}

	// My Tick
	if (size < sizeof(UINT64))
	{
		return NULL;
	}
	my_tick = READ_UINT64(buf);
	buf += sizeof(UINT64);
	size -= sizeof(UINT64);

	// Your Tick
	if (size < sizeof(UINT64))
	{
		return NULL;
	}
	your_tick = READ_UINT64(buf);
	buf += sizeof(UINT64);
	size -= sizeof(UINT64);

	// inner_size
	if (size < sizeof(USHORT))
	{
		return NULL;
	}
	inner_size = READ_USHORT(buf);
	buf += sizeof(USHORT);
	size -= sizeof(USHORT);

	// compress_flag
	if (size < sizeof(UCHAR))
	{
		return NULL;
	}
	compress_flag = *((UCHAR *)buf);
	buf += sizeof(UCHAR);
	size -= sizeof(UCHAR);

	if (size < inner_size)
	{
		return NULL;
	}

	// inner_data
	if (inner_size >= 1)
	{
		inner_data = buf;
		buf += inner_size;
		size -= inner_size;
	}

	if (a->PlainTextMode == false)
	{
		// padding
		if (size < UDP_ACCELERATION_PACKET_IV_SIZE)
		{
			return false;
		}
		pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE;
		buf += pad_size;
		size -= pad_size;

		// verify
		if (size != UDP_ACCELERATION_PACKET_IV_SIZE)
		{
			return NULL;
		}

		verify = buf;

		if (IsZero(verify, UDP_ACCELERATION_PACKET_IV_SIZE) == false)
		{
			return NULL;
		}
	}

	if (my_tick < a->LastRecvYourTick)
	{
		if ((a->LastRecvYourTick - my_tick) >= ((UINT64)UDP_ACCELERATION_WINDOW_SIZE_MSEC))
		{
			return NULL;
		}
	}

	a->LastRecvMyTick = MAX(a->LastRecvMyTick, your_tick);
	a->LastRecvYourTick = MAX(a->LastRecvYourTick, my_tick);

	if (inner_size >= 1)
	{
		b = NewBlock(Clone(inner_data, inner_size), inner_size, compress_flag ? -1 : 0);
	}

	if (a->LastSetSrcIpAndPortTick < a->LastRecvYourTick)
	{
		a->LastSetSrcIpAndPortTick = a->LastRecvYourTick;

		Copy(&a->YourIp, src_ip, sizeof(IP));
		a->YourPort = src_port;
	}

	if (a->LastRecvMyTick != 0)
	{
		if ((a->LastRecvMyTick + (UINT64)(UDP_ACCELERATION_WINDOW_SIZE_MSEC)) >= a->Now)
		{
			a->LastRecvTick = a->Now;

			a->IsReachedOnce = true;

			if (a->FirstStableReceiveTick == 0)
			{
				a->FirstStableReceiveTick = a->Now;
			}
		}
	}

	return b;
}
예제 #20
0
// Processing of the interrupt
void EtherIPProcInterrupts(ETHERIP_SERVER *s)
{
	// Validate arguments
	if (s == NULL)
	{
		return;
	}

	// If EtherIP settings have been changed, and the change may effect to this connection, disconnect
	if (s->Ipc != NULL)
	{
		if (s->Ike->IPsec->EtherIPIdListSettingVerNo != s->LastEtherIPSettingVerNo)
		{
			ETHERIP_ID id;
			bool ok = true;

			s->LastEtherIPSettingVerNo = s->Ike->IPsec->EtherIPIdListSettingVerNo;

			if (SearchEtherIPId(s->IPsec, &id, s->ClientId) == false &&
				SearchEtherIPId(s->IPsec, &id, "*") == false)
			{
				ok = false;
			}
			else
			{
				if (StrCmpi(s->CurrentEtherIPIdSetting.HubName, id.HubName) != 0 ||
					StrCmpi(s->CurrentEtherIPIdSetting.UserName, id.UserName) != 0 ||
					StrCmp(s->CurrentEtherIPIdSetting.Password, id.Password) != 0)
				{
					ok = false;
				}
			}

			if (ok == false)
			{
				// Disconnect immediately since setting of EtherIP seems to have been changed
				FreeIPC(s->Ipc);
				s->Ipc = NULL;

				EtherIPLog(s, "LE_RECONNECT");
			}
		}
	}

	// Connect if IPC connection is not completed
	Lock(s->Lock);
	{
		if (s->Ipc == NULL)
		{
			if (s->IpcConnectThread == NULL)
			{
				if ((s->LastConnectFailedTick == 0) || ((s->LastConnectFailedTick + (UINT64)ETHERIP_VPN_CONNECT_RETRY_INTERVAL) <= s->Now))
				{
					Lock(s->IPsec->LockSettings);
					{
						Copy(&s->CurrentIPSecServiceSetting, &s->IPsec->Services, sizeof(IPSEC_SERVICES));
					}
					Unlock(s->IPsec->LockSettings);

					s->IpcConnectThread = NewThread(EtherIPIpcConnectThread, s);
					AddThreadToThreadList(s->Ike->ThreadList, s->IpcConnectThread);
					AddRef(s->Ref);
				}
			}
		}
	}
	Unlock(s->Lock);

	if (s->Ipc != NULL)
	{
		// Set to get hit the SockEvent when a packet arrives via the IPC
		IPCSetSockEventWhenRecvL2Packet(s->Ipc, s->SockEvent);

		// IPC interrupt processing
		IPCProcessInterrupts(s->Ipc);

		// Receive the MAC frame which arrived via the IPC
		while (true)
		{
			BLOCK *b = IPCRecvL2(s->Ipc);
			UCHAR *dst;
			UINT dst_size;

			if (b == NULL)
			{
				break;
			}

			if (b->Size >= 14)
			{
				BLOCK *block;

				// Store the arrived MAC frame by adding an EtherIP header to the reception packet queue

				if (s->L2TPv3 == false)
				{
					dst_size = b->Size + 2;
					dst = Malloc(dst_size);

					dst[0] = 0x30;
					dst[1] = 0x00;

					Copy(dst + 2, b->Buf, b->Size);
				}
				else
				{
					dst = Clone(b->Buf, b->Size);
					dst_size = b->Size;
				}

				block = NewBlock(dst, dst_size, 0);

				Add(s->SendPacketList, block);
			}

			FreeBlock(b);
		}

		if (IsIPCConnected(s->Ipc) == false)
		{
			// IPC connection is disconnected
			FreeIPC(s->Ipc);
			s->Ipc = NULL;
		}
	}
}
예제 #21
0
CTextRenderer::CGlyph* CTextRenderer::CGlyphCache::NewGlyph(CGlyphId GlyphId, int Width, int Height)
{	
	ivec2 Granularity;
	Granularity.x = (Width%m_PPG == 0 ? (Width / m_PPG) : (Width / m_PPG) + 1);
	Granularity.y = (Height%m_PPG == 0 ? (Height / m_PPG) : (Height / m_PPG) + 1);
	if(Granularity.x < 1)
		Granularity.x = 1;
	if(Granularity.y < 1)
		Granularity.y = 1;
	
	//First pass: find a free slot in blocks
		//We use backward iteration because non-full blockes are at the end
	for(int i=m_Blocks.size()-1; i>=0; i--)
	{
		if(m_Blocks[i].m_Granularity == Granularity)
		{
			if(!m_Blocks[i].IsFull())
			{
				CGlyph* pGlyph = &m_Glyphs[m_Glyphs.add(CGlyph(GlyphId))];
				
				pGlyph->m_Width = Width;
				pGlyph->m_Height = Height;
				pGlyph->m_Granularity = Granularity;
				pGlyph->m_Block = i;
				pGlyph->m_BlockPos = m_Blocks[i].m_Size;
				UpdateGlyph(pGlyph);
		
				m_Blocks[pGlyph->m_Block].m_Size++;
				
				return pGlyph;
			}
			else
				break; //Only the last block of this granularity can be non-full
		}
	}
	
	//Second pass: find the oldest glyph with the same granularity
	int OldestTick = m_RenderTick;
	int OldestGlyph = -1;
	for(int i=0; i<m_Glyphs.size(); i++)
	{
		if(m_Glyphs[i].m_Granularity == Granularity && m_Glyphs[i].m_RenderTick < OldestTick)
		{
			OldestTick = m_Glyphs[i].m_RenderTick;
			OldestGlyph = i;
		}
	}
	
	if(OldestGlyph >= 0) //Replace the glyph
	{
		CGlyph Glyph = CGlyph(GlyphId);
		Glyph.m_Block = m_Glyphs[OldestGlyph].m_Block;
		Glyph.m_BlockPos = m_Glyphs[OldestGlyph].m_BlockPos;
		
		m_Glyphs.remove_index(OldestGlyph);
		
		int GlyphId = m_Glyphs.add(Glyph);
		CGlyph* pGlyph = &m_Glyphs[GlyphId];
		
		pGlyph->m_Width = Width;
		pGlyph->m_Height = Height;
		pGlyph->m_Granularity = Granularity;
		UpdateGlyph(pGlyph);
		UpdateVersion();
		
		return pGlyph;
	}
	else //Add a new block
	{
		int BlockId = NewBlock(Granularity);

		CGlyph* pGlyph = &m_Glyphs[m_Glyphs.add(CGlyph(GlyphId))];
		
		pGlyph->m_Width = Width;
		pGlyph->m_Height = Height;
		pGlyph->m_Granularity = Granularity;
		pGlyph->m_Block = BlockId;
		pGlyph->m_BlockPos = 0;
		
		UpdateGlyph(pGlyph);
		
		m_Blocks[pGlyph->m_Block].m_Size++;
		
		return pGlyph;
	}
}