tcp_output: don't try to send SACK option larger than txsegsize.

fix a panic like "panic: m_copydata: off 0, len -7".
This commit is contained in:
yamt 2006-10-08 11:01:46 +00:00
parent 85ff1590b2
commit 713f438722
1 changed files with 14 additions and 6 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_output.c,v 1.146 2006/10/07 16:16:42 yamt Exp $ */ /* $NetBSD: tcp_output.c,v 1.147 2006/10/08 11:01:46 yamt Exp $ */
/* /*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -142,7 +142,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.146 2006/10/07 16:16:42 yamt Exp $"); __KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.147 2006/10/08 11:01:46 yamt Exp $");
#include "opt_inet.h" #include "opt_inet.h"
#include "opt_ipsec.h" #include "opt_ipsec.h"
@ -676,11 +676,19 @@ again:
TCP_REASS_LOCK(tp); TCP_REASS_LOCK(tp);
sack_numblks = tcp_sack_numblks(tp); sack_numblks = tcp_sack_numblks(tp);
if (sack_numblks) { if (sack_numblks) {
if ((tp->rcv_sack_flags & TCPSACK_HAVED) != 0) { int sackoptlen;
/* don't duplicate D-SACK. */
use_tso = 0; sackoptlen = TCP_SACK_OPTLEN(sack_numblks);
if (sackoptlen > txsegsize_nosack) {
sack_numblks = 0; /* give up SACK */
txsegsize = txsegsize_nosack;
} else {
if ((tp->rcv_sack_flags & TCPSACK_HAVED) != 0) {
/* don't duplicate D-SACK. */
use_tso = 0;
}
txsegsize = txsegsize_nosack - sackoptlen;
} }
txsegsize = txsegsize_nosack - TCP_SACK_OPTLEN(sack_numblks);
} else { } else {
txsegsize = txsegsize_nosack; txsegsize = txsegsize_nosack;
} }