- tcp_connection_set_state (tc0, TCP_STATE_CLOSING);
- tcp_program_ack (wrk, tc0);
- /* Wait for ACK but not forever */
- tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
+
+ if (tc0->flags & TCP_CONN_FINPNDG)
+ {
+ /* If data is outstanding, stay in FIN_WAIT_1 and try to finish
+ * sending it. Since we already received a fin, do not wait
+ * for too long. */
+ tc0->flags |= TCP_CONN_FINRCVD;
+ tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_CLOSEWAIT_TIME);
+ }
+ else
+ {
+ tcp_connection_set_state (tc0, TCP_STATE_CLOSING);
+ tcp_program_ack (wrk, tc0);
+ /* Wait for ACK for our FIN but not forever */
+ tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
+ }