- Ensure that the connection failure gets delivered if the socket is not yet ready to receive or has shutdown receive

svn path=/trunk/; revision=59706
This commit is contained in:
Cameron Gutman 2013-08-12 04:08:20 +00:00
parent 578fec3cac
commit fbc6d8b085
2 changed files with 13 additions and 11 deletions

View file

@ -264,12 +264,10 @@ TCPFinEventHandler(void *arg, const err_t err)
const NTSTATUS Status = TCPTranslateError(err);
KIRQL OldIrql;
ASSERT(Connection->SocketContext == NULL);
ASSERT(Connection->AddressFile);
ASSERT(err != ERR_OK);
/* First off all, remove the PCB pointer */
Connection->SocketContext = NULL;
/* Complete all outstanding requests now */
FlushAllQueues(Connection, Status);

View file

@ -251,11 +251,14 @@ InternalRecvEventHandler(void *arg, PTCP_PCB pcb, struct pbuf *p, const err_t er
{
Connection->SocketContext = NULL;
tcp_arg(pcb, NULL);
TCPFinEventHandler(Connection, ERR_OK);
}
else
{
/* Remotely initiated close */
TCPRecvEventHandler(arg);
}
}
return ERR_OK;
}
@ -299,16 +302,18 @@ InternalErrorEventHandler(void *arg, const err_t err)
PCONNECTION_ENDPOINT Connection = arg;
/* Make sure the socket didn't get closed */
if (!arg) return;
if (!arg || Connection->SocketContext == NULL) return;
/* The PCB is dead now */
Connection->SocketContext = NULL;
/* Defer the error delivery until all data is gone */
/* Give them one shot to receive the remaining data */
Connection->ReceiveShutdown = TRUE;
Connection->ReceiveShutdownStatus = TCPTranslateError(err);
TCPRecvEventHandler(Connection);
TCPRecvEventHandler(arg);
/* Terminate the connection */
TCPFinEventHandler(Connection, err);
}
static
@ -663,6 +668,7 @@ LibTCPShutdownCallback(void *arg)
/* The PCB is not ours anymore */
msg->Input.Shutdown.Connection->SocketContext = NULL;
tcp_arg(pcb, NULL);
TCPFinEventHandler(msg->Input.Shutdown.Connection, ERR_CLSD);
}
}
@ -724,8 +730,6 @@ LibTCPCloseCallback(void *arg)
/* Check if the PCB was already "closed" but the client doesn't know it yet */
if (!msg->Input.Close.Connection->SocketContext)
{
if (msg->Input.Close.Callback)
TCPFinEventHandler(msg->Input.Close.Connection, ERR_CLSD);
msg->Output.Close.Error = ERR_OK;
goto done;
}