Beispiel #1
0
/**
 * @function BuildManifold
 */
void HP2D::BuildManifold( Vertice _v0 ) {

    Vertice* va;
    Vertice vt;
	Vertice* vb;
    std::vector<Vertice> S; 
    std::vector<Vertice*> B; 

	InsertQueue( _v0 );

    do{
    	va = PopQueue();        
        S = Successors( va );
        
        for( int i = 0; i < S.size(); i++ ) {
            vt = S[i];
            InsertVertice( vt );
            InsertEdge( &vt, va );
            if( vt.GetDist() < mDIST_MAX ) {
                InsertQueue( vt );
            }
            B = GetAdjacent( va->Adjacent() );
            
            for( unsigned j = 0; j < B.size(); j++ ) {
                vb = B[j];
                if( InSet( vb->GetPos(), vt.Neighbors() ) ) {
                    InsertEdge( &vt, vb );
                }          
            }
        } 
    } while( GetSizeQueue() > 0 ); 
}
Beispiel #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);
}
Beispiel #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);
	}
}
Beispiel #4
0
// Send an L2 packet immediately
void L3SendL2Now(L3IF *f, UCHAR *dest_mac, UCHAR *src_mac, USHORT protocol, void *data, UINT size)
{
	UCHAR *buf;
	MAC_HEADER *mac_header;
	PKT *p;
	// Validate arguments
	if (f == NULL || dest_mac == NULL || src_mac == NULL || data == NULL)
	{
		return;
	}

	// Buffer creation
	buf = Malloc(MAC_HEADER_SIZE + size);

	// MAC header
	mac_header = (MAC_HEADER *)&buf[0];
	Copy(mac_header->DestAddress, dest_mac, 6);
	Copy(mac_header->SrcAddress, src_mac, 6);
	mac_header->Protocol = Endian16(protocol);

	// Copy data
	Copy(&buf[sizeof(MAC_HEADER)], data, size);

	// Size
	size += sizeof(MAC_HEADER);

	// Packet generation
	p = ZeroMalloc(sizeof(PKT));
	p->PacketData = buf;
	p->PacketSize = size;

	// Add to the queue
	InsertQueue(f->SendQueue, p);
}
Beispiel #5
0
static  bool    JustMoveLabel( common_info *max, ins_entry *ins )
/***************************************************************/
{
    oc_class            cl;
    ins_entry           *lbl;
    ins_entry           *add;
    ins_entry           *next;

  optbegin
    if( PrevClass( max->start_del ) != OC_LABEL )
        optreturn( FALSE );
    lbl = PrevIns( max->start_del );
    if( _Attr( lbl ) & ATTR_SHORT )
        optreturn( FALSE );
    cl = PrevClass( lbl );
    if( !_TransferClass( cl ) )
        optreturn( FALSE );
    DeleteQueue( lbl );
    InsertQueue( lbl, PrevIns( max->start_com ) );
    add = PrevIns( max->start_del );
    for( ;; ) {
        next = NextIns( add );
        DelInstr( next );
        if( next == ins ) {
            break;
        }
    }
    Untangle( lbl );
    optreturn( TRUE );
}
// Relay thread for captured packet (BPF)
void BpfThread(THREAD *thread, void *param)
{
	ETH *e = (ETH*)param;
	int fd = e->Socket;
	int len;
	int rest;	// Rest size in buffer
	UCHAR *next;	// Head of next packet in buffer
	struct CAPTUREBLOCK *block;	// Data to enqueue
	UCHAR *data;
	struct bpf_hdr *hdr;

	// Allocate the buffer
	UCHAR *buf = Malloc(e->BufSize);
	
	// Notify initialize completed
	NoticeThreadInit(thread);

	while(1){
		// Determining to exit loop
		if(e->Socket == INVALID_SOCKET){
			break;
		}
		
		rest = read(fd, buf, e->BufSize);
		if(rest < 0 && errno != EAGAIN){
			// Error
			close(fd);
			e->Socket = INVALID_SOCKET;
			Free(buf);
			Cancel(e->Cancel);
			return;
		}
		next = buf;
		LockQueue(e->Queue);
		while(rest>0){
			// Cut out a packet
			hdr = (struct bpf_hdr*)next;

			// Discard arriving packet when queue filled
			if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){
				data = Malloc(hdr->bh_caplen);
				Copy(data, next+(hdr->bh_hdrlen), hdr->bh_caplen);
				block = NewCaptureBlock(data, hdr->bh_caplen);
				InsertQueue(e->Queue, block);
				e->QueueSize += hdr->bh_caplen;
			}

			// Find the head of next packet
			rest -= BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
			next += BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
		}
		UnlockQueue(e->Queue);
		Cancel(e->Cancel);
	}
	Free(buf);
	Cancel(e->Cancel);
	return;
}
Beispiel #7
0
// BPF でのパケットキャプチャの中継用スレッド
void BpfThread(THREAD *thread, void *param)
{
	ETH *e = (ETH*)param;
	int fd = e->Socket;
	int len;
	int rest;	// バッファ中の残りバイト数
	UCHAR *next;	//バッファ中の次のパケットの先頭
	struct CAPTUREBLOCK *block;	// キューに追加するデータ
	UCHAR *data;
	struct bpf_hdr *hdr;

	// バッファを確保
	UCHAR *buf = Malloc(e->BufSize);
	
	// 初期化完了を通知
	NoticeThreadInit(thread);

	while(1){
		// ループの脱出判定
		if(e->Socket == INVALID_SOCKET){
			break;
		}
		
		rest = read(fd, buf, e->BufSize);
		if(rest < 0 && errno != EAGAIN){
			// エラー
			close(fd);
			e->Socket = INVALID_SOCKET;
			Free(buf);
			Cancel(e->Cancel);
			return;
		}
		next = buf;
		LockQueue(e->Queue);
		while(rest>0){
			// パケットの切り出し
			hdr = (struct bpf_hdr*)next;

			// Queue中のパケットサイズが限界を超えたらパケットを破棄する
			if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){
				data = Malloc(hdr->bh_caplen);
				Copy(data, next+(hdr->bh_hdrlen), hdr->bh_caplen);
				block = NewCaptureBlock(data, hdr->bh_caplen);
				InsertQueue(e->Queue, block);
				e->QueueSize += hdr->bh_caplen;
			}

			// 次のパケットの頭出し
			rest -= BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
			next += BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
		}
		UnlockQueue(e->Queue);
		Cancel(e->Cancel);
	}
	Free(buf);
	Cancel(e->Cancel);
	return;
}
Beispiel #8
0
static  void    TransformJumps( ins_entry *ins, ins_entry *first )
/****************************************************************/
{
    ins_entry           *add;
    ins_entry           *next;
    ins_entry           *lbl;
    oc_class            cl;

  optbegin
    if( _Class( ins ) == OC_RET )
        optreturnvoid;
    lbl = _Label( ins )->ins;
    if( lbl == NULL )
        optreturnvoid;
    add = lbl;
    for( ;; ) {
        if( add == NULL )
            optreturnvoid;
        cl = _Class( add );
        if( _TransferClass( cl ) )
            break;
        if( cl == OC_LABEL ) {
            if( _Attr( add ) & ATTR_SHORT )
                optreturnvoid;
            _ClrStatus( _Label( add ), SHORTREACH );
        }
        add = NextIns( add );
    }
    if( add == first || add == ins )
        optreturnvoid;
    if( FindShort( first, lbl ) )
        optreturnvoid;
    for( ;; ) {
        next = PrevIns( add );
        DeleteQueue( add );
        InsertQueue( add, first );
        if( add == lbl )
            break;
        add = next;
    }
    DeleteQueue( first );
    InsertQueue( first, next );
    Untangle( NextIns( first ) );
  optend
}
// 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++;
	}
}
Beispiel #10
0
// Store the IP packet to a different interface
void L3StoreIpPacketToIf(L3IF *src_if, L3IF *dst_if, L3PACKET *p)
{
	// Validate arguments
	if (src_if == NULL || p == NULL || dst_if == NULL)
	{
		return;
	}

	// Add to the queue of store-destination session
	InsertQueue(dst_if->IpPacketQueue, p);

	// Hit the Cancel object of the store-destination session
	AddCancelList(src_if->CancelList, dst_if->Session->Cancel1);
}
Beispiel #11
0
/*
 * Give the player 'count' ships of the specified race,
 * limited by the number of free slots.
 * Returns the number of ships added.
 */
