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

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.

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -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;
}

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 );

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,

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;
}

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 */

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);
}

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:

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;
}

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);