mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 01:42:30 +00:00
AFD: Fixed handling of cancelling in flight requests when closing the socket.
Closing a socket doesn't crash but still hangs. Needs work. oskittcp: corrected problem with send data, trying out slightly different scheme of dealing with closed socket. tcpip: added support for SEL_FIN in socket state callback and corrected support for returning error in TCPReceiveData. svn path=/trunk/; revision=10650
This commit is contained in:
parent
36d2e136c7
commit
c24ef8433f
|
@ -25,3 +25,4 @@ by looking over bsd cross-reference but it's one of the more lightly
|
|||
documented parts of bsd. A wierd thing about sbappend is that it seems to
|
||||
want to see an M_EOR flag at the end of the so->so_rcv->sb_mb chain. When
|
||||
it gets there it should append the input chain.
|
||||
|
||||
|
|
|
@ -255,6 +255,7 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
|
|||
uio.uio_resid = Len;
|
||||
mb.m_data = Data;
|
||||
mb.m_len = Len;
|
||||
mb.m_flags = M_EOR;
|
||||
error = sosend( socket, NULL, &uio, (struct mbuf *)&mb, NULL, 0 );
|
||||
printf("uio.uio_resid = %d\n", uio.uio_resid);
|
||||
*OutLen = uio.uio_resid;
|
||||
|
|
|
@ -77,6 +77,10 @@ void wakeup( struct socket *so, void *token ) {
|
|||
OS_DbgPrint(OSK_MID_TRACE,("Socket readable\n"));
|
||||
flags |= SEL_READ;
|
||||
}
|
||||
if( so->so_state & SS_CANTRCVMORE ) {
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Socket can't be read any longer\n"));
|
||||
flags |= SEL_FIN;
|
||||
}
|
||||
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Wakeup %x (socket %x, state %x)!\n",
|
||||
token, so,
|
||||
|
|
|
@ -402,9 +402,13 @@ m_copydata(m, off, len, cp)
|
|||
if (m == 0)
|
||||
panic("m_copydata");
|
||||
count = min(m->m_len - off, len);
|
||||
#ifdef __REACTOS__
|
||||
memcpy(cp, mtod(m, caddr_t) + off, count);
|
||||
#else
|
||||
bcopy(mtod(m, caddr_t) + off, cp, count);
|
||||
OS_DbgPrint(OSK_MID_TRACE,("buf %x, len %d\n", m, m->m_len));
|
||||
OskitDumpBuffer(m->m_data, m->m_len);
|
||||
#endif
|
||||
OS_DbgPrint(OSK_MID_TRACE,("buf %x, len %d\n", m, count));
|
||||
OskitDumpBuffer(m->m_data, count);
|
||||
len -= count;
|
||||
cp += count;
|
||||
off = 0;
|
||||
|
|
|
@ -541,8 +541,12 @@ soreceive(so, paddr, uio, _mp0, controlp, flagsp)
|
|||
if( mp0->m_len == 0 )
|
||||
return 0;
|
||||
|
||||
if( so->so_rcv.sb_cc == 0 && so->so_rcv.sb_sel.si_flags & SEL_FIN )
|
||||
if( so->so_rcv.sb_cc == 0 &&
|
||||
/*so->so_rcv.sb_sel.si_flags & SEL_FIN*/
|
||||
(so->so_state & SS_CANTRCVMORE) ) {
|
||||
OS_DbgPrint(OSK_MID_TRACE, ("Receive: SEL_FIN\n"));
|
||||
return OSK_ESHUTDOWN;
|
||||
}
|
||||
|
||||
while( mb->m_nextpkt && total < mp0->m_len ) {
|
||||
OS_DbgPrint(OSK_MID_TRACE, ("Looking at packet %x\n", mb));
|
||||
|
@ -601,7 +605,7 @@ soreceive(so, paddr, uio, _mp0, controlp, flagsp)
|
|||
|
||||
uio->uio_resid = total;
|
||||
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Leaving (success)\n"));
|
||||
OS_DbgPrint(OSK_MID_TRACE,("Leaving (success: %d bytes)\n", total));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: main.c,v 1.4 2004/07/29 04:10:53 arty Exp $
|
||||
/* $Id: main.c,v 1.5 2004/08/22 18:42:42 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/main.c
|
||||
|
@ -22,7 +22,8 @@
|
|||
extern NTSTATUS DDKAPI MmCopyFromCaller( PVOID Dst, PVOID Src, UINT Size );
|
||||
|
||||
/* See debug.h for debug/trace constants */
|
||||
DWORD DebugTraceLevel = DEBUG_ULTRA;
|
||||
//DWORD DebugTraceLevel = DEBUG_ULTRA;
|
||||
DWORD DebugTraceLevel = 0;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
@ -163,6 +164,8 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
for( i = 0; i < IN_FLIGHT_REQUESTS; i++ ) {
|
||||
NTSTATUS Status = STATUS_NO_SUCH_FILE;
|
||||
if( InFlightRequest[i]->InFlightRequest ) {
|
||||
AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %d (%x)\n",
|
||||
i, InFlightRequest[i]->InFlightRequest));
|
||||
InFlightRequest[i]->InFlightRequest->IoStatus.Status = Status;
|
||||
InFlightRequest[i]->InFlightRequest->IoStatus.Information = 0;
|
||||
IoCancelIrp( InFlightRequest[i]->InFlightRequest );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: read.c,v 1.3 2004/08/22 02:15:57 arty Exp $
|
||||
/* $Id: read.c,v 1.4 2004/08/22 18:42:42 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/read.c
|
||||
|
@ -77,6 +77,9 @@ NTSTATUS DDKAPI ReceiveComplete
|
|||
|
||||
if( !SocketAcquireStateLock( FCB ) ) return Status;
|
||||
|
||||
/* Reset in flight request because the last has been completed */
|
||||
FCB->ReceiveIrp.InFlightRequest = NULL;
|
||||
|
||||
if( NT_SUCCESS(Irp->IoStatus.Status) ) {
|
||||
/* Update the receive window */
|
||||
FCB->Recv.Content = Irp->IoStatus.Information;
|
||||
|
@ -120,7 +123,7 @@ NTSTATUS DDKAPI ReceiveComplete
|
|||
}
|
||||
}
|
||||
|
||||
if( FCB->Recv.Window && !FCB->Recv.Content ) {
|
||||
if( NT_SUCCESS(Status) && FCB->Recv.Window && !FCB->Recv.Content ) {
|
||||
AFD_DbgPrint(MID_TRACE,
|
||||
("Exhausted our buffer. Requesting new: %x\n", FCB));
|
||||
|
||||
|
@ -180,6 +183,24 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
RecvReq->BufferCount,
|
||||
TRUE );
|
||||
|
||||
/* Launch a new recv request if we have no data */
|
||||
|
||||
if( FCB->Recv.Window && !(FCB->Recv.Content - FCB->Recv.BytesUsed) &&
|
||||
!FCB->ReceiveIrp.InFlightRequest ) {
|
||||
FCB->Recv.Content = 0;
|
||||
FCB->Recv.BytesUsed = 0;
|
||||
AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
|
||||
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
|
||||
FCB->Connection.Object,
|
||||
TDI_RECEIVE_NORMAL,
|
||||
FCB->Recv.Window,
|
||||
FCB->Recv.Size,
|
||||
&FCB->ReceiveIrp.Iosb,
|
||||
ReceiveComplete,
|
||||
FCB );
|
||||
} else Status = STATUS_SUCCESS;
|
||||
|
||||
if( NT_SUCCESS(Status) )
|
||||
Status = TryToSatisfyRecvRequestFromBuffer
|
||||
( FCB, RecvReq, &TotalBytesCopied );
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: write.c,v 1.3 2004/08/22 02:15:57 arty Exp $
|
||||
/* $Id: write.c,v 1.4 2004/08/22 18:42:42 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/write.c
|
||||
|
@ -32,6 +32,9 @@ NTSTATUS DDKAPI SendComplete
|
|||
|
||||
if( !SocketAcquireStateLock( FCB ) ) return Status;
|
||||
|
||||
FCB->SendIrp.InFlightRequest = NULL;
|
||||
/* Request is not in flight any longer */
|
||||
|
||||
if( !NT_SUCCESS(Status) ) {
|
||||
/* Complete all following send IRPs with error */
|
||||
|
||||
|
@ -119,8 +122,6 @@ NTSTATUS DDKAPI SendComplete
|
|||
if( Status == STATUS_PENDING )
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
SocketStateUnlock( FCB );
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
|
||||
|
||||
return UnlockAndMaybeComplete( FCB, Status, Irp, TotalBytesCopied,
|
||||
|
@ -130,9 +131,9 @@ NTSTATUS DDKAPI SendComplete
|
|||
NextIrp));
|
||||
InsertHeadList( &FCB->PendingIrpList[FUNCTION_SEND],
|
||||
&Irp->Tail.Overlay.ListEntry );
|
||||
}
|
||||
|
||||
SocketStateUnlock( FCB );
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
#ifndef __TCP_H
|
||||
#define __TCP_H
|
||||
|
||||
typedef VOID
|
||||
(*PTCP_COMPLETION_ROUTINE)( PVOID Context, NTSTATUS Status, ULONG Count );
|
||||
|
||||
/* TCPv4 header structure */
|
||||
typedef struct TCPv4_HEADER {
|
||||
USHORT SourcePort; /* Source port */
|
||||
|
|
|
@ -220,7 +220,7 @@ VOID DispDataRequestComplete(
|
|||
Irp->IoStatus.Information));
|
||||
TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
|
||||
|
||||
IRPFinish(Irp, STATUS_SUCCESS);
|
||||
IRPFinish(Irp, Irp->IoStatus.Status);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
#include "precomp.h"
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
|
||||
#ifndef NDEBUG
|
||||
DWORD DebugTraceLevel = 0x7fffffff;
|
||||
|
@ -494,6 +494,7 @@ TiDispatchInternal(
|
|||
switch (IrpSp->MinorFunction) {
|
||||
case TDI_RECEIVE:
|
||||
Status = DispTdiReceive(Irp);
|
||||
Complete = FALSE;
|
||||
break;
|
||||
|
||||
case TDI_RECEIVE_DATAGRAM:
|
||||
|
@ -519,6 +520,7 @@ TiDispatchInternal(
|
|||
|
||||
case TDI_CONNECT:
|
||||
Status = DispTdiConnect(Irp);
|
||||
Complete = FALSE; /* Completed by the TCP event handler */
|
||||
break;
|
||||
|
||||
case TDI_DISCONNECT:
|
||||
|
|
|
@ -12,9 +12,6 @@
|
|||
|
||||
extern ULONG TCP_IPIdentification;
|
||||
|
||||
typedef VOID
|
||||
(*PTCP_COMPLETION_ROUTINE)( PVOID Context, NTSTATUS Status, ULONG Count );
|
||||
|
||||
int TCPSocketState(void *ClientData,
|
||||
void *WhichSocket,
|
||||
void *WhichConnection,
|
||||
|
@ -44,7 +41,7 @@ int TCPSocketState(void *ClientData,
|
|||
/* Frees the bucket allocated in TCPConnect */
|
||||
ExFreePool( Bucket );
|
||||
}
|
||||
} else if( NewState & SEL_READ ) {
|
||||
} else if( (NewState & SEL_READ) || (NewState & SEL_FIN) ) {
|
||||
while( !IsListEmpty( &Connection->ReceiveRequest ) ) {
|
||||
PIRP Irp;
|
||||
OSK_UINT RecvLen = 0, Received = 0;
|
||||
|
@ -71,6 +68,10 @@ int TCPSocketState(void *ClientData,
|
|||
TI_DbgPrint(MID_TRACE,
|
||||
("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
|
||||
|
||||
if( NewState & SEL_FIN ) {
|
||||
Status = STATUS_END_OF_FILE;
|
||||
Received = 0;
|
||||
} else
|
||||
Status = TCPTranslateError
|
||||
( OskitTCPRecv( Connection->SocketContext,
|
||||
RecvBuffer,
|
||||
|
|
|
@ -111,7 +111,7 @@ NTSTATUS TCPTranslateError( int OskitError ) {
|
|||
|
||||
switch( OskitError ) {
|
||||
case 0: Status = STATUS_SUCCESS; break;
|
||||
/*case OAK_EADDRNOTAVAIL: */
|
||||
case OSK_EADDRNOTAVAIL:
|
||||
case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break;
|
||||
case OSK_ECONNREFUSED:
|
||||
case OSK_ECONNRESET: Status = STATUS_REMOTE_NOT_LISTENING; break;
|
||||
|
@ -260,6 +260,8 @@ NTSTATUS TCPReceiveData
|
|||
NTSTATUS Status;
|
||||
PTDI_BUCKET Bucket;
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("Called for %d bytes\n", ReceiveLength));
|
||||
|
||||
Connection = Request->Handle.ConnectionContext;
|
||||
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
|
@ -276,8 +278,11 @@ NTSTATUS TCPReceiveData
|
|||
&Received,
|
||||
ReceiveFlags ) );
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("OskitTCPReceive: %x, %d\n", Status, Received));
|
||||
|
||||
/* Keep this request around ... there was no data yet */
|
||||
if( Status == STATUS_PENDING || Received == 0 ) {
|
||||
if( Status == STATUS_PENDING ||
|
||||
(Status == STATUS_SUCCESS && Received == 0) ) {
|
||||
/* Freed in TCPSocketState */
|
||||
Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) );
|
||||
if( !Bucket ) return STATUS_NO_MEMORY;
|
||||
|
@ -285,6 +290,8 @@ NTSTATUS TCPReceiveData
|
|||
Bucket->Request = *Request;
|
||||
InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry );
|
||||
Status = STATUS_PENDING;
|
||||
} else {
|
||||
TI_DbgPrint(MID_TRACE,("Got status %x, bytes %d\n", Status, Received));
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
|
Loading…
Reference in a new issue