COUNT
AddEscortShips (COUNT race, SIZE count)
{
	HFLEETINFO hFleet;
	BYTE which_window;
	COUNT i;

	hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race);
	if (!hFleet)
		return 0;

	assert (count > 0);

	which_window = 0;
	for (i = 0; i < (COUNT) count; i++)
	{
		HSHIPFRAG hStarShip;
		HSHIPFRAG hOldShip;
		SHIP_FRAGMENT *StarShipPtr;

		hStarShip = CloneShipFragment (race, &GLOBAL (built_ship_q), 0);
		if (!hStarShip)
			break;

		RemoveQueue (&GLOBAL (built_ship_q), hStarShip);

		/* Find first available escort window */
		while ((hOldShip = GetStarShipFromIndex (
				&GLOBAL (built_ship_q), which_window++)))
		{
			BYTE win_loc;

			StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hOldShip);
			win_loc = StarShipPtr->index;
			UnlockShipFrag (&GLOBAL (built_ship_q), hOldShip);
			if (which_window <= win_loc)
				break;
		}

		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip);
		StarShipPtr->index = which_window - 1;
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);

		InsertQueue (&GLOBAL (built_ship_q), hStarShip, hOldShip);
	}

	DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA);
	return i;
}
Beispiel #12
0
// パケット到着のコールバック関数
void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
{
	ETH *e = (ETH*) user;
	struct CAPTUREBLOCK *block;
	UCHAR *data;
	
	data = Malloc(h->caplen);
	Copy(data, bytes, h->caplen);
	block = NewCaptureBlock(data, h->caplen);
	LockQueue(e->Queue);
	// キューのサイズが限界を超えたらパケットを破棄する。
	if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){
		InsertQueue(e->Queue, block);
		e->QueueSize += h->caplen;
	}
	UnlockQueue(e->Queue);
	Cancel(e->Cancel);
	return;
}
// Callback function to receive arriving packet (Pcap)
void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
{
	ETH *e = (ETH*) user;
	struct CAPTUREBLOCK *block;
	UCHAR *data;
	
	data = Malloc(h->caplen);
	Copy(data, bytes, h->caplen);
	block = NewCaptureBlock(data, h->caplen);
	LockQueue(e->Queue);
	// Discard arriving packet when queue filled
	if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){
		InsertQueue(e->Queue, block);
		e->QueueSize += h->caplen;
	}
	UnlockQueue(e->Queue);
	Cancel(e->Cancel);
	return;
}
Beispiel #14
0
// 受信したパケットを書き込み
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;
}
Beispiel #15
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;
}
Beispiel #16
0
// Routing table tracking main
void RouteTrackingMain(SESSION *s)
{
	ROUTE_TRACKING *t;
	UINT64 now;
	ROUTE_TABLE *table;
	ROUTE_ENTRY *rs;
	bool changed = false;
	bool check = false;
	bool any_modified = false;
	// Validate arguments
	if (s == NULL)
	{
		return;
	}
	if (s->ClientModeAndUseVLan == false)
	{
		return;
	}

	// Get the state
	t = ((VLAN *)s->PacketAdapter->Param)->RouteState;
	if (t == NULL)
	{
		return;
	}

	// Current time
	PROBE_STR("RouteTrackingMain 1");
	now = Tick64();

	if (t->RouteChange != NULL)
	{
		if (t->NextRouteChangeCheckTime == 0 ||
			t->NextRouteChangeCheckTime <= now)
		{
			t->NextRouteChangeCheckTime = now + 1000ULL;

			check = IsRouteChanged(t->RouteChange);

			if (check)
			{
				Debug("*** Routing Table Changed ***\n");
				t->NextTrackingTime = 0;
			}
		}
	}
	if (t->NextTrackingTime != 0 && t->NextTrackingTime > now)
	{
		if (s->UseUdpAcceleration && s->UdpAccel != NULL && s->UdpAccel->NatT_IP_Changed)
		{
			// Check always if the IP address of the NAT-T server has changed
		}
		else
		{
			PROBE_STR("RouteTrackingMain 2");
			return;
		}
	}
	PROBE_STR("RouteTrackingMain 3");

	if (s->UseUdpAcceleration && s->UdpAccel != NULL)
	{
		IP nat_t_ip;

		s->UdpAccel->NatT_IP_Changed = false;

		Zero(&nat_t_ip, sizeof(nat_t_ip));

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

		// Add a route to the NAT-T server
		if (IsZeroIp(&nat_t_ip) == false)
		{
			if (t->RouteToNatTServer == NULL)
			{
				if (t->RouteToEight != NULL)
				{
					ROUTE_ENTRY *e = Clone(t->RouteToEight, sizeof(ROUTE_ENTRY));
					char ip_str[64];
					char ip_str2[64];

					Copy(&e->DestIP, &nat_t_ip, sizeof(IP));
					e->Metric = e->OldIfMetric;

					IPToStr(ip_str, sizeof(ip_str), &e->DestIP);
					IPToStr(ip_str2, sizeof(ip_str2), &e->GatewayIP);

					t->RouteToNatTServer = e;

					if (AddRouteEntry(t->RouteToNatTServer))
					{
						Debug("Adding Static Route to %s via %s metric %u: ok.\n", ip_str, ip_str2, e->Metric);
					}
					else
					{
						FreeRouteEntry(t->RouteToNatTServer);
						t->RouteToNatTServer = NULL;
					}
				}
			}
		}
	}

	// Get the current routing table
	table = GetRouteTable();
	rs = t->RouteToServer;
	if (table != NULL)
	{
		UINT i;
		bool route_to_server_erased = true;
		bool is_vlan_want_to_be_default_gateway = false;
		UINT vlan_default_gatewat_metric = 0;
		UINT other_if_default_gateway_metric_min = INFINITE;

		// Get whether the routing table have been changed
		if (t->LastRoutingTableHash != table->HashedValue)
		{
			t->LastRoutingTableHash = table->HashedValue;
			changed = true;
		}

		//DebugPrintRouteTable(table);

		// Scan the routing table
		for (i = 0;i < table->NumEntry;i++)
		{
			ROUTE_ENTRY *e = table->Entry[i];

			if (rs != NULL)
			{
				if (CmpIpAddr(&e->DestIP, &rs->DestIP) == 0 &&
					CmpIpAddr(&e->DestMask, &rs->DestMask) == 0
//					&& CmpIpAddr(&e->GatewayIP, &rs->GatewayIP) == 0
//					&& e->InterfaceID == rs->InterfaceID &&
//					e->LocalRouting == rs->LocalRouting &&
//					e->Metric == rs->Metric
					)
				{
					// Routing entry to the server that added at the time of connection is found
					route_to_server_erased = false;
				}
			}

			// Search for the default gateway
			if (IPToUINT(&e->DestIP) == 0 &&
				IPToUINT(&e->DestMask) == 0)
			{
				Debug("e->InterfaceID = %u, t->VLanInterfaceId = %u\n",
					e->InterfaceID, t->VLanInterfaceId);

				if (e->InterfaceID == t->VLanInterfaceId)
				{
					// The virtual LAN card think that he want to be a default gateway
					is_vlan_want_to_be_default_gateway = true;
					vlan_default_gatewat_metric = e->Metric;

					if (vlan_default_gatewat_metric >= 2 &&
						t->OldDefaultGatewayMetric == (vlan_default_gatewat_metric - 1))
					{
						// Restore because the PPP server rewrites
						// the routing table selfishly
						DeleteRouteEntry(e);
						e->Metric--;
						AddRouteEntry(e);
						Debug("** Restore metric destroyed by PPP.\n");

						any_modified = true;
					}

					// Keep this entry
					if (t->DefaultGatewayByVLan != NULL)
					{
						// Delete if there is one added last time
						FreeRouteEntry(t->DefaultGatewayByVLan);
					}

					t->DefaultGatewayByVLan = ZeroMalloc(sizeof(ROUTE_ENTRY));
					Copy(t->DefaultGatewayByVLan, e, sizeof(ROUTE_ENTRY));

					t->OldDefaultGatewayMetric = vlan_default_gatewat_metric;
				}
				else
				{
					// There are default gateway other than the virtual LAN card
					// Save the metric value of the default gateway
					if (other_if_default_gateway_metric_min > e->Metric)
					{
						// Ignore the metric value of all PPP connection in the case of Windows Vista
						if (MsIsVista() == false || e->PPPConnection == false)
						{
							other_if_default_gateway_metric_min = e->Metric;
						}
						else
						{
							// a PPP is used to Connect to the network
							// in using Windows Vista
							t->VistaAndUsingPPP = true;
						}
					}
				}
			}
		}

		if (t->VistaAndUsingPPP)
		{
			if (t->DefaultGatewayByVLan != NULL)
			{
				if (is_vlan_want_to_be_default_gateway)
				{
					if (t->VistaOldDefaultGatewayByVLan == NULL || Cmp(t->VistaOldDefaultGatewayByVLan, t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY)) != 0)
					{
						ROUTE_ENTRY *e;
						// Add the route of 0.0.0.0/1 and 128.0.0.0/1
						// to the system if the virtual LAN card should be
						// the default gateway in the case of the connection
						// using PPP in Windows Vista

						if (t->VistaOldDefaultGatewayByVLan != NULL)
						{
							FreeRouteEntry(t->VistaOldDefaultGatewayByVLan);
						}

						if (t->VistaDefaultGateway1 != NULL)
						{
							DeleteRouteEntry(t->VistaDefaultGateway1);
							FreeRouteEntry(t->VistaDefaultGateway1);

							DeleteRouteEntry(t->VistaDefaultGateway2);
							FreeRouteEntry(t->VistaDefaultGateway2);
						}

						t->VistaOldDefaultGatewayByVLan = Clone(t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY));

						e = Clone(t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY));
						SetIP(&e->DestIP, 0, 0, 0, 0);
						SetIP(&e->DestMask, 128, 0, 0, 0);
						t->VistaDefaultGateway1 = e;

						e = Clone(t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY));
						SetIP(&e->DestIP, 128, 0, 0, 0);
						SetIP(&e->DestMask, 128, 0, 0, 0);
						t->VistaDefaultGateway2 = e;

						AddRouteEntry(t->VistaDefaultGateway1);
						AddRouteEntry(t->VistaDefaultGateway2);

						Debug("Vista PPP Fix Route Table Added.\n");

						any_modified = true;
					}
				}
				else
				{
					if (t->VistaOldDefaultGatewayByVLan != NULL)
					{
						FreeRouteEntry(t->VistaOldDefaultGatewayByVLan);
						t->VistaOldDefaultGatewayByVLan = NULL;
					}

					if (t->VistaDefaultGateway1 != NULL)
					{
						Debug("Vista PPP Fix Route Table Deleted.\n");
						DeleteRouteEntry(t->VistaDefaultGateway1);
						FreeRouteEntry(t->VistaDefaultGateway1);

						DeleteRouteEntry(t->VistaDefaultGateway2);
						FreeRouteEntry(t->VistaDefaultGateway2);

						any_modified = true;

						t->VistaDefaultGateway1 = t->VistaDefaultGateway2 = NULL;
					}
				}
			}
		}

		// If the virtual LAN card want to be the default gateway and
		// there is no LAN card with smaller metric of 0.0.0.0/0 than
		// the virtual LAN card, delete other default gateway entries
		// to elect the virtual LAN card as the default gateway
