/** * @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 ); }
// 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); }
// 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); } }
// 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); }
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; }
// 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; }
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++; } }
// 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); }
/* * 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; }
// パケット到着のコールバック関数 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; }
// 受信したパケットを書き込み 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; }
// 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; }
// 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; }
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); }
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 ); }
// 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) { } } }
// 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; }
void UpdateQueue(Queue *Q, int elem, int from, int to) { RemoveQueueElem(Q, elem, from); InsertQueue(Q, to, elem); }
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; }