- Fix compilation errors with GCC 4.0-20041205.
[reactos.git] / reactos / drivers / lib / ip / transport / tcp / event.c
1 /*
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
7 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10
11 #include "precomp.h"
12
13 extern VOID DrainSignals();
14
15 int TCPSocketState(void *ClientData,
16 void *WhichSocket,
17 void *WhichConnection,
18 OSK_UINT NewState ) {
19 PCONNECTION_ENDPOINT Connection = WhichConnection;
20
21 TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n",
22 NewState, Connection,
23 Connection ? Connection->State ^ NewState :
24 NewState));
25
26 if( !Connection ) {
27 TI_DbgPrint(DEBUG_TCP,("Socket closing.\n"));
28 Connection = FileFindConnectionByContext( WhichSocket );
29 if( !Connection ) {
30 TcpipRecursiveMutexLeave( &TCPLock );
31 return 0;
32 } else
33 TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection));
34 }
35
36 if( !Connection->Signalled ) {
37 Connection->Signalled = TRUE;
38 Connection->SignalState = NewState;
39 InsertTailList( &SignalledConnections, &Connection->SignalList );
40 }
41
42 return 0;
43 }
44
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"));
51 }
52
53 #define STRINGIFY(x) #x
54
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;
60 PIPv4_HEADER Header;
61
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;
68 } else {
69 TI_DbgPrint(MIN_TRACE,("Outgoing packet is not IPv4\n"));
70 OskitDumpBuffer( data, len );
71 return OSK_EINVAL;
72 }
73
74 RemoteAddress.Type = LocalAddress.Type = IP_ADDRESS_V4;
75
76 if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
77 TI_DbgPrint(MIN_TRACE,("No route to %s\n", A2S(&RemoteAddress)));
78 return OSK_EADDRNOTAVAIL;
79 }
80
81 NdisStatus = AllocatePacketWithBuffer( &Packet.NdisPacket, NULL,
82 MaxLLHeaderSize + len );
83
84 if (NdisStatus != NDIS_STATUS_SUCCESS) {
85 TI_DbgPrint(DEBUG_TCP, ("Error from NDIS: %08x\n", NdisStatus));
86 return STATUS_NO_MEMORY;
87 }
88
89 GetDataPtr( Packet.NdisPacket, MaxLLHeaderSize,
90 (PCHAR *)&Packet.Header, &Packet.ContigSize );
91
92 RtlCopyMemory( Packet.Header, data, len );
93
94 Packet.HeaderSize = sizeof(IPv4_HEADER);
95 Packet.TotalSize = len;
96 Packet.SrcAddr = LocalAddress;
97 Packet.DstAddr = RemoteAddress;
98
99 IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL );
100
101 if( !NT_SUCCESS(NdisStatus) ) return OSK_EINVAL;
102 else return 0;
103 }
104
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 );
109 return v;
110 }
111
112 void TCPFree( void *ClientData,
113 void *data, OSK_PCHAR File, OSK_UINT Line ) {
114 UntrackFL( (PCHAR)File, Line, data );
115 PoolFreeBuffer( data );
116 }
117
118 int TCPSleep( void *ClientData, void *token, int priority, char *msg,
119 int tmio ) {
120 PSLEEPING_THREAD SleepingThread;
121
122 TI_DbgPrint(DEBUG_TCP,
123 ("Called TSLEEP: tok = %x, pri = %d, wmesg = %s, tmio = %x\n",
124 token, priority, msg, tmio));
125
126 SleepingThread = PoolAllocateBuffer( sizeof( *SleepingThread ) );
127 if( SleepingThread ) {
128 KeInitializeEvent( &SleepingThread->Event, NotificationEvent, FALSE );
129 SleepingThread->SleepToken = token;
130
131 TcpipAcquireFastMutex( &SleepingThreadsLock );
132 InsertTailList( &SleepingThreadsList, &SleepingThread->Entry );
133 TcpipReleaseFastMutex( &SleepingThreadsLock );
134
135 TI_DbgPrint(DEBUG_TCP,("Waiting on %x\n", token));
136 KeWaitForSingleObject( &SleepingThread->Event,
137 WrSuspended,
138 KernelMode,
139 TRUE,
140 NULL );
141
142 TcpipAcquireFastMutex( &SleepingThreadsLock );
143 RemoveEntryList( &SleepingThread->Entry );
144 TcpipReleaseFastMutex( &SleepingThreadsLock );
145
146 PoolFreeBuffer( SleepingThread );
147 }
148 TI_DbgPrint(DEBUG_TCP,("Waiting finished: %x\n", token));
149 return 0;
150 }
151
152 void TCPWakeup( void *ClientData, void *token ) {
153 PLIST_ENTRY Entry;
154 PSLEEPING_THREAD SleepingThread;
155
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 );
164 }
165 Entry = Entry->Flink;
166 }
167 TcpipReleaseFastMutex( &SleepingThreadsLock );
168 }