diff options
author | Niels Provos <provos@cvs.openbsd.org> | 2002-03-01 22:29:30 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 2002-03-01 22:29:30 +0000 |
commit | 88eb9e205f021f67565cdcb0ed25974c3892e780 (patch) | |
tree | 0a9143f884ca32a8fcb4448b4137c8c3a36dc306 | |
parent | 7654fe675bb68865e2eec2bec559901d94dc31ea (diff) |
remove tcp_fasttimo and convert delayed acks to the timeout(9) API instead.
adapated from netbsd. okay angelos@
-rw-r--r-- | sys/netinet/in_proto.c | 4 | ||||
-rw-r--r-- | sys/netinet/tcp_input.c | 6 | ||||
-rw-r--r-- | sys/netinet/tcp_output.c | 12 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 8 | ||||
-rw-r--r-- | sys/netinet/tcp_timer.c | 65 | ||||
-rw-r--r-- | sys/netinet/tcp_timer.h | 6 | ||||
-rw-r--r-- | sys/netinet/tcp_var.h | 31 |
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)); |