From Bugzilla Helper: User-Agent: Mozilla/4.75 [en] (X11; U; Linux 2.4.7 i686) Description of problem: Both 2.2.X kernels and 2.4.X kernels fail to free sk->write_queue memory on transition from TCP_CLOSE_WAIT to TCP_LAST_ACK. For certain ill behaved connections, this results in the socket buffer being full in LAST_ACK for a long time. Many of such connections can cause the kernel to waste hundreds of MB (if available). How reproducible: Always Steps to Reproduce: 1. run an HTTP proxy (e.g. traffic_server (Inktomi) or likely squid) 2. the proxy sends data 3. before the socket buffer drains a FIN arrives from the client (connection is now in CLOSE_WAIT with data in Send-Q) 4. the proxy closes the connection (connection now in LAST_ACK) FIN sent 5. ACK not received (lost) 6. memory wasted in Send-Q Actual Results: after a long run of clients with the above behavior, netstat reports hundreds of megabytes of data in Send-Q of connections in LAST_ACK state. Expected Results: netstat reports all connections in LAST_ACK have at most the FIN packet waiting Additional info: See the URL also for the patches, but here is the one for 2.4.7: *** linux-2.4.7.orig/net/ipv4/tcp.c Tue Jul 24 14:48:58 2001 --- linux-2.4.7/net/ipv4/tcp.c Tue Jul 24 14:51:48 2001 *************** *** 1711,1716 **** --- 1711,1722 ---- int next = (int) new_state[sk->state]; int ns = (next & TCP_STATE_MASK); + if (sk->state == TCP_CLOSE_WAIT) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + tcp_writequeue_purge(sk); + tp->send_head = 0; + } + tcp_set_state(sk, ns); return (next & TCP_ACTION_FIN); Basically just purge the write_queue on this transition. I have tested this code and it works.
This is assigned to the wrong person. Re-assigning.
This suggested change is invalid. The sender must attempt to send the rest of the send queue before the ACK. So if the socket is holding onto the memory this is because the receiving side has not ACK'd the data yet. Once the data is ACK'd the send queue data will be freed up. shutdown(SEND) or close() does not mean "all pending send data is invalid", it means "send all pending data then FIN". We free up the data as early as is legally possible.