- Fix user-initiated hard connection closures

svn path=/trunk/; revision=53173
This commit is contained in:
Cameron Gutman 2011-08-11 06:39:17 +00:00
parent 0d496d7999
commit 5ea7b9c764

View file

@ -643,7 +643,6 @@ LibTCPCloseCallback(void *arg)
{ {
struct lwip_callback_msg *msg = arg; struct lwip_callback_msg *msg = arg;
PTCP_PCB pcb = msg->Input.Close.Connection->SocketContext; PTCP_PCB pcb = msg->Input.Close.Connection->SocketContext;
int state;
/* Empty the queue even if we're already "closed" */ /* Empty the queue even if we're already "closed" */
LibTCPEmptyQueue(msg->Input.Close.Connection); LibTCPEmptyQueue(msg->Input.Close.Connection);
@ -657,29 +656,36 @@ LibTCPCloseCallback(void *arg)
/* Clear the PCB pointer */ /* Clear the PCB pointer */
msg->Input.Close.Connection->SocketContext = NULL; msg->Input.Close.Connection->SocketContext = NULL;
/* Save the old PCB state */ switch (pcb->state)
state = pcb->state;
msg->Output.Close.Error = tcp_close(pcb);
if (!msg->Output.Close.Error)
{ {
if (msg->Input.Close.Callback) case CLOSED:
{ case LISTEN:
/* Call the FIN handler in the cases where it will not be called by lwIP */ case SYN_SENT:
switch (state) msg->Output.Close.Error = tcp_close(pcb);
{
case CLOSED:
case LISTEN:
case SYN_SENT:
TCPFinEventHandler(msg->Input.Close.Connection, ERR_OK);
break;
default: if (!msg->Output.Close.Error && msg->Input.Close.Callback)
break; TCPFinEventHandler(msg->Input.Close.Connection, ERR_OK);
} break;
}
default:
if (msg->Input.Close.Connection->SendShutdown &&
msg->Input.Close.Connection->ReceiveShutdown)
{
/* Abort the connection */
tcp_abort(pcb);
/* Aborts always succeed */
msg->Output.Close.Error = ERR_OK;
}
else
{
/* Start the graceful close process (or send RST for pending data) */
msg->Output.Close.Error = tcp_close(pcb);
}
break;
} }
else
if (msg->Output.Close.Error)
{ {
/* Restore the PCB pointer */ /* Restore the PCB pointer */
msg->Input.Close.Connection->SocketContext = pcb; msg->Input.Close.Connection->SocketContext = pcb;