- Fix (hopefully) the final disconnect bugs

svn path=/trunk/; revision=52783
This commit is contained in:
Cameron Gutman 2011-07-22 15:11:01 +00:00
parent 2374f5b1aa
commit acd4c15b61
4 changed files with 30 additions and 27 deletions

View file

@ -603,12 +603,13 @@ DisconnectComplete(PDEVICE_OBJECT DeviceObject,
IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT );
}
if (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE)
FCB->PollState |= AFD_EVENT_DISCONNECT;
else
if (!(FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE))
{
/* Signal complete connection closure immediately */
FCB->PollState |= AFD_EVENT_ABORT;
FCB->PollStatus[FD_CLOSE_BIT] = Irp->IoStatus.Status;
PollReeval(FCB->DeviceExt, FCB->FileObject);
FCB->PollStatus[FD_CLOSE_BIT] = Irp->IoStatus.Status;
PollReeval(FCB->DeviceExt, FCB->FileObject);
}
SocketStateUnlock(FCB);
@ -721,6 +722,7 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
FCB->DisconnectFlags = Flags;
FCB->DisconnectTimeout = DisReq->Timeout;
FCB->DisconnectPending = TRUE;
FCB->SendClosed = TRUE;
Status = QueueUserModeIrp(FCB, Irp, FUNCTION_DISCONNECT);
if (Status == STATUS_PENDING)

View file

@ -32,8 +32,8 @@ static VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information
{
FCB->TdiReceiveClosed = TRUE;
/* Signal unexpected termination immediately */
FCB->PollState |= AFD_EVENT_ABORT;
/* Signal complete connection failure immediately */
FCB->PollState |= AFD_EVENT_CLOSE;
FCB->PollStatus[FD_CLOSE_BIT] = Status;
PollReeval( FCB->DeviceExt, FCB->FileObject );
@ -232,13 +232,12 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
PollReeval( FCB->DeviceExt, FCB->FileObject );
}
else if (CantReadMore(FCB) &&
!(FCB->PollState & (AFD_EVENT_ABORT | AFD_EVENT_CLOSE)) &&
IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]))
!(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT)))
{
FCB->PollState &= ~AFD_EVENT_RECEIVE;
/* Signal delayed close event */
FCB->PollState |= AFD_EVENT_ABORT;
/* Signal graceful receive shutdown */
FCB->PollState |= AFD_EVENT_DISCONNECT;
FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS;
PollReeval( FCB->DeviceExt, FCB->FileObject );

View file

@ -351,26 +351,28 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
}
}
if (FCB->DisconnectPending && (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE))
if (FCB->PollState & AFD_EVENT_CLOSE)
{
AFD_DbgPrint(MIN_TRACE,("No more sends\n"));
/* We're pending a send shutdown so don't accept anymore sends */
return UnlockAndMaybeComplete(FCB, STATUS_FILE_CLOSED, Irp, 0);
AFD_DbgPrint(MIN_TRACE,("Connection reset by remote peer\n"));
/* This is an unexpected remote disconnect */
return UnlockAndMaybeComplete(FCB, FCB->PollStatus[FD_CLOSE_BIT], Irp, 0);
}
if (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT))
if (FCB->PollState & AFD_EVENT_ABORT)
{
AFD_DbgPrint(MIN_TRACE,("Connection aborted\n"));
/* This is an abortive socket closure on our side */
return UnlockAndMaybeComplete(FCB, FCB->PollStatus[FD_CLOSE_BIT], Irp, 0);
}
if (FCB->SendClosed)
{
AFD_DbgPrint(MIN_TRACE,("No more sends\n"));
if (FCB->PollStatus[FD_CLOSE_BIT] == STATUS_SUCCESS)
{
/* This is a local send shutdown or a graceful remote disconnect */
return UnlockAndMaybeComplete(FCB, STATUS_FILE_CLOSED, Irp, 0);
}
else
{
/* This is an unexpected remote disconnect */
return UnlockAndMaybeComplete(FCB, FCB->PollStatus[FD_CLOSE_BIT], Irp, 0);
}
/* This is a graceful send closure */
return UnlockAndMaybeComplete(FCB, STATUS_FILE_CLOSED, Irp, 0);
}
if( !(SendReq = LockRequest( Irp, IrpSp )) )

View file

@ -173,7 +173,7 @@ typedef struct _AFD_STORED_DATAGRAM {
} AFD_STORED_DATAGRAM, *PAFD_STORED_DATAGRAM;
typedef struct _AFD_FCB {
BOOLEAN Locked, Critical, Overread, NonBlocking, OobInline, TdiReceiveClosed;
BOOLEAN Locked, Critical, Overread, NonBlocking, OobInline, TdiReceiveClosed, SendClosed;
UINT State, Flags, GroupID, GroupType;
KIRQL OldIrql;
UINT LockCount;