patch-1.3.11 linux/net/ipv4/tcp.c
Next file: linux/net/ipv4/udp.c
Previous file: linux/net/ipv4/ip_fw.c
Back to the patch index
Back to the overall index
- Lines: 183
- Date:
Tue Jul 18 14:54:29 1995
- Orig file:
v1.3.10/linux/net/ipv4/tcp.c
- Orig date:
Fri Jul 7 13:42:58 1995
diff -u --recursive --new-file v1.3.10/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
@@ -145,6 +145,11 @@
* sk->retransmits misupdating fixed.
* Fixed tcp_write_timeout: stuck close,
* and TCP syn retries gets used now.
+ * Mark Yarvis : In tcp_read_wakeup(), don't send an
+ * ack if stat is TCP_CLOSED.
+ * Alan Cox : Look up device on a retransmit - routes may
+ * change. Doesn't yet cope with MSS shrink right
+ * but its a start!
*
*
* To Fix:
@@ -439,6 +444,7 @@
struct proto *prot;
struct device *dev;
int ct=0;
+ struct rtable *rt;
prot = sk->prot;
skb = sk->send_head;
@@ -454,6 +460,12 @@
skb->when = jiffies;
/*
+ * Discard the surplus MAC header
+ */
+
+ skb_pull(skb,((unsigned char *)skb->ip_hdr)-skb->data);
+
+ /*
* In general it's OK just to use the old packet. However we
* need to use the current ack and window fields. Urg and
* urg_ptr could possibly stand to be updated as well, but we
@@ -462,60 +474,89 @@
* changing the packet, we have to issue a new IP identifier.
*/
- iph = (struct iphdr *)(skb->data + dev->hard_header_len);
+ iph = (struct iphdr *)skb->data;
th = (struct tcphdr *)(((char *)iph) + (iph->ihl << 2));
- size = skb->len - (((unsigned char *) th) - skb->data);
+ size = ntohs(iph->tot_len) - (iph->ihl<<2);
/*
* Note: We ought to check for window limits here but
* currently this is done (less efficiently) elsewhere.
- * We do need to check for a route change but can't handle
- * that until we have the new 1.3.x buffers in.
- *
*/
iph->id = htons(ip_id_count++);
ip_send_check(iph);
-
- /*
- * This is not the right way to handle this. We have to
- * issue an up to date window and ack report with this
- * retransmit to keep the odd buggy tcp that relies on
- * the fact BSD does this happy.
- * We don't however need to recalculate the entire
- * checksum, so someone wanting a small problem to play
- * with might like to implement RFC1141/RFC1624 and speed
- * this up by avoiding a full checksum.
- */
-
- th->ack_seq = ntohl(sk->acked_seq);
- th->window = ntohs(tcp_select_window(sk));
- tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
/*
- * If the interface is (still) up and running, kick it.
+ * Put a MAC header back on (may cause ARPing)
*/
-
- if (dev->flags & IFF_UP)
+
+ if(skb->localroute)
+ rt=ip_rt_local(iph->daddr,NULL,NULL);
+ else
+ rt=ip_rt_route(iph->daddr,NULL,NULL);
+
+ if(rt==NULL) /* Deep poo */
+ {
+ if(skb->sk)
+ {
+ skb->sk->err=ENETUNREACH;
+ skb->sk->error_report(skb->sk);
+ }
+ }
+ else
{
+ dev=rt->rt_dev;
+ skb->raddr=rt->rt_gateway;
+ if(skb->raddr==0)
+ skb->raddr=iph->daddr;
+ skb->dev=dev;
+ skb->arp=1;
+ if(dev->hard_header)
+ {
+ if(dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, skb->len)<0)
+ skb->arp=0;
+ }
+
/*
- * If the packet is still being sent by the device/protocol
- * below then don't retransmit. This is both needed, and good -
- * especially with connected mode AX.25 where it stops resends
- * occurring of an as yet unsent anyway frame!
- * We still add up the counts as the round trip time wants
- * adjusting.
+ * This is not the right way to handle this. We have to
+ * issue an up to date window and ack report with this
+ * retransmit to keep the odd buggy tcp that relies on
+ * the fact BSD does this happy.
+ * We don't however need to recalculate the entire
+ * checksum, so someone wanting a small problem to play
+ * with might like to implement RFC1141/RFC1624 and speed
+ * this up by avoiding a full checksum.
*/
- if (sk && !skb_device_locked(skb))
+
+ th->ack_seq = ntohl(sk->acked_seq);
+ th->window = ntohs(tcp_select_window(sk));
+ tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
+
+ /*
+ * If the interface is (still) up and running, kick it.
+ */
+
+ if (dev->flags & IFF_UP)
{
- /* Remove it from any existing driver queue first! */
- skb_unlink(skb);
- /* Now queue it */
- ip_statistics.IpOutRequests++;
- dev_queue_xmit(skb, dev, sk->priority);
+ /*
+ * If the packet is still being sent by the device/protocol
+ * below then don't retransmit. This is both needed, and good -
+ * especially with connected mode AX.25 where it stops resends
+ * occurring of an as yet unsent anyway frame!
+ * We still add up the counts as the round trip time wants
+ * adjusting.
+ */
+ if (sk && !skb_device_locked(skb))
+ {
+ /* Remove it from any existing driver queue first! */
+ skb_unlink(skb);
+ /* Now queue it */
+ ip_statistics.IpOutRequests++;
+ dev_queue_xmit(skb, dev, sk->priority);
+ }
}
}
-
+
/*
* Count retransmissions
*/
@@ -1772,6 +1813,13 @@
return;
/*
+ * If we're closed, don't send an ack, or we'll get a RST
+ * from the closed destination.
+ */
+ if ((sk->state == TCP_CLOSE) || (sk->state == TCP_TIME_WAIT))
+ return;
+
+ /*
* FIXME: we need to put code here to prevent this routine from
* being called. Being called once in a while is ok, so only check
* if this is the second time in a row.
@@ -3034,8 +3082,7 @@
* Ack and window will in general have changed since this packet was put
* on the write queue.
*/
- iph = (struct iphdr *)(skb->data +
- skb->dev->hard_header_len);
+ iph = skb->ip_hdr;
th = (struct tcphdr *)(((char *)iph) +(iph->ihl << 2));
size = skb->len - (((unsigned char *) th) - skb->data);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this