mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 13:02:59 +00:00
Create a branch for header work.
svn path=/branches/header-work/; revision=45691
This commit is contained in:
parent
14fe274b1c
commit
9ea495ba33
19538 changed files with 0 additions and 1063950 deletions
249
lib/drivers/ip/transport/tcp/event.c
Normal file
249
lib/drivers/ip/transport/tcp/event.c
Normal file
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS TCP/IP protocol driver
|
||||
* FILE: transport/tcp/event.c
|
||||
* PURPOSE: Transmission Control Protocol -- Events from oskittcp
|
||||
* PROGRAMMERS: Art Yerkes
|
||||
* REVISIONS:
|
||||
* CSH 01/08-2000 Created
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
int TCPSocketState(void *ClientData,
|
||||
void *WhichSocket,
|
||||
void *WhichConnection,
|
||||
OSK_UINT NewState ) {
|
||||
PCONNECTION_ENDPOINT Connection = WhichConnection;
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("Connection: %x Flags: %c%c%c%c%c\n",
|
||||
Connection,
|
||||
NewState & SEL_CONNECT ? 'C' : 'c',
|
||||
NewState & SEL_READ ? 'R' : 'r',
|
||||
NewState & SEL_FIN ? 'F' : 'f',
|
||||
NewState & SEL_ACCEPT ? 'A' : 'a',
|
||||
NewState & SEL_WRITE ? 'W' : 'w'));
|
||||
|
||||
/* If this socket is missing its socket context, that means that it
|
||||
* has been created as a new connection in sonewconn but not accepted
|
||||
* yet. We can safely ignore event notifications on these sockets.
|
||||
* Once they are accepted, they will get a socket context and we will
|
||||
* be able to process them.
|
||||
*/
|
||||
if (!Connection)
|
||||
return 0;
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n",
|
||||
NewState, Connection,
|
||||
Connection->SignalState ^ NewState,
|
||||
NewState));
|
||||
|
||||
Connection->SignalState = NewState;
|
||||
|
||||
HandleSignalledConnection(Connection);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TCPPacketSendComplete( PVOID Context,
|
||||
PNDIS_PACKET NdisPacket,
|
||||
NDIS_STATUS NdisStatus ) {
|
||||
TI_DbgPrint(DEBUG_TCP,("called %x\n", NdisPacket));
|
||||
FreeNdisPacket(NdisPacket);
|
||||
TI_DbgPrint(DEBUG_TCP,("done\n"));
|
||||
}
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
|
||||
int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
|
||||
NDIS_STATUS NdisStatus;
|
||||
PNEIGHBOR_CACHE_ENTRY NCE;
|
||||
IP_PACKET Packet = { 0 };
|
||||
IP_ADDRESS RemoteAddress, LocalAddress;
|
||||
PIPv4_HEADER Header;
|
||||
|
||||
if( *data == 0x45 ) { /* IPv4 */
|
||||
Header = (PIPv4_HEADER)data;
|
||||
LocalAddress.Type = IP_ADDRESS_V4;
|
||||
LocalAddress.Address.IPv4Address = Header->SrcAddr;
|
||||
RemoteAddress.Type = IP_ADDRESS_V4;
|
||||
RemoteAddress.Address.IPv4Address = Header->DstAddr;
|
||||
} else {
|
||||
TI_DbgPrint(MIN_TRACE,("Outgoing packet is not IPv4\n"));
|
||||
OskitDumpBuffer( data, len );
|
||||
return OSK_EINVAL;
|
||||
}
|
||||
|
||||
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
|
||||
TI_DbgPrint(MIN_TRACE,("Unable to get route to %s\n", A2S(&RemoteAddress)));
|
||||
return OSK_EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
NdisStatus = AllocatePacketWithBuffer( &Packet.NdisPacket, NULL, len );
|
||||
|
||||
if (NdisStatus != NDIS_STATUS_SUCCESS) {
|
||||
TI_DbgPrint(DEBUG_TCP, ("Error from NDIS: %08x\n", NdisStatus));
|
||||
return OSK_ENOBUFS;
|
||||
}
|
||||
|
||||
GetDataPtr( Packet.NdisPacket, 0,
|
||||
(PCHAR *)&Packet.Header, &Packet.ContigSize );
|
||||
|
||||
RtlCopyMemory( Packet.Header, data, len );
|
||||
|
||||
Packet.HeaderSize = sizeof(IPv4_HEADER);
|
||||
Packet.TotalSize = len;
|
||||
Packet.SrcAddr = LocalAddress;
|
||||
Packet.DstAddr = RemoteAddress;
|
||||
|
||||
if (!NT_SUCCESS(IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL )))
|
||||
{
|
||||
FreeNdisPacket(Packet.NdisPacket);
|
||||
return OSK_EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Memory management routines
|
||||
*
|
||||
* By far the most requests for memory are either for 128 or 2049 byte blocks,
|
||||
* so we want to satisfy those from lookaside lists. Unfortunately, the
|
||||
* TCPFree() function doesn't pass the size of the block to be freed, so we
|
||||
* need to keep track of it ourselves. We do it by prepending each block with
|
||||
* 4 bytes, indicating if this is a 'L'arge (2049), 'S'mall (128) or 'O'ther
|
||||
* block.
|
||||
*/
|
||||
|
||||
/* Set to some non-zero value to get a profile of memory allocation sizes */
|
||||
#define MEM_PROFILE 0
|
||||
|
||||
#define SMALL_SIZE 128
|
||||
#define LARGE_SIZE 2049
|
||||
|
||||
#define SIGNATURE_LARGE 'LLLL'
|
||||
#define SIGNATURE_SMALL 'SSSS'
|
||||
#define SIGNATURE_OTHER 'OOOO'
|
||||
static NPAGED_LOOKASIDE_LIST LargeLookasideList;
|
||||
static NPAGED_LOOKASIDE_LIST SmallLookasideList;
|
||||
|
||||
NTSTATUS
|
||||
TCPMemStartup( void )
|
||||
{
|
||||
ExInitializeNPagedLookasideList( &LargeLookasideList,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
LARGE_SIZE + sizeof( ULONG ),
|
||||
OSK_LARGE_TAG,
|
||||
0 );
|
||||
ExInitializeNPagedLookasideList( &SmallLookasideList,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
SMALL_SIZE + sizeof( ULONG ),
|
||||
OSK_SMALL_TAG,
|
||||
0 );
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void *TCPMalloc( void *ClientData,
|
||||
OSK_UINT Bytes, OSK_PCHAR File, OSK_UINT Line ) {
|
||||
void *v;
|
||||
ULONG Signature;
|
||||
|
||||
#if 0 != MEM_PROFILE
|
||||
static OSK_UINT *Sizes = NULL, *Counts = NULL, ArrayAllocated = 0;
|
||||
static OSK_UINT ArrayUsed = 0, AllocationCount = 0;
|
||||
OSK_UINT i, NewSize, *NewArray;
|
||||
int Found;
|
||||
|
||||
Found = 0;
|
||||
for ( i = 0; i < ArrayUsed && ! Found; i++ ) {
|
||||
Found = ( Sizes[i] == Bytes );
|
||||
if ( Found ) {
|
||||
Counts[i]++;
|
||||
}
|
||||
}
|
||||
if ( ! Found ) {
|
||||
if ( ArrayAllocated <= ArrayUsed ) {
|
||||
NewSize = ( 0 == ArrayAllocated ? 16 : 2 * ArrayAllocated );
|
||||
NewArray = exAllocatePool( NonPagedPool, 2 * NewSize * sizeof( OSK_UINT ) );
|
||||
if ( NULL != NewArray ) {
|
||||
if ( 0 != ArrayAllocated ) {
|
||||
memcpy( NewArray, Sizes,
|
||||
ArrayAllocated * sizeof( OSK_UINT ) );
|
||||
exFreePool( Sizes );
|
||||
memcpy( NewArray + NewSize, Counts,
|
||||
ArrayAllocated * sizeof( OSK_UINT ) );
|
||||
exFreePool( Counts );
|
||||
}
|
||||
Sizes = NewArray;
|
||||
Counts = NewArray + NewSize;
|
||||
ArrayAllocated = NewSize;
|
||||
} else if ( 0 != ArrayAllocated ) {
|
||||
exFreePool( Sizes );
|
||||
exFreePool( Counts );
|
||||
ArrayAllocated = 0;
|
||||
}
|
||||
}
|
||||
if ( ArrayUsed < ArrayAllocated ) {
|
||||
Sizes[ArrayUsed] = Bytes;
|
||||
Counts[ArrayUsed] = 1;
|
||||
ArrayUsed++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( 0 == (++AllocationCount % MEM_PROFILE) ) {
|
||||
TI_DbgPrint(DEBUG_TCP, ("Memory allocation size profile:\n"));
|
||||
for ( i = 0; i < ArrayUsed; i++ ) {
|
||||
TI_DbgPrint(DEBUG_TCP,
|
||||
("Size %4u Count %5u\n", Sizes[i], Counts[i]));
|
||||
}
|
||||
TI_DbgPrint(DEBUG_TCP, ("End of memory allocation size profile\n"));
|
||||
}
|
||||
#endif /* MEM_PROFILE */
|
||||
|
||||
if ( SMALL_SIZE == Bytes ) {
|
||||
v = ExAllocateFromNPagedLookasideList( &SmallLookasideList );
|
||||
Signature = SIGNATURE_SMALL;
|
||||
} else if ( LARGE_SIZE == Bytes ) {
|
||||
v = ExAllocateFromNPagedLookasideList( &LargeLookasideList );
|
||||
Signature = SIGNATURE_LARGE;
|
||||
} else {
|
||||
v = ExAllocatePoolWithTag( NonPagedPool, Bytes + sizeof(ULONG),
|
||||
OSK_OTHER_TAG );
|
||||
Signature = SIGNATURE_OTHER;
|
||||
}
|
||||
if( v ) {
|
||||
*((ULONG *) v) = Signature;
|
||||
v = (void *)((char *) v + sizeof(ULONG));
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void TCPFree( void *ClientData,
|
||||
void *data, OSK_PCHAR File, OSK_UINT Line ) {
|
||||
ULONG Signature;
|
||||
|
||||
data = (void *)((char *) data - sizeof(ULONG));
|
||||
Signature = *((ULONG *) data);
|
||||
if ( SIGNATURE_SMALL == Signature ) {
|
||||
ExFreeToNPagedLookasideList( &SmallLookasideList, data );
|
||||
} else if ( SIGNATURE_LARGE == Signature ) {
|
||||
ExFreeToNPagedLookasideList( &LargeLookasideList, data );
|
||||
} else if ( SIGNATURE_OTHER == Signature ) {
|
||||
ExFreePoolWithTag( data, OSK_OTHER_TAG );
|
||||
} else {
|
||||
ASSERT( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TCPMemShutdown( void )
|
||||
{
|
||||
ExDeleteNPagedLookasideList( &SmallLookasideList );
|
||||
ExDeleteNPagedLookasideList( &LargeLookasideList );
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue