亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來(lái)到蟲(chóng)蟲(chóng)下載站! | ?? 資源下載 ?? 資源專(zhuān)輯 ?? 關(guān)于我們
? 蟲(chóng)蟲(chóng)下載站

?? broadcast.c

?? Vitual Ring Routing 管你知不知道
?? C
字號(hào):
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// (c) Microsoft Corporation. All rights reserved. 
//
// This file is part of the Microsoft Virtual Ring Routing distribution.
// You should have received a copy of the Microsoft Research Shared Source
// license agreement (MSR-SSLA) for this software; see the file "license.txt".
// If not, please see http://research.microsoft.com/vrr/license.htm,
// or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
//

//
// Maintains list of broadcast packets received and potentially awaiting tx iff acting as a relay.
//

#include "headers.h"

//* BroadcastListInit
//
//  Initialize Broadcast list.
//
void
BroadcastListInit(BroadcastList *BL)
{
    KeInitializeSpinLock(&BL->Lock);
    BL->FirstBLE = BL->LastBLE = SentinelBLE(BL);
}

//* AddRefBLE
void
AddRefBLE(BroadcastListEntry *BLE)
{
    InterlockedIncrement(&BLE->RefCnt);
}

//* ReleaseBLE
void
ReleaseBLE(BroadcastListEntry *BLE)
{
    if (InterlockedDecrement(&BLE->RefCnt) == 0) {
        if (BLE->Buffer != NULL)
            ExFreePool(BLE->Buffer);
        ExFreePool(BLE);
    }
}

//* RemoveBLE
//
//  Caller must hold BL->Lock.
//
void
RemoveBLE(
    BroadcastList *BL,
    BroadcastListEntry *BLE)
{
    //
    // Sanity checks.
    //
    VRRASSERT(BLE != (BroadcastListEntry *)BL);

    //
    // Adjust pointers and free memory.
    //
    BLE->Next->Prev = BLE->Prev;
    BLE->Prev->Next = BLE->Next;
    ReleaseBLE(BLE);
    ReleaseBLE(BLE);
}

//* InsertBLE
//
//  Insert BLE into Broadcast List.
//
//  Caller must hold the BL->Lock.
//
void
InsertBLE(
    MiniportAdapter *VA,
    BroadcastListEntry *BLE)
{
    BroadcastList *BL = &VA->BL;
    BroadcastListEntry *NextBLE;
    uint RemoveNext = FALSE;

    VRRASSERT(BL != NULL);
    VRRASSERT(BLE != NULL);

    //
    // Find insertion point for the BLE in the list.
    //
    for (NextBLE = BL->FirstBLE; 
         NextBLE != SentinelBLE(BL);
         NextBLE = NextBLE->Next) {

         if (VirtualAddressLessThan(BLE->Origin,NextBLE->Origin))
             continue;
         if (VirtualAddressGreaterThan(BLE->Origin,NextBLE->Origin))
             break;
         if (BLE->FrameSeqNo < NextBLE->FrameSeqNo)
             continue;
         if (BLE->FrameSeqNo > NextBLE->FrameSeqNo)
             break;
         if (BLE->Timeout > NextBLE->Timeout)
             continue;
    }

    //
    // Insert the new BLE immediately prior to NextBLE.
    //
    BLE->Prev = NextBLE->Prev;
    BLE->Prev->Next = BLE;
    BLE->Next = NextBLE;
    BLE->Next->Prev = BLE;
    AddRefBLE(BLE);
    AddRefBLE(BLE);

    if (RemoveNext == TRUE)
        RemoveBLE(BL,NextBLE);
   
}

//* CreateBLE
//
//  Allocate a new Broadcast List entry.
//
BroadcastListEntry *
CreateBLE(
    VirtualAddress Origin,
    uint FrameSeqNo)
{
    BroadcastListEntry *BLE;

    BLE = ExAllocatePool(NonPagedPool, sizeof *BLE);
    if (BLE == NULL)
        return NULL;

    //
    // Initialize the BLE.
    //
    RtlZeroMemory(BLE, sizeof *BLE);
    RtlCopyMemory(BLE->Origin,Origin,sizeof(VirtualAddress));
    BLE->FrameSeqNo = FrameSeqNo;

    return BLE;
}

//* FindBLE
//
//  Returns BLE iff in Broadcast List, else NULL.
//
//  Caller must hold the BL->Lock.
//
BroadcastListEntry *
FindBLE(
    BroadcastList *BL,
    VirtualAddress Origin,
    uint FrameSeqNo)
{
    BroadcastListEntry *BLE;

    VRRASSERT(BL != NULL);

    for (BLE = BL->FirstBLE; 
         BLE != SentinelBLE(BL);
         BLE = BLE->Next) {
         
        if (VirtualAddressEqual(BLE->Origin, Origin))
        if (FrameSeqNo == BLE->FrameSeqNo)
            return BLE;
    }

    return NULL;    
}

//* IsBroadcastRelay
//
//  Returns TRUE iff acting as relay for broadcast packets.
//
uint 
IsBroadcastRelay(
    MiniportAdapter *VA)
{
    return InterlockedCompareExchange(&VA->BroadcastRelay,FALSE,FALSE);
}

//* BroadcastListCleanup
//
// Flush the Broadcast list.
//
void
BroadcastListCleanup(
    MiniportAdapter *VA)
{
    BroadcastListEntry *BLE;
    BroadcastList *BL = &VA->BL;
    KIRQL OldIrql;

    KeAcquireSpinLock(&VA->BL.Lock, &OldIrql);
    while ((BLE = BL->FirstBLE) != SentinelBLE(BL))
        RemoveBLE(BL, BLE);
    KeReleaseSpinLock(&VA->BL.Lock, OldIrql);
}

//* BroadcastPacketComplete
//
//  Completion handler after sending a broadcast packet.
//  Cleans up the SRP packet from which NDIS packets were cloned.
//
void
BroadcastPacketComplete(
    MiniportAdapter *VA,
    SRPacket *srp,
    NDIS_STATUS Status)
{
    UNREFERENCED_PARAMETER(VA);
    UNREFERENCED_PARAMETER(Status);

    SRPacketFree(srp);
}


//* BroadcastOnEachAdapter
//
//  Sends a packet via every physical adapter simultaneously.
//  The operation completes when the last underlying transmit completes.
//  The operation completes successfully only if every
//  underlying transmit is successful.
//
void
BroadcastOnEachAdapter(
    MiniportAdapter *VA,
    SRPacket *srp,
    char *Buffer,
    uint BufferLen)
{
    ProtocolAdapter *PA;
    NDIS_PACKET *PacketList = NULL;
    NDIS_PACKET *Packet;
    NDIS_STATUS Status;
    KIRQL OldIrql;
    uint HeaderLength = SROptionListLength((InternalOption *)srp->VrrHello);

    //
    // We start with one reference (our own) for the SRPacket.
    //
    srp->ForwardCount = 1;
    srp->ForwardStatus = NDIS_STATUS_SUCCESS;

    //
    // First we build a temporary list of packet structures
    // and corresponding physical adapters. While doing this,
    // we also initialize the transmission count.
    // It starts with one, for our own reference for OrigPacket.
    //
    KeAcquireSpinLock(&VA->Lock, &OldIrql);
    for (PA = VA->PhysicalAdapters;
         PA != NULL;
         PA = PA->Next) {

        void *Data;
        EtherHeader *Ether;
        VRRHeader *VRR;
        char* pPayload;
        InternalOption *IntOpt;

        //
        // Unpack SRPacket into NDIS packet for transmission.
        // Do this manually: we hold VA->Lock which prevents
        // us using the normal tx path through FindNextHop.
        //
        Status = MiniportMakeEmptyPacket(VA,
                        sizeof(EtherHeader) + sizeof(VRRHeader) + HeaderLength + BufferLen,
                        &Packet, &Data);

        if (Status != NDIS_STATUS_SUCCESS) {
            KdPrint(("VrrBroadcast: MiniportMakeEmptyPacket() -> %8x\n",Status));
            continue;
        }

        //
        // Initialize ether header.
        //
        Ether = (EtherHeader *) Data;
        //RtlFillMemory(Ether->Dest, IEEE_802_ADDR_LENGTH, (uchar)0xff);
        RtlCopyMemory(Ether->Dest, srp->EtherDest, sizeof(VirtualAddress));
        Ether->Type = ETYPE_MSFT;

        //
        // Initialize VRR header.
        //
        VRR = (VRRHeader *) (Ether + 1);
        VRR->Code = VRR_CODE;
        RtlCopyMemory(VRR->IV, srp->IV, VRR_IV_LENGTH);
        VRR->HeaderLength = (ushort) HeaderLength;
        RtlCopyMemory(VRR->Source, VA->Address, sizeof(VirtualAddress));
        RtlFillMemory(VRR->Dest, sizeof(VirtualAddress), (uchar)0xff);
        RtlCopyMemory(VRR->Origin, srp->Origin, sizeof(VirtualAddress));
        VRR->FrameSeqNo = RtlUlongByteSwap(srp->FrameSeqNo);
        VRR->HopCount = srp->HopCount + 1;
        RtlCopyMemory(VRR->MAC, VA->CryptoKeyMAC, VRR_MAC_LENGTH);

        //
        // Initialize packet payload.
        //
        pPayload = (char *)(VRR + 1);
        if (BufferLen != 0)
            RtlCopyMemory(pPayload,Buffer,BufferLen);

        //
        // Remember the packet and corresponding physical adapter.
        // We temporarily use the OrigPacket field to build our list.
        //
        PC(Packet)->PA = PA;
        PC(Packet)->OrigPacket = PacketList;
        PacketList = Packet;
        srp->ForwardCount++;
    }
    KeReleaseSpinLock(&VA->Lock, OldIrql);

    //
    // Now we can transmit the packet via each physical adapter,
    // using the new packet structures.
    //
    while ((Packet = PacketList) != NULL) {
        PacketList = PC(Packet)->OrigPacket;
        PA = PC(Packet)->PA;

        //
        // Send the packet via a physical adapter.
        //
        PC(Packet)->srp = srp;
        PC(Packet)->TransmitComplete = VrrBroadcastComplete;
        ProtocolTransmit(PA, Packet);
    }

    //
    // Release our reference for the original packet.
    //
    if (InterlockedDecrement((PLONG)&srp->ForwardCount) == 0) {
        //
        // Complete the operation.
        //
        (*srp->TransmitComplete)(VA, srp, srp->ForwardStatus);
    }
}

//* BroadcastBLE
//
//  Creates a packet to send a broadcast.
//
static NDIS_STATUS
BroadcastBLE(
    MiniportAdapter *VA,
    BroadcastListEntry *BLE)
{
    SRPacket *SRP;
    NDIS_STATUS Status;
    KIRQL OldIrql;

    //
    // Initialize an SRPacket for the packet.
    //
    SRP = ExAllocatePool(NonPagedPool, sizeof *SRP);
    if (SRP == NULL) {
        return NDIS_STATUS_RESOURCES;
    }
    RtlZeroMemory(SRP, sizeof *SRP);

    //
    // Initialize the source & destination of this packet.
    //
    RtlCopyMemory(SRP->EtherDest, BLE->EthDest, sizeof(VirtualAddress));
    RtlCopyMemory(SRP->Source, VA->Address, sizeof(VirtualAddress));
    RtlCopyMemory(SRP->Dest, BLE->EthDest, sizeof(VirtualAddress));
    RtlCopyMemory(SRP->Origin, BLE->Origin, sizeof(VirtualAddress));
    SRP->FrameSeqNo = BLE->FrameSeqNo;
    SRP->HopCount = BLE->HopCount;
    SRP->TransmitComplete = VrrBroadcastSRPComplete;

    BroadcastOnEachAdapter(VA, SRP, BLE->Buffer, BLE->BufferLen);

    return NDIS_STATUS_SUCCESS;
}

//* UpdateBroadcastList
//
//  Update existing BLE or create a new one.
//
//  Returns TRUE iff a new BLE was created.
//
//  Caller must not hold BL->Lock.
//
uint
UpdateBroadcastList(
    MiniportAdapter *VA,
    VirtualAddress Origin,
    uint FrameSeqNo,
    uchar HopCount,
    VirtualAddress Source,
    VirtualAddress EthDest,
    uint Forward,
    uchar Buffer[],
    uint BufferLen)
{
    BroadcastList *BL = &VA->BL;
    BroadcastListEntry *BLE;
    uint NewBLE = FALSE;
    KIRQL OldIrql;
    Time Now = KeQueryInterruptTime();
    Time Timeout = 0;

    VRRASSERT(IsIEEEGroupAddress(EthDest));

    KeAcquireSpinLock(&VA->BL.Lock, &OldIrql);

    //
    // BLE have unique keys (Origin,FrameSeqNo).
    // Decide whether this is new or duplicate broadcast.
    //
    if (FindBLE(BL, Origin,FrameSeqNo) == NULL)
        NewBLE = TRUE;

    //
    // Update non-key fields within the BLE.
    //
    if ((BLE=CreateBLE(Origin,FrameSeqNo)) != NULL) {
        InsertBLE(VA, BLE);
        BLE->HopCount = HopCount;
        RtlCopyMemory(BLE->Source,Source,sizeof(VirtualAddress));
        RtlCopyMemory(BLE->EthDest,EthDest,sizeof(VirtualAddress));
        BLE->Timeout = Now + BLE_LIFETIME;
        BLE->Forward = Forward;
        BLE->Flags = (NewBLE) ? BLE_FLAG_NEW : BLE_FLAG_DUP;
        if (NewBLE == TRUE &&
            (BLE->Buffer = ExAllocatePool(NonPagedPool,BufferLen)) != NULL) {
            BLE->BufferLen = BufferLen;
            RtlCopyMemory(BLE->Buffer,Buffer,BufferLen);
        }
        if (NewBLE == TRUE && BLE->Forward == TRUE) {
            //
            // Avoid tripping over assert gt zero in reschedule timeout code.
            //
            Timeout = Now + BC_JITTER + (1 * MILLISECOND);
            BLE->TxTimeout = Timeout;

            //
            // Inline tx when MaxJitter==0 avoids inaccuracy in timeout scheduling.
            //
            if (VA->BroadcastJitterMaxMs == 0) {
                BroadcastBLE(VA,BLE);
                BLE->TxTimeout = 0;
            }
        }
    }

    KeReleaseSpinLock(&VA->BL.Lock, OldIrql);

    if (Timeout != 0)
        MiniportRescheduleTimeout(VA,Now,Timeout);

    return NewBLE;
}

//* BroadcastListTimeout
//
//  Housekeeping of Broadcast List.
//
Time
BroadcastListTimeout(
    MiniportAdapter *VA,
    Time Now)
{
    NDIS_STATUS Status;
    LARGE_INTEGER Timestamp;
    LARGE_INTEGER Frequency;
    KIRQL OldIrql;
    Time NextTimeout = Now + MIN_BLE_TIMOUT_INTERVAL;
    BroadcastList *BL = &VA->BL;
    BroadcastListEntry *BLE;
    BroadcastListEntry *NextBLE;

    KeAcquireSpinLock(&VA->BL.Lock, &OldIrql);

    for (BLE = VA->BL.FirstBLE;
         BLE != SentinelBLE(&VA->BL);
         BLE = NextBLE) {

        Time BLETimeout = BLE->Timeout;

        NextBLE = BLE->Next;

        if (BLE->TxTimeout != 0 && BLE->TxTimeout < Now) {
            BroadcastBLE(VA,BLE);
            BLE->TxTimeout = 0;
        }

        if (BLETimeout < Now)
            RemoveBLE(BL,BLE);

        if (BLETimeout > Now && BLETimeout < NextTimeout)
            NextTimeout = BLETimeout;
        
    }

    KeReleaseSpinLock(&VA->BL.Lock, OldIrql);

    return NextTimeout;
}

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产一区二区三区久久久 | 亚洲一区二区精品久久av| 欧美国产精品v| 久久久亚洲精品石原莉奈| 精品国产人成亚洲区| 欧美一区二区在线观看| 欧美一区二区三区免费| 欧美一区二区在线视频| 日韩精品一区二区三区在线播放| 日韩欧美区一区二| 精品国产第一区二区三区观看体验 | 国产精品91xxx| 国产一区二区不卡| 国产精品69久久久久水密桃| 国产91丝袜在线观看| 不卡的av在线播放| 日本精品视频一区二区| 欧美视频中文字幕| 欧美一区二区私人影院日本| 久久一夜天堂av一区二区三区| 久久这里只有精品视频网| 国产欧美日韩激情| 亚洲欧美自拍偷拍色图| 一区二区三区四区不卡在线 | 欧美主播一区二区三区美女| 日韩毛片一二三区| 一区二区三区中文免费| 香蕉加勒比综合久久| 美国欧美日韩国产在线播放| 风间由美一区二区三区在线观看 | 午夜久久福利影院| 久久国产精品72免费观看| 国产伦精品一区二区三区免费| 成人久久久精品乱码一区二区三区| 91在线国产观看| 欧美日韩国产经典色站一区二区三区| 777欧美精品| 国产视频911| 亚洲一区在线观看网站| 久久精品国产精品亚洲综合| 国产91精品露脸国语对白| 色综合激情久久| 欧美一级精品在线| 国产日韩欧美精品电影三级在线 | 成人成人成人在线视频| 欧美日韩三级在线| 国产日产亚洲精品系列| 午夜电影网一区| 成人在线视频一区二区| 欧美美女直播网站| 国产婷婷色一区二区三区四区 | 国产精品资源在线观看| 欧美性做爰猛烈叫床潮| 国产亚洲一本大道中文在线| 亚洲va欧美va人人爽| 风流少妇一区二区| 欧美一级免费观看| 亚洲精品成a人| 韩国一区二区三区| 欧美日韩精品二区第二页| 中文字幕不卡在线| 美女www一区二区| 欧美亚洲高清一区| 国产精品福利一区| 久久不见久久见免费视频7| 色噜噜狠狠色综合欧洲selulu| 久久亚洲免费视频| 日韩在线观看一区二区| 一本色道久久综合亚洲91| 久久久不卡网国产精品二区| 性久久久久久久久| 色婷婷综合在线| 欧美激情综合在线| 青青青伊人色综合久久| 色又黄又爽网站www久久| 中文字幕精品三区| 久久99久久久久久久久久久| 欧美日韩精品一区二区在线播放| 国产精品激情偷乱一区二区∴| 精品亚洲porn| 制服.丝袜.亚洲.另类.中文| 一区二区三区四区av| 99在线精品观看| 中文字幕精品综合| 国产成人av电影免费在线观看| 欧美一区二区视频观看视频| 亚洲一级二级在线| 91视频一区二区| 国产精品午夜在线| 成人免费视频视频在线观看免费| 26uuu色噜噜精品一区| 久久精品国产秦先生| 日韩欧美中文字幕制服| 日韩一区精品视频| 欧美日韩日日骚| 一级中文字幕一区二区| 91蜜桃视频在线| 亚洲欧美日韩国产成人精品影院 | 色综合久久天天综合网| 亚洲欧洲三级电影| 国产成a人无v码亚洲福利| 久久九九99视频| 国产白丝网站精品污在线入口| 久久精品在这里| 成人动漫一区二区| 国产精品美女久久久久久久久| 国产91对白在线观看九色| 26uuu色噜噜精品一区| 国产一区二区三区视频在线播放| 日韩精品一区二区三区视频在线观看| 老司机精品视频一区二区三区| 精品国产自在久精品国产| 国产乱码精品一区二区三| 日本一区二区三区久久久久久久久不| 成人性生交大片免费看中文网站| 国产精品国产三级国产| 一本色道**综合亚洲精品蜜桃冫| 一区二区三区资源| 欧美日韩国产影片| 免费观看久久久4p| 久久久一区二区| 成人黄色免费短视频| 一区二区三区在线播放| 欧美精品三级在线观看| 精品一区二区三区在线播放视频 | 国产视频在线观看一区二区三区| 成人免费观看男女羞羞视频| 亚洲日本电影在线| 在线不卡a资源高清| 九色综合国产一区二区三区| 国产欧美一区二区在线| 欧美中文一区二区三区| 麻豆成人久久精品二区三区小说| 久久女同精品一区二区| www.日本不卡| 午夜精品影院在线观看| 久久久九九九九| 色悠悠亚洲一区二区| 日本vs亚洲vs韩国一区三区| 26uuu精品一区二区| 一本在线高清不卡dvd| 欧美a一区二区| 国产精品女主播在线观看| 欧美日韩中文字幕一区| 国产精品正在播放| 亚洲精品乱码久久久久久久久| 91麻豆精品国产91久久久久| 高清久久久久久| 视频一区在线视频| 国产欧美一区二区精品性色超碰| 欧洲视频一区二区| 国产成人亚洲精品狼色在线| 亚洲主播在线观看| 久久久久久免费网| 欧美久久免费观看| 国产成人综合亚洲91猫咪| 一个色在线综合| 亚洲精品一线二线三线| 在线亚洲高清视频| 懂色av噜噜一区二区三区av| 亚洲不卡在线观看| 国产精品毛片久久久久久久| 91麻豆精品国产91久久久久久 | 国产午夜亚洲精品不卡| 欧美这里有精品| 国产成a人亚洲精| 老鸭窝一区二区久久精品| 亚洲精品日日夜夜| 美女高潮久久久| 亚洲免费av网站| 国产肉丝袜一区二区| 67194成人在线观看| 99re这里只有精品首页| 韩国精品免费视频| 日韩中文字幕区一区有砖一区 | 亚洲免费观看高清完整版在线观看| 日韩欧美一级二级三级久久久| 91日韩精品一区| 韩国中文字幕2020精品| 日韩二区三区四区| 亚洲国产欧美一区二区三区丁香婷| 日本一区二区动态图| 久久婷婷一区二区三区| 欧美一区二区三区人| 欧美日韩在线播放三区四区| 91蝌蚪国产九色| 成人一道本在线| 国产精品一二三四五| 蜜乳av一区二区| 偷偷要91色婷婷| 亚洲第一狼人社区| 亚洲美女淫视频| 国产精品久久久一区麻豆最新章节| 精品国产伦一区二区三区免费| 91精品国产综合久久福利软件 | 欧美一区二区久久久| 欧亚洲嫩模精品一区三区| 色婷婷久久一区二区三区麻豆| av网站免费线看精品| 成人性视频网站|