1
0
mirror of https://github.com/openbsd/src.git synced 2025-01-10 06:47:55 -08:00

Path MTU discovery based on NetBSD but with the decision to use the DF

flag delayed to ip_output().  That halves the code and reduces most of
the route lookups. okay deraadt@
This commit is contained in:
provos 2000-09-18 22:06:36 +00:00
parent 27142ee4fb
commit 62c4355e0f
12 changed files with 375 additions and 56 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: in.h,v 1.40 2000/06/18 07:06:13 itojun Exp $ */
/* $OpenBSD: in.h,v 1.41 2000/09/18 22:06:36 provos Exp $ */
/* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */
/*
@ -447,7 +447,9 @@ struct ip_mreq {
#define IPCTL_IPSEC_FIRSTUSE 24
#define IPCTL_IPSEC_ENC_ALGORITHM 25
#define IPCTL_IPSEC_AUTH_ALGORITHM 26
#define IPCTL_MAXID 27
#define IPCTL_MTUDISC 27 /* allow path MTU discovery */
#define IPCTL_MTUDISCTIMEOUT 28 /* allow path MTU discovery */
#define IPCTL_MAXID 29
#define IPCTL_NAMES { \
{ 0, 0 }, \
@ -477,6 +479,8 @@ struct ip_mreq {
{ "ipsec-firstuse", CTLTYPE_INT }, \
{ "ipsec-enc-alg", CTLTYPE_STRING }, \
{ "ipsec-auth-alg", CTLTYPE_STRING }, \
{ "mtudisc", CTLTYPE_INT }, \
{ "mtudisctimeout", CTLTYPE_INT }, \
}
/* INET6 stuff */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: in_pcb.c,v 1.42 2000/04/27 09:23:21 itojun Exp $ */
/* $OpenBSD: in_pcb.c,v 1.43 2000/09/18 22:06:37 provos Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@ -859,6 +859,43 @@ in_pcblookup(table, faddrp, fport_arg, laddrp, lport_arg, flags)
return (match);
}
struct rtentry *
in_pcbrtentry(inp)
struct inpcb *inp;
{
struct route *ro;
ro = &inp->inp_route;
/*
* No route yet, so try to acquire one.
*/
if (ro->ro_rt == NULL) {
switch(sotopf(inp->inp_socket)) {
#ifdef INET6
case PF_INET6:
if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6))
break;
ro->ro_dst.sa_family = AF_INET6;
ro->ro_dst.sa_len = sizeof(struct sockaddr_in6);
((struct sockaddr_in6 *) &ro->ro_dst)->sin6_addr =
inp->inp_faddr6;
rtalloc(ro);
break;
#endif /* INET6 */
case PF_INET:
if (inp->inp_faddr.s_addr != INADDR_ANY)
break;
ro->ro_dst.sa_family = AF_INET;
ro->ro_dst.sa_len = sizeof(ro->ro_dst);
satosin(&ro->ro_dst)->sin_addr = inp->inp_faddr;
rtalloc(ro);
break;
}
}
return (ro->ro_rt);
}
struct sockaddr_in *
in_selectsrc(sin, ro, soopts, mopts, errorp)
struct sockaddr_in *sin;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: in_pcb.h,v 1.25 2000/06/18 17:32:48 itojun Exp $ */
/* $OpenBSD: in_pcb.h,v 1.26 2000/09/18 22:06:37 provos Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
@ -260,6 +260,8 @@ void in_setsockaddr __P((struct inpcb *, struct mbuf *));
int in_baddynamic __P((u_int16_t, u_int16_t));
extern struct sockaddr_in *in_selectsrc __P((struct sockaddr_in *,
struct route *, int, struct ip_moptions *, int *));
struct rtentry *
in_pcbrtentry __P((struct inpcb *));
/* INET6 stuff */
int in6_pcbnotify __P((struct inpcbtable *, struct sockaddr *,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip_icmp.c,v 1.21 2000/05/15 11:07:32 itojun Exp $ */
/* $OpenBSD: ip_icmp.c,v 1.22 2000/09/18 22:06:37 provos Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
@ -92,6 +92,9 @@ static int ip_next_mtu __P((int, int));
/*static*/ int ip_next_mtu __P((int, int));
#endif
void icmp_mtudisc __P((struct icmp *));
void icmp_mtudisc_timeout __P((struct rtentry *, struct rttimer *));
extern struct protosw inetsw[];
/*
@ -391,6 +394,8 @@ icmp_input(m, va_alist)
printf("deliver to protocol %d\n", icp->icmp_ip.ip_p);
#endif
icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
if (code == PRC_MSGSIZE && ip_mtudisc)
icmp_mtudisc(icp);
/*
* XXX if the packet contains [IPv4 AH TCP], we can't make a
* notification to TCP layer.
@ -712,3 +717,147 @@ icmp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
}
/* NOTREACHED */
}
void
icmp_mtudisc(icp)
struct icmp *icp;
{
struct rtentry *rt;
struct sockaddr *dst = sintosa(&icmpsrc);
u_long mtu = ntohs(icp->icmp_nextmtu); /* Why a long? IPv6 */
int error;
/* Table of common MTUs: */
static u_short mtu_table[] = {65535, 65280, 32000, 17914, 9180, 8166,
4352, 2002, 1492, 1006, 508, 296, 68, 0};
rt = rtalloc1(dst, 1);
if (rt == 0)
return;
/* If we didn't get a host route, allocate one */
if ((rt->rt_flags & RTF_HOST) == 0) {
struct rtentry *nrt;
error = rtrequest((int) RTM_ADD, dst,
(struct sockaddr *) rt->rt_gateway,
(struct sockaddr *) 0,
RTF_GATEWAY | RTF_HOST | RTF_DYNAMIC, &nrt);
if (error) {
rtfree(rt);
rtfree(nrt);
return;
}
nrt->rt_rmx = rt->rt_rmx;
rtfree(rt);
rt = nrt;
}
error = rt_timer_add(rt, icmp_mtudisc_timeout, ip_mtudisc_timeout_q);
if (error) {
rtfree(rt);
return;
}
if (mtu == 0) {
int i = 0;
mtu = icp->icmp_ip.ip_len; /* NTOHS happened in deliver: */
/* Some 4.2BSD-based routers incorrectly adjust the ip_len */
if (mtu > rt->rt_rmx.rmx_mtu && rt->rt_rmx.rmx_mtu != 0)
mtu -= (icp->icmp_ip.ip_hl << 2);
/* If we still can't guess a value, try the route */
if (mtu == 0) {
mtu = rt->rt_rmx.rmx_mtu;
/* If no route mtu, default to the interface mtu */
if (mtu == 0)
mtu = rt->rt_ifp->if_mtu;
}
for (i = 0; i < sizeof(mtu_table) / sizeof(mtu_table[0]); i++)
if (mtu > mtu_table[i]) {
mtu = mtu_table[i];
break;
}
}
/*
* XXX: RTV_MTU is overloaded, since the admin can set it
* to turn off PMTU for a route, and the kernel can
* set it to indicate a serious problem with PMTU
* on a route. We should be using a separate flag
* for the kernel to indicate this.
*/
if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0) {
if (mtu < 296 || mtu > rt->rt_ifp->if_mtu)
rt->rt_rmx.rmx_locks |= RTV_MTU;
else if (rt->rt_rmx.rmx_mtu > mtu ||
rt->rt_rmx.rmx_mtu == 0)
rt->rt_rmx.rmx_mtu = mtu;
}
if (rt)
rtfree(rt);
}
/*
* Return the next larger or smaller MTU plateau (table from RFC 1191)
* given current value MTU. If DIR is less than zero, a larger plateau
* is returned; otherwise, a smaller value is returned.
*/
int
ip_next_mtu(mtu, dir) /* XXX */
int mtu;
int dir;
{
static u_short mtutab[] = {
65535, 32000, 17914, 8166, 4352, 2002, 1492, 1006, 508, 296,
68, 0
};
int i;
for (i = 0; i < (sizeof mtutab) / (sizeof mtutab[0]); i++) {
if (mtu >= mtutab[i])
break;
}
if (dir < 0) {
if (i == 0) {
return 0;
} else {
return mtutab[i - 1];
}
} else {
if (mtutab[i] == 0) {
return 0;
} else if(mtu > mtutab[i]) {
return mtutab[i];
} else {
return mtutab[i + 1];
}
}
}
void
icmp_mtudisc_timeout(rt, r)
struct rtentry *rt;
struct rttimer *r;
{
if (rt == NULL)
panic("icmp_mtudisc_timeout: bad route to timeout");
if ((rt->rt_flags & (RTF_DYNAMIC | RTF_HOST)) ==
(RTF_DYNAMIC | RTF_HOST)) {
rtrequest((int) RTM_DELETE, (struct sockaddr *)rt_key(rt),
rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
} else {
if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0) {
rt->rt_rmx.rmx_mtu = 0;
}
}
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip_input.c,v 1.56 2000/05/15 11:07:33 itojun Exp $ */
/* $OpenBSD: ip_input.c,v 1.57 2000/09/18 22:06:37 provos Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@ -76,6 +76,12 @@
#ifndef IPSENDREDIRECTS
#define IPSENDREDIRECTS 1
#endif
#ifndef IPMTUDISC
#define IPMTUDISC 0
#endif
#ifndef IPMTUDISCTIMEOUT
#define IPMTUDISCTIMEOUT (10 * 60) /* as per RFC 1191 */
#endif
int encdebug = 0;
int ipsec_acl = 1;
@ -107,11 +113,15 @@ int ipforwarding = IPFORWARDING;
int ipsendredirects = IPSENDREDIRECTS;
int ip_dosourceroute = 0; /* no src-routing unless sysctl'd to enable */
int ip_defttl = IPDEFTTL;
int ip_mtudisc = IPMTUDISC;
u_int ip_mtudisc_timeout = IPMTUDISCTIMEOUT;
int ip_directedbcast = IPDIRECTEDBCAST;
#ifdef DIAGNOSTIC
int ipprintfs = 0;
#endif
struct rttimer_queue *ip_mtudisc_timeout_q = NULL;
int ipsec_auth_default_level = IPSEC_AUTH_LEVEL_DEFAULT;
int ipsec_esp_trans_default_level = IPSEC_ESP_TRANS_LEVEL_DEFAULT;
int ipsec_esp_network_default_level = IPSEC_ESP_NETWORK_LEVEL_DEFAULT;
@ -224,6 +234,9 @@ ip_init()
LIST_INIT(&ipq);
ipintrq.ifq_maxlen = ipqmaxlen;
TAILQ_INIT(&in_ifaddr);
if (ip_mtudisc != 0)
ip_mtudisc_timeout_q =
rt_timer_queue_create(ip_mtudisc_timeout);
/* Fill in list of ports not to allocate dynamically. */
bzero((void *)&baddynamicports, sizeof(baddynamicports));
@ -1469,6 +1482,8 @@ ip_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
void *newp;
size_t newlen;
{
int error;
/* All sysctl names at this level are terminal. */
if (namelen != 1)
return (ENOTDIR);
@ -1496,6 +1511,24 @@ ip_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
case IPCTL_DIRECTEDBCAST:
return (sysctl_int(oldp, oldlenp, newp, newlen,
&ip_directedbcast));
case IPCTL_MTUDISC:
error = sysctl_int(oldp, oldlenp, newp, newlen,
&ip_mtudisc);
if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL) {
ip_mtudisc_timeout_q =
rt_timer_queue_create(ip_mtudisc_timeout);
} else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != NULL) {
rt_timer_queue_destroy(ip_mtudisc_timeout_q, TRUE);
ip_mtudisc_timeout_q = NULL;
}
return error;
case IPCTL_MTUDISCTIMEOUT:
error = sysctl_int(oldp, oldlenp, newp, newlen,
&ip_mtudisc_timeout);
if (ip_mtudisc_timeout_q != NULL)
rt_timer_queue_change(ip_mtudisc_timeout_q,
ip_mtudisc_timeout);
return (error);
case IPCTL_IPPORT_FIRSTAUTO:
return (sysctl_int(oldp, oldlenp, newp, newlen,
&ipport_firstauto));

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip_output.c,v 1.79 2000/07/29 22:51:22 angelos Exp $ */
/* $OpenBSD: ip_output.c,v 1.80 2000/09/18 22:06:37 provos Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@ -545,6 +545,14 @@ ip_output(m0, va_alist)
m->m_flags &= ~M_BCAST;
sendit:
/*
* If we're doing Path MTU discovery, we need to set DF unless
* the route's MTU is locked.
*/
if ((flags & IP_MTUDISC) && ro->ro_rt &&
(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU) == 0)
ip->ip_off |= IP_DF;
#ifdef IPSEC
/*
* Check if the packet needs encapsulation.

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip_var.h,v 1.13 2000/01/02 09:00:19 angelos Exp $ */
/* $OpenBSD: ip_var.h,v 1.14 2000/09/18 22:06:38 provos Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/*
@ -154,12 +154,17 @@ struct ipstat {
#define IP_RAWOUTPUT 0x2 /* raw ip header exists */
#define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */
#define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */
#define IP_MTUDISC 0x0400 /* pmtu discovery, set DF */
#define IP_ENCAPSULATED 0x0800 /* encapsulated already */
struct ipstat ipstat;
LIST_HEAD(ipqhead, ipq) ipq; /* ip reass. queue */
int ip_defttl; /* default IP ttl */
int ip_mtudisc; /* mtu discovery */
u_int ip_mtudisc_timeout; /* seconds to timeout mtu discovery */
struct rttimer_queue *ip_mtudisc_timeout_q;
int ip_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
int ip_dooptions __P((struct mbuf *));
void ip_drain __P((void));

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_input.c,v 1.69 2000/09/05 21:57:41 provos Exp $ */
/* $OpenBSD: tcp_input.c,v 1.70 2000/09/18 22:06:38 provos Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@ -2743,13 +2743,14 @@ tcp_xmit_timer(tp, rtt)
int
tcp_mss(tp, offer)
register struct tcpcb *tp;
u_int offer;
int offer;
{
struct route *ro;
register struct rtentry *rt;
struct ifnet *ifp;
register int rtt, mss;
register int rtt, mss, mssopt;
u_long bufsize;
int iphlen, is_ipv6 = 0;
struct inpcb *inp;
struct socket *so;
@ -2796,6 +2797,23 @@ tcp_mss(tp, offer)
}
ifp = rt->rt_ifp;
mssopt = mss = tcp_mssdflt;
switch (tp->pf) {
#ifdef INET6
case AF_INET6:
iphlen = sizeof(struct ip6_hdr);
is_ipv6 = 1;
break;
#endif
case AF_INET:
iphlen = sizeof(struct ip);
break;
default:
/* the family does not support path MTU discovery */
goto out;
}
#ifdef RTV_MTU /* if route characteristics exist ... */
/*
* While we're here, check if there's an initial rtt
@ -2823,58 +2841,52 @@ tcp_mss(tp, offer)
((tp->t_srtt >> 2) + tp->t_rttvar) >> 1,
tp->t_rttmin, TCPTV_REXMTMAX);
}
/*
* if there's an mtu associated with the route and we support
* path MTU discovery for the underlying protocol family, use it.
*/
/*
* XXX It's wrong to use PMTU values to determine the MSS we
* are going to advertise; we should only use the input interface's
* MTU instead (see draft-ietf-tcpimpl-pmtud-03.txt). tcp_mss()
* should be changed to be aware whether it's called for input or
* output MSS calculation, and act accordingly.
*/
if (rt->rt_rmx.rmx_mtu) {
/*
* One may wish to lower MSS to take into account options,
* especially security-related options.
*/
mss = rt->rt_rmx.rmx_mtu - sizeof(struct tcphdr);
switch (tp->pf) {
#ifdef INET6
case AF_INET6:
mss -= sizeof(struct ip6_hdr);
break;
#endif
#ifdef notdef /* no IPv4 path MTU discovery yet */
case AF_INET:
mss -= sizeof(struct ip);
break;
#endif
default:
/* the family does not support path MTU discovery */
mss = 0;
break;
}
mss = rt->rt_rmx.rmx_mtu - iphlen - sizeof(struct tcphdr);
} else
mss = 0;
#else
mss = 0;
#endif /* RTV_MTU */
if (mss == 0) {
if (!ifp)
/*
* ifp may be null and rmx_mtu may be zero in certain
* v6 cases (e.g., if ND wasn't able to resolve the
* destination host.
*/
mss = ifp ? ifp->if_mtu - sizeof(struct tcpiphdr) : 0;
switch (tp->pf) {
case AF_INET:
if (!in_localaddr(inp->inp_faddr))
mss = min(mss, tcp_mssdflt);
break;
goto out;
else if (ip_mtudisc || ifp->if_flags & IFF_LOOPBACK)
mss = ifp->if_mtu - iphlen - sizeof(struct tcphdr);
#ifdef INET6
else if (is_ipv6) {
if (IN6_IS_ADDR_V4MAPPED(&inp->inp_faddr6)) {
/* mapped addr case */
struct in_addr d;
bcopy(&inp->inp_faddr6.s6_addr32[3], &d, sizeof(d));
if (in_localaddr(d))
mss = ifp->if_mtu - iphlen - sizeof(struct tcphdr);
} else {
if (in6_localaddr(&inp->inp_faddr6))
mss = ifp->if_mtu - iphlen - sizeof(struct tcphdr);
}
}
#endif /* INET6 */
else if (inp && in_localaddr(inp->inp_faddr))
mss = ifp->if_mtu - iphlen - sizeof(struct tcphdr);
/* Calculate the value that we offer in TCPOPT_MAXSEG */
if (offer != -1) {
mssopt = ifp->if_mtu - iphlen - sizeof(struct tcphdr);
mssopt = max(tcp_mssdflt, mssopt);
}
out:
/*
* The current mss, t_maxseg, is initialized to the default value.
* If we compute a smaller value, reduce the current mss.
@ -2883,7 +2895,7 @@ tcp_mss(tp, offer)
* unless we received an offer at least that large from peer.
* However, do not accept offers under 32 bytes.
*/
if (offer)
if (offer && offer != -1)
mss = min(mss, offer);
mss = max(mss, 64); /* sanity - at least max opt. space */
/*
@ -2953,7 +2965,8 @@ tcp_mss(tp, offer)
tp->snd_ssthresh = max(2 * mss, rt->rt_rmx.rmx_ssthresh);
}
#endif /* RTV_MTU */
return (mss);
return (offer != -1 ? mssopt : mss);
}
#endif /* TUBA_INCLUDE */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_output.c,v 1.31 2000/09/05 21:57:41 provos Exp $ */
/* $OpenBSD: tcp_output.c,v 1.32 2000/09/18 22:06:38 provos Exp $ */
/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
/*
@ -1033,7 +1033,9 @@ send:
ip->ip_tos = tp->t_inpcb->inp_ip.ip_tos;
}
error = ip_output(m, tp->t_inpcb->inp_options,
&tp->t_inpcb->inp_route, so->so_options & SO_DONTROUTE,
&tp->t_inpcb->inp_route,
(ip_mtudisc ? IP_MTUDISC : 0) |
(so->so_options & SO_DONTROUTE),
0, tp->t_inpcb);
break;
#endif /* INET */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_subr.c,v 1.30 2000/07/11 19:18:17 provos Exp $ */
/* $OpenBSD: tcp_subr.c,v 1.31 2000/09/18 22:06:38 provos Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
@ -406,7 +406,8 @@ tcp_respond(tp, template, m, ack, seq, flags)
th->th_sum = in_cksum(m, tlen);
((struct ip *)ti)->ip_len = tlen;
((struct ip *)ti)->ip_ttl = ip_defttl;
ip_output(m, NULL, ro, 0, NULL, tp ? tp->t_inpcb : NULL);
ip_output(m, NULL, ro, ip_mtudisc ? IP_MTUDISC : 0, NULL,
tp ? tp->t_inpcb : NULL);
}
}
@ -729,10 +730,8 @@ tcp6_ctlinput(cmd, sa, d)
return;
if (cmd == PRC_QUENCH)
notify = tcp_quench;
#if 0
else if (cmd == PRC_MSGSIZE)
notify = tcp_mtudisc;
#endif
else if (!PRC_IS_REDIRECT(cmd) &&
((unsigned)cmd > PRC_NCMDS || inet6ctlerrmap[cmd] == 0))
return;
@ -809,6 +808,8 @@ tcp_ctlinput(cmd, sa, v)
notify = tcp_quench;
else if (PRC_IS_REDIRECT(cmd))
notify = in_rtchange, ip = 0;
else if (cmd == PRC_MSGSIZE && ip_mtudisc)
notify = tcp_mtudisc, ip = 0;
else if (cmd == PRC_HOSTDEAD)
ip = 0;
else if (errno == 0)
@ -839,6 +840,52 @@ tcp_quench(inp, errno)
tp->snd_cwnd = tp->t_maxseg;
}
/*
* On receipt of path MTU corrections, flush old route and replace it
* with the new one. Retransmit all unacknowledged packets, to ensure
* that all packets will be received.
*/
void
tcp_mtudisc(inp, errno)
struct inpcb *inp;
int errno;
{
struct tcpcb *tp = intotcpcb(inp);
struct rtentry *rt = in_pcbrtentry(inp);
if (tp != 0) {
if (rt != 0) {
/*
* If this was not a host route, remove and realloc.
*/
if ((rt->rt_flags & RTF_HOST) == 0) {
in_rtchange(inp, errno);
if ((rt = in_pcbrtentry(inp)) == 0)
return;
}
/*
* Slow start out of the error condition. We
* use the MTU because we know it's smaller
* than the previously transmitted segment.
*
* Note: This is more conservative than the
* suggestion in RFC 2414
*/
if (rt->rt_rmx.rmx_mtu != 0) {
tcp_mss(tp, -1);
tp->snd_cwnd = rt->rt_rmx.rmx_mtu;
}
}
/*
* Resend unacknowledged packets.
*/
tp->snd_nxt = tp->snd_una;
tcp_output(tp);
}
}
#ifdef TCP_SIGNATURE
int
tcp_signature_tdb_attach()

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_timer.c,v 1.16 1999/12/21 17:49:28 provos Exp $ */
/* $OpenBSD: tcp_timer.c,v 1.17 2000/09/18 22:06:38 provos Exp $ */
/* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */
/*
@ -236,6 +236,24 @@ tcp_timers(tp, timer)
rto * tcp_backoff[tp->t_rxtshift],
tp->t_rttmin, TCPTV_REXMTMAX);
tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
#if 0
/*
* If we are losing and we are trying path MTU discovery,
* try turning it off. This will avoid black holes in
* the network which suppress or fail to send "packet
* too big" ICMP messages. We should ideally do
* lots more sophisticated searching to find the right
* value here...
*/
if (ip_mtudisc && tp->t_rxtshift > TCP_MAXRXTSHIFT / 6) {
struct rtentry *rt = NULL;
if (tp->t_inpcb)
rt = in_pcbrtentry(tp->t_inpcb);
/* XXX: Black hole recovery code goes here */
}
#endif
/*
* If losing, let the lower level know and try for
* a better route. Also, if we backed off this far,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_var.h,v 1.29 2000/07/11 16:53:22 provos Exp $ */
/* $OpenBSD: tcp_var.h,v 1.30 2000/09/18 22:06:38 provos Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@ -342,7 +342,8 @@ void tcp_init __P((void));
int tcp6_input __P((struct mbuf **, int *, int));
#endif
void tcp_input __P((struct mbuf *, ...));
int tcp_mss __P((struct tcpcb *, u_int));
int tcp_mss __P((struct tcpcb *, int));
void tcp_mtudisc __P((struct inpcb *, int));
struct tcpcb *
tcp_newtcpcb __P((struct inpcb *));
void tcp_notify __P((struct inpcb *, int));