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 extern VOID
DrainSignals();
15 int TCPSocketState(void *ClientData
,
17 void *WhichConnection
,
19 PCONNECTION_ENDPOINT Connection
= WhichConnection
;
21 TI_DbgPrint(DEBUG_TCP
,("Called: NewState %x (Conn %x) (Change %x)\n",
23 Connection
? Connection
->State
^ NewState
:
27 TI_DbgPrint(DEBUG_TCP
,("Socket closing.\n"));
28 Connection
= FileFindConnectionByContext( WhichSocket
);
30 TcpipRecursiveMutexLeave( &TCPLock
);
33 TI_DbgPrint(DEBUG_TCP
,("Found socket %x\n", Connection
));
36 if( !Connection
->Signalled
) {
37 Connection
->Signalled
= TRUE
;
38 Connection
->SignalState
= NewState
;
39 InsertTailList( &SignalledConnections
, &Connection
->SignalList
);
45 void TCPPacketSendComplete( PVOID Context
,
46 PNDIS_PACKET NdisPacket
,
47 NDIS_STATUS NdisStatus
) {
48 TI_DbgPrint(DEBUG_TCP
,("called %x\n", NdisPacket
));
49 FreeNdisPacket(NdisPacket
);
50 TI_DbgPrint(DEBUG_TCP
,("done\n"));
53 #define STRINGIFY(x) #x
55 int TCPPacketSend(void *ClientData
, OSK_PCHAR data
, OSK_UINT len
) {
56 NDIS_STATUS NdisStatus
;
57 PNEIGHBOR_CACHE_ENTRY NCE
;
58 IP_PACKET Packet
= { 0 };
59 IP_ADDRESS RemoteAddress
, LocalAddress
;
62 if( *data
== 0x45 ) { /* IPv4 */
63 Header
= (PIPv4_HEADER
)data
;
64 LocalAddress
.Type
= IP_ADDRESS_V4
;
65 LocalAddress
.Address
.IPv4Address
= Header
->SrcAddr
;
66 RemoteAddress
.Type
= IP_ADDRESS_V4
;
67 RemoteAddress
.Address
.IPv4Address
= Header
->DstAddr
;
69 TI_DbgPrint(MIN_TRACE
,("Outgoing packet is not IPv4\n"));
70 OskitDumpBuffer( data
, len
);
74 RemoteAddress
.Type
= LocalAddress
.Type
= IP_ADDRESS_V4
;
76 if(!(NCE
= RouteGetRouteToDestination( &RemoteAddress
))) {
77 TI_DbgPrint(MIN_TRACE
,("No route to %s\n", A2S(&RemoteAddress
)));
78 return OSK_EADDRNOTAVAIL
;
81 NdisStatus
= AllocatePacketWithBuffer( &Packet
.NdisPacket
, NULL
,
82 MaxLLHeaderSize
+ len
);
84 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
85 TI_DbgPrint(DEBUG_TCP
, ("Error from NDIS: %08x\n", NdisStatus
));
86 return STATUS_NO_MEMORY
;
89 GetDataPtr( Packet
.NdisPacket
, MaxLLHeaderSize
,
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 IPSendDatagram( &Packet
, NCE
, TCPPacketSendComplete
, NULL
);
101 if( !NT_SUCCESS(NdisStatus
) ) return OSK_EINVAL
;
105 void *TCPMalloc( void *ClientData
,
106 OSK_UINT Bytes
, OSK_PCHAR File
, OSK_UINT Line
) {
107 void *v
= PoolAllocateBuffer( Bytes
);
108 if( v
) TrackWithTag( FOURCC('f','b','s','d'), v
, (PCHAR
)File
, Line
);
112 void TCPFree( void *ClientData
,
113 void *data
, OSK_PCHAR File
, OSK_UINT Line
) {
114 UntrackFL( (PCHAR
)File
, Line
, data
);
115 PoolFreeBuffer( data
);
118 int TCPSleep( void *ClientData
, void *token
, int priority
, char *msg
,
120 PSLEEPING_THREAD SleepingThread
;
122 TI_DbgPrint(DEBUG_TCP
,
123 ("Called TSLEEP: tok = %x, pri = %d, wmesg = %s, tmio = %x\n",
124 token
, priority
, msg
, tmio
));
126 SleepingThread
= PoolAllocateBuffer( sizeof( *SleepingThread
) );
127 if( SleepingThread
) {
128 KeInitializeEvent( &SleepingThread
->Event
, NotificationEvent
, FALSE
);
129 SleepingThread
->SleepToken
= token
;
131 TcpipAcquireFastMutex( &SleepingThreadsLock
);
132 InsertTailList( &SleepingThreadsList
, &SleepingThread
->Entry
);
133 TcpipReleaseFastMutex( &SleepingThreadsLock
);
135 TI_DbgPrint(DEBUG_TCP
,("Waiting on %x\n", token
));
136 KeWaitForSingleObject( &SleepingThread
->Event
,
142 TcpipAcquireFastMutex( &SleepingThreadsLock
);
143 RemoveEntryList( &SleepingThread
->Entry
);
144 TcpipReleaseFastMutex( &SleepingThreadsLock
);
146 PoolFreeBuffer( SleepingThread
);
148 TI_DbgPrint(DEBUG_TCP
,("Waiting finished: %x\n", token
));
152 void TCPWakeup( void *ClientData
, void *token
) {
154 PSLEEPING_THREAD SleepingThread
;
156 TcpipAcquireFastMutex( &SleepingThreadsLock
);
157 Entry
= SleepingThreadsList
.Flink
;
158 while( Entry
!= &SleepingThreadsList
) {
159 SleepingThread
= CONTAINING_RECORD(Entry
, SLEEPING_THREAD
, Entry
);
160 TI_DbgPrint(DEBUG_TCP
,("Sleeper @ %x\n", SleepingThread
));
161 if( SleepingThread
->SleepToken
== token
) {
162 TI_DbgPrint(DEBUG_TCP
,("Setting event to wake %x\n", token
));
163 KeSetEvent( &SleepingThread
->Event
, IO_NETWORK_INCREMENT
, FALSE
);
165 Entry
= Entry
->Flink
;
167 TcpipReleaseFastMutex( &SleepingThreadsLock
);