Index: sys/netinet/tcp.h =================================================================== --- sys/netinet/tcp.h +++ sys/netinet/tcp.h @@ -80,6 +80,8 @@ u_short th_urp; /* urgent pointer */ }; +#define PAD(len) ((((len) / 4) + !!((len) % 4)) * 4) + #define TCPOPT_EOL 0 #define TCPOLEN_EOL 1 #define TCPOPT_PAD 0 /* padding after EOL */ @@ -87,17 +89,17 @@ #define TCPOPT_NOP 1 #define TCPOLEN_NOP 1 #define TCPOPT_MAXSEG 2 -#define TCPOLEN_MAXSEG 4 -#define TCPOPT_WINDOW 3 -#define TCPOLEN_WINDOW 3 -#define TCPOPT_SACK_PERMITTED 4 -#define TCPOLEN_SACK_PERMITTED 2 -#define TCPOPT_SACK 5 -#define TCPOLEN_SACKHDR 2 -#define TCPOLEN_SACK 8 /* 2*sizeof(tcp_seq) */ -#define TCPOPT_TIMESTAMP 8 -#define TCPOLEN_TIMESTAMP 10 -#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ +#define TCPOLEN_MAXSEG 4 +#define TCPOPT_WINDOW 3 +#define TCPOLEN_WINDOW 3 +#define TCPOPT_SACK_PERMITTED 4 +#define TCPOLEN_SACK_PERMITTED 2 +#define TCPOPT_SACK 5 +#define TCPOLEN_SACKHDR 2 +#define TCPOLEN_SACK 8 /* 2*sizeof(tcp_seq) */ +#define TCPOPT_TIMESTAMP 8 +#define TCPOLEN_TIMESTAMP 10 +#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ #define TCPOPT_SIGNATURE 19 /* Keyed MD5: RFC 2385 */ #define TCPOLEN_SIGNATURE 18 #define TCPOPT_FAST_OPEN 34 Index: sys/netinet/tcp_output.c =================================================================== --- sys/netinet/tcp_output.c +++ sys/netinet/tcp_output.c @@ -590,6 +590,18 @@ if (len) { if (len >= tp->t_maxseg) goto send; + /* + * As the TCP header options are now + * considered when setting up the initial + * window, we would not send the last segment + * if we skip considering the option length here. + * Note: this may not work when tcp headers change + * very dynamically in the future. + */ + if ((((tp->t_flags & TF_SIGNATURE) ? PAD(TCPOLEN_SIGNATURE) : 0) + + ((tp->t_flags & TF_RCVD_TSTMP) ? PAD(TCPOLEN_TIMESTAMP) : 0) + + len) >= tp->t_maxseg) + goto send; /* * NOTE! on localhost connections an 'ack' from the remote * end may occur synchronously with the output and cause Index: sys/netinet/tcp_subr.c =================================================================== --- sys/netinet/tcp_subr.c +++ sys/netinet/tcp_subr.c @@ -3013,7 +3013,6 @@ * but this is harmless, since result of tcp_maxseg() is used * only in cwnd and ssthresh estimations. */ -#define PAD(len) ((((len) / 4) + !!((len) % 4)) * 4) if (TCPS_HAVEESTABLISHED(tp->t_state)) { if (tp->t_flags & TF_RCVD_TSTMP) optlen = TCPOLEN_TSTAMP_APPA;