Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

229 lines
6.5 KiB

/*************************************************************************
*
* ignore.c
*
* Ignore duplicate (retry) connections for IPX
*
* Copyright 1998, Microsoft
*
*************************************************************************/
#include <ntddk.h>
#include <tdi.h>
/*
* 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 <afd.h>
#include <isnkrnl.h>
#include <ndis.h>
#include <wsnwlink.h>
#include <winstaw.h>
#define _DEFCHARINFO_
#include <icadd.h>
#include <ctxdd.h>
#include <icaipx.h>
//#include <cxstatus.h>
#include <sdapi.h>
#include <td.h>
#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 );
}
}