patch-2.1.34 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: 409
- Date:
Mon Apr 14 09:31:10 1997
- Orig file:
v2.1.33/linux/net/ipv4/tcp_ipv4.c
- Orig date:
Sun Apr 13 10:18:23 1997
diff -u --recursive --new-file v2.1.33/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.23 1997/03/17 04:49:38 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.30 1997/04/13 10:31:44 davem Exp $
*
* IPv4 specific functions
*
@@ -581,11 +581,11 @@
tcp_init_xmit_timers(sk);
/* Now works the right way instead of a hacked initial setting */
- sk->retransmits = 0;
+ atomic_set(&sk->retransmits, 0);
skb_queue_tail(&sk->write_queue, buff);
- sk->packets_out++;
+ atomic_inc(&sk->packets_out);
buff->when = jiffies;
skb1 = skb_clone(buff, GFP_KERNEL);
@@ -663,8 +663,8 @@
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- sk->ssthresh = max(sk->cong_window >> 1, 2);
- sk->cong_window = sk->ssthresh + 3;
+ sk->ssthresh = max(tp->snd_cwnd >> 1, 2);
+ tp->snd_cwnd = sk->ssthresh + 3;
tp->high_seq = tp->snd_nxt;
return;
@@ -800,56 +800,41 @@
static void tcp_v4_send_synack(struct sock *sk, struct open_request *req)
{
- struct tcp_v4_open_req *af_req = (struct tcp_v4_open_req *) req;
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
struct sk_buff * skb;
struct tcphdr *th;
unsigned char *ptr;
int mss;
- int tmp;
skb = sock_wmalloc(sk, MAX_SYN_SIZE, 1, GFP_ATOMIC);
-
if (skb == NULL)
- {
return;
- }
- tmp = ip_build_pkt(skb, sk, af_req->loc_addr, af_req->rmt_addr,
- af_req->opt);
-
- if (tmp < 0)
- {
+ if(ip_build_pkt(skb, sk, req->af.v4_req.loc_addr,
+ req->af.v4_req.rmt_addr, req->af.v4_req.opt) < 0) {
kfree_skb(skb, FREE_WRITE);
return;
}
- mss = skb->dst->pmtu;
-
- mss -= sizeof(struct iphdr) + sizeof(struct tcphdr);
-
+ mss = (skb->dst->pmtu - sizeof(struct iphdr) + sizeof(struct tcphdr));
if (sk->user_mss)
mss = min(mss, sk->user_mss);
+ skb->h.th = th = (struct tcphdr *) skb_put(skb, sizeof(struct tcphdr));
- th =(struct tcphdr *) skb_put(skb, sizeof(struct tcphdr));
- skb->h.th = th;
+ /* Yuck, make this header setup more efficient... -DaveM */
memset(th, 0, sizeof(struct tcphdr));
-
th->syn = 1;
th->ack = 1;
-
th->source = sk->dummy_th.source;
th->dest = req->rmt_port;
-
skb->seq = req->snt_isn;
skb->end_seq = skb->seq + 1;
-
th->seq = ntohl(skb->seq);
th->ack_seq = htonl(req->rcv_isn + 1);
th->doff = sizeof(*th)/4 + 1;
-
th->window = ntohs(tp->rcv_wnd);
+ /* FIXME: csum_partial() of a four byte quantity is itself! -DaveM */
ptr = skb_put(skb, TCPOLEN_MSS);
ptr[0] = TCPOPT_MSS;
ptr[1] = TCPOLEN_MSS;
@@ -858,8 +843,7 @@
skb->csum = csum_partial(ptr, TCPOLEN_MSS, 0);
th->check = tcp_v4_check(th, sizeof(*th) + TCPOLEN_MSS,
- af_req->loc_addr,
- af_req->rmt_addr,
+ req->af.v4_req.loc_addr, req->af.v4_req.rmt_addr,
csum_partial((char *)th, sizeof(*th), skb->csum));
ip_queue_xmit(skb);
@@ -868,13 +852,9 @@
static void tcp_v4_or_free(struct open_request *req)
{
- struct tcp_v4_open_req *af_req = (struct tcp_v4_open_req *) req;
-
- if (af_req->req.sk)
- return;
-
- if (af_req->opt)
- kfree_s(af_req->opt, sizeof(struct options) + af_req->opt->optlen);
+ if(!req->sk && req->af.v4_req.opt)
+ kfree_s(req->af.v4_req.opt,
+ sizeof(struct options) + req->af.v4_req.opt->optlen);
}
static struct or_calltable or_ipv4 = {
@@ -890,11 +870,11 @@
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_v4_open_req *af_req;
struct open_request *req;
struct tcphdr *th = skb->h.th;
__u32 saddr = skb->nh.iph->saddr;
__u32 daddr = skb->nh.iph->daddr;
+ __u16 req_mss;
/* If the socket is dead, don't accept the connection. */
if (sk->dead)
@@ -916,55 +896,40 @@
goto exit;
}
- af_req = kmalloc(sizeof(struct tcp_v4_open_req), GFP_ATOMIC);
-
- if (af_req == NULL)
- {
+ req = tcp_openreq_alloc();
+ if (req == NULL) {
tcp_statistics.TcpAttemptFails++;
goto exit;
}
sk->ack_backlog++;
- req = (struct open_request *) af_req;
-
- memset(af_req, 0, sizeof(struct tcp_v4_open_req));
req->rcv_isn = skb->seq;
req->snt_isn = isn;
-
- /* mss */
- req->mss = tcp_parse_options(th);
-
- if (!req->mss)
- {
- req->mss = 536;
- }
-
+ req_mss = tcp_parse_options(th);
+ if (!req_mss)
+ req_mss = 536;
+ req->mss = req_mss;
req->rmt_port = th->source;
+ req->af.v4_req.loc_addr = daddr;
+ req->af.v4_req.rmt_addr = saddr;
- af_req->loc_addr = daddr;
- af_req->rmt_addr = saddr;
-
- /*
- * options
- */
-
- if (opt && opt->optlen)
- {
- af_req->opt = (struct ip_options*) kmalloc(sizeof(struct ip_options) +
- opt->optlen, GFP_ATOMIC);
- if (af_req->opt)
- {
- if (ip_options_echo(af_req->opt, skb))
- {
- kfree_s(af_req->opt, sizeof(struct options) +
- opt->optlen);
- af_req->opt = NULL;
+ /* IPv4 options */
+ req->af.v4_req.opt = NULL;
+ if (opt && opt->optlen) {
+ int opt_size = sizeof(struct ip_options) + opt->optlen;
+
+ req->af.v4_req.opt = kmalloc(opt_size, GFP_ATOMIC);
+ if (req->af.v4_req.opt) {
+ if (ip_options_echo(req->af.v4_req.opt, skb)) {
+ kfree_s(req->af.v4_req.opt, opt_size);
+ req->af.v4_req.opt = NULL;
}
}
}
-
req->class = &or_ipv4;
+ req->retrans = 0;
+ req->sk = NULL;
tcp_v4_send_synack(sk, req);
@@ -973,7 +938,8 @@
tcp_synq_queue(&sk->tp_pinfo.af_tcp, req);
sk->data_ready(sk, 0);
- exit:
+
+exit:
kfree_skb(skb, FREE_READ);
return 0;
}
@@ -981,7 +947,6 @@
struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
struct open_request *req)
{
- struct tcp_v4_open_req *af_req = (struct tcp_v4_open_req *) req;
struct tcp_opt *newtp;
struct sock *newsk;
struct rtable *rt;
@@ -989,9 +954,7 @@
newsk = sk_alloc(GFP_ATOMIC);
if (newsk == NULL)
- {
return NULL;
- }
memcpy(newsk, sk, sizeof(*newsk));
@@ -1022,15 +985,17 @@
newsk->prot->init(newsk);
newsk->cong_count = 0;
+#if 0 /* Don't mess up the initialization we did in the init routine! */
newsk->ssthresh = 0;
+#endif
newtp->backoff = 0;
newsk->intr = 0;
newsk->proc = 0;
newsk->done = 0;
newsk->partial = NULL;
newsk->pair = NULL;
- newsk->wmem_alloc = 0;
- newsk->rmem_alloc = 0;
+ atomic_set(&newsk->wmem_alloc, 0);
+ atomic_set(&newsk->rmem_alloc, 0);
newsk->localroute = sk->localroute;
newsk->max_unacked = MAX_WINDOW - TCP_WINDOW_DIFF;
@@ -1055,8 +1020,8 @@
newtp->snd_nxt = newsk->write_seq;
newsk->urg_data = 0;
- newsk->packets_out = 0;
- newsk->retransmits = 0;
+ atomic_set(&newsk->packets_out, 0);
+ atomic_set(&newsk->retransmits, 0);
newsk->linger=0;
newsk->destroy = 0;
init_timer(&newsk->timer);
@@ -1075,15 +1040,14 @@
newsk->socket = NULL;
- newsk->daddr = af_req->rmt_addr;
- newsk->saddr = af_req->loc_addr;
- newsk->rcv_saddr = af_req->loc_addr;
+ newsk->daddr = req->af.v4_req.rmt_addr;
+ newsk->saddr = req->af.v4_req.loc_addr;
+ newsk->rcv_saddr = req->af.v4_req.loc_addr;
/*
* options / mss / route_cache
*/
- newsk->opt = af_req->opt;
-
+ newsk->opt = req->af.v4_req.opt;
if (ip_route_output(&rt,
newsk->opt && newsk->opt->srr ? newsk->opt->faddr : newsk->daddr,
newsk->saddr, newsk->ip_tos, NULL)) {
@@ -1099,16 +1063,11 @@
newsk->mtu = snd_mss;
/* sanity check */
if (newsk->mtu < 64)
- {
newsk->mtu = 64;
- }
snd_mss -= sizeof(struct iphdr) + sizeof(struct tcphdr);
-
if (sk->user_mss)
- {
snd_mss = min(snd_mss, sk->user_mss);
- }
newsk->mss = min(req->mss, snd_mss);
@@ -1120,77 +1079,50 @@
struct sock *tcp_v4_check_req(struct sock *sk, struct sk_buff *skb)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- struct open_request *req;
+ struct open_request *req = tp->syn_wait_queue;
- /*
- * assumption: the socket is not in use.
+ /* assumption: the socket is not in use.
* as we checked the user count on tcp_rcv and we're
* running from a soft interrupt.
*/
-
- req = tp->syn_wait_queue;
-
if (!req)
- {
return sk;
- }
do {
- struct tcp_v4_open_req *af_req;
-
- af_req = (struct tcp_v4_open_req *) req;
-
- if (af_req->rmt_addr == skb->nh.iph->saddr &&
- af_req->loc_addr == skb->nh.iph->daddr &&
- req->rmt_port == skb->h.th->source)
- {
+ if (req->af.v4_req.rmt_addr == skb->nh.iph->saddr &&
+ req->af.v4_req.loc_addr == skb->nh.iph->daddr &&
+ req->rmt_port == skb->h.th->source) {
u32 flg;
- if (req->sk)
- {
- /*
- * socket already created but not
+ if (req->sk) {
+ /* socket already created but not
* yet accepted()...
*/
-
sk = req->sk;
break;
}
- /* match */
-
- /*
- * Check for syn retransmission
- */
+ /* Check for syn retransmission */
flg = *(((u32 *)skb->h.th) + 3);
flg &= __constant_htonl(0x002f0000);
-
if ((flg == __constant_htonl(0x00020000)) &&
- (!after(skb->seq, req->rcv_isn)))
- {
- /*
- * retransmited syn
+ (!after(skb->seq, req->rcv_isn))) {
+ /* retransmited syn
* FIXME: must send an ack
*/
return NULL;
}
sk = tp->af_specific->syn_recv_sock(sk, skb, req);
-
tcp_dec_slow_timer(TCP_SLT_SYNACK);
-
if (sk == NULL)
- {
return NULL;
- }
req->expires = 0UL;
req->sk = sk;
break;
}
-
- req = req->dl_next;
- } while (req != tp->syn_wait_queue);
+ } while ((req = req->dl_next) != tp->syn_wait_queue);
skb_orphan(skb);
skb_set_owner_r(skb, sk);
@@ -1422,8 +1354,8 @@
* See draft-stevens-tcpca-spec-01 for discussion of the
* initialization of these values.
*/
- sk->cong_window = 1;
- sk->ssthresh = 0x7fffffff;
+ tp->snd_cwnd = 1;
+ sk->ssthresh = 0x7fffffff; /* Infinity */
sk->priority = 1;
sk->state = TCP_CLOSE;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov