Messages in this thread Patch in this message |  | | Date | Sun, 4 Aug 96 00:32 BST | From | (Alan Cox) | Subject | TCP/buffering changes |
| |
* * Ok Linus this looks like the working diff. * * 1. sock_wmalloc/rmalloc allow an allocation to succeed if no * memory is allocated. Its up to the protocol to handle limits * gracefully beyond this. At worst we can slightly overcommit * socket resources beyond those requested. * * 2. TCP sleep for memory is fixed * * 3. Pedro's eth_copy_csum fix * * 4. POSIX 1003.1g compliance oddities while Im fixing tcp * MSG_PEEK prevents errors being reported (so you can peek * when there is an error to see whats next, without upsetting * the error state) * EINVAL and ECONNABORTED error return fixes. * * 5. Fixed the sk->mss == 0 bug reports. sk->mss can be 0 if the * remote offers us a zero window and we send before the first * ack opening the window. We don't chop our mss to fit their * largest window until we see one offered now. * * Alan * * diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/net/core/sock.c linux/net/core/sock.c --- linux.vanilla/net/core/sock.c Sun Jul 28 13:33:17 1996 +++ linux/net/core/sock.c Sat Aug 3 23:23:04 1996 @@ -348,7 +363,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, int priority) { if (sk) { - if (force || sk->wmem_alloc + size < sk->sndbuf) { + if (force || !sk->wmem_alloc || sk->wmem_alloc + size < sk->sndbuf) { struct sk_buff * skb = alloc_skb(size, priority); if (skb) atomic_add(skb->truesize, &sk->wmem_alloc); @@ -362,7 +377,7 @@ struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority) { if (sk) { - if (force || sk->rmem_alloc + size < sk->rcvbuf) { + if (force || !sk->rmem_alloc || sk->rmem_alloc + size < sk->rcvbuf) { struct sk_buff *skb = alloc_skb(size, priority); if (skb) atomic_add(skb->truesize, &sk->rmem_alloc); diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/net/ethernet/eth.c linux/net/ethernet/eth.c --- linux.vanilla/net/ethernet/eth.c Sun Jul 28 13:33:18 1996 +++ linux/net/ethernet/eth.c Sat Aug 3 19:18:34 1996 @@ -273,7 +273,7 @@ int ip_length; IS_SKB(dest); - eth=(struct ethhdr *)dest->data; + eth=(struct ethhdr *)src; if(eth->h_proto!=htons(ETH_P_IP)) { memcpy(dest->data,src,length); diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c --- linux.vanilla/net/ipv4/af_inet.c Sun Jul 28 13:33:18 1996 +++ linux/net/ipv4/af_inet.c Wed Jul 31 18:25:36 1996 @@ -814,7 +814,7 @@ /* check this error. */ if (sk->state != TCP_CLOSE) - return(-EIO); + return(-EINVAL); if(addr_len<sizeof(struct sockaddr_in)) return -EINVAL; @@ -1104,6 +1104,12 @@ destroy_sock(sk2); newsock->data = NULL; return err; + } + if (sk2->state == TCP_CLOSE) + { + destroy_sock(sk2); + newsock->data=NULL; + return -ECONNABORTED; } newsock->state = SS_CONNECTED; return(0); diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/net/ipv4/tcp.c linux/net/ipv4/tcp.c --- linux.vanilla/net/ipv4/tcp.c Sun Jul 28 13:33:19 1996 +++ linux/net/ipv4/tcp.c Sat Aug 3 23:16:42 1996 @@ -856,16 +856,24 @@ lock_sock(sk); } +extern __inline int tcp_memory_free(struct sock *sk, int umem) +{ + if(!sk->wmem_alloc || sk->wmem_alloc+umem>=sk->sndbuf) + return 0; + return 1; +} + /* * Wait for more memory for a socket */ -static void wait_for_tcp_memory(struct sock * sk) +static void wait_for_tcp_memory(struct sock * sk, int umem) { release_sock(sk); cli(); - if (sk->wmem_alloc*2 > sk->sndbuf && + /* THIS LINE HAS TO BE CORRECT AND MATCH SOCK_WMALLOC OR KERBOOM */ + if ( !tcp_memory_free(sk,umem) && (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 +972,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; @@ -1095,7 +1107,7 @@ return -ERESTARTSYS; } - wait_for_tcp_memory(sk); + wait_for_tcp_memory(sk, tmp); continue; } @@ -1428,7 +1440,7 @@ if (copied) break; - if (sk->err) + if (sk->err && !(flags&MSG_PEEK)) { copied = sock_error(sk); break;
|  |