patch-2.0.11 linux/net/ipv4/tcp.c

Next file: linux/net/ipv4/tcp_input.c
Previous file: linux/net/ipv4/rarp.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.10/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
@@ -856,6 +856,11 @@
 	lock_sock(sk);
 }
 
+static inline int tcp_memory_free(struct sock *sk)
+{
+	return sk->wmem_alloc < sk->sndbuf;
+}
+
 /*
  *	Wait for more memory for a socket
  */
@@ -863,9 +868,9 @@
 {
 	release_sock(sk);
 	cli();
-	if (sk->wmem_alloc*2 > sk->sndbuf &&
+	if (!tcp_memory_free(sk) &&
 	    (sk->state == TCP_ESTABLISHED||sk->state == TCP_CLOSE_WAIT)
-		&& sk->err == 0)
+		&& sk->err == 0 /* && check shutdown ?? */)
 	{
 		sk->socket->flags &= ~SO_NOSPACE;
 		interruptible_sleep_on(sk->sleep);
@@ -964,16 +969,20 @@
 			 */
 #ifndef CONFIG_NO_PATH_MTU_DISCOVERY
 			/*
-			 *	FIXME:  I'm almost sure that this fragment is BUG,
-			 *		but it works... I do not know why 8) --ANK
-			 *
 			 *	Really, we should rebuild all the queues...
 			 *	It's difficult. Temporary hack is to send all
 			 *	queued segments with allowed fragmentation.
 			 */
 			{
+				/*
+				 *	new_mss may be zero. That indicates
+				 *	we don't have a window estimate for
+				 *	the remote box yet. 
+				 *		-- AC
+				 */
+				
 				int new_mss = min(sk->mtu, sk->max_window);
-				if (new_mss < sk->mss)
+				if (new_mss && new_mss < sk->mss)
 				{
 					tcp_send_partial(sk);
 					sk->mss = new_mss;
@@ -1428,7 +1437,7 @@
 		if (copied)
 			break;
 
-		if (sk->err)
+		if (sk->err && !(flags&MSG_PEEK))
 		{
 			copied = sock_error(sk);
 			break;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov