diff --git a/reactos/drivers/net/tcpip/include/rawip.h b/reactos/drivers/net/tcpip/include/rawip.h index fbd0961d9fa..c3599a5b7fd 100644 --- a/reactos/drivers/net/tcpip/include/rawip.h +++ b/reactos/drivers/net/tcpip/include/rawip.h @@ -11,7 +11,8 @@ NTSTATUS RawIPSendDatagram( PTDI_REQUEST Request, PTDI_CONNECTION_INFORMATION ConnInfo, PNDIS_BUFFER Buffer, - ULONG DataSize); + ULONG DataSize, + PULONG DataUsed); VOID RawIPReceive( PNET_TABLE_ENTRY NTE, diff --git a/reactos/drivers/net/tcpip/include/tcp.h b/reactos/drivers/net/tcpip/include/tcp.h index c71391ba8ae..d3f876926b8 100644 --- a/reactos/drivers/net/tcpip/include/tcp.h +++ b/reactos/drivers/net/tcpip/include/tcp.h @@ -104,9 +104,10 @@ NTSTATUS TCPReceiveData( NTSTATUS TCPSendData( PTDI_REQUEST Request, - PTDI_CONNECTION_INFORMATION ConnInfo, PNDIS_BUFFER Buffer, - ULONG DataSize); + ULONG DataSize, + ULONG Flags, + PULONG DataUsed); NTSTATUS TCPStartup( VOID); diff --git a/reactos/drivers/net/tcpip/include/titypes.h b/reactos/drivers/net/tcpip/include/titypes.h index 46955a231a9..ced8385c559 100644 --- a/reactos/drivers/net/tcpip/include/titypes.h +++ b/reactos/drivers/net/tcpip/include/titypes.h @@ -100,7 +100,8 @@ typedef NTSTATUS (*DATAGRAM_SEND_ROUTINE)( PTDI_REQUEST Request, PTDI_CONNECTION_INFORMATION ConnInfo, PNDIS_BUFFER Buffer, - ULONG DataSize); + ULONG DataSize, + PULONG DataUsed); /* Datagram completion handler prototype */ typedef VOID (*DATAGRAM_COMPLETION_ROUTINE)( @@ -295,54 +296,31 @@ typedef struct _TCP_SEGMENT { ULONG BytesDelivered; /* Number of bytes already delivered to the client */ } TCP_SEGMENT, *PTCP_SEGMENT; +typedef struct _TDI_BUCKET { + LIST_ENTRY Entry; + TDI_REQUEST Request; +} TDI_BUCKET, *PTDI_BUCKET; /* Transport connection context structure A.K.A. Transmission Control Block (TCB) in TCP terminology. The FileObject->FsContext2 field holds a pointer to this structure */ typedef struct _CONNECTION_ENDPOINT { - LIST_ENTRY ListEntry; /* Entry on list */ - KSPIN_LOCK Lock; /* Spin lock to protect this structure */ - ULONG RefCount; /* Number of references to this object */ - PVOID ClientContext; /* Pointer to client context information */ - PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */ - PVOID SocketContext; /* Context for lower layer */ - -#if 0 - PIP_ADDRESS LocalAddress; /* Pointer to local IP address */ - USHORT LocalPort; /* Local port number (network byte order) */ - - PIP_ADDRESS RemoteAddress; /* Pointer to remote IP address */ - USHORT RemotePort; /* Remote port number (network byte order) */ - - CONNECTION_STATE State; /* Connection state */ - /* Send sequence variables */ - ULONG SendUnacknowledged; /* Highest sequence number that is acknowledged */ - ULONG SendNext; /* Sequence number of last data block sent */ - ULONG SendWindow; /* Maximum allowed number of octets in a segment */ - ULONG SendUrgentPointer; /* Sequence number of start of urgent data */ - ULONG SendWL1; /* Sequence number used for last window update */ - ULONG SendWL2; /* Acknowledgment number used for last window update */ - ULONG SendISS; /* Initial send sequence number */ - - /* Receive sequence variables */ - ULONG ReceiveNext; /* Next sequence number expected and start of receive window */ - ULONG ReceiveWindow; /* Maximum allowed number of octets in a segment */ - ULONG ReceiveUrgentPointer; /* Sequence number of start of urgent data */ - ULONG ReceiveIRS; /* Initial receive sequence number */ - ULONG ReceiveDelivered; /* Next sequence number to be delivered to the client */ - - /* Statistics for computing the retransmission timeout */ - ULONG TimestampSend; /* Timestamp when sending a segment */ - ULONG TimestampAck; /* Timestamp when receiving acknowledgment */ -#endif - - /* Requests */ - PTDI_REQUEST ListenRequest; /* Queued listen request */ - LIST_ENTRY ReceiveRequests; /* Queued receive requests */ - - /* Queues */ - LIST_ENTRY ReceivedSegments;/* Segments that are received */ - + LIST_ENTRY ListEntry; /* Entry on list */ + KSPIN_LOCK Lock; /* Spin lock to protect this structure */ + ULONG RefCount; /* Number of references to this object */ + PVOID ClientContext; /* Pointer to client context information */ + PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */ + PVOID SocketContext; /* Context for lower layer */ + + UINT State; /* Socket state W.R.T. oskit */ + + /* Requests */ + LIST_ENTRY ConnectRequest; /* Queued connect rqueusts */ + LIST_ENTRY ListenRequest; /* Queued listen requests */ + LIST_ENTRY ReceiveRequest; /* Queued receive requests */ + + /* Queues */ + LIST_ENTRY ReceivedSegments;/* Segments that are received */ } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT; diff --git a/reactos/drivers/net/tcpip/include/udp.h b/reactos/drivers/net/tcpip/include/udp.h index 02464046c3a..532324f6013 100644 --- a/reactos/drivers/net/tcpip/include/udp.h +++ b/reactos/drivers/net/tcpip/include/udp.h @@ -42,7 +42,8 @@ NTSTATUS UDPSendDatagram( PTDI_REQUEST Request, PTDI_CONNECTION_INFORMATION ConnInfo, PNDIS_BUFFER Buffer, - ULONG DataSize); + ULONG DataSize, + PULONG DataUsed); NTSTATUS UDPReceiveDatagram( PTDI_REQUEST Request, diff --git a/reactos/drivers/net/tcpip/tcpip/address.c b/reactos/drivers/net/tcpip/tcpip/address.c index 3443675e974..cafb98f13e4 100644 --- a/reactos/drivers/net/tcpip/tcpip/address.c +++ b/reactos/drivers/net/tcpip/tcpip/address.c @@ -210,11 +210,22 @@ NTSTATUS AddrBuildAddress( PTDI_ADDRESS_IP ValidAddr; PIP_ADDRESS IPAddress; - if (TdiAddress->AddressType != TDI_ADDRESS_TYPE_IP) - return STATUS_INVALID_ADDRESS; + TI_DbgPrint(MID_TRACE,("Address in:\n")); + OskitDumpBuffer( TdiAddress, sizeof(*TdiAddress) ); - if (TdiAddress->AddressLength != TDI_ADDRESS_LENGTH_IP) + if (TdiAddress->AddressType != TDI_ADDRESS_TYPE_IP) { + TI_DbgPrint + (MID_TRACE,("AddressType %x, Not valid\n", + TdiAddress->AddressType)); return STATUS_INVALID_ADDRESS; + } + if (TdiAddress->AddressLength < TDI_ADDRESS_LENGTH_IP) { + TI_DbgPrint + (MID_TRACE,("AddressLength %x, Not valid (expected %x)\n", + TdiAddress->AddressLength, TDI_ADDRESS_LENGTH_IP)); + return STATUS_INVALID_ADDRESS; + } + ValidAddr = (PTDI_ADDRESS_IP)TdiAddress->Address; @@ -226,6 +237,9 @@ NTSTATUS AddrBuildAddress( *Address = IPAddress; *Port = ValidAddr->sin_port; + TI_DbgPrint(MID_TRACE,("Address out:\n")); + OskitDumpBuffer( IPAddress, sizeof(*IPAddress) ); + return STATUS_SUCCESS; } diff --git a/reactos/drivers/net/tcpip/tcpip/dispatch.c b/reactos/drivers/net/tcpip/tcpip/dispatch.c index fe1ec1e7fa5..7473e0c01fa 100644 --- a/reactos/drivers/net/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/net/tcpip/tcpip/dispatch.c @@ -187,9 +187,10 @@ VOID DispDataRequestComplete( PTRANSPORT_CONTEXT TranContext; KIRQL OldIrql; - TI_DbgPrint(DEBUG_IRP, ("Called.\n")); + TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n", + Context, Status, Count)); - Irp = (PIRP)Context; + Irp = Context; IrpSp = IoGetCurrentIrpStackLocation(Irp); TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext; @@ -218,6 +219,10 @@ VOID DispDataRequestComplete( Irp->IoStatus.Status = Status; Irp->IoStatus.Information = Count; + TI_DbgPrint(MID_TRACE, ("Irp->IoStatus.Status = %x\n", + Irp->IoStatus.Status)); + TI_DbgPrint(MID_TRACE, ("Irp->IoStatus.Information = %d\n", + Irp->IoStatus.Information)); TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp)); IRPFinish(Irp, STATUS_SUCCESS); @@ -687,6 +692,7 @@ NTSTATUS DispTdiReceive( IrpSp->FileObject->FsContext, Irp, (PDRIVER_CANCEL)DispCancelRequest); + TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress)); if (NT_SUCCESS(Status)) { Status = TCPReceiveData( @@ -786,46 +792,63 @@ NTSTATUS DispTdiSend( * Status of operation */ { - PIO_STACK_LOCATION IrpSp; - TDI_REQUEST Request; - PTDI_REQUEST_KERNEL_SEND SendInfo; - PTRANSPORT_CONTEXT TranContext; - NTSTATUS Status; + PIO_STACK_LOCATION IrpSp; + PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo; + PTRANSPORT_CONTEXT TranContext; + TDI_REQUEST Request; + NTSTATUS Status; + ULONG BytesReceived; - TI_DbgPrint(DEBUG_IRP, ("Called.\n")); + TI_DbgPrint(DEBUG_IRP, ("Called.\n")); - IrpSp = IoGetCurrentIrpStackLocation(Irp); - SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters); - TranContext = IrpSp->FileObject->FsContext; + IrpSp = IoGetCurrentIrpStackLocation(Irp); + ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters); - /* Initialize a send request */ - Request.Handle.AddressHandle = TranContext->Handle.AddressHandle; - Request.RequestNotifyObject = DispDataRequestComplete; - Request.RequestContext = Irp; - - Status = DispPrepareIrpForCancel( - IrpSp->FileObject->FsContext, - Irp, - (PDRIVER_CANCEL)DispCancelRequest); - if (NT_SUCCESS(Status)) { - - /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress - must be of type PTDI_ADDRESS_IP */ - - Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)( - &Request, NULL, - (PNDIS_BUFFER)Irp->MdlAddress, SendInfo->SendLength); - if (Status != STATUS_PENDING) { - DispDataRequestComplete(Irp, Status, 0); - /* Return STATUS_PENDING because DispPrepareIrpForCancel - marks Irp as pending */ - Status = STATUS_PENDING; - } + TranContext = IrpSp->FileObject->FsContext; + if (TranContext == NULL) + { + TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); + return STATUS_INVALID_CONNECTION; } - TI_DbgPrint(DEBUG_IRP, ("Leaving.\n")); + if (TranContext->Handle.ConnectionContext == NULL) + { + TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); + return STATUS_INVALID_CONNECTION; + } - return Status; + /* Initialize a receive request */ + Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext; + Request.RequestNotifyObject = DispDataRequestComplete; + Request.RequestContext = Irp; + Status = DispPrepareIrpForCancel( + IrpSp->FileObject->FsContext, + Irp, + (PDRIVER_CANCEL)DispCancelRequest); + TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress)); + if (NT_SUCCESS(Status)) + { + TI_DbgPrint(MID_TRACE,("About to TCPSendData\n")); + Status = TCPSendData( + &Request, + (PNDIS_BUFFER)Irp->MdlAddress, + ReceiveInfo->ReceiveLength, + ReceiveInfo->ReceiveFlags, + &BytesReceived); + if (Status != STATUS_PENDING) + { + DispDataRequestComplete(Irp, Status, BytesReceived); + } + } + + if (Status != STATUS_PENDING) + { + IrpSp->Control &= ~SL_PENDING_RETURNED; + } + + TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status)); + + return Status; } @@ -867,9 +890,10 @@ NTSTATUS DispTdiSendDatagram( Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)( &Request, DgramInfo->SendDatagramInformation, - (PNDIS_BUFFER)Irp->MdlAddress, DgramInfo->SendLength); + (PNDIS_BUFFER)Irp->MdlAddress, DgramInfo->SendLength, + &Irp->IoStatus.Information); if (Status != STATUS_PENDING) { - DispDataRequestComplete(Irp, Status, 0); + DispDataRequestComplete(Irp, Status, Irp->IoStatus.Information); /* Return STATUS_PENDING because DispPrepareIrpForCancel marks Irp as pending */ Status = STATUS_PENDING; diff --git a/reactos/drivers/net/tcpip/tcpip/fileobjs.c b/reactos/drivers/net/tcpip/tcpip/fileobjs.c index a482a62152f..0386d5823ab 100644 --- a/reactos/drivers/net/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/net/tcpip/tcpip/fileobjs.c @@ -456,6 +456,9 @@ NTSTATUS FileOpenConnection( /* Initialize spin lock that protects the connection endpoint file object */ KeInitializeSpinLock(&Connection->Lock); + InitializeListHead(&Connection->ConnectRequest); + InitializeListHead(&Connection->ListenRequest); + InitializeListHead(&Connection->ReceiveRequest); /* Reference the object */ Connection->RefCount = 1; @@ -469,9 +472,6 @@ NTSTATUS FileOpenConnection( IPPROTO_TCP ); DbgPrint("STATUS from OSKITTCP was %08x\n", Status); - /* Initialize receive requests queue */ - InitializeListHead(&Connection->ReceiveRequests); - /* Initialize received segments queue */ InitializeListHead(&Connection->ReceivedSegments); diff --git a/reactos/drivers/net/tcpip/tcpip/main.c b/reactos/drivers/net/tcpip/tcpip/main.c index 3e906921d45..e7d4ee3f5de 100644 --- a/reactos/drivers/net/tcpip/tcpip/main.c +++ b/reactos/drivers/net/tcpip/tcpip/main.c @@ -213,7 +213,14 @@ CP (Address->TAAddressCount != 1) || (Address->Address[0].AddressLength < TDI_ADDRESS_LENGTH_IP) || (Address->Address[0].AddressType != TDI_ADDRESS_TYPE_IP)) { - TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n")); + TI_DbgPrint(MIN_TRACE, ("Parameters are invalid:\n")); + TI_DbgPrint(MIN_TRACE, ("AddressCount: %d\n", Address->TAAddressCount)); + if( Address->TAAddressCount == 1 ) { + TI_DbgPrint(MIN_TRACE, ("AddressLength: %\n", + Address->Address[0].AddressLength)); + TI_DbgPrint(MIN_TRACE, ("AddressType: %\n", + Address->Address[0].AddressType)); + } ExFreePool(Context); return STATUS_INVALID_PARAMETER; } @@ -578,11 +585,12 @@ TiDispatch( NTSTATUS Status; PIO_STACK_LOCATION IrpSp; + IrpSp = IoGetCurrentIrpStackLocation(Irp); + TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp)); Irp->IoStatus.Information = 0; - IrpSp = IoGetCurrentIrpStackLocation(Irp); #ifdef _MSC_VER Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp); if (NT_SUCCESS(Status)) { diff --git a/reactos/drivers/net/tcpip/transport/rawip/rawip.c b/reactos/drivers/net/tcpip/transport/rawip/rawip.c index cdb75f61f96..d3e23afabb5 100644 --- a/reactos/drivers/net/tcpip/transport/rawip/rawip.c +++ b/reactos/drivers/net/tcpip/transport/rawip/rawip.c @@ -84,7 +84,8 @@ NTSTATUS RawIPSendDatagram( PTDI_REQUEST Request, PTDI_CONNECTION_INFORMATION ConnInfo, PNDIS_BUFFER Buffer, - ULONG DataSize) + ULONG DataSize, + PULONG DataUsed ) /* * FUNCTION: Sends a raw IP datagram to a remote address * ARGUMENTS: @@ -110,6 +111,8 @@ NTSTATUS RawIPSendDatagram( TI_DbgPrint(MID_TRACE,("Packet.NdisPacket %x\n", Packet.NdisPacket)); + *DataUsed = BufferLen; + if( Status == NDIS_STATUS_SUCCESS ) Status = BuildRawIPPacket( &Packet, BufferLen, diff --git a/reactos/drivers/net/tcpip/transport/tcp/event.c b/reactos/drivers/net/tcpip/transport/tcp/event.c index 4f74debad59..a8ca6ff7c3f 100644 --- a/reactos/drivers/net/tcpip/transport/tcp/event.c +++ b/reactos/drivers/net/tcpip/transport/tcp/event.c @@ -23,150 +23,93 @@ extern ULONG TCP_IPIdentification; -void TCPRecvNotify( PCONNECTION_ENDPOINT Connection, UINT Flags ) { - int error = 0; - NTSTATUS Status = 0; - CHAR DataBuffer[1024]; - UINT BytesRead = 0, BytesTaken = 0; - PTDI_IND_RECEIVE ReceiveHandler; - PTDI_IND_DISCONNECT DisconnectHandler; - PVOID HandlerContext; - SOCKADDR Addr; +typedef VOID +(*PTCP_COMPLETION_ROUTINE)( PVOID Context, NTSTATUS Status, ULONG Count ); - TI_DbgPrint(MID_TRACE,("XX> Called\n")); - - do { - error = OskitTCPRecv( Connection->SocketContext, - &Addr, - DataBuffer, - 1024, - &BytesRead, - Flags | OSK_MSG_DONTWAIT | OSK_MSG_PEEK ); +int TCPSocketState(void *ClientData, + void *WhichSocket, + void *WhichConnection, + OSK_UINT NewState ) { + PCONNECTION_ENDPOINT Connection = WhichConnection; + PTCP_COMPLETION_ROUTINE Complete; + PTDI_BUCKET Bucket; + PLIST_ENTRY Entry; - switch( error ) { - case 0: - ReceiveHandler = Connection->AddressFile->ReceiveHandler; - HandlerContext = Connection->AddressFile->ReceiveHandlerContext; - - TI_DbgPrint(MID_TRACE,("Received %d bytes\n", BytesRead)); - - if( Connection->AddressFile->RegisteredReceiveHandler ) - Status = ReceiveHandler( HandlerContext, - NULL, - TDI_RECEIVE_NORMAL, - BytesRead, - BytesRead, - &BytesTaken, - DataBuffer, - NULL ); - else - Status = STATUS_UNSUCCESSFUL; - - if( Status == STATUS_SUCCESS ) { - OskitTCPRecv( Connection->SocketContext, - &Addr, - DataBuffer, - BytesTaken, - &BytesRead, - Flags | OSK_MSG_DONTWAIT ); - } - break; + TI_DbgPrint(MID_TRACE,("Called: NewState %x\n", NewState)); - case OSK_ESHUTDOWN: - case OSK_ECONNRESET: - DisconnectHandler = Connection->AddressFile->DisconnectHandler; - HandlerContext = Connection->AddressFile->DisconnectHandlerContext; - - if( Connection->AddressFile->RegisteredDisconnectHandler ) - Status = DisconnectHandler( HandlerContext, - NULL, - 0, - NULL, - 0, - NULL, - (error == OSK_ESHUTDOWN) ? - TDI_DISCONNECT_RELEASE : - TDI_DISCONNECT_ABORT ); - else - Status = STATUS_UNSUCCESSFUL; - break; - - default: - assert( 0 ); - break; - } - } while( error == 0 && BytesRead > 0 && BytesTaken > 0 ); - - TI_DbgPrint(MID_TRACE,("XX> Leaving\n")); -} - -void TCPCloseNotify( PCONNECTION_ENDPOINT Connection ) { - NTSTATUS Status; - PTDI_IND_DISCONNECT DisconnectHandler; - PVOID HandlerContext; - - DisconnectHandler = Connection->AddressFile->DisconnectHandler; - HandlerContext = Connection->AddressFile->DisconnectHandlerContext; - - /* XXX Distinguish TDI_DISCONNECT_RELEASE from TDI_DISCONNECT_ABORT */ - if( Connection->AddressFile->RegisteredDisconnectHandler ) - Status = DisconnectHandler( HandlerContext, - NULL, - 0, - NULL, - 0, - NULL, - TDI_DISCONNECT_ABORT ); - else - Status = STATUS_UNSUCCESSFUL; - - return Status; -} - -char *FlagNames[] = { "SEL_CONNECT", - "SEL_FIN", - "SEL_ACCEPT", - "SEL_OOB", - "SEL_READ", - "SEL_WRITE", - 0 }; -int FlagValues[] = { SEL_CONNECT, - SEL_FIN, - SEL_ACCEPT, - SEL_OOB, - SEL_READ, - SEL_WRITE, - 0 }; - -void TCPSocketState( void *ClientData, - void *WhichSocket, - void *WhichConnection, - OSK_UINT Flags, - OSK_UINT SocketState ) { - int i; - PCONNECTION_ENDPOINT Connection = - (PCONNECTION_ENDPOINT)WhichConnection; - - TI_DbgPrint(MID_TRACE,("TCPSocketState: (socket %x) %x %x\n", - WhichSocket, Flags, SocketState)); - - for( i = 0; FlagValues[i]; i++ ) { - if( Flags & FlagValues[i] ) - TI_DbgPrint(MID_TRACE,("Flag %s\n", FlagNames[i])); + if( !Connection ) { + TI_DbgPrint(MID_TRACE,("Socket closing.\n")); + return 0; } - if( Flags & SEL_CONNECT ) - /* TCPConnectNotify( Connection ); */ ; - if( Flags & SEL_FIN ) - TCPCloseNotify( Connection ); - if( Flags & SEL_ACCEPT ) - /* TCPAcceptNotify( Connection ); */ ; - if( Flags & SEL_OOB ) - TCPRecvNotify( Connection, MSG_OOB ); - if( Flags & SEL_WRITE ) - /* TCPSendNotify( Connection ); */ ; - if( Flags & SEL_READ ) - TCPRecvNotify( Connection, 0 ); + 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 ) { + 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)); + + 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 { + InsertHeadList( &Connection->ReceiveRequest, + &Bucket->Entry ); + } + } + } + + return 0; } void TCPPacketSendComplete( PVOID Context, @@ -294,6 +237,12 @@ int TCPPacketSend(void *ClientData, &RemoteAddress.Address.IPv4Address, &RemotePort ); + DbgPrint("OSKIT SENDING PACKET *** %x:%d -> %x:%d\n", + LocalAddress.Address.IPv4Address, + LocalPort, + RemoteAddress.Address.IPv4Address, + RemotePort); + NCE = RouterGetRoute( &RemoteAddress, NULL ); if( !NCE ) return OSK_EADDRNOTAVAIL; @@ -302,8 +251,7 @@ int TCPPacketSend(void *ClientData, ADE_UNICAST, &LocalAddress.Address.IPv4Address ); - if( Connection ) - KeAcquireSpinLock( &Connection->Lock, &OldIrql ); + KeRaiseIrql( DISPATCH_LEVEL, &OldIrql ); NdisStatus = AllocatePacketWithBuffer( &SendRequest->PacketToSend, data, len ); @@ -333,8 +281,7 @@ int TCPPacketSend(void *ClientData, DbgPrint("Transmit called without connection.\n"); end: - if( Connection ) - KeReleaseSpinLock( &Connection->Lock, OldIrql ); + KeLowerIrql( OldIrql ); if( !NT_SUCCESS(NdisStatus) ) return OSK_EINVAL; else return 0; diff --git a/reactos/drivers/net/tcpip/transport/tcp/tcp.c b/reactos/drivers/net/tcpip/transport/tcp/tcp.c index da778a0641a..71745bfef3e 100644 --- a/reactos/drivers/net/tcpip/transport/tcp/tcp.c +++ b/reactos/drivers/net/tcpip/transport/tcp/tcp.c @@ -52,11 +52,10 @@ VOID TCPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket) } /* event.c */ -void TCPSocketState( void *ClientData, - void *WhichSocket, - void *WhichConnection, - OSK_UINT SelFlags, - OSK_UINT SocketState ); +int TCPSocketState( void *ClientData, + void *WhichSocket, + void *WhichConnection, + OSK_UINT NewState ); int TCPPacketSend( void *ClientData, void *WhichSocket, @@ -67,7 +66,7 @@ int TCPPacketSend( void *ClientData, OSKITTCP_EVENT_HANDLERS EventHandlers = { NULL, /* Client Data */ TCPSocketState, /* SocketState */ - TCPPacketSend, /* PacketSend */ + TCPPacketSend, /* PacketSend */ }; NTSTATUS TCPStartup(VOID) @@ -129,6 +128,8 @@ NTSTATUS TCPTranslateError( int OskitError ) { case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break; case OSK_ECONNREFUSED: case OSK_ECONNRESET: Status = STATUS_REMOTE_NOT_LISTENING; break; + case OSK_EINPROGRESS: + case OSK_EAGAIN: Status = STATUS_PENDING; break; default: Status = STATUS_INVALID_CONNECTION; break; } @@ -143,20 +144,30 @@ NTSTATUS TCPConnect KIRQL OldIrql; NTSTATUS Status; SOCKADDR_IN AddressToConnect; - PCONNECTION_ENDPOINT Connection; - - Connection = Request->Handle.ConnectionContext; - - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - + PCONNECTION_ENDPOINT Connection = Request->Handle.ConnectionContext; PIP_ADDRESS RemoteAddress; USHORT RemotePort; + PTDI_BUCKET Bucket; - Status = AddrBuildAddress( - (PTA_ADDRESS)(&((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress)-> - Address[0]), - &RemoteAddress, - &RemotePort); + DbgPrint("TCPConnect: Called\n"); + + Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) ); + if( !Bucket ) return STATUS_NO_MEMORY; + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + /* Freed in TCPSocketState */ + Bucket->Request = *Request; + InsertHeadList( &Connection->ConnectRequest, &Bucket->Entry ); + + Status = AddrBuildAddress + ((PTA_ADDRESS)ConnInfo->RemoteAddress, + &RemoteAddress, + &RemotePort); + + DbgPrint("Connecting to address %x:%x\n", + RemoteAddress->Address.IPv4Address, + RemotePort); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MID_TRACE, ("Could not AddrBuildAddress in TCPConnect\n")); @@ -171,11 +182,16 @@ NTSTATUS TCPConnect sizeof(AddressToConnect.sin_addr) ); AddressToConnect.sin_port = RemotePort; KeReleaseSpinLock(&Connection->Lock, OldIrql); + + Status = OskitTCPConnect(Connection->SocketContext, + Connection, + &AddressToConnect, + sizeof(AddressToConnect)); - return TCPTranslateError( OskitTCPConnect(Connection->SocketContext, - Connection, - &AddressToConnect, - sizeof(AddressToConnect)) ); + if( Status == OSK_EINPROGRESS || Status == STATUS_SUCCESS ) + return STATUS_PENDING; + else + return Status; } NTSTATUS TCPClose @@ -209,38 +225,76 @@ NTSTATUS TCPReceiveData ULONG ReceiveLength, ULONG ReceiveFlags, PULONG BytesReceived ) { + KIRQL OldIrql; PCONNECTION_ENDPOINT Connection; PCHAR DataBuffer; UINT DataLen, Received = 0; + NTSTATUS Status; + PTDI_BUCKET Bucket; Connection = Request->Handle.ConnectionContext; + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + NdisQueryBuffer( Buffer, &DataBuffer, &DataLen ); - return TCPTranslateError + TI_DbgPrint(MID_TRACE,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen)); + + Status = TCPTranslateError ( OskitTCPRecv ( Connection->SocketContext, DataBuffer, DataLen, &Received, ReceiveFlags ) ); + + /* Keep this request around ... there was no data yet */ + if( Status == STATUS_PENDING || Received == 0 ) { + /* Freed in TCPSocketState */ + Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) ); + if( !Bucket ) return STATUS_NO_MEMORY; + + Bucket->Request = *Request; + InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry ); + Status = STATUS_PENDING; + } + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + TI_DbgPrint(MID_TRACE,("Status %x\n", Status)); + + return Status; } NTSTATUS TCPSendData ( PTDI_REQUEST Request, - PTDI_CONNECTION_INFORMATION ConnInfo, PNDIS_BUFFER Buffer, - ULONG DataSize ) { + ULONG DataSize, + ULONG Flags, + PULONG DataUsed ) { + KIRQL OldIrql; + NTSTATUS Status; PCONNECTION_ENDPOINT Connection; PCHAR BufferData; ULONG PacketSize; int error; + Connection = Request->Handle.ConnectionContext; + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + NdisQueryBuffer( Buffer, &BufferData, &PacketSize ); - Connection = Request->Handle.ConnectionContext; - return OskitTCPSend( Connection->SocketContext, - BufferData, PacketSize, 0 ); + TI_DbgPrint(MID_TRACE,("Connection = %x\n", Connection)); + TI_DbgPrint(MID_TRACE,("Connection->SocketContext = %x\n", + Connection->SocketContext)); + + Status = OskitTCPSend( Connection->SocketContext, + BufferData, PacketSize, (OSK_UINT *)DataUsed, 0 ); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + return Status; } NTSTATUS TCPTimeout(VOID) { diff --git a/reactos/drivers/net/tcpip/transport/udp/udp.c b/reactos/drivers/net/tcpip/transport/udp/udp.c index 768d02f0109..5415aa32f24 100644 --- a/reactos/drivers/net/tcpip/transport/udp/udp.c +++ b/reactos/drivers/net/tcpip/transport/udp/udp.c @@ -168,7 +168,8 @@ NTSTATUS UDPSendDatagram( PTDI_REQUEST Request, PTDI_CONNECTION_INFORMATION ConnInfo, PNDIS_BUFFER Buffer, - ULONG DataSize) + ULONG DataSize, + PULONG DataUsed ) /* * FUNCTION: Sends an UDP datagram to a remote address * ARGUMENTS: @@ -183,6 +184,12 @@ NTSTATUS UDPSendDatagram( PDATAGRAM_SEND_REQUEST SendRequest; PADDRESS_FILE AddrFile = (PADDRESS_FILE)Request->Handle.AddressHandle; + PCHAR BufferData; + UINT BufferLen; + + NdisQueryBuffer( Buffer, &BufferData, &BufferLen ); + + *DataUsed = BufferLen; BuildUDPPacket( SendRequest, (PIP_ADDRESS)&AddrFile->ADE->Address->Address.