2004-09-29 05:10:48 +00:00
|
|
|
/*
|
|
|
|
* 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"
|
|
|
|
|
2004-12-01 08:14:15 +00:00
|
|
|
extern VOID DrainSignals();
|
2004-09-29 05:10:48 +00:00
|
|
|
|
|
|
|
int TCPSocketState(void *ClientData,
|
|
|
|
void *WhichSocket,
|
|
|
|
void *WhichConnection,
|
|
|
|
OSK_UINT NewState ) {
|
|
|
|
PCONNECTION_ENDPOINT Connection = WhichConnection;
|
|
|
|
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n",
|
2004-11-21 20:54:52 +00:00
|
|
|
NewState, Connection,
|
|
|
|
Connection ? Connection->State ^ NewState :
|
|
|
|
NewState));
|
|
|
|
|
2004-09-29 05:10:48 +00:00
|
|
|
if( !Connection ) {
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP,("Socket closing.\n"));
|
2004-11-21 20:54:52 +00:00
|
|
|
Connection = FileFindConnectionByContext( WhichSocket );
|
|
|
|
if( !Connection ) {
|
|
|
|
TcpipRecursiveMutexLeave( &TCPLock );
|
|
|
|
return 0;
|
|
|
|
} else
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection));
|
2004-09-29 05:10:48 +00:00
|
|
|
}
|
|
|
|
|
2004-12-01 08:14:15 +00:00
|
|
|
if( !Connection->Signalled ) {
|
|
|
|
Connection->Signalled = TRUE;
|
|
|
|
Connection->SignalState = NewState;
|
|
|
|
InsertTailList( &SignalledConnections, &Connection->SignalList );
|
2004-11-21 20:54:52 +00:00
|
|
|
}
|
2004-11-09 09:39:38 +00:00
|
|
|
|
2004-09-29 05:10:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCPPacketSendComplete( PVOID Context,
|
|
|
|
PNDIS_PACKET NdisPacket,
|
|
|
|
NDIS_STATUS NdisStatus ) {
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP,("called %x\n", NdisPacket));
|
2004-11-07 20:37:21 +00:00
|
|
|
FreeNdisPacket(NdisPacket);
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP,("done\n"));
|
2004-09-29 05:10:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define STRINGIFY(x) #x
|
|
|
|
|
|
|
|
int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
|
|
|
|
NDIS_STATUS NdisStatus;
|
2004-11-30 00:10:41 +00:00
|
|
|
PNEIGHBOR_CACHE_ENTRY NCE;
|
2004-09-29 05:10:48 +00:00
|
|
|
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 {
|
|
|
|
DbgPrint("Don't currently handle IPv6\n");
|
|
|
|
KeBugCheck(4);
|
|
|
|
}
|
|
|
|
|
|
|
|
RemoteAddress.Type = LocalAddress.Type = IP_ADDRESS_V4;
|
|
|
|
|
2004-11-30 00:10:41 +00:00
|
|
|
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress )))
|
|
|
|
return OSK_EADDRNOTAVAIL;
|
2004-09-29 05:10:48 +00:00
|
|
|
|
2004-11-07 20:37:21 +00:00
|
|
|
NdisStatus = AllocatePacketWithBuffer( &Packet.NdisPacket, NULL,
|
|
|
|
MaxLLHeaderSize + len );
|
2004-09-29 05:10:48 +00:00
|
|
|
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS) {
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP, ("Error from NDIS: %08x\n", NdisStatus));
|
2004-10-03 20:38:48 +00:00
|
|
|
return STATUS_NO_MEMORY;
|
2004-09-29 05:10:48 +00:00
|
|
|
}
|
|
|
|
|
2004-11-07 20:37:21 +00:00
|
|
|
GetDataPtr( Packet.NdisPacket, MaxLLHeaderSize,
|
|
|
|
(PCHAR *)&Packet.Header, &Packet.ContigSize );
|
|
|
|
|
|
|
|
RtlCopyMemory( Packet.Header, data, len );
|
2004-09-29 05:10:48 +00:00
|
|
|
|
|
|
|
Packet.HeaderSize = sizeof(IPv4_HEADER);
|
|
|
|
Packet.TotalSize = len;
|
|
|
|
Packet.SrcAddr = LocalAddress;
|
|
|
|
Packet.DstAddr = RemoteAddress;
|
|
|
|
|
2004-11-30 00:10:41 +00:00
|
|
|
IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL );
|
2004-12-01 08:14:15 +00:00
|
|
|
|
2004-09-29 05:10:48 +00:00
|
|
|
if( !NT_SUCCESS(NdisStatus) ) return OSK_EINVAL;
|
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *TCPMalloc( void *ClientData,
|
|
|
|
OSK_UINT Bytes, OSK_PCHAR File, OSK_UINT Line ) {
|
2004-11-07 20:37:21 +00:00
|
|
|
void *v = PoolAllocateBuffer( Bytes );
|
2004-09-29 05:10:48 +00:00
|
|
|
if( v ) TrackWithTag( FOURCC('f','b','s','d'), v, File, Line );
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCPFree( void *ClientData,
|
|
|
|
void *data, OSK_PCHAR File, OSK_UINT Line ) {
|
|
|
|
UntrackFL( File, Line, data );
|
2004-11-07 20:37:21 +00:00
|
|
|
PoolFreeBuffer( data );
|
2004-09-29 05:10:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int TCPSleep( void *ClientData, void *token, int priority, char *msg,
|
|
|
|
int tmio ) {
|
|
|
|
PSLEEPING_THREAD SleepingThread;
|
|
|
|
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP,
|
2004-09-29 05:10:48 +00:00
|
|
|
("Called TSLEEP: tok = %x, pri = %d, wmesg = %s, tmio = %x\n",
|
|
|
|
token, priority, msg, tmio));
|
|
|
|
|
2004-11-07 20:37:21 +00:00
|
|
|
SleepingThread = PoolAllocateBuffer( sizeof( *SleepingThread ) );
|
2004-09-29 05:10:48 +00:00
|
|
|
if( SleepingThread ) {
|
|
|
|
KeInitializeEvent( &SleepingThread->Event, NotificationEvent, FALSE );
|
|
|
|
SleepingThread->SleepToken = token;
|
|
|
|
|
2004-11-07 20:37:21 +00:00
|
|
|
TcpipAcquireFastMutex( &SleepingThreadsLock );
|
2004-09-29 05:10:48 +00:00
|
|
|
InsertTailList( &SleepingThreadsList, &SleepingThread->Entry );
|
2004-11-07 20:37:21 +00:00
|
|
|
TcpipReleaseFastMutex( &SleepingThreadsLock );
|
2004-09-29 05:10:48 +00:00
|
|
|
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP,("Waiting on %x\n", token));
|
2004-09-29 05:10:48 +00:00
|
|
|
KeWaitForSingleObject( &SleepingThread->Event,
|
|
|
|
WrSuspended,
|
|
|
|
KernelMode,
|
|
|
|
TRUE,
|
|
|
|
NULL );
|
|
|
|
|
2004-11-07 20:37:21 +00:00
|
|
|
TcpipAcquireFastMutex( &SleepingThreadsLock );
|
2004-09-29 05:10:48 +00:00
|
|
|
RemoveEntryList( &SleepingThread->Entry );
|
2004-11-07 20:37:21 +00:00
|
|
|
TcpipReleaseFastMutex( &SleepingThreadsLock );
|
2004-09-29 05:10:48 +00:00
|
|
|
|
2004-11-07 20:37:21 +00:00
|
|
|
PoolFreeBuffer( SleepingThread );
|
2004-09-29 05:10:48 +00:00
|
|
|
}
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP,("Waiting finished: %x\n", token));
|
2004-09-29 05:10:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCPWakeup( void *ClientData, void *token ) {
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
PSLEEPING_THREAD SleepingThread;
|
|
|
|
|
2004-11-07 20:37:21 +00:00
|
|
|
TcpipAcquireFastMutex( &SleepingThreadsLock );
|
2004-09-29 05:10:48 +00:00
|
|
|
Entry = SleepingThreadsList.Flink;
|
|
|
|
while( Entry != &SleepingThreadsList ) {
|
|
|
|
SleepingThread = CONTAINING_RECORD(Entry, SLEEPING_THREAD, Entry);
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP,("Sleeper @ %x\n", SleepingThread));
|
2004-09-29 05:10:48 +00:00
|
|
|
if( SleepingThread->SleepToken == token ) {
|
2004-12-01 08:14:15 +00:00
|
|
|
TI_DbgPrint(DEBUG_TCP,("Setting event to wake %x\n", token));
|
2004-09-29 05:10:48 +00:00
|
|
|
KeSetEvent( &SleepingThread->Event, IO_NETWORK_INCREMENT, FALSE );
|
|
|
|
}
|
|
|
|
Entry = Entry->Flink;
|
|
|
|
}
|
2004-11-07 20:37:21 +00:00
|
|
|
TcpipReleaseFastMutex( &SleepingThreadsLock );
|
2004-09-29 05:10:48 +00:00
|
|
|
}
|