Leaked source code of windows server 2003
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.
 
 
 
 
 
 

294 lines
8.5 KiB

/*++
Copyright (c) 1997-2001 Microsoft Corporation
Module Name:
NsPacketRoutines.h
Abstract:
This file contains the code for the packet-routines used for
connection routines.
The inbound routines have the exact same logic as the outbound routines.
However, for reasons of efficiency the two are separate routines,
to avoid the cost of indexing on 'NsDirection' for every packet
processed.
To avoid duplicating the code, then, this header file consolidates the code
in one location. This file is included twice in NsPacket.c, and before each
inclusion, either 'NS_INBOUND' or 'NS_OUTBOUND' is defined.
This causes the compiler to generate the code for separate functions,
as desired, while avoiding the unpleasantness of code-duplication.
Each routine is invoked from 'NsProcess*Packet' at dispatch level
with no locks held and with a reference acquired for the connection
entry.
Author:
Jonathan Burstein (jonburs) 20-July-2001
Environment:
Kernel mode
Revision History:
--*/
#ifdef NS_INBOUND
#define NS_POSITIVE NsInboundDirection
#define NS_NEGATIVE NsOutboundDirection
#define NS_TCP_ROUTINE NsInboundTcpPacketRoutine
#define NS_UDP_ROUTINE NsInboundUdpPacketRoutine
#define NS_TCP_TRANSLATE_PORT_ROUTINE NsInboundTcpTranslatePortPacketRoutine
#define NS_UDP_TRANSLATE_PORT_ROUTINE NsInboundUdpTranslatePortPacketRoutine
#define NS_PACKET_FIN NS_CONNECTION_FLAG_IB_FIN
#define NS_TRANSLATE_PORTS_TCP() \
pContext->pTcpHeader->SourcePort = \
CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsOutboundDirection])
#define NS_TRANSLATE_PORTS_UDP() \
pContext->pUdpHeader->SourcePort = \
CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsOutboundDirection])
#else
#define NS_POSITIVE NsOutboundDirection
#define NS_NEGATIVE NsInboundDirection
#define NS_TCP_ROUTINE NsOutboundTcpPacketRoutine
#define NS_UDP_ROUTINE NsOutboundUdpPacketRoutine
#define NS_TCP_TRANSLATE_PORT_ROUTINE NsOutboundTcpTranslatePortPacketRoutine
#define NS_UDP_TRANSLATE_PORT_ROUTINE NsOutboundUdpTranslatePortPacketRoutine
#define NS_PACKET_FIN NS_CONNECTION_FLAG_OB_FIN
#define NS_TRANSLATE_PORTS_TCP() \
pContext->pTcpHeader->DestinationPort = \
CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsInboundDirection])
#define NS_TRANSLATE_PORTS_UDP() \
pContext->pUdpHeader->DestinationPort = \
CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsInboundDirection])
#endif
NTSTATUS
FASTCALL
NS_TCP_ROUTINE(
PNS_CONNECTION_ENTRY pConnection,
PNS_PACKET_CONTEXT pContext
)
{
KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
//
// Update the connection state based on the flags in the packet:
//
// When a RST is seen, mark the connection for deletion
// When a FIN is seen, mark the connection appropriately
// When both FINs have been seen, mark the connection for deletion
//
if (TCP_FLAG(pContext->pTcpHeader, RST))
{
pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
}
else if (TCP_FLAG(pContext->pTcpHeader, FIN))
{
pConnection->ulFlags |= NS_PACKET_FIN;
if (NS_CONNECTION_FIN(pConnection))
{
pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
//
// Perform a final update of the timestamp for the connection.
// From this point on the timestamp is used to determine when
// this connection has left the time-wait state.
//
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
}
}
//
// Update the timestamp for the connection (if this connection is not in
// a timer-wait state -- i.e., both FINs have not been seen).
//
if (!NS_CONNECTION_FIN(pConnection))
{
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
}
KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
//
// Periodically resplay the connection entry
//
NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
return STATUS_SUCCESS;
} // NS_TCP_ROUTINE
NTSTATUS
FASTCALL
NS_UDP_ROUTINE(
PNS_CONNECTION_ENTRY pConnection,
PNS_PACKET_CONTEXT pContext
)
{
KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
//
// Update the timestamp for the connection
//
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
//
// Periodically resplay the connection entry
//
NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
return STATUS_SUCCESS;
} // NS_UDP_ROUTINE
NTSTATUS
FASTCALL
NS_TCP_TRANSLATE_PORT_ROUTINE(
PNS_CONNECTION_ENTRY pConnection,
PNS_PACKET_CONTEXT pContext
)
{
ULONG ulChecksumDelta;
//
// Translate the port information in the packet
//
NS_TRANSLATE_PORTS_TCP();
//
// Update the protocol checksum
//
CHECKSUM_XFER(ulChecksumDelta, pContext->pTcpHeader->Checksum);
ulChecksumDelta += pConnection->ulProtocolChecksumDelta[NS_POSITIVE];
CHECKSUM_FOLD(ulChecksumDelta);
CHECKSUM_XFER(pContext->pTcpHeader->Checksum, ulChecksumDelta);
KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
//
// Update the connection state based on the flags in the packet:
//
// When a RST is seen, mark the connection for deletion
// When a FIN is seen, mark the connection appropriately
// When both FINs have been seen, mark the connection for deletion
//
if (TCP_FLAG(pContext->pTcpHeader, RST))
{
pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
}
else if (TCP_FLAG(pContext->pTcpHeader, FIN))
{
pConnection->ulFlags |= NS_PACKET_FIN;
if (NS_CONNECTION_FIN(pConnection))
{
pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
//
// Perform a final update of the timestamp for the connection.
// From this point on the timestamp is used to determine when
// this connection has left the time-wait state.
//
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
}
}
//
// Update the timestamp for the connection (if this connection is not in
// a timer-wait state -- i.e., both FINs have not been seen).
//
if (!NS_CONNECTION_FIN(pConnection))
{
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
}
KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
//
// Periodically resplay the connection entry
//
NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
return STATUS_SUCCESS;
} // NS_TCP_TRANSLATE_PORT_ROUTINE
NTSTATUS
FASTCALL
NS_UDP_TRANSLATE_PORT_ROUTINE(
PNS_CONNECTION_ENTRY pConnection,
PNS_PACKET_CONTEXT pContext
)
{
ULONG ulChecksumDelta;
//
// Translate the port information in the packet
//
NS_TRANSLATE_PORTS_UDP();
//
// Update the protocol checksum if the original packet contained
// a checksum (UDP checksum is optional)
//
if (0 != pContext->pUdpHeader->Checksum)
{
CHECKSUM_XFER(ulChecksumDelta, pContext->pUdpHeader->Checksum);
ulChecksumDelta += pConnection->ulProtocolChecksumDelta[NS_POSITIVE];
CHECKSUM_FOLD(ulChecksumDelta);
CHECKSUM_XFER(pContext->pUdpHeader->Checksum, ulChecksumDelta);
}
KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
//
// Update the timestamp for the connection
//
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
//
// Periodically resplay the connection entry
//
NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
return STATUS_SUCCESS;
} // NS_UDP_TRANSLATE_PORT_ROUTINE
#undef NS_POSITIVE
#undef NS_NEGATIVE
#undef NS_TCP_ROUTINE
#undef NS_UDP_ROUTINE
#undef NS_TCP_TRANSLATE_PORT_ROUTINE
#undef NS_UDP_TRANSLATE_PORT_ROUTINE
#undef NS_PACKET_FIN
#undef NS_TRANSLATE_PORTS_TCP
#undef NS_TRANSLATE_PORTS_UDP