|
|
/* dwRetval = MgmAddGroupMembershipEntry(g_MgmIgmprtrHandle, 0, 0,
pge->Group, 0, IfIndex, NHAddr);
dwRetval = MgmDeleteGroupMembershipEntry(g_MgmIgmprtrHandle, 0, 0, pge->Group, 0, pite->IfIndex, NHAddr); */
//=============================================================================
// Copyright (c) 1997 Microsoft Corporation
// File: table2.c
//
// Abstract:
// This module implements some of the routines associated with getting
// entries. and some debug routines
//
// GetRasClientByAddr, GetIfByIndex, InsertIfByAddr, MatchIpAddrBinding,
// GetGroupFromGroupTable, GetGIFromGIList, GetGIFromGIList.
//
// DebugPrintGIList, DebugPrintGroups, DebugPrintLocks
//
// Author: K.S.Lokesh (lokeshs@) 11-1-97
//
// Revision History:
//=============================================================================
#include "pchigmp.h"
#pragma hdrstop
//------------------------------------------------------------------------------
// _GetRasClientByAddr
// Returns pointer to Ras clients RasTableEntry
//------------------------------------------------------------------------------
PRAS_TABLE_ENTRY GetRasClientByAddr ( DWORD NHAddr, PRAS_TABLE prt ) { PRAS_TABLE_ENTRY pite = NULL; PLIST_ENTRY phead, ple; PRAS_TABLE_ENTRY prte=NULL;
phead = &prt->HashTableByAddr[RAS_HASH_VALUE(NHAddr)];
for (ple=phead->Flink; ple!=phead; ple=ple->Flink) {
prte = CONTAINING_RECORD(ple, RAS_TABLE_ENTRY, HTLinkByAddr);
if (prte->NHAddr == NHAddr) { break; } }
return (ple == phead) ? NULL: prte; }
//------------------------------------------------------------------------------
// _GetIfByIndex
//
// returns the interface with the given index.
// assumes the interface bucket is either read or write locked
//------------------------------------------------------------------------------
PIF_TABLE_ENTRY GetIfByIndex( DWORD IfIndex ) { PIF_TABLE_ENTRY pite = NULL; PLIST_ENTRY phead, ple;
phead = &g_pIfTable->HashTableByIndex[IF_HASH_VALUE(IfIndex)];
for (ple=phead->Flink; ple!=phead; ple=ple->Flink) {
pite = CONTAINING_RECORD(ple, IF_TABLE_ENTRY, HTLinkByIndex);
if (pite->IfIndex == IfIndex) { break; } }
return (ple == phead) ? NULL: pite; }
//------------------------------------------------------------------------------
// _InsertIfByAddr
//
// inserts the activated interface into the list of interfaces sorted by address.
// assumes the table is locked for writing
//------------------------------------------------------------------------------
DWORD InsertIfByAddr( PIF_TABLE_ENTRY piteInsert ) {
PIF_TABLE_ENTRY pite; INT cmp, cmp1; DWORD InsertAddr; PLIST_ENTRY phead, ple;
phead = &g_pIfTable->ListByAddr;
InsertAddr = piteInsert->IpAddr;
//
// search for the insertion point
//
for (ple=phead->Flink; ple!=phead; ple=ple->Flink) {
pite = CONTAINING_RECORD(ple, IF_TABLE_ENTRY, LinkByAddr);
if ( (cmp1 = INET_CMP(InsertAddr, pite->IpAddr, cmp)) < 0) break;
//
// return error if there are duplicate addresses.
// no error for unnumbered interfaces, ie for addr==0
//
else if ( (cmp1==0) && (InsertAddr!=0) ) return ERROR_ALREADY_EXISTS; }
InsertTailList(ple, &piteInsert->LinkByAddr);
return NO_ERROR; }
//------------------------------------------------------------------------------
// MatchIpAddrBinding //
// finds if the interface is bound to any address equal to IpAddr //
//------------------------------------------------------------------------------
BOOL MatchIpAddrBinding( PIF_TABLE_ENTRY pite, DWORD IpAddr ) { PIGMP_IP_ADDRESS paddr; DWORD i; PIGMP_IF_BINDING pib;
pib = pite->pBinding; paddr = IGMP_BINDING_FIRST_ADDR(pib);
for (i=0; i<pib->AddrCount; i++,paddr++) { if (IpAddr==paddr->IpAddr) break; }
return (i<pib->AddrCount)? TRUE: FALSE; }
//------------------------------------------------------------------------------
// _InsertInGroupsList
//
// Inserts a newly created group in the New or Main group list.
// Calls: May call _MergeGroupLists() to merge the New and Main lists
//------------------------------------------------------------------------------
VOID InsertInGroupsList ( PGROUP_TABLE_ENTRY pgeNew ) { PGROUP_TABLE_ENTRY pgeTmp; PLIST_ENTRY pHead, ple; DWORD GroupLittleEndian = pgeNew->GroupLittleEndian; BOOL bInsertInNew; //
// insert the group in main list if less than 20 entries, else insert in
// the New list
//
bInsertInNew = (g_Info.CurrentGroupMemberships > 20);
pHead = bInsertInNew ? &g_pGroupTable->ListByGroupNew : &g_pGroupTable->ListByGroup.Link;
for (ple=pHead->Flink; ple!=pHead; ple=ple->Flink) { pgeTmp = CONTAINING_RECORD(ple, GROUP_TABLE_ENTRY, LinkByGroup); if (GroupLittleEndian<pgeTmp->GroupLittleEndian) break; } InsertTailList(ple, &pgeNew->LinkByGroup);
if (bInsertInNew) {
// increment count of
g_pGroupTable->NumGroupsInNewList++;
//
// merge lists if required
//
if (MERGE_GROUP_LISTS_REQUIRED()) {
MergeGroupLists();
} }
return; }
//------------------------------------------------------------------------------
// _InsertInIfGroupsList
// Inserts a newly created group in the New or Main group list.
// Calls: May call MergeIfGroupLists() to merge the New and Main lists
//------------------------------------------------------------------------------
VOID InsertInIfGroupsList ( PIF_TABLE_ENTRY pite, PGI_ENTRY pgiNew ) { PGI_ENTRY pgiTmp; PLIST_ENTRY pHead, ple; DWORD GroupLittleEndian = pgiNew->pGroupTableEntry->GroupLittleEndian; BOOL bInsertInNew;
//
// insert the group in main list if less than 20 entries, else insert in
// the New list
//
bInsertInNew = (pite->Info.CurrentGroupMemberships > 20);
pHead = bInsertInNew ? &pite->ListOfSameIfGroupsNew : &pite->ListOfSameIfGroups;
for (ple=pHead->Flink; ple!=pHead; ple=ple->Flink) { pgiTmp = CONTAINING_RECORD(ple, GI_ENTRY, LinkBySameIfGroups); if (GroupLittleEndian<pgiTmp->pGroupTableEntry->GroupLittleEndian) break; } InsertTailList(ple, &pgiNew->LinkBySameIfGroups);
if (bInsertInNew) {
// increment count of
pite->NumGIEntriesInNewList++;
//
// merge lists if required
//
if (MERGE_IF_GROUPS_LISTS_REQUIRED(pite)) {
MergeIfGroupsLists(pite);
} }
return; }//end _InsertInIfGroupsList
//------------------------------------------------------------------------------
// InsertInProxyList
//------------------------------------------------------------------------------
VOID InsertInProxyList ( PIF_TABLE_ENTRY pite, PPROXY_GROUP_ENTRY pNewProxyEntry ) { PPROXY_GROUP_ENTRY pTmpProxyEntry; PLIST_ENTRY pHead, ple; DWORD GroupLittleEndian = pNewProxyEntry->GroupLittleEndian; BOOL bInsertInNew;
//
// dont insert in new list if less than 20 entries, else insert in
// the New list
//
bInsertInNew = (pite->NumGIEntriesInNewList > 20);
pHead = bInsertInNew ? &pite->ListOfSameIfGroupsNew : &pite->ListOfSameIfGroups;
for (ple=pHead->Flink; ple!=pHead; ple=ple->Flink) { pTmpProxyEntry = CONTAINING_RECORD(ple, PROXY_GROUP_ENTRY, LinkBySameIfGroups); if (GroupLittleEndian<pTmpProxyEntry->GroupLittleEndian) break; } InsertTailList(ple, &pNewProxyEntry->LinkBySameIfGroups);
if (bInsertInNew) {
// increment count of
pite->NumGIEntriesInNewList++;
//
// merge lists if required
//
if (MERGE_PROXY_LISTS_REQUIRED(pite)) {
MergeProxyLists(pite);
} }
return; }//end _InsertInProxyList
//------------------------------------------------------------------------------
// _GetGroupFromGroupTable
// Returns the group entry. If group entry does not exist and bCreateFlag is
// set, then it will take a group-list lock and create a new entry.
// Locks:
// Assumes lock on group bucket.
// takes group-list lock if new group is being created.
// If read only, assumes lock on group list
//------------------------------------------------------------------------------
PGROUP_TABLE_ENTRY GetGroupFromGroupTable ( DWORD Group, BOOL *bCreate, //set to true if new one created
LONGLONG llCurrentTime ) { PGROUP_TABLE_ENTRY pge; //group table entry
PLIST_ENTRY pHead, ple; DWORD Error = NO_ERROR; DWORD bCreateLocal; DWORD GroupLittleEndian = NETWORK_TO_LITTLE_ENDIAN(Group); bCreateLocal = (bCreate==NULL) ? FALSE : *bCreate;
if (llCurrentTime==0) llCurrentTime = GetCurrentIgmpTime();
BEGIN_BREAKOUT_BLOCK1 { // get pointer to the head of the group bucket
pHead = &g_pGroupTable->HashTableByGroup[GROUP_HASH_VALUE(Group)].Link;
// search for the group
for (ple=pHead->Flink; ple!=pHead; ple=ple->Flink) { pge = CONTAINING_RECORD(ple, GROUP_TABLE_ENTRY, HTLinkByGroup); if (GroupLittleEndian>=pge->GroupLittleEndian) { break; } }
//
// group entry not found
//
if ( (ple==pHead) || (pge->GroupLittleEndian!=GroupLittleEndian) ) {
//
// create and initialize new entry
//
if (bCreateLocal) { bCreateLocal = TRUE; pge = IGMP_ALLOC(sizeof(GROUP_TABLE_ENTRY), 0x800010,0xaaaa);
PROCESS_ALLOC_FAILURE2(pge, "Error %d allocation %d bytes for Group table entry", Error, sizeof(GROUP_TABLE_ENTRY), GOTO_END_BLOCK1);
InsertTailList(ple, &pge->HTLinkByGroup); InitializeListHead(&pge->LinkByGroup);
pge->Group = Group; pge->GroupLittleEndian = GroupLittleEndian; pge->NumVifs = 0; pge->Status = CREATED_FLAG; pge->GroupUpTime = llCurrentTime;
//
// insert it into the list of all groups after taking the group
// list lock
//
{ PGROUP_TABLE_ENTRY pgeTmp; PLIST_ENTRY pHeadTmp, pleTmp;
// take group list lock
ACQUIRE_GROUP_LIST_LOCK("_GetGroupFromGroupTable");
// initialize GI list head
InitializeListHead(&pge->ListOfGIs);
// insert in group list
InsertInGroupsList(pge);
// release group lock
RELEASE_GROUP_LIST_LOCK("_GetGroupFromGroupTable"); }
// update statistics
InterlockedIncrement(&g_Info.CurrentGroupMemberships); InterlockedIncrement(&g_Info.GroupMembershipsAdded); } // not found group, and do not create new group. So return NULL.
else { pge = NULL; GOTO_END_BLOCK1; } } //
// group entry found
//
else { bCreateLocal = FALSE; }
} END_BREAKOUT_BLOCK1;
if (bCreate!=NULL) *bCreate = bCreateLocal;
#if DBG
DebugPrintGroupsList(1); #endif
return pge; } //end _GetGroupFromGroupTable
//------------------------------------------------------------------------------
// _GetGIFromGIList
//
// returns the GI entry if it exists. If the bCreate flag is set, then it creates
// a new GI entry if it does not exist.
//
// Locks: Assumes shared interface lock. If ras interface, also assumes shared
// Ras interface lock.
// Assumes lock on group bucket.
// Takes IF_GROUP_LIST_LOCK if new entry is to be created.
// On return: bCreate is set to TRUE if a new entry was created
//------------------------------------------------------------------------------
PGI_ENTRY GetGIFromGIList ( PGROUP_TABLE_ENTRY pge, PIF_TABLE_ENTRY pite, DWORD dwInputSrcAddr, //used for NHAddr
BOOL bStaticGroup, BOOL *bCreate, LONGLONG llCurrentTime ) { DWORD IfIndex = pite->IfIndex; BOOL bRasClient; PLIST_ENTRY pHead, ple; PGI_ENTRY pgie; PRAS_TABLE_ENTRY prte; PRAS_TABLE prt; BOOL bRasNewGroup = TRUE; //true if 1st ras group
DWORD NHAddr; DWORD Error = NO_ERROR, dwRetval, i; BOOL bFound = FALSE, bCreateLocal;
Trace2(ENTER1, "Entering _GetGIFromGIList() IfIndex(%0x) Group(%d.%d.%d.%d)", IfIndex, PRINT_IPADDR(pge->Group));
//DebugPrintIfGroups(pite,0);//deldel
bCreateLocal = (bCreate==NULL) ? FALSE : *bCreate;
if (llCurrentTime==0) llCurrentTime = GetCurrentIgmpTime(); BEGIN_BREAKOUT_BLOCK1 { //
// find out if ras-server.
//
bRasClient = IS_RAS_SERVER_IF(pite->IfType); if (bRasClient) { prt = pite->pRasTable;
// get ras client
prte = GetRasClientByAddr(dwInputSrcAddr, prt); } NHAddr = bRasClient ? dwInputSrcAddr : 0;
//
// search for GI entry
//
pHead = &pge->ListOfGIs;
for (ple=pHead->Flink; ple!=pHead; ple=ple->Flink) { pgie = CONTAINING_RECORD(ple, GI_ENTRY, LinkByGI); if (pgie->IfIndex>IfIndex) break;
//
// GI with same interface index
//
else if (pgie->IfIndex==IfIndex) {
// the GI entry might belong to some interface being deleted
if ( (pite!=pgie->pIfTableEntry) ||(IS_IF_DELETED(pgie->pIfTableEntry)) ) continue;
//multiple entries for ras clients
if (bRasClient) {
//
// I set this even if the ras client is marked to be deleted
//
bRasNewGroup = FALSE;
// the GI entry might belong to some other ras interface
// being deleted
if ( (prte!=pgie->pRasTableEntry) || (pgie->pRasTableEntry->Status&DELETED_FLAG) ) continue;
if (pgie->NHAddr>dwInputSrcAddr) { break; } // found GI entry for ras interface
else if (pgie->NHAddr==dwInputSrcAddr) { bFound = TRUE; break; } } // found GI entry for non ras interface
else { bFound = TRUE; break; } } }// end for loop:search through list of GIs
//
// GIentry not found
//
if ( !bFound) {
// dont create new GI entry. Hence, return NULL
if (!bCreateLocal) { pgie = NULL; GOTO_END_BLOCK1; }
//
// create and initialize new GI-entry
//
pgie = IGMP_ALLOC_AND_ZERO(sizeof(GI_ENTRY), 0x800011, pite->IfIndex);
PROCESS_ALLOC_FAILURE2(pgie, "Error %d allocating %d bytes for group-interface entry", Error, sizeof(GI_ENTRY), GOTO_END_BLOCK1);
pgie->IfIndex = IfIndex; pgie->Status = CREATED_FLAG; pgie->bRasClient = bRasClient;
// insert in GI list
InsertTailList(ple, &pgie->LinkByGI);
//
// set back pointers to the interface entry, and group entry
//
pgie->pIfTableEntry = pite; pgie->pGroupTableEntry = pge;
//
// Take lock on Interface-Group List before inserting into it
// for ras client, insert it into ras client list also
//
ACQUIRE_IF_GROUP_LIST_LOCK(pite->IfIndex, "_GetGIFromGIList");
// insert in ras client list
if (bRasClient) {
PLIST_ENTRY pleTmp, pHeadRasClient; PGI_ENTRY pgieRasClient;
pHeadRasClient = &prte->ListOfSameClientGroups; for (pleTmp=pHeadRasClient->Flink; pleTmp!=pHeadRasClient; pleTmp=pleTmp->Flink) { pgieRasClient = CONTAINING_RECORD(pleTmp, GI_ENTRY, LinkBySameClientGroups); if (pge->Group < pgieRasClient->pGroupTableEntry->Group) break; } InsertTailList(pleTmp, &pgie->LinkBySameClientGroups); }
InsertInIfGroupsList(pite, pgie);
RELEASE_IF_GROUP_LIST_LOCK(pite->IfIndex, "_GetGIFromGIList");
//
// if ras
//
pgie->NHAddr = (bRasClient)? dwInputSrcAddr : 0; pgie->pRasTableEntry = (bRasClient)? prte : NULL;
//
// initialize GroupMembershipTimer
//
pgie->GroupMembershipTimer.Function = T_MembershipTimer; pgie->GroupMembershipTimer.Timeout = pite->Config.GroupMembershipTimeout; pgie->GroupMembershipTimer.Context = &pgie->GroupMembershipTimer.Context; pgie->GroupMembershipTimer.Status = TIMER_STATUS_CREATED;
//
// initialize LastMemQueryTimer timer
//
pgie->LastMemQueryCount = 0; //last member countdown inactive
pgie->LastMemQueryTimer.Function = T_LastMemQueryTimer; pgie->LastMemQueryTimer.Context = &pgie->LastMemQueryTimer.Context; pgie->LastMemQueryTimer.Status = TIMER_STATUS_CREATED;
//
// initialize the LastVer1ReportTimer
// the timeout value is set to GroupMembership timeout
pgie->LastVer1ReportTimer.Function = T_LastVer1ReportTimer; pgie->LastVer1ReportTimer.Timeout = pite->Config.GroupMembershipTimeout; pgie->LastVer1ReportTimer.Context = &pgie->LastVer1ReportTimer.Context; pgie->LastVer1ReportTimer.Status = TIMER_STATUS_CREATED;
pgie->LastVer2ReportTimer.Function = T_LastVer2ReportTimer; pgie->LastVer2ReportTimer.Timeout = pite->Config.GroupMembershipTimeout; pgie->LastVer2ReportTimer.Context = &pgie->LastVer2ReportTimer.Context; pgie->LastVer2ReportTimer.Status = TIMER_STATUS_CREATED;
// set version based on current interface version
pgie->Version = (IS_IF_VER1(pite)) ? 1 : ((IS_IF_VER2(pite))?2:3);
//
// initialize GI_INFO
//
ZeroMemory(&pgie->Info, sizeof(GI_INFO)); pgie->Info.GroupUpTime = llCurrentTime; if (!bStaticGroup) { pgie->Info.GroupExpiryTime = llCurrentTime + CONFIG_TO_SYSTEM_TIME(pite->Config.GroupMembershipTimeout); } pgie->Info.V1HostPresentTimeLeft = 0; pgie->Info.V2HostPresentTimeLeft = 0; pgie->Info.LastReporter = dwInputSrcAddr;
//
// v3 fields
//
pgie->V3InclusionList = (PLIST_ENTRY) IGMP_ALLOC(sizeof(LIST_ENTRY)*SOURCES_BUCKET_SZ, 0x800020, pite->IfIndex); PROCESS_ALLOC_FAILURE2(pgie->V3InclusionList, "Error %d allocating sources table:%d bytes", Error, sizeof(LIST_ENTRY)*SOURCES_BUCKET_SZ, GOTO_END_BLOCK1); for (i=0; i<SOURCES_BUCKET_SZ; i++) InitializeListHead(&pgie->V3InclusionList[i]); InitializeListHead(&pgie->V3InclusionListSorted); pgie->NumSources = 0; pgie->FilterType = INCLUSION; InitializeListHead(&pgie->V3ExclusionList); InitializeListHead(&pgie->V3SourcesQueryList); pgie->V3SourcesQueryCount = 0;
// V3SourcesQueryTimer
pgie->V3SourcesQueryTimer.Function = T_V3SourcesQueryTimer; pgie->V3SourcesQueryTimer.Context = &pgie->V3SourcesQueryTimer.Context; pgie->V3SourcesQueryTimer.Status = TIMER_STATUS_CREATED;
// set static group flag
pgie->bStaticGroup = bStaticGroup;
//
// increment the count of number of If's for that group
// I increment once for each virtual interface
//
InterlockedIncrement(&pge->NumVifs);
if (!bRasClient||(bRasClient&bRasNewGroup) ) { InterlockedIncrement(&pite->Info.CurrentGroupMemberships); InterlockedIncrement(&pite->Info.GroupMembershipsAdded); } //
// update stats for ras client
//
if ((bRasClient) && (g_Config.RasClientStats) ) { InterlockedIncrement(&prte->Info.CurrentGroupMemberships); InterlockedIncrement(&prte->Info.GroupMembershipsAdded); } //
// Join the group to MGM
//
// call mgm to join the group only if the interface is
// activated, enabled by mgm, either mprotocol exists or else
// igmprtr is a querier on this interface
if (CAN_ADD_GROUPS_TO_MGM(pite) && (pgie->bStaticGroup||!IS_IF_VER3(pite)) ) { MGM_ADD_GROUP_MEMBERSHIP_ENTRY(pite, NHAddr, 0, 0, pge->Group, 0xffffffff, MGM_JOIN_STATE_FLAG); }
//
// v3 no MGM calls, as I create an inclusion list with null members.
//
} // if GI entry not found
// GI entry found
else { if (bStaticGroup) pgie->bStaticGroup = TRUE; bCreateLocal = FALSE; } } END_BREAKOUT_BLOCK1;
if (bCreate!=NULL) *bCreate = bCreateLocal;
Trace0(LEAVE1, "Leaving _GetGIFromGIList()");
//Trace1(ENTER1, "GetGiFromGiList returned:%0x", (DWORD)pgie);//deldel
return pgie;
} //end _GetGIFromGIList
//------------------------------------------------------------------------------
// _DebugPrintGIList
//------------------------------------------------------------------------------
VOID DebugPrintGIList ( PGROUP_TABLE_ENTRY pge, LONGLONG llCurTime ) { PGI_ENTRY pgie; PLIST_ENTRY pHead, ple;
pHead = &pge->ListOfGIs;
for (ple=pHead->Flink; ple!=pHead; ple=ple->Flink) {
pgie = CONTAINING_RECORD(ple, GI_ENTRY, LinkByGI);
if (pgie->Status&IF_DELETED_FLAG) continue;
//
// GI info
//
Trace4(GROUP, "---If(%0x: %d.%d.%d.%d) NHAddr(%d.%d.%d.%d) GroupMembershipTimer(%d sec)", pgie->IfIndex, PRINT_IPADDR(pgie->pIfTableEntry->IpAddr), PRINT_IPADDR(pgie->NHAddr), (pgie->GroupMembershipTimer.Timeout-llCurTime)/1000 );
//
// if leave being processed
//
if (IS_TIMER_ACTIVE(pgie->LastMemQueryTimer)) { Trace2(GROUP, " *Leave received: LastMemQueryCount:%d LastMemQueryTimeLeft(%d ms)", pgie->LastMemQueryCount, (DWORD) (pgie->LastMemQueryTimer.Timeout-llCurTime) ); } }
Trace0(GROUP, "");
return; }
//------------------------------------------------------------------------------
// DebugPrintGroups
//------------------------------------------------------------------------------
VOID APIENTRY DebugPrintGroups ( DWORD Flags ) { DWORD Group, i, j, k; DWORD IfIndex; PLIST_ENTRY pHead, ple; DWORD Count; PGROUP_TABLE_ENTRY pge; //group table entry
LONGLONG llCurTime = GetCurrentIgmpTime();
j = 1;
Trace0(GROUP, ""); for (i=0; i<GROUP_HASH_TABLE_SZ; i++) { ACQUIRE_GROUP_LOCK(i, "_DebugPrintGroups"); pHead = &g_pGroupTable->HashTableByGroup[i].Link;
for (ple=pHead->Flink; ple!=pHead; ple=ple->Flink) { pge = CONTAINING_RECORD(ple, GROUP_TABLE_ENTRY, HTLinkByGroup);
//
// print group info
//
Trace3(GROUP, "(%d) Group:%d.%d.%d.%d UpTime(%lu sec)", j++, PRINT_IPADDR(pge->Group), (llCurTime-pge->GroupUpTime)/1000);
// print GI list
DebugPrintGIList(pge, llCurTime);
}
RELEASE_GROUP_LOCK(i, "_DebugPrintGroups");
}
return; }
VOID DebugPrintIfGroups( PIF_TABLE_ENTRY pite, DWORD flag ) { PGI_ENTRY pgiTmp; PLIST_ENTRY pHead, ple; BOOL bInsertInNew; DWORD count=0; PPROXY_GROUP_ENTRY proxyge; ACQUIRE_IF_GROUP_LIST_LOCK(pite->IfIndex, "_DebugPrintIfGroups");
Trace0(ERR, "---------------DebugPrintIfGroups---------------------"); Trace1(ERR, "Ipaddr: %d.%d.%d.%d", PRINT_IPADDR(pite->IpAddr) ); Trace1(ERR, "CurrentGroupMemberships: %d",pite->Info.CurrentGroupMemberships);
pHead = &pite->ListOfSameIfGroups;
for (ple=pHead->Flink; ple!=pHead && count<300; ple=ple->Flink) {
if (!(flag&IGMP_IF_PROXY)) { pgiTmp = CONTAINING_RECORD(ple, GI_ENTRY, LinkBySameIfGroups); Trace5(SOURCES, "%d: main list: %x:%x:%x: %d.%d.%d.%d", ++count, (ULONG_PTR)ple, (ULONG_PTR)ple->Flink, (ULONG_PTR)ple->Blink, PRINT_IPADDR(pgiTmp->pGroupTableEntry->Group)); } else { proxyge = CONTAINING_RECORD(ple, PROXY_GROUP_ENTRY, LinkBySameIfGroups); Trace5(SOURCES, "%d: proxyMailList: %x:%x:%x: %d.%d.%d.%d", ++count, (ULONG_PTR)ple, (ULONG_PTR)ple->Flink, (ULONG_PTR)ple->Blink, PRINT_IPADDR(proxyge->Group)); } }
pHead = &pite->ListOfSameIfGroupsNew; Trace1(ERR, "NumGIEntriesInNewList:%d", pite->NumGIEntriesInNewList); for (ple=pHead->Flink; ple!=pHead && count<300; ple=ple->Flink) {
if (!(flag&IGMP_IF_PROXY)) { pgiTmp = CONTAINING_RECORD(ple, GI_ENTRY, LinkBySameIfGroups); Trace5(ERR, "%d: NewList: %x:%x:%x: %d.%d.%d.%d", ++count, (ULONG_PTR)ple, (ULONG_PTR)ple->Flink, (ULONG_PTR)ple->Blink, PRINT_IPADDR(pgiTmp->pGroupTableEntry->Group)); } else { proxyge = CONTAINING_RECORD(ple, PROXY_GROUP_ENTRY, LinkBySameIfGroups); Trace5(ERR, "%d: ProxyNewList: %x:%x:%x: %d.%d.%d.%d", ++count, (ULONG_PTR)ple, (ULONG_PTR)ple->Flink, (ULONG_PTR)ple->Blink, PRINT_IPADDR(proxyge->Group)); } }
Trace0(ERR, "-------------------------------------------------------------"); RELEASE_IF_GROUP_LIST_LOCK(pite->IfIndex, "_DebugPrintIfGroups");
//ASSERT(count<300);//deldel
}
DWORD APIENTRY DebugPrintLocks( ) { DWORD Group;
Trace0(KSL, "QUEUEING WORKER THREAD TO DEBUGPRINTLOCKS"); QueueIgmpWorker(DebugPrintLocks, NULL); Trace0(KSL, "QUEUED WORKER THREAD TO DEBUGPRINTLOCKS");
return NO_ERROR; }
VOID DebugPrintLists( PLIST_ENTRY pHead ) { DWORD count=0;
PLIST_ENTRY ple; for (ple=pHead->Flink; (ple!=pHead)&&(count<16); ple=ple->Flink,count++) { Trace3(ERR, "ple:%lu ple->Flink:%lu: ple->Blink:%lu", ple, ple->Flink, ple->Blink);
} }
//------------------------------------------------------------------------------
// _ForcePrintGroupsList
//------------------------------------------------------------------------------
VOID DebugForcePrintGroupsList ( DWORD Flags ) { BOOL bMain = FALSE; CHAR str[2][5] = {"new", "main"}; LIST_ENTRY *ple, *pHead; PGROUP_TABLE_ENTRY pge;
if (g_Info.CurrentGroupMemberships > 40 && !(Flags&ENSURE_EMPTY) ) return;
Trace0(ENTER1, "Entering _ForcePrintGroupsList()");
pHead = &g_pGroupTable->ListByGroupNew;
if (Flags&ENSURE_EMPTY) { if (IsListEmpty(pHead)) return;// list empty as expected
DbgPrint("Cleanup: Group Lists should be empty\n"); IgmpDbgBreakPoint(); }
do { for (ple=pHead->Flink; ple!=pHead; ple=ple->Flink) {
pge = CONTAINING_RECORD(ple, GROUP_TABLE_ENTRY, LinkByGroup);
Trace3(KSL, "%s-group list: <%d.%d.%d.%d> pge:%0x", str[bMain], PRINT_IPADDR(pge->Group), (ULONG_PTR)pge);
if (!IS_MCAST_ADDR(pge->Group)) {
#if DBG
IgmpDbgBreakPoint(); #endif
Trace0(ERR, "==============================================================="); Trace2(ERR, "bad group(%d.%d.%d.%d)(pge:%0x) while checking main-group", PRINT_IPADDR(pge->Group), (ULONG_PTR)pge); Trace0(ERR, "==============================================================="); return; } }
if (!bMain) { pHead = &g_pGroupTable->ListByGroup.Link; bMain = TRUE; } else break; } while (1); Trace0(LEAVE1, "Leaving _ForcePrintGroupsList()");
}
//------------------------------------------------------------------------------
// DebugPrintGroupsList
//------------------------------------------------------------------------------
VOID DebugPrintGroupsList ( DWORD Flags ) { BOOL bMain = FALSE; CHAR str[2][5] = {"new", "main"}; LIST_ENTRY *ple, *pHead; PGROUP_TABLE_ENTRY pge; static DWORD StaticCount; BOOL bPrint = FALSE;
if (StaticCount++==30) { bPrint = TRUE; StaticCount = 0; }
if (g_Info.CurrentGroupMemberships > 40) return; pHead = &g_pGroupTable->ListByGroupNew;
do { for (ple=pHead->Flink; ple!=pHead; ple=ple->Flink) {
pge = CONTAINING_RECORD(ple, GROUP_TABLE_ENTRY, LinkByGroup);
//if ((Flags)&&(bPrint))
if (0) Trace3(KSL, "%s-group list: <%d.%d.%d.%d> pge:%0x", str[bMain], PRINT_IPADDR(pge->Group), (ULONG_PTR)pge);
if (!IS_MCAST_ADDR(pge->Group)) { if (!bPrint) { DebugForcePrintGroupsList(1); return; } #if DBG
IgmpDbgBreakPoint(); #endif
Trace0(ERR, "==============================================================="); Trace2(ERR, "bad group(%d.%d.%d.%d)(pge:%0x) while checking main-group", PRINT_IPADDR(pge->Group), (ULONG_PTR)pge); Trace0(ERR, "==============================================================="); return; } }
if (!bMain) { pHead = &g_pGroupTable->ListByGroup.Link; bMain = TRUE; } else break; } while (1); //Trace0(LEAVE1, "Leaving _PrintGroupsList()");
}
|