Return error code that oskit understands. Fixes ftp upload.
[reactos.git] / reactos / drivers / lib / ip / transport / tcp / event.c
index f29f5bb..182f20a 100644 (file)
 
 #include "precomp.h"
 
-extern ULONG TCP_IPIdentification;
-extern LIST_ENTRY SleepingThreadsList;
-extern FAST_MUTEX SleepingThreadsLock;
-
 int TCPSocketState(void *ClientData,
-                  void *WhichSocket, 
+                  void *WhichSocket,
                   void *WhichConnection,
                   OSK_UINT NewState ) {
     PCONNECTION_ENDPOINT Connection = WhichConnection;
-    PTCP_COMPLETION_ROUTINE Complete;
-    PTDI_BUCKET Bucket;
-    PLIST_ENTRY Entry;
 
-    TI_DbgPrint(MID_TRACE,("Called: NewState %x (Conn %x)\n", 
-                          NewState, Connection));
+    TI_DbgPrint(MID_TRACE,("Flags: %c%c%c%c\n",
+                          NewState & SEL_CONNECT ? 'C' : 'c',
+                          NewState & SEL_READ    ? 'R' : 'r',
+                          NewState & SEL_FIN     ? 'F' : 'f',
+                          NewState & SEL_ACCEPT  ? 'A' : 'a'));
+
+    TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n",
+                          NewState, Connection,
+                          Connection ? Connection->State ^ NewState :
+                          NewState));
 
     if( !Connection ) {
-       TI_DbgPrint(MID_TRACE,("Socket closing.\n"));
-       return 0;
+       TI_DbgPrint(DEBUG_TCP,("Socket closing.\n"));
+       Connection = FileFindConnectionByContext( WhichSocket );
+       if( !Connection )
+           return 0;
+       else
+           TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection));
     }
 
