Messages in this thread Patch in this message | | | Date | Fri, 13 Aug 1999 04:59:38 -0700 | From | "David S. Miller" <> | Subject | PATCH (was Possible Linux/Solaris 7 TCP bug) |
| |
This is hindering my work quite badly so I'd be very grateful if some TCP guru could take a look at the trace and tell me which OS is the one in fault (for which one I'll need to wait for a patch, that is).
Please try this patch, it should fix the stuck connections.
--- ./include/net/tcp.h.~1~ Wed Aug 11 04:48:56 1999 +++ ./include/net/tcp.h Fri Aug 13 04:29:02 1999 @@ -142,7 +139,8 @@ nonagle; /* And these are ours. */ - __u32 rcv_nxt,snd_nxt; + __u32 rcv_nxt, snd_nxt; + __u16 window; struct tcp_func *af_specific; struct tcp_bind_bucket *tb; struct tcp_tw_bucket *next_death; --- ./net/ipv4/tcp_input.c.~1~ Sun Aug 8 01:44:24 1999 +++ ./net/ipv4/tcp_input.c Fri Aug 13 04:40:55 1999 @@ -1006,7 +1006,8 @@ tcp_tw_reschedule(tw); } /* Ack old packets if necessary */ - if (!after(TCP_SKB_CB(skb)->end_seq, tw->rcv_nxt)) + if (!after(TCP_SKB_CB(skb)->end_seq, tw->rcv_nxt) && + (th->doff * 4) > len) return TCP_TW_ACK; return 0; } @@ -1067,7 +1068,8 @@ tw->family = sk->family; tw->reuse = sk->reuse; tw->rcv_nxt = sk->tp_pinfo.af_tcp.rcv_nxt; - tw->snd_nxt = sk->tp_pinfo.af_tcp.snd_nxt; + tw->snd_nxt = sk->tp_pinfo.af_tcp.snd_nxt; + tw->window = tcp_select_window(sk); tw->af_specific = sk->tp_pinfo.af_tcp.af_specific; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) --- ./net/ipv4/tcp_ipv4.c.~1~ Thu Aug 12 08:35:18 1999 +++ ./net/ipv4/tcp_ipv4.c Fri Aug 13 04:31:33 1999 @@ -1026,7 +1028,7 @@ * * Assumes that the caller did basic address and flag checks. */ -static void tcp_v4_send_ack(struct sk_buff *skb, __u32 seq, __u32 ack) +static void tcp_v4_send_ack(struct sk_buff *skb, __u32 seq, __u32 ack, __u16 window) { struct tcphdr *th = skb->h.th; struct tcphdr rth; @@ -1042,6 +1044,8 @@ rth.ack_seq = ack; rth.ack = 1; + rth.window = htons(window); + memset(&arg, 0, sizeof arg); arg.iov[0].iov_base = (unsigned char *)&rth; arg.iov[0].iov_len = sizeof rth; @@ -1774,10 +1778,12 @@ do_time_wait: /* Sorry for the ugly switch. 2.3 will have a better solution. */ switch (tcp_timewait_state_process((struct tcp_tw_bucket *)sk, - skb, th, skb->len)) { + skb, th, skb->len)) { case TCP_TW_ACK: - tcp_v4_send_ack(skb, ((struct tcp_tw_bucket *)sk)->snd_nxt, - ((struct tcp_tw_bucket *)sk)->rcv_nxt); + tcp_v4_send_ack(skb, + ((struct tcp_tw_bucket *)sk)->snd_nxt, + ((struct tcp_tw_bucket *)sk)->rcv_nxt, + ((struct tcp_tw_bucket *)sk)->window); goto discard_it; case TCP_TW_RST: goto no_tcp_socket; --- ./net/ipv6/tcp_ipv6.c.~1~ Thu Aug 12 08:35:24 1999 +++ ./net/ipv6/tcp_ipv6.c Fri Aug 13 04:31:29 1999 @@ -1121,7 +1121,7 @@ kfree_skb(buff); } -static void tcp_v6_send_ack(struct sk_buff *skb, __u32 seq, __u32 ack) +static void tcp_v6_send_ack(struct sk_buff *skb, __u32 seq, __u32 ack, __u16 window) { struct tcphdr *th = skb->h.th, *t1; struct sk_buff *buff; @@ -1144,6 +1144,8 @@ t1->seq = seq; t1->ack_seq = ack; + t1->window = htons(window); + buff->csum = csum_partial((char *)t1, sizeof(*t1), 0); fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr; @@ -1461,10 +1463,12 @@ do_time_wait: switch (tcp_timewait_state_process((struct tcp_tw_bucket *)sk, - skb, th, skb->len)) { + skb, th, skb->len)) { case TCP_TW_ACK: - tcp_v6_send_ack(skb, ((struct tcp_tw_bucket *)sk)->snd_nxt, - ((struct tcp_tw_bucket *)sk)->rcv_nxt); + tcp_v6_send_ack(skb, + ((struct tcp_tw_bucket *)sk)->snd_nxt, + ((struct tcp_tw_bucket *)sk)->rcv_nxt, + ((struct tcp_tw_bucket *)sk)->window); goto discard_it; case TCP_TW_RST: goto no_tcp_socket; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |