summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>2002-03-01 22:29:30 +0000
committerNiels Provos <provos@cvs.openbsd.org>2002-03-01 22:29:30 +0000
commit88eb9e205f021f67565cdcb0ed25974c3892e780 (patch)
tree0a9143f884ca32a8fcb4448b4137c8c3a36dc306 /sys/netinet
parent7654fe675bb68865e2eec2bec559901d94dc31ea (diff)
remove tcp_fasttimo and convert delayed acks to the timeout(9) API instead.
adapated from netbsd. okay angelos@
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in_proto.c4
-rw-r--r--sys/netinet/tcp_input.c6
-rw-r--r--sys/netinet/tcp_output.c12
-rw-r--r--sys/netinet/tcp_subr.c8
-rw-r--r--sys/netinet/tcp_timer.c65
-rw-r--r--sys/netinet/tcp_timer.h6
-rw-r--r--sys/netinet/tcp_var.h31
7 files changed, 99 insertions, 33 deletions
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index e6263a75d2a..e7c04fa2b38 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_proto.c,v 1.33 2002/01/12 00:51:59 ericj Exp $ */
+/* $OpenBSD: in_proto.c,v 1.34 2002/03/01 22:29:29 provos Exp $ */
/* $NetBSD: in_proto.c,v 1.14 1996/02/18 18:58:32 christos Exp $ */
/*
@@ -196,7 +196,7 @@ struct protosw inetsw[] = {
{ SOCK_STREAM, &inetdomain, IPPROTO_TCP, PR_CONNREQUIRED|PR_WANTRCVD|PR_ABRTACPTDIS,
tcp_input, 0, tcp_ctlinput, tcp_ctloutput,
tcp_usrreq,
- tcp_init, tcp_fasttimo, tcp_slowtimo, tcp_drain, tcp_sysctl
+ tcp_init, 0, tcp_slowtimo, tcp_drain, tcp_sysctl
},
{ SOCK_RAW, &inetdomain, IPPROTO_RAW, PR_ATOMIC|PR_ADDR,
rip_input, rip_output, 0, rip_ctloutput,
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 5f53d9bd494..85074de4cd5 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.104 2002/01/24 22:42:48 provos Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.105 2002/03/01 22:29:29 provos Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -995,7 +995,7 @@ findpcb:
if (th->th_flags & TH_PUSH)
tp->t_flags |= TF_ACKNOW;
else
- tp->t_flags |= TF_DELACK;
+ TCP_SET_DELACK(tp);
m_adj(m, iphlen + off);
sbappend(&so->so_rcv, m);
sorwakeup(so);
@@ -1981,7 +1981,7 @@ dodata: /* XXX */
if (th->th_flags & TH_PUSH)
tp->t_flags |= TF_ACKNOW;
else
- tp->t_flags |= TF_DELACK;
+ TCP_SET_DELACK(tp);
tp->rcv_nxt += tlen;
tiflags = th->th_flags & TH_FIN;
tcpstat.tcps_rcvpack++;
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index b46f70a499c..83b71bf0058 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_output.c,v 1.47 2002/02/05 17:03:11 provos Exp $ */
+/* $OpenBSD: tcp_output.c,v 1.48 2002/03/01 22:29:29 provos Exp $ */
/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
/*
@@ -1107,9 +1107,16 @@ out:
tp->t_softerror = error;
return (0);
}
+
+ /* Restart the delayed ACK timer, if necessary. */
+ if (tp->t_flags & TF_DELACK)
+ TCP_RESTART_DELACK(tp);
+
return (error);
}
tcpstat.tcps_sndtotal++;
+ if (tp->t_flags & TF_DELACK)
+ tcpstat.tcps_delack++;
/*
* Data sent (as far as we can tell).
@@ -1120,7 +1127,8 @@ out:
if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv))
tp->rcv_adv = tp->rcv_nxt + win;
tp->last_ack_sent = tp->rcv_nxt;
- tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
+ tp->t_flags &= ~TF_ACKNOW;
+ TCP_CLEAR_DELACK(tp);
#if defined(TCP_SACK)
if (sendalot && --maxburst)
#else
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 2416d8bc73f..16b87a19c38 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_subr.c,v 1.57 2002/01/24 22:42:49 provos Exp $ */
+/* $OpenBSD: tcp_subr.c,v 1.58 2002/03/01 22:29:29 provos Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
@@ -183,6 +183,9 @@ tcp_init()
icmp6_mtudisc_callback_register(tcp6_mtudisc_callback);
#endif /* INET6 */
+
+ /* Initialize timer state. */
+ tcp_timer_init();
}
/*
@@ -472,6 +475,7 @@ tcp_newtcpcb(struct inpcb *inp)
tp->t_maxseg = tcp_mssdflt;
tp->t_maxopd = 0;
+ TCP_INIT_DELACK(tp);
for (i = 0; i < TCPT_NTIMERS; i++)
TCP_TIMER_INIT(tp, i);
@@ -665,6 +669,8 @@ tcp_close(struct tcpcb *tp)
/* free the reassembly queue, if any */
tcp_freeq(tp);
+ TCP_CLEAR_DELACK(tp);
+
#ifdef TCP_SACK
/* Free SACK holes. */
q = p = tp->snd_holes;
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 763650405e1..f05bd00cfef 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_timer.c,v 1.26 2002/01/15 19:18:01 provos Exp $ */
+/* $OpenBSD: tcp_timer.c,v 1.27 2002/03/01 22:29:29 provos Exp $ */
/* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */
/*
@@ -36,13 +36,13 @@
* @(#)tcp_timer.c 8.1 (Berkeley) 6/10/93
*/
-#ifndef TUBA_INCLUDE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
+#include <sys/kernel.h>
#include <net/route.h>
@@ -57,34 +57,55 @@
#include <netinet/tcp_var.h>
#include <netinet/ip_icmp.h>
-int tcp_keepidle = TCPTV_KEEP_IDLE;
-int tcp_keepintvl = TCPTV_KEEPINTVL;
-int tcp_maxpersistidle = TCPTV_KEEP_IDLE; /* max idle time in persist */
+int tcp_keepidle;
+int tcp_keepintvl;
+int tcp_maxpersistidle; /* max idle time in persist */
int tcp_maxidle;
-#endif /* TUBA_INCLUDE */
+
+/*
+ * Time to delay the ACK. This is initialized in tcp_init(), unless
+ * its patched.
+ */
+int tcp_delack_ticks;
+
/*
- * Fast timeout routine for processing delayed acks
+ * Timer state initialization, called from tcp_init().
*/
void
-tcp_fasttimo()
+tcp_timer_init(void)
{
- register struct inpcb *inp;
- register struct tcpcb *tp;
+
+ if (tcp_keepidle == 0)
+ tcp_keepidle = TCPTV_KEEP_IDLE;
+
+ if (tcp_keepintvl == 0)
+ tcp_keepintvl = TCPTV_KEEPINTVL;
+
+ if (tcp_maxpersistidle == 0)
+ tcp_maxpersistidle = TCPTV_KEEP_IDLE;
+
+ if (tcp_delack_ticks == 0)
+ tcp_delack_ticks = TCP_DELACK_TICKS;
+}
+
+/*
+ * Callout to process delayed ACKs for a TCPCB.
+ */
+void
+tcp_delack(void *arg)
+{
+ struct tcpcb *tp = arg;
int s;
+ /*
+ * If tcp_output() wasn't able to transmit the ACK
+ * for whatever reason, it will restart the delayed
+ * ACK callout.
+ */
+
s = splsoftnet();
- inp = tcbtable.inpt_queue.cqh_first;
- if (inp) /* XXX */
- for (; inp != (struct inpcb *)&tcbtable.inpt_queue;
- inp = inp->inp_queue.cqe_next) {
- if ((tp = (struct tcpcb *)inp->inp_ppcb) &&
- (tp->t_flags & TF_DELACK)) {
- tp->t_flags &= ~TF_DELACK;
- tp->t_flags |= TF_ACKNOW;
- tcpstat.tcps_delack++;
- (void) tcp_output(tp);
- }
- }
+ tp->t_flags |= TF_ACKNOW;
+ (void) tcp_output(tp);
splx(s);
}
diff --git a/sys/netinet/tcp_timer.h b/sys/netinet/tcp_timer.h
index 45064e1d9fa..03523dd8f31 100644
--- a/sys/netinet/tcp_timer.h
+++ b/sys/netinet/tcp_timer.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_timer.h,v 1.6 2002/01/14 19:26:10 provos Exp $ */
+/* $OpenBSD: tcp_timer.h,v 1.7 2002/03/01 22:29:29 provos Exp $ */
/* $NetBSD: tcp_timer.h,v 1.6 1995/03/26 20:32:37 jtc Exp $ */
/*
@@ -109,6 +109,8 @@
#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */
+#define TCP_DELACK_TICKS (hz / PR_FASTHZ) /* time to delay ACK */
+
#ifdef TCPTIMERS
char *tcptimers[] =
{ "REXMT", "PERSIST", "KEEP", "2MSL" };
@@ -147,5 +149,7 @@ extern int tcp_keepintvl; /* time between keepalive probes */
extern int tcp_maxidle; /* time to drop after starting probes */
extern int tcp_ttl; /* time to live for TCP segs */
extern int tcp_backoff[];
+
+void tcp_timer_init(void);
#endif /* _KERNEL */
#endif /* _NETINET_TCP_TIMER_H_ */
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 87d9f95b6a7..f77f3ab0eb9 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.38 2002/01/15 19:18:01 provos Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.39 2002/03/01 22:29:29 provos Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -83,6 +83,7 @@ struct tcpcb {
struct mbuf *t_template; /* skeletal packet for transmit */
struct inpcb *t_inpcb; /* back pointer to internet pcb */
+ struct timeout t_delack_to; /* delayed ACK callback */
/*
* The following fields are used as in the protocol specification.
* See RFC783, Dec. 1981, page 21.
@@ -177,6 +178,33 @@ struct tcpcb {
#define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb)
#define sototcpcb(so) (intotcpcb(sotoinpcb(so)))
+#ifdef _KERNEL
+extern int tcp_delack_ticks;
+void tcp_delack(void *);
+
+#define TCP_INIT_DELACK(tp) \
+ timeout_set(&(tp)->t_delack_to, tcp_delack, tp)
+
+#define TCP_RESTART_DELACK(tp) \
+ timeout_add(&(tp)->t_delack_to, tcp_delack_ticks)
+
+#define TCP_SET_DELACK(tp) \
+do { \
+ if (((tp)->t_flags & TF_DELACK) == 0) { \
+ (tp)->t_flags |= TF_DELACK; \
+ TCP_RESTART_DELACK(tp); \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define TCP_CLEAR_DELACK(tp) \
+do { \
+ if ((tp)->t_flags & TF_DELACK) { \
+ (tp)->t_flags &= ~TF_DELACK; \
+ timeout_del(&(tp)->t_delack_to); \
+ } \
+} while (/*CONSTCOND*/0)
+#endif /* _KERNEL */
+
/*
* The smoothed round-trip time and estimated variance
* are stored as fixed point numbers scaled by the values below.
@@ -345,7 +373,6 @@ struct tcpcb *
void tcp_dooptions __P((struct tcpcb *, u_char *, int, struct tcphdr *,
int *, u_int32_t *, u_int32_t *));
void tcp_drain __P((void));
-void tcp_fasttimo __P((void));
void tcp_init __P((void));
#if defined(INET6) && !defined(TCP6)
int tcp6_input __P((struct mbuf **, int *, int));