-    if( (NewState & SEL_CONNECT) && 
-       !(Connection->State & SEL_CONNECT) ) {
-       while( !IsListEmpty( &Connection->ConnectRequest ) ) {
-           Connection->State |= SEL_CONNECT;
-           Entry = RemoveHeadList( &Connection->ConnectRequest );
-           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-           Complete = Bucket->Request.RequestNotifyObject;
-           TI_DbgPrint(MID_TRACE,
-                       ("Completing Connect Request %x\n", Bucket->Request));
-           Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
-           /* Frees the bucket allocated in TCPConnect */
-           ExFreePool( Bucket );
-       }
-    } else if( (NewState & SEL_READ) || (NewState & SEL_FIN) ) {
-       TI_DbgPrint(MID_TRACE,("Readable (or closed): irp list %s\n",
-                              IsListEmpty(&Connection->ReceiveRequest) ?
-                              "empty" : "nonempty"));
-
-       while( !IsListEmpty( &Connection->ReceiveRequest ) ) {
-           PIRP Irp;
-           OSK_UINT RecvLen = 0, Received = 0;
-           OSK_PCHAR RecvBuffer = 0;
-           PMDL Mdl;
-           NTSTATUS Status;
-
-           Entry = RemoveHeadList( &Connection->ReceiveRequest );
-           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-           Complete = Bucket->Request.RequestNotifyObject;
-
-           TI_DbgPrint(MID_TRACE,
-                       ("Readable, Completing read request %x\n", 
-                        Bucket->Request));
-
-           Irp = Bucket->Request.RequestContext;
-           Mdl = Irp->MdlAddress;
-
-           TI_DbgPrint(MID_TRACE,
-                       ("Getting the user buffer from %x\n", Mdl));
-
-           NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
-
-           TI_DbgPrint(MID_TRACE,
-                       ("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
-
-           if( NewState & SEL_FIN && !RecvLen ) {
-               Status = STATUS_END_OF_FILE;
-               Received = 0;
-           } else 
-               Status = TCPTranslateError
-                   ( OskitTCPRecv( Connection->SocketContext,
-                                   RecvBuffer,
-                                   RecvLen,
-                                   &Received,
-                                   0 ) );
-
-           TI_DbgPrint(MID_TRACE,("TCP Bytes: %d\n", Received));
-
-           if( Status == STATUS_SUCCESS && Received != 0 ) {
-               TI_DbgPrint(MID_TRACE,("Received %d bytes with status %x\n",
-                                      Received, Status));
-               
-               TI_DbgPrint(MID_TRACE,
-                           ("Completing Receive Request: %x\n", 
-                            Bucket->Request));
-
-               Complete( Bucket->Request.RequestContext,
-                         STATUS_SUCCESS, Received );
-           } else if( Status == STATUS_PENDING || 
-                      (Status == STATUS_SUCCESS && Received == 0) ) {
-               InsertHeadList( &Connection->ReceiveRequest,
-                               &Bucket->Entry );
-               break;
-           } else {
-               TI_DbgPrint(MID_TRACE,
-                           ("Completing Receive request: %x %x\n",
-                            Bucket->Request, Status));
-               Complete( Bucket->Request.RequestContext, Status, 0 );
-           }
-       }
-    } 
+    TI_DbgPrint(MID_TRACE,("Connection signalled: %d\n",
+                          Connection->Signalled));
+
+    Connection->SignalState |= NewState;
+    if( !Connection->Signalled ) {
+       Connection->Signalled = TRUE;
+       InsertTailList( &SignalledConnections, &Connection->SignalList );
+    }
 
     return 0;
 }
@@ -118,23 +51,20 @@ int TCPSocketState(void *ClientData,
 void TCPPacketSendComplete( PVOID Context,
                            PNDIS_PACKET NdisPacket,
                            NDIS_STATUS NdisStatus ) {
-    TI_DbgPrint(MID_TRACE,("called\n"));
+    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 ) {
-    NTSTATUS Status;
-    KIRQL OldIrql;
     NDIS_STATUS NdisStatus;
-    ROUTE_CACHE_NODE *RCN;
+    PNEIGHBOR_CACHE_ENTRY NCE;
     IP_PACKET Packet = { 0 };
     IP_ADDRESS RemoteAddress, LocalAddress;
     PIPv4_HEADER Header;
 
-    TI_DbgPrint(MID_TRACE,("TCP OUTPUT (%x:%d):\n", data, len));
-    OskitDumpBuffer( data, len );
-
     if( *data == 0x45 ) { /* IPv4 */
        Header = (PIPv4_HEADER)data;
        LocalAddress.Type = IP_ADDRESS_V4;
@@ -142,50 +72,37 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
        RemoteAddress.Type = IP_ADDRESS_V4;
        RemoteAddress.Address.IPv4Address = Header->DstAddr;
     } else {
-       DbgPrint("Don't currently handle IPv6\n");
-       KeBugCheck(4);
+       TI_DbgPrint(MIN_TRACE,("Outgoing packet is not IPv4\n"));
+       OskitDumpBuffer( data, len );
+       return OSK_EINVAL;
     }
 
     RemoteAddress.Type = LocalAddress.Type = IP_ADDRESS_V4;
 
-    DbgPrint("OSKIT SENDING PACKET *** %x -> %x\n",
-            LocalAddress.Address.IPv4Address,
-            RemoteAddress.Address.IPv4Address);
-    
-    ASSERT( (LocalAddress.Address.IPv4Address & 0xc0000000) != 0xc0000000 );
-       
-
-    Status = RouteGetRouteToDestination( &RemoteAddress,
-                                        NULL,
-                                        &RCN );
-    
-    if( !NT_SUCCESS(Status) || !RCN ) return OSK_EADDRNOTAVAIL;
+    if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
+       TI_DbgPrint(MIN_TRACE,("No route to %s\n", A2S(&RemoteAddress)));
+       return OSK_EADDRNOTAVAIL;
+    }
 
-    KeRaiseIrql( DISPATCH_LEVEL, &OldIrql );
+    NdisStatus = AllocatePacketWithBuffer( &Packet.NdisPacket, NULL,
+                                          MaxLLHeaderSize + len );
 
-    NdisStatus = 
-       AllocatePacketWithBuffer( &Packet.NdisPacket, data, len );
-    
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
-       TI_DbgPrint(MAX_TRACE, ("Error from NDIS: %08x\n", NdisStatus));
-       goto end;
+       TI_DbgPrint(DEBUG_TCP, ("Error from NDIS: %08x\n", NdisStatus));
+       return OSK_ENOBUFS;
     }
 
-    AdjustPacket( Packet.NdisPacket, 0, MaxLLHeaderSize );
-    GetDataPtr( Packet.NdisPacket, 0, (PCHAR *)&Packet.Header, &Packet.ContigSize );
-    TI_DbgPrint(MAX_TRACE,("PC(Packet.NdisPacket) is %s (%x)\n", STRINGIFY(PC(Packet.NdisPacket)), PC(Packet.NdisPacket)));
-    PC(Packet.NdisPacket)->Complete = TCPPacketSendComplete;
-    OskitDumpBuffer((PCHAR)(PC(Packet.NdisPacket)),sizeof(*(PC(Packet.NdisPacket))));
+    GetDataPtr( Packet.NdisPacket, MaxLLHeaderSize,
+               (PCHAR *)&Packet.Header, &Packet.ContigSize );
+
+    RtlCopyMemory( Packet.Header, data, len );
 
     Packet.HeaderSize = sizeof(IPv4_HEADER);
     Packet.TotalSize = len;
     Packet.SrcAddr = LocalAddress;
     Packet.DstAddr = RemoteAddress;
 
-    IPSendFragment( Packet.NdisPacket, RCN->NCE );
-
-end:
-    KeLowerIrql( OldIrql );
+    IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL );
 
     if( !NT_SUCCESS(NdisStatus) ) return OSK_EINVAL;
     else return 0;
@@ -193,48 +110,48 @@ end:
 
 void *TCPMalloc( void *ClientData,
                 OSK_UINT Bytes, OSK_PCHAR File, OSK_UINT Line ) {
-    void *v = ExAllocatePool( NonPagedPool, Bytes );
-    if( v ) TrackWithTag( FOURCC('f','b','s','d'), v, File, Line );
+    void *v = PoolAllocateBuffer( Bytes );
+    if( v ) TrackWithTag( FOURCC('f','b','s','d'), v, (PCHAR)File, Line );
     return v;
 }
 
 void TCPFree( void *ClientData,
              void *data, OSK_PCHAR File, OSK_UINT Line ) {
-    UntrackFL( File, Line, data );
-    ExFreePool( data );
+    UntrackFL( (PCHAR)File, Line, data );
+    PoolFreeBuffer( data );
 }
 
 int TCPSleep( void *ClientData, void *token, int priority, char *msg,
              int tmio ) {
     PSLEEPING_THREAD SleepingThread;
-    
-    TI_DbgPrint(MID_TRACE,
+
+    TI_DbgPrint(DEBUG_TCP,
                ("Called TSLEEP: tok = %x, pri = %d, wmesg = %s, tmio = %x\n",
                 token, priority, msg, tmio));
 
-    SleepingThread = ExAllocatePool( NonPagedPool, sizeof( *SleepingThread ) );
+    SleepingThread = PoolAllocateBuffer( sizeof( *SleepingThread ) );
     if( SleepingThread ) {
        KeInitializeEvent( &SleepingThread->Event, NotificationEvent, FALSE );
        SleepingThread->SleepToken = token;
 
-       ExAcquireFastMutex( &SleepingThreadsLock );
+       TcpipAcquireFastMutex( &SleepingThreadsLock );
        InsertTailList( &SleepingThreadsList, &SleepingThread->Entry );
-       ExReleaseFastMutex( &SleepingThreadsLock );
+       TcpipReleaseFastMutex( &SleepingThreadsLock );
 
-       TI_DbgPrint(MID_TRACE,("Waiting on %x\n", token));
+       TI_DbgPrint(DEBUG_TCP,("Waiting on %x\n", token));
        KeWaitForSingleObject( &SleepingThread->Event,
                               WrSuspended,
                               KernelMode,
                               TRUE,
                               NULL );
 
-       ExAcquireFastMutex( &SleepingThreadsLock );
+       TcpipAcquireFastMutex( &SleepingThreadsLock );
        RemoveEntryList( &SleepingThread->Entry );
-       ExReleaseFastMutex( &SleepingThreadsLock );
+       TcpipReleaseFastMutex( &SleepingThreadsLock );
 
-       ExFreePool( SleepingThread );
+       PoolFreeBuffer( SleepingThread );
     }
-    TI_DbgPrint(MID_TRACE,("Waiting finished: %x\n", token));
+    TI_DbgPrint(DEBUG_TCP,("Waiting finished: %x\n", token));
     return 0;
 }
 
@@ -242,16 +159,16 @@ void TCPWakeup( void *ClientData, void *token ) {
     PLIST_ENTRY Entry;
     PSLEEPING_THREAD SleepingThread;
 
-    ExAcquireFastMutex( &SleepingThreadsLock );
+    TcpipAcquireFastMutex( &SleepingThreadsLock );
     Entry = SleepingThreadsList.Flink;
     while( Entry != &SleepingThreadsList ) {
        SleepingThread = CONTAINING_RECORD(Entry, SLEEPING_THREAD, Entry);
-       TI_DbgPrint(MID_TRACE,("Sleeper @ %x\n", SleepingThread));
+       TI_DbgPrint(DEBUG_TCP,("Sleeper @ %x\n", SleepingThread));
        if( SleepingThread->SleepToken == token ) {
-           TI_DbgPrint(MID_TRACE,("Setting event to wake %x\n", token));
+           TI_DbgPrint(DEBUG_TCP,("Setting event to wake %x\n", token));
            KeSetEvent( &SleepingThread->Event, IO_NETWORK_INCREMENT, FALSE );
        }
        Entry = Entry->Flink;
     }
-    ExReleaseFastMutex( &SleepingThreadsLock );
+    TcpipReleaseFastMutex( &SleepingThreadsLock );
 }