Fix TCP segment size computation. From Rick Byersm, PR kern/14799.

This commit is contained in:
jmcneill 2001-12-03 01:45:43 +00:00
parent bfc80822c7
commit 078a8c0cc3
1 changed files with 17 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_output.c,v 1.75 2001/11/13 00:32:41 lukem Exp $ */
/* $NetBSD: tcp_output.c,v 1.76 2001/12/03 01:45:43 jmcneill Exp $ */
/*
%%% portions-copyright-nrl-95
@ -115,7 +115,7 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.75 2001/11/13 00:32:41 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.76 2001/12/03 01:45:43 jmcneill Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -190,6 +190,7 @@ tcp_segsize(struct tcpcb *tp, int *txsegsizep, int *rxsegsizep)
struct ifnet *ifp;
int size;
int iphlen;
int optlen;
#ifdef DIAGNOSTIC
if (tp->t_inpcb && tp->t_in6pcb)
@ -258,7 +259,12 @@ tcp_segsize(struct tcpcb *tp, int *txsegsizep, int *rxsegsizep)
}
}
#endif
size -= tcp_optlen(tp);
/*
* Now we must make room for whatever extra TCP/IP options are in
* the packet.
*/
optlen = tcp_optlen(tp);
/*
* XXX tp->t_ourmss should have the right size, but without this code
* fragmentation will occur... need more investigation
@ -266,27 +272,28 @@ tcp_segsize(struct tcpcb *tp, int *txsegsizep, int *rxsegsizep)
#ifdef INET
if (inp) {
#ifdef IPSEC
size -= ipsec4_hdrsiz_tcp(tp);
optlen += ipsec4_hdrsiz_tcp(tp);
#endif
size -= ip_optlen(inp);
optlen += ip_optlen(inp);
}
#endif
#ifdef INET6
#ifdef INET
if (in6p && tp->t_family == AF_INET) {
#ifdef IPSEC
size -= ipsec4_hdrsiz_tcp(tp);
optlen += ipsec4_hdrsiz_tcp(tp);
#endif
/* XXX size -= ip_optlen(in6p); */
} else
#endif
if (in6p && tp->t_family == AF_INET6) {
#ifdef IPSEC
size -= ipsec6_hdrsiz_tcp(tp);
optlen += ipsec6_hdrsiz_tcp(tp);
#endif
size -= ip6_optlen(in6p);
optlen += ip6_optlen(in6p);
}
#endif
size -= optlen;
out:
/*
@ -297,8 +304,8 @@ tcp_segsize(struct tcpcb *tp, int *txsegsizep, int *rxsegsizep)
* ipseclen is subtracted from both sides, this may not be right.
* I'm not quite sure about this (could someone comment).
*/
*txsegsizep = min(tp->t_peermss, size);
*rxsegsizep = min(tp->t_ourmss, size);
*txsegsizep = min(tp->t_peermss - optlen, size);
*rxsegsizep = min(tp->t_ourmss - optlen, size);
if (*txsegsizep != tp->t_segsz) {
/*