patch-2.1.37 linux/net/ipv4/tcp_ipv4.c
Next file: linux/net/ipv4/tcp_output.c
Previous file: linux/net/ipv4/tcp_input.c
Back to the patch index
Back to the overall index
- Lines: 229
- Date:
Mon May 12 10:35:44 1997
- Orig file:
v2.1.36/linux/net/ipv4/tcp_ipv4.c
- Orig date:
Wed Apr 23 19:01:30 1997
diff -u --recursive --new-file v2.1.36/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_ipv4.c,v 1.39 1997/04/22 02:53:14 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.42 1997/04/29 16:09:46 schenk Exp $
*
* IPv4 specific functions
*
@@ -465,7 +465,7 @@
struct sk_buff *buff;
struct sk_buff *skb1;
int tmp;
- struct tcphdr *t1;
+ struct tcphdr *th;
struct rtable *rt;
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
@@ -546,20 +546,17 @@
return(-ENETUNREACH);
}
- t1 = (struct tcphdr *) skb_put(buff,sizeof(struct tcphdr));
- buff->h.th = t1;
+ th = (struct tcphdr *) skb_put(buff,sizeof(struct tcphdr));
+ buff->h.th = th;
- memcpy(t1,(void *)&(sk->dummy_th), sizeof(*t1));
+ memcpy(th,(void *)&(sk->dummy_th), sizeof(*th));
buff->seq = sk->write_seq++;
- t1->seq = htonl(buff->seq);
+ th->seq = htonl(buff->seq);
tp->snd_nxt = sk->write_seq;
buff->end_seq = sk->write_seq;
- t1->ack = 0;
- t1->window = htons(512);
- t1->syn = 1;
+ th->ack = 0;
+ th->syn = 1;
- /* Use 512 or whatever user asked for. */
- tp->window_clamp = rt->u.dst.window;
sk->mtu = rt->u.dst.pmtu;
if ((sk->ip_pmtudisc == IP_PMTUDISC_DONT ||
@@ -577,13 +574,26 @@
sk->mss = (sk->mtu - sizeof(struct iphdr) -
sizeof(struct tcphdr));
+ if (sk->mss < 1) {
+ printk(KERN_DEBUG "intial sk->mss below 1\n");
+ sk->mss = 1; /* Sanity limit */
+ }
+
+ tp->window_clamp = rt->u.dst.window;
+ tcp_select_initial_window(sock_rspace(sk)/2,sk->mss,
+ &tp->rcv_wnd,
+ &tp->window_clamp,
+ sysctl_tcp_window_scaling,
+ &tp->rcv_wscale);
+ th->window = htons(tp->rcv_wnd);
+
tmp = tcp_syn_build_options(buff, sk->mss, sysctl_tcp_sack,
sysctl_tcp_timestamps,
- sysctl_tcp_window_scaling?tp->rcv_wscale:0);
+ sysctl_tcp_window_scaling,tp->rcv_wscale);
buff->csum = 0;
- t1->doff = (sizeof(*t1)+ tmp)>>2;
+ th->doff = (sizeof(*th)+ tmp)>>2;
- tcp_v4_send_check(sk, t1, sizeof(struct tcphdr) + tmp, buff);
+ tcp_v4_send_check(sk, th, sizeof(struct tcphdr) + tmp, buff);
tcp_set_state(sk,TCP_SYN_SENT);
@@ -803,7 +813,6 @@
static void tcp_v4_send_synack(struct sock *sk, struct open_request *req)
{
- struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
struct sk_buff * skb;
struct tcphdr *th;
int tmp;
@@ -829,6 +838,11 @@
*/
req->mss = min(mss, req->mss);
+ if (req->mss < 1) {
+ printk(KERN_DEBUG "initial req->mss below 1\n");
+ req->mss = 1;
+ }
+
/* Yuck, make this header setup more efficient... -DaveM */
memset(th, 0, sizeof(struct tcphdr));
th->syn = 1;
@@ -839,7 +853,16 @@
skb->end_seq = skb->seq + 1;
th->seq = ntohl(skb->seq);
th->ack_seq = htonl(req->rcv_isn + 1);
- th->window = ntohs(tp->rcv_wnd);
+ if (req->rcv_wnd == 0) {
+ /* Set this up on the first call only */
+ req->window_clamp = skb->dst->window;
+ tcp_select_initial_window(sock_rspace(sk)/2,req->mss,
+ &req->rcv_wnd,
+ &req->window_clamp,
+ req->wscale_ok,
+ &req->rcv_wscale);
+ }
+ th->window = htons(req->rcv_wnd);
/* XXX Partial csum of 4 byte quantity is itself! -DaveM
* Yes, but it's a bit harder to special case now. It's
@@ -850,7 +873,7 @@
*/
tmp = tcp_syn_build_options(skb, req->mss, req->sack_ok, req->tstamp_ok,
- (req->snd_wscale)?tp->rcv_wscale:0);
+ req->wscale_ok,req->rcv_wscale);
skb->csum = 0;
th->doff = (sizeof(*th) + tmp)>>2;
th->check = tcp_v4_check(th, sizeof(*th) + tmp,
@@ -881,7 +904,7 @@
int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr, __u32 isn)
{
struct ip_options *opt = (struct ip_options *) ptr;
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ struct tcp_opt tp;
struct open_request *req;
struct tcphdr *th = skb->h.th;
__u32 saddr = skb->nh.iph->saddr;
@@ -913,19 +936,20 @@
sk->ack_backlog++;
+ req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */
+
req->rcv_isn = skb->seq;
req->snt_isn = isn;
- tp->tstamp_ok = tp->sack_ok = tp->snd_wscale = 0;
- tcp_parse_options(th,tp);
- if (tp->saw_tstamp) {
- tp->ts_recent = tp->rcv_tsval;
- tp->ts_recent_stamp = jiffies;
- }
- req->mss = tp->in_mss;
- req->tstamp_ok = tp->tstamp_ok;
- req->sack_ok = tp->sack_ok;
- req->snd_wscale = tp->snd_wscale;
- req->ts_recent = tp->ts_recent;
+ tp.tstamp_ok = tp.sack_ok = tp.wscale_ok = tp.snd_wscale = 0;
+ tp.in_mss = 536;
+ tcp_parse_options(th,&tp);
+ if (tp.saw_tstamp)
+ req->ts_recent = tp.rcv_tsval;
+ req->mss = tp.in_mss;
+ req->tstamp_ok = tp.tstamp_ok;
+ req->sack_ok = tp.sack_ok;
+ req->snd_wscale = tp.snd_wscale;
+ req->wscale_ok = tp.wscale_ok;
req->rmt_port = th->source;
req->af.v4_req.loc_addr = daddr;
req->af.v4_req.rmt_addr = saddr;
@@ -1004,8 +1028,6 @@
atomic_set(&newsk->rmem_alloc, 0);
newsk->localroute = sk->localroute;
- newsk->max_unacked = MAX_WINDOW - TCP_WINDOW_DIFF;
-
newsk->err = 0;
newsk->shutdown = 0;
newsk->ack_backlog = 0;
@@ -1060,7 +1082,6 @@
newsk->dst_cache = &rt->u.dst;
- newtp->window_clamp = rt->u.dst.window;
snd_mss = rt->u.dst.pmtu;
/* FIXME: is mtu really the same as snd_mss? */
@@ -1072,10 +1093,19 @@
newtp->sack_ok = req->sack_ok;
newtp->tstamp_ok = req->tstamp_ok;
- newtp->snd_wscale = req->snd_wscale;
- newtp->ts_recent = req->ts_recent;
- newtp->ts_recent_stamp = jiffies;
+ newtp->window_clamp = req->window_clamp;
+ newtp->rcv_wnd = req->rcv_wnd;
+ newtp->wscale_ok = req->wscale_ok;
+ if (newtp->wscale_ok) {
+ newtp->snd_wscale = req->snd_wscale;
+ newtp->rcv_wscale = req->rcv_wscale;
+ } else {
+ newtp->snd_wscale = newtp->rcv_wscale = 0;
+ newtp->window_clamp = min(newtp->window_clamp,65535);
+ }
if (newtp->tstamp_ok) {
+ newtp->ts_recent = req->ts_recent;
+ newtp->ts_recent_stamp = jiffies;
newtp->tcp_header_len = sizeof(struct tcphdr) + 12; /* FIXME: define constant! */
newsk->dummy_th.doff += 3;
} else {
@@ -1219,9 +1249,8 @@
case CHECKSUM_HW:
if (tcp_v4_check(th,len,saddr,daddr,skb->csum)) {
struct iphdr * iph = skb->nh.iph;
- printk(KERN_DEBUG "TCPv4 bad checksum from %08x:%04x to %08x:%04x, ack = %u, seq = %u, len=%d/%d/%d\n",
+ printk(KERN_DEBUG "TCPv4 bad checksum from %08x:%04x to %08x:%04x, len=%d/%d/%d\n",
saddr, ntohs(th->source), daddr,
- ntohl(th->ack_seq), ntohl(th->seq),
ntohs(th->dest), len, skb->len, ntohs(iph->tot_len));
goto discard_it;
}
@@ -1346,10 +1375,12 @@
tp->ato = 0;
tp->iat = (HZ/5) << 3;
- tp->rcv_wnd = 8192;
+ /* FIXME: tie this to sk->rcvbuf? (May be unnecessary) */
+ /* tp->rcv_wnd = 8192; */
tp->tstamp_ok = 0;
tp->sack_ok = 0;
- tp->in_mss = 0;
+ tp->wscale_ok = 0;
+ tp->in_mss = 536;
tp->snd_wscale = 0;
tp->sacks = 0;
tp->saw_tstamp = 0;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov