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:
Art Yerkes
2004-08-22 18:42:42 +00:00
parent 36d2e136c7
commit c24ef8433f
13 changed files with 84 additions and 32 deletions
+2 -1
View File
@@ -24,4 +24,5 @@ mean or why they're happening. I'm trying to figure out sbappend especially
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.
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;
}
+5 -2
View File
@@ -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 );
+25 -4
View File
@@ -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
@@ -76,6 +76,9 @@ NTSTATUS DDKAPI ReceiveComplete
AFD_DbgPrint(MID_TRACE,("Called\n"));
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 */
@@ -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,9 +183,27 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
RecvReq->BufferCount,
TRUE );
Status = TryToSatisfyRecvRequestFromBuffer
( FCB, RecvReq, &TotalBytesCopied );
/* 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 );
if( Status != STATUS_PENDING ) {
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount );
return UnlockAndMaybeComplete( FCB, Status, Irp,
+6 -5
View File
@@ -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 );
}
SocketStateUnlock( FCB );
return STATUS_SUCCESS;
}
+3
View File
@@ -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 */
+1 -1
View File
@@ -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);
}
+3 -1
View File
@@ -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 -11
View File
@@ -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,12 +68,16 @@ int TCPSocketState(void *ClientData,
TI_DbgPrint(MID_TRACE,
("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
Status = TCPTranslateError
( OskitTCPRecv( Connection->SocketContext,
RecvBuffer,
RecvLen,
&Received,
0 ) );
if( NewState & SEL_FIN ) {
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));
@@ -96,7 +97,7 @@ int TCPSocketState(void *ClientData,
&Bucket->Entry );
}
}
}
}
return 0;
}
+10 -3
View File
@@ -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);
@@ -274,10 +276,13 @@ NTSTATUS TCPReceiveData
DataBuffer,
DataLen,
&Received,
ReceiveFlags ) );
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);