Fix TCP segment size computation. From Rick Byersm, PR kern/14799.
This commit is contained in:
parent
bfc80822c7
commit
078a8c0cc3
|
@ -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) {
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue