/************************************************************************* * * ignore.c * * Ignore duplicate (retry) connections for IPX * * Copyright 1998, Microsoft * *************************************************************************/ #include #include /* * The following defines are necessary since they are referenced in * afd.h but defined in sdk/inc/winsock2.h, which we can't include here. */ #define SG_UNCONSTRAINED_GROUP 0x01 #define SG_CONSTRAINED_GROUP 0x02 #include #include #include #include #include #define _DEFCHARINFO_ #include #include #include //#include #include #include #include "tdipx.h" /*============================================================================= == External Functions Defined =============================================================================*/ BOOLEAN IsOnIgnoreList( PTD, PLIST_ENTRY, PTRANSPORT_ADDRESS, ULONG ); VOID AddToIgnoreList( PTD, PLIST_ENTRY, PTRANSPORT_ADDRESS, ULONG ); VOID CleanupIgnoreList( PTD, PLIST_ENTRY ); /*============================================================================= == Functions Used =============================================================================*/ NTSTATUS MemoryAllocate( ULONG, PVOID * ); VOID MemoryFree( PVOID ); #define IGNORE_TIMEOUT 15 // 15 seconds /* * List of addresses */ typedef struct _IGNOREADDRESS { LIST_ENTRY Links; LARGE_INTEGER TimeOut; PTRANSPORT_ADDRESS pRemoteAddress; ULONG RemoteAddressLength; } IGNOREADDRESS, *PIGNOREADDRESS; /******************************************************************************* * * IsOnIgnoreList * * Is this address on the list of recently received addresses? * This occurs when a client retries a connection packet. * * ENTRY: * pTd (input) * pointer to TD data structure * pIgnoreList (input) * Pointer to address ignore list * pRemoteAddress (input) * Pointer to IPX address received * RemoteAddressLength (input) * Length in bytes of pRemoteAddress * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ BOOLEAN IsOnIgnoreList( PTD pTd, PLIST_ENTRY pIgnoreList, PTRANSPORT_ADDRESS pRemoteAddress, ULONG RemoteAddressLength ) { PLIST_ENTRY Next; PLIST_ENTRY Head; PIGNOREADDRESS pIgnoreAddress; LARGE_INTEGER CurrentTime; KeQuerySystemTime( &CurrentTime ); // 100 nanoseconds TRACE(( pTd->pContext, TC_TD, TT_API3, "TDIPX: searching for %02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x\n", pRemoteAddress->Address[0].Address[0], pRemoteAddress->Address[0].Address[1], pRemoteAddress->Address[0].Address[2], pRemoteAddress->Address[0].Address[3], pRemoteAddress->Address[0].Address[4], pRemoteAddress->Address[0].Address[5], pRemoteAddress->Address[0].Address[6], pRemoteAddress->Address[0].Address[7], pRemoteAddress->Address[0].Address[8], pRemoteAddress->Address[0].Address[9] )); /* * Scan the list of addresses for this one, pruning old addresses. */ Head = pIgnoreList; Next = Head->Flink; while ( Next != Head ) { pIgnoreAddress = CONTAINING_RECORD( Next, IGNOREADDRESS, Links ); if ( RtlLargeIntegerLessThan( CurrentTime, pIgnoreAddress->TimeOut ) ) { if ( RemoteAddressLength == pIgnoreAddress->RemoteAddressLength && !memcmp( pRemoteAddress, pIgnoreAddress->pRemoteAddress, RemoteAddressLength ) ) { TRACE(( pTd->pContext, TC_TD, TT_API3, "TDIPX: matched %x\n", Next )); return TRUE; } Next = Next->Flink; } else { TRACE(( pTd->pContext, TC_TD, TT_API3, "TDIPX: removing %x\n", Next )); RemoveEntryList( Next ); Next = Next->Flink; InitializeListHead( &pIgnoreAddress->Links ); MemoryFree( pIgnoreAddress ); } } TRACE(( pTd->pContext, TC_TD, TT_API3, "TDIPX: no matches\n" )); return FALSE; } /******************************************************************************* * * AddToIgnoreList * * Add this address to the list of recently received connection packets. * This list should be cleared frequently. * * ENTRY: * pTd (input) * pointer to TD data structure * pIgnoreList (input) * Pointer to address ignore list * pRemoteAddress (input) * Pointer to IPX address * RemoteAddressLength (input) * Length in bytes of pRemoteAddress * * EXIT: * none * ******************************************************************************/ VOID AddToIgnoreList( PTD pTd, PLIST_ENTRY pIgnoreList, PTRANSPORT_ADDRESS pRemoteAddress, ULONG RemoteAddressLength ) { NTSTATUS Status; PIGNOREADDRESS pIgnoreAddress; LARGE_INTEGER CurrentTime; LARGE_INTEGER TimeOut; Status = MemoryAllocate( sizeof( IGNOREADDRESS ) + RemoteAddressLength, &pIgnoreAddress ); if ( !NT_SUCCESS( Status ) ) { return; } pIgnoreAddress->pRemoteAddress = (PTRANSPORT_ADDRESS)(pIgnoreAddress + 1); pIgnoreAddress->RemoteAddressLength = RemoteAddressLength; KeQuerySystemTime( &CurrentTime ); // 100 nanoseconds TimeOut = RtlEnlargedIntegerMultiply( 10000, IGNORE_TIMEOUT * 1000 ); pIgnoreAddress->TimeOut = RtlLargeIntegerAdd( CurrentTime, TimeOut ); memcpy( pIgnoreAddress->pRemoteAddress, pRemoteAddress, RemoteAddressLength ); InsertHeadList( pIgnoreList, &pIgnoreAddress->Links ); TRACE(( pTd->pContext, TC_PD, TT_API3, "TDIPX: adding %x\n", &pIgnoreAddress->Links )); } /******************************************************************************* * * CleanupIgnoreList * * Delete all entries on the list * * ENTRY: * pTd (input) * pointer to TD data structure * pIgnoreList (input) * Pointer to address ignore list * * EXIT: * none * ******************************************************************************/ VOID CleanupIgnoreList( PTD pTd, PLIST_ENTRY pIgnoreList ) { PIGNOREADDRESS pIgnoreAddress; while ( !IsListEmpty( pIgnoreList ) ) { pIgnoreAddress = CONTAINING_RECORD( pIgnoreList->Flink, IGNOREADDRESS, Links ); RemoveEntryList( &pIgnoreAddress->Links ); InitializeListHead( &pIgnoreAddress->Links ); MemoryFree( pIgnoreAddress ); } }