2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: transport/tcp/event.c
5 * PURPOSE: Transmission Control Protocol -- Events from oskittcp
6 * PROGRAMMERS: Art Yerkes
8 * CSH 01/08-2000 Created
13 int TCPSocketState(void *ClientData
,
15 void *WhichConnection
,
17 PCONNECTION_ENDPOINT Connection
= WhichConnection
;
19 TI_DbgPrint(DEBUG_TCP
,("Connection: %x Flags: %c%c%c%c%c\n",
21 NewState
& SEL_CONNECT
? 'C' : 'c',
22 NewState
& SEL_READ
? 'R' : 'r',
23 NewState
& SEL_FIN
? 'F' : 'f',
24 NewState
& SEL_ACCEPT
? 'A' : 'a',
25 NewState
& SEL_WRITE
? 'W' : 'w'));
27 /* If this socket is missing its socket context, that means that it
28 * has been created as a new connection in sonewconn but not accepted
29 * yet. We can safely ignore event notifications on these sockets.
30 * Once they are accepted, they will get a socket context and we will
31 * be able to process them.
36 TI_DbgPrint(DEBUG_TCP
,("Called: NewState %x (Conn %x) (Change %x)\n",
38 Connection
->SignalState
^ NewState
,
41 Connection
->SignalState
= NewState
;
43 HandleSignalledConnection(Connection
);
48 void TCPPacketSendComplete( PVOID Context
,
49 PNDIS_PACKET NdisPacket
,
50 NDIS_STATUS NdisStatus
) {
51 TI_DbgPrint(DEBUG_TCP
,("called %x\n", NdisPacket
));
52 FreeNdisPacket(NdisPacket
);
53 TI_DbgPrint(DEBUG_TCP
,("done\n"));
56 #define STRINGIFY(x) #x
58 int TCPPacketSend(void *ClientData
, OSK_PCHAR data
, OSK_UINT len
) {
59 NDIS_STATUS NdisStatus
;
60 PNEIGHBOR_CACHE_ENTRY NCE
;
61 IP_PACKET Packet
= { 0 };
62 IP_ADDRESS RemoteAddress
, LocalAddress
;
65 if( *data
== 0x45 ) { /* IPv4 */
66 Header
= (PIPv4_HEADER
)data
;
67 LocalAddress
.Type
= IP_ADDRESS_V4
;
68 LocalAddress
.Address
.IPv4Address
= Header
->SrcAddr
;
69 RemoteAddress
.Type
= IP_ADDRESS_V4
;
70 RemoteAddress
.Address
.IPv4Address
= Header
->DstAddr
;
72 TI_DbgPrint(MIN_TRACE
,("Outgoing packet is not IPv4\n"));
73 OskitDumpBuffer( data
, len
);
77 if(!(NCE
= RouteGetRouteToDestination( &RemoteAddress
))) {
78 TI_DbgPrint(MIN_TRACE
,("Unable to get route to %s\n", A2S(&RemoteAddress
)));
79 return OSK_EADDRNOTAVAIL
;
82 NdisStatus
= AllocatePacketWithBuffer( &Packet
.NdisPacket
, NULL
, len
);
84 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
85 TI_DbgPrint(DEBUG_TCP
, ("Error from NDIS: %08x\n", NdisStatus
));
89 GetDataPtr( Packet
.NdisPacket
, 0,
90 (PCHAR
*)&Packet
.Header
, &Packet
.ContigSize
);
92 RtlCopyMemory( Packet
.Header
, data
, len
);
94 Packet
.HeaderSize
= sizeof(IPv4_HEADER
);
95 Packet
.TotalSize
= len
;
96 Packet
.SrcAddr
= LocalAddress
;
97 Packet
.DstAddr
= RemoteAddress
;
99 if (!NT_SUCCESS(IPSendDatagram( &Packet
, NCE
, TCPPacketSendComplete
, NULL
)))
101 FreeNdisPacket(Packet
.NdisPacket
);
108 /* Memory management routines
110 * By far the most requests for memory are either for 128 or 2049 byte blocks,
111 * so we want to satisfy those from lookaside lists. Unfortunately, the
112 * TCPFree() function doesn't pass the size of the block to be freed, so we
113 * need to keep track of it ourselves. We do it by prepending each block with
114 * 4 bytes, indicating if this is a 'L'arge (2049), 'S'mall (128) or 'O'ther
118 /* Set to some non-zero value to get a profile of memory allocation sizes */
119 #define MEM_PROFILE 0
121 #define SMALL_SIZE 128
122 #define LARGE_SIZE 2049
124 #define SIGNATURE_LARGE 'LLLL'
125 #define SIGNATURE_SMALL 'SSSS'
126 #define SIGNATURE_OTHER 'OOOO'
127 static NPAGED_LOOKASIDE_LIST LargeLookasideList
;
128 static NPAGED_LOOKASIDE_LIST SmallLookasideList
;
131 TCPMemStartup( void )
133 ExInitializeNPagedLookasideList( &LargeLookasideList
,
137 LARGE_SIZE
+ sizeof( ULONG
),
140 ExInitializeNPagedLookasideList( &SmallLookasideList
,
144 SMALL_SIZE
+ sizeof( ULONG
),
148 return STATUS_SUCCESS
;
151 void *TCPMalloc( void *ClientData
,
152 OSK_UINT Bytes
, OSK_PCHAR File
, OSK_UINT Line
) {
157 static OSK_UINT
*Sizes
= NULL
, *Counts
= NULL
, ArrayAllocated
= 0;
158 static OSK_UINT ArrayUsed
= 0, AllocationCount
= 0;
159 OSK_UINT i
, NewSize
, *NewArray
;
163 for ( i
= 0; i
< ArrayUsed
&& ! Found
; i
++ ) {
164 Found
= ( Sizes
[i
] == Bytes
);
170 if ( ArrayAllocated
<= ArrayUsed
) {
171 NewSize
= ( 0 == ArrayAllocated
? 16 : 2 * ArrayAllocated
);
172 NewArray
= exAllocatePool( NonPagedPool
, 2 * NewSize
* sizeof( OSK_UINT
) );
173 if ( NULL
!= NewArray
) {
174 if ( 0 != ArrayAllocated
) {
175 memcpy( NewArray
, Sizes
,
176 ArrayAllocated
* sizeof( OSK_UINT
) );
178 memcpy( NewArray
+ NewSize
, Counts
,
179 ArrayAllocated
* sizeof( OSK_UINT
) );
180 exFreePool( Counts
);
183 Counts
= NewArray
+ NewSize
;
184 ArrayAllocated
= NewSize
;
185 } else if ( 0 != ArrayAllocated
) {
187 exFreePool( Counts
);
191 if ( ArrayUsed
< ArrayAllocated
) {
192 Sizes
[ArrayUsed
] = Bytes
;
193 Counts
[ArrayUsed
] = 1;
198 if ( 0 == (++AllocationCount
% MEM_PROFILE
) ) {
199 TI_DbgPrint(DEBUG_TCP
, ("Memory allocation size profile:\n"));
200 for ( i
= 0; i
< ArrayUsed
; i
++ ) {
201 TI_DbgPrint(DEBUG_TCP
,
202 ("Size %4u Count %5u\n", Sizes
[i
], Counts
[i
]));
204 TI_DbgPrint(DEBUG_TCP
, ("End of memory allocation size profile\n"));
206 #endif /* MEM_PROFILE */
208 if ( SMALL_SIZE
== Bytes
) {
209 v
= ExAllocateFromNPagedLookasideList( &SmallLookasideList
);
210 Signature
= SIGNATURE_SMALL
;
211 } else if ( LARGE_SIZE
== Bytes
) {
212 v
= ExAllocateFromNPagedLookasideList( &LargeLookasideList
);
213 Signature
= SIGNATURE_LARGE
;
215 v
= ExAllocatePoolWithTag( NonPagedPool
, Bytes
+ sizeof(ULONG
),
217 Signature
= SIGNATURE_OTHER
;
220 *((ULONG
*) v
) = Signature
;
221 v
= (void *)((char *) v
+ sizeof(ULONG
));
227 void TCPFree( void *ClientData
,
228 void *data
, OSK_PCHAR File
, OSK_UINT Line
) {
231 data
= (void *)((char *) data
- sizeof(ULONG
));
232 Signature
= *((ULONG
*) data
);
233 if ( SIGNATURE_SMALL
== Signature
) {
234 ExFreeToNPagedLookasideList( &SmallLookasideList
, data
);
235 } else if ( SIGNATURE_LARGE
== Signature
) {
236 ExFreeToNPagedLookasideList( &LargeLookasideList
, data
);
237 } else if ( SIGNATURE_OTHER
== Signature
) {
238 ExFreePoolWithTag( data
, OSK_OTHER_TAG
);
245 TCPMemShutdown( void )
247 ExDeleteNPagedLookasideList( &SmallLookasideList
);
248 ExDeleteNPagedLookasideList( &LargeLookasideList
);