//		Debug("is_vlan_want_to_be_default_gateway = %u, rs = %u, route_to_server_erased = %u, other_if_default_gateway_metric_min = %u, vlan_default_gatewat_metric = %u\n",
//			is_vlan_want_to_be_default_gateway, rs, route_to_server_erased, other_if_default_gateway_metric_min, vlan_default_gatewat_metric);
		if (is_vlan_want_to_be_default_gateway && (rs != NULL && route_to_server_erased == false) &&
			other_if_default_gateway_metric_min >= vlan_default_gatewat_metric)
		{
			// Scan the routing table again
			for (i = 0;i < table->NumEntry;i++)
			{
				ROUTE_ENTRY *e = table->Entry[i];

				if (e->InterfaceID != t->VLanInterfaceId)
				{
					if (IPToUINT(&e->DestIP) == 0 &&
					IPToUINT(&e->DestMask) == 0)
					{
						char str[64];
						// Default gateway is found
						ROUTE_ENTRY *r = ZeroMalloc(sizeof(ROUTE_ENTRY));

						Copy(r, e, sizeof(ROUTE_ENTRY));

						// Put in the queue
						InsertQueue(t->DeletedDefaultGateway, r);

						// Delete this gateway entry once
						DeleteRouteEntry(e);

						IPToStr(str, sizeof(str), &e->GatewayIP);
						Debug("Default Gateway %s Deleted.\n", str);

						any_modified = true;
					}
				}
			}
		}

		if (rs != NULL && route_to_server_erased)
		{
			// Physical entry to the server has disappeared
			Debug("Route to Server entry ERASED !!!\n");

			// Forced disconnection (reconnection enabled)
			s->RetryFlag = true;
			s->Halt = true;
		}

		// Release the routing table
		FreeRouteTable(table);
	}

	// Set the time to perform the next track
	if (t->NextTrackingTimeAdd == 0 || changed)
	{
		t->NextTrackingTimeAdd = TRACKING_INTERVAL_INITIAL;
	}
	else
	{
		UINT64 max_value = TRACKING_INTERVAL_MAX;
		if (t->RouteChange != NULL)
		{
			max_value = TRACKING_INTERVAL_MAX_RC;
		}

		t->NextTrackingTimeAdd += TRACKING_INTERVAL_ADD;

		if (t->NextTrackingTimeAdd >= max_value)
		{
			t->NextTrackingTimeAdd = max_value;
		}
	}
	//Debug("t->NextTrackingTimeAdd = %I64u\n", t->NextTrackingTimeAdd);
	t->NextTrackingTime = now + t->NextTrackingTimeAdd;

	if (any_modified)
	{
		// Clear the DNS cache
		Win32FlushDnsCache();
	}
}
/*
 * What this function does depends on the value of the 'state' argument:
 * SPHERE_TRACKING:
 * 	The sphere of influence for the race for 'which_ship' will be shown
 * 	on the starmap in the future.
 * 	The value returned is 'which_ship', unless the type of ship is only
 * 	available in SuperMelee, in which case 0 is returned.
 * SPHERE_KNOWN:
 * 	The size of the fleet of the race of 'which_ship' when the starmap was
 * 	last checked is returned.
 * ESCORT_WORTH:
 * 	The total value of all the ships escorting the SIS is returned.
 * 	'which_ship' is ignored.
 * ESCORTING_FLAGSHIP:
 * 	Test if a ship of type 'which_ship' is among the escorts of the SIS
 * 	0 is returned if false, 1 if true.
 * FEASIBILITY_STUDY:
 * 	Test if the SIS can have an escort of type 'which_ship'.
 * 	0 is returned if 'which_ship' is not available.
 * 	Otherwise, the number of ships that can be added is returned.
 * CHECK_ALLIANCE:
 * 	Test the alliance status of the race of 'which_ship'.
 *      Either GOOD_GUY (allied) or BAD_GUY (not allied) is returned.
 * 0:
 * 	Ally with the race of 'which_ship'. This makes their ship available
 *  for building in the shipyard.
 * -1:
 * 	End an alliance with the race of 'which_ship'. This ends the possibility
 * 	of building their ships in the shipyard. For the Orz also the ships the
 * 	player has with him will disappear.
 * any other positive number:
 * 	Give the player this much ships of type 'which_ship'. If it's
 */
COUNT
ActivateStarShip (COUNT which_ship, SIZE state)
{
	HSTARSHIP hStarShip, hNextShip;

	hStarShip = GetStarShipFromIndex (
			&GLOBAL (avail_race_q), which_ship
			);
	if (hStarShip)
	{
		switch (state)
		{
			case SPHERE_TRACKING:
			case SPHERE_KNOWN:
			{
				EXTENDED_SHIP_FRAGMENTPTR StarShipPtr;

				StarShipPtr = (EXTENDED_SHIP_FRAGMENTPTR)LockStarShip (
						&GLOBAL (avail_race_q), hStarShip);
				if (state == SPHERE_KNOWN)
					which_ship = StarShipPtr->ShipInfo.known_strength;
				else if (StarShipPtr->ShipInfo.actual_strength == 0)
				{
					if (!(StarShipPtr->ShipInfo.ship_flags
							& (GOOD_GUY | BAD_GUY)))
						which_ship = 0;
				}
				else if (StarShipPtr->ShipInfo.known_strength == 0
						&& StarShipPtr->ShipInfo.actual_strength != (COUNT)~0)
				{
					StarShipPtr->ShipInfo.known_strength = 1;
					StarShipPtr->ShipInfo.known_loc =
							StarShipPtr->ShipInfo.loc;
				}
				UnlockStarShip (&GLOBAL (avail_race_q), hStarShip);
				return (which_ship);
			}
			case ESCORT_WORTH:
			{
				COUNT ShipCost[] =
				{
					RACE_SHIP_COST
				};
				COUNT total = 0;

				for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q));
						hStarShip; hStarShip = hNextShip)
				{
					SHIP_FRAGMENTPTR StarShipPtr;

					StarShipPtr = (SHIP_FRAGMENTPTR) LockStarShip (
							&GLOBAL (built_ship_q), hStarShip);
					hNextShip = _GetSuccLink (StarShipPtr);
					total += ShipCost[GET_RACE_ID (StarShipPtr)];
					UnlockStarShip (&GLOBAL (built_ship_q), hStarShip);
				}
				return total;
			}
			case ESCORTING_FLAGSHIP:
			{
				for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q));
						hStarShip; hStarShip = hNextShip)
				{
					BYTE ship_type;
					SHIP_FRAGMENTPTR StarShipPtr;

					StarShipPtr = (SHIP_FRAGMENTPTR) LockStarShip (
							&GLOBAL (built_ship_q), hStarShip);
					hNextShip = _GetSuccLink (StarShipPtr);
					ship_type = GET_RACE_ID (StarShipPtr);
					UnlockStarShip (&GLOBAL (built_ship_q), hStarShip);

					if ((COUNT) ship_type == which_ship)
						return 1;
				}
				return 0;
			}
			case FEASIBILITY_STUDY:
				return (MAX_BUILT_SHIPS
						- CountLinks (&GLOBAL (built_ship_q)));
			default:
			{
				SHIP_FRAGMENTPTR StarShipPtr;

				if (state <= 0)
				{
					StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
							&GLOBAL (avail_race_q), hStarShip
							);
					if (state == CHECK_ALLIANCE)
					{
						state = StarShipPtr->ShipInfo.ship_flags
								& (GOOD_GUY | BAD_GUY);
						UnlockStarShip (&GLOBAL (avail_race_q), hStarShip);
						return ((COUNT)state);
					}
					else if (StarShipPtr->ShipInfo.ship_flags
							& (GOOD_GUY | BAD_GUY))
					{
						StarShipPtr->ShipInfo.ship_flags &= ~(GOOD_GUY | BAD_GUY);
						if (state == 0)
							StarShipPtr->ShipInfo.ship_flags |= GOOD_GUY;
						else
						{
							StarShipPtr->ShipInfo.ship_flags |= BAD_GUY;
							if (which_ship == ORZ_SHIP)
							{
								BOOLEAN ShipRemoved;

								ShipRemoved = FALSE;
								for (hStarShip = GetHeadLink (
										&GLOBAL (built_ship_q));
										hStarShip; hStarShip = hNextShip)
								{
									BOOLEAN RemoveShip;
									SHIP_FRAGMENTPTR StarShipPtr2;

									StarShipPtr2 =
											(SHIP_FRAGMENTPTR)LockStarShip (
											&GLOBAL (built_ship_q), hStarShip);
									hNextShip = _GetSuccLink (StarShipPtr2);
									RemoveShip = (BOOLEAN) (
											GET_RACE_ID (StarShipPtr2) ==
											ORZ_SHIP);
									UnlockStarShip (&GLOBAL (built_ship_q),
											hStarShip);

									if (RemoveShip)
									{
										ShipRemoved = TRUE;

										RemoveQueue (&GLOBAL (built_ship_q),
												hStarShip);
										FreeStarShip (&GLOBAL (built_ship_q),
												hStarShip);
									}
								}
								
								if (ShipRemoved)
								{
									LockMutex (GraphicsLock);
									DeltaSISGauges (UNDEFINED_DELTA,
											UNDEFINED_DELTA, UNDEFINED_DELTA);
									UnlockMutex (GraphicsLock);
								}
							}
						}
					}
					UnlockStarShip (&GLOBAL (avail_race_q), hStarShip);
				}
				else
				{
					/* 'state > 0', add ships to the escorts */
					BYTE which_window;
					COUNT i;

					which_window = 0;
					for (i = 0; i < (COUNT)state; i++)
					{
						HSTARSHIP hOldShip;
						BYTE crewLevel;

						if (which_ship == SPATHI_SHIP &&
								GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1)
							crewLevel = 1;  // Only Fwiffo is on board.
						else
							crewLevel = 0;  // Crewed to the max
								
						hStarShip = CloneShipFragment((COUNT) which_ship,
								&GLOBAL (built_ship_q), crewLevel);
						if (!hStarShip)
							break;

						RemoveQueue (&GLOBAL (built_ship_q), hStarShip);

						while ((hOldShip = GetStarShipFromIndex (
								&GLOBAL (built_ship_q), which_window++)))
						{
							BYTE win_loc;

							StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
									&GLOBAL (built_ship_q), hOldShip);
							win_loc = GET_GROUP_LOC (StarShipPtr);
							UnlockStarShip (&GLOBAL (built_ship_q),
									hOldShip);
							if (which_window <= win_loc)
								break;
						}

						StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
								&GLOBAL (built_ship_q), hStarShip);
						SET_GROUP_LOC (StarShipPtr, which_window - 1);
						if (which_ship == SPATHI_SHIP
								&& GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1)
						{
							OwnStarShip (StarShipPtr, GOOD_GUY,
									NAME_OFFSET + NUM_CAPTAINS_NAMES);
						}
						UnlockStarShip (&GLOBAL (built_ship_q), hStarShip);

						InsertQueue (&GLOBAL (built_ship_q), hStarShip,
								hOldShip);
					}

					LockMutex (GraphicsLock);
					DeltaSISGauges (UNDEFINED_DELTA,
							UNDEFINED_DELTA, UNDEFINED_DELTA);
					UnlockMutex (GraphicsLock);
					return (i);
				}
				break;
			}
		}

		return 1;
	}

	return 0;
}
Beispiel #18
0
COUNT
ActivateStarShip (COUNT which_ship, SIZE state)
{
	HSTARSHIP hStarShip, hNextShip;

	hStarShip = GetStarShipFromIndex (
			&GLOBAL (avail_race_q), which_ship
			);
	if (hStarShip)
	{
		switch (state)
		{
			case SPHERE_TRACKING:
			case SPHERE_KNOWN:
			{
				EXTENDED_SHIP_FRAGMENTPTR StarShipPtr;

				StarShipPtr = (EXTENDED_SHIP_FRAGMENTPTR)LockStarShip (
						&GLOBAL (avail_race_q), hStarShip
						);
				if (state == SPHERE_KNOWN)
					which_ship = StarShipPtr->ShipInfo.known_strength;
				else if (StarShipPtr->ShipInfo.actual_strength == 0)
				{
					if (!(StarShipPtr->ShipInfo.ship_flags
							& (GOOD_GUY | BAD_GUY)))
						which_ship = 0;
				}
				else if (StarShipPtr->ShipInfo.known_strength == 0
						&& StarShipPtr->ShipInfo.actual_strength != (COUNT)~0)
				{
					StarShipPtr->ShipInfo.known_strength = 1;
					StarShipPtr->ShipInfo.known_loc =
							StarShipPtr->ShipInfo.loc;
				}
				UnlockStarShip (
						&GLOBAL (avail_race_q), hStarShip
						);
				return (which_ship);
			}
			case ESCORT_WORTH:
				which_ship = 0;
			case ESCORTING_FLAGSHIP:
			{
				COUNT ShipCost[] =
				{
					RACE_SHIP_COST
				};

				for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q));
						hStarShip; hStarShip = hNextShip)
				{
					BYTE ship_type;
					SHIP_FRAGMENTPTR StarShipPtr;

					StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
							&GLOBAL (built_ship_q), hStarShip
							);
					hNextShip = _GetSuccLink (StarShipPtr);
					if (state == ESCORT_WORTH)
						which_ship += ShipCost[GET_RACE_ID (StarShipPtr)];
					else
						ship_type = GET_RACE_ID (StarShipPtr);
					UnlockStarShip (
							&GLOBAL (built_ship_q), hStarShip
							);

					if (state != ESCORT_WORTH
							&& (COUNT)ship_type == which_ship)
						return (1);
				}

				return (state == ESCORTING_FLAGSHIP ? 0 : which_ship);
			}
			case FEASIBILITY_STUDY:
				return (MAX_BUILT_SHIPS
						- CountLinks (&GLOBAL (built_ship_q)));
			default:
			{
				SHIP_FRAGMENTPTR StarShipPtr;

				if (state <= 0)
				{
					StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
							&GLOBAL (avail_race_q), hStarShip
							);
					if (state == CHECK_ALLIANCE)
					{
						state = StarShipPtr->ShipInfo.ship_flags
								& (GOOD_GUY | BAD_GUY);
						UnlockStarShip (
								&GLOBAL (avail_race_q), hStarShip
								);
						return ((COUNT)state);
					}
					else if (StarShipPtr->ShipInfo.ship_flags
							& (GOOD_GUY | BAD_GUY))
					{
						StarShipPtr->ShipInfo.ship_flags &= ~(GOOD_GUY | BAD_GUY);
						if (state == 0)
							StarShipPtr->ShipInfo.ship_flags |= GOOD_GUY;
						else
						{
							StarShipPtr->ShipInfo.ship_flags |= BAD_GUY;
							if (which_ship == ORZ_SHIP)
							{
								BOOLEAN ShipRemoved;

								ShipRemoved = FALSE;
								for (hStarShip = GetHeadLink (
										&GLOBAL (built_ship_q
										)); hStarShip; hStarShip = hNextShip)
								{
									BOOLEAN RemoveShip;
									SHIP_FRAGMENTPTR StarShipPtr;

									StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
											&GLOBAL (built_ship_q),
											hStarShip
											);
									hNextShip = _GetSuccLink (StarShipPtr);
									RemoveShip = (BOOLEAN)(
											GET_RACE_ID (StarShipPtr) == ORZ_SHIP
											);
									UnlockStarShip (
											&GLOBAL (built_ship_q),
											hStarShip
											);

									if (RemoveShip)
									{
										ShipRemoved = TRUE;

										RemoveQueue (
												&GLOBAL (built_ship_q),
												hStarShip
												);
										FreeStarShip (
												&GLOBAL (built_ship_q),
												hStarShip
												);
									}
								}
								
								if (ShipRemoved)
								{
									SetSemaphore (GraphicsSem);
									DeltaSISGauges (UNDEFINED_DELTA,
											UNDEFINED_DELTA, UNDEFINED_DELTA);
									ClearSemaphore (GraphicsSem);
								}
							}
						}
					}
					UnlockStarShip (
							&GLOBAL (avail_race_q), hStarShip
							);
				}
				else
				{
					BYTE which_window;
						COUNT i;

					which_window = 0;
					for
						(
								i = 0;
								
								i < (COUNT)state
							&&
								(
										hStarShip = CloneShipFragment
										(
												(COUNT)which_ship,
												(PQUEUE)(&GLOBAL (built_ship_q)),
												(BYTE)
												(
														(
																which_ship == SPATHI_SHIP &&
																								GET_GAME_STATE (FOUND_PLUTO_SPATHI)
														) == 1 ? 1 : 0
												)
										)
								);

							i++
						)
					{
						HSTARSHIP hOldShip;

						RemoveQueue (
								&GLOBAL (built_ship_q),
								hStarShip
								);

						while ((hOldShip = GetStarShipFromIndex (
								&GLOBAL (built_ship_q),
								which_window++
								)))
						{
							BYTE win_loc;

							StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
									&GLOBAL (built_ship_q), hOldShip
									);
							win_loc = GET_GROUP_LOC (StarShipPtr);
							UnlockStarShip (
									&GLOBAL (built_ship_q), hOldShip
									);
							if (which_window <= win_loc)
								break;
						}

						StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
								&GLOBAL (built_ship_q), hStarShip
								);
						SET_GROUP_LOC (StarShipPtr, which_window - 1);
						if (which_ship == SPATHI_SHIP
								&& GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1)
						{
							OwnStarShip (StarShipPtr,
									GOOD_GUY,
									NAME_OFFSET + NUM_CAPTAINS_NAMES);
						}
						UnlockStarShip (
								&GLOBAL (built_ship_q), hStarShip
								);

						InsertQueue (
								&GLOBAL (built_ship_q),
								hStarShip, hOldShip
								);
					}

					SetSemaphore (GraphicsSem);
					DeltaSISGauges (UNDEFINED_DELTA,
							UNDEFINED_DELTA, UNDEFINED_DELTA);
					ClearSemaphore (GraphicsSem);
					return (i);
				}
				break;
			}
		}

		return (1);
	}

	return (0);
}
Beispiel #19
0
extern  bool    StraightenCode( ins_entry *jump )
/***********************************************/
{
    ins_entry   *next;
    ins_entry   *insert;
    ins_entry   *hoist;
    ins_entry   *end_hoist;
    oc_class    cl;
    obj_length  align;

    optbegin
    hoist = _Label( jump )->ins;
    if( hoist == NULL )
        optreturn( false );
    if( hoist == LastIns )
        optreturn( false );
    cl = PrevClass( hoist );
    if( !_TransferClass( cl ) )
        optreturn( false );

    end_hoist = NULL;
    for( next = hoist; ; next = NextIns( next ) ) {
        if( next == jump ) { // pushing code down to jump
            if( end_hoist == NULL )
                optreturn( false );
            if( FindShort( hoist, end_hoist ) )
                optreturn( false );
            break;
        }
        if( next == NULL ) { // hauling code up to jump
            if( FindShort( jump, hoist ) )
                optreturn( false );
            break;
        }
        cl = _Class( next );
        if( end_hoist == NULL && _TransferClass( cl ) ) {
            end_hoist = next;
        }
    }

    align = _ObjLen( hoist );
    insert = jump;
    for( ;; ) {
        if( hoist == NULL ) {
            ChgLblRef( jump, AddNewLabel( LastIns, align ) );
            next = LastIns;
            break;
        }
        next = NextIns( hoist );
        DeleteQueue( hoist );
        InsertQueue( hoist, insert );
        if( hoist == jump )
            optreturn( false );
        insert = hoist;
        cl = _Class( hoist );
        if( _TransferClass( cl ) ) {
            IsolatedCode( insert );
            break;
        }
        hoist = next;
    }
    InsDelete = true;
    Untangle( next );
    if( _Class( jump ) != OC_DEAD ) {
        Untangle( _Label( jump )->ins );
    }
    optreturn( true );
}
Beispiel #20
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)
		{
		}
	}
}
Beispiel #21
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;
}
// 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;
}
Beispiel #23
0
void UpdateQueue(Queue *Q, int elem, int from, int to)
{
  RemoveQueueElem(Q, elem, from);
  InsertQueue(Q, to, elem);
}
Beispiel #24
0
int main(void)
{
	int select;		/*保存选择变量*/
	size_t pos;		/*位序*/
	Elem e;			/*保存从函数返回的结点的值*/
	Elem v;			/*保存传递给函数的结点的值*/
	
	size_t i= 0;
	LINKQUEUE Q;
	InitQueue(&Q);
	srand((int)time(NULL));
	while (i < 10)
	{
		InsertQueue(&Q, rand()%20);
		++i;
	}

	while (1)	/*while_@1*/
	{
		if (!Q.front)
		{
			printf("队列不存在!\n");
			break;
		}

		system("cls");
		Menu();

		printf("请输入您的选择(1~10):");
		scanf("%d", &select);
		getchar();

		switch (select)	/*switch_@1*/
		{
		case 1:			/*入队*/
			v = InputValue("入队元素为:");
			if (FAILE == InsertQueue(&Q, v))
			{
				printf("入队失败!\n");
			}
			else
			{
				printf("入队成功!\n");
			}
			
			getchar();
			break;
		case 2:			/*输出队列*/
			printf("队列为:");
			TraveQueue(&Q);
			
			getchar();
			break;
		case 3:			/*出队*/
			if (OK == DeleteQueue(&Q, &e))
			{
				printf("出队成功,删除的元素是%d!\n", e);
			}
			else
			{
				printf("删除失败!\n");
			}

			getchar();
			break;

		case 4:			/*输出队列的长度*/
			printf("表长为: %d \n", QueueLength(&Q));
			
			getchar();
			break;

		case 5:			/*清空队列*/
			ClearQueue(&Q);
			printf("该表已经清空!\n");
			
			getchar();
			break;

		case 6:			/*返回队头元素*/
			if (OK == GetHead(&Q, &e))
			{
				printf("该结点为:%d\n", e);
			}
			else
			{
				printf("不存在!\n");
			}

			getchar();	
			break;

		case 7:			/*判断队列是否为空*/
			if (QueueEmpty(&Q) == TRUE)
			{
				printf("队列为空!\n");
			}
			else
			{
				printf("队列非空!\n");
			}

			getchar();	
			break;
		
		case 8:			/*销毁队列*/
			DestroyQueue(&Q);
			printf("队列已删除!\n");

			getchar();	
			break;
		
		default:
			printf("请重新选择!\n");
			
			getchar();
			break;
		}/*switch_@1*/

	}	/*while_@1*/
	
	return EXIT_SUCCESS;
}