diff options
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/tcp_input.c | 44 | ||||
-rw-r--r-- | sys/netinet/tcp_reass.c | 44 | ||||
-rw-r--r-- | sys/netinet/tcp_var.h | 11 |
3 files changed, 58 insertions, 41 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 7c59d2a..149c7d0 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -769,7 +769,7 @@ findpcb: * present in a SYN segment. See tcp_timewait(). */ if (thflags & TH_SYN) - tcp_dooptions(&to, optp, optlen, 1); + tcp_dooptions(&to, optp, optlen, TO_SYN); if (tcp_timewait(inp, &to, th, m, tlen)) goto findpcb; /* @@ -972,7 +972,7 @@ findpcb: tcp_trace(TA_INPUT, ostate, tp, (void *)tcp_saveipgen, &tcp_savetcp, 0); #endif - tcp_dooptions(&to, optp, optlen, 1); + tcp_dooptions(&to, optp, optlen, TO_SYN); if (!syncache_add(&inc, &to, th, inp, &so, m)) goto drop; /* XXX: does not happen */ if (so == NULL) { @@ -1096,11 +1096,23 @@ after_listen: tiwin = th->th_win << tp->snd_scale; /* + * Parse options on any incoming segment. + */ + tcp_dooptions(&to, optp, optlen, (thflags & TH_SYN) ? TO_SYN : 0); + + /* + * If echoed timestamp is later than the current time, + * fall back to non RFC1323 RTT calculation. + */ + if ((to.to_flags & TOF_TS) && (to.to_tsecr != 0) && + TSTMP_GT(to.to_tsecr, ticks)) + to.to_tsecr = 0; + + /* * Process options only when we get SYN/ACK back. The SYN case * for incoming connections is handled in tcp_syncache. * XXX this is traditional behavior, may need to be cleaned up. */ - tcp_dooptions(&to, optp, optlen, thflags & TH_SYN); if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) { if ((to.to_flags & TOF_SCALE) && (tp->t_flags & TF_REQ_SCALE)) { @@ -2594,11 +2606,11 @@ drop: * Parse TCP options and place in tcpopt. */ static void -tcp_dooptions(to, cp, cnt, is_syn) +tcp_dooptions(to, cp, cnt, flags) struct tcpopt *to; u_char *cp; int cnt; - int is_syn; + int flags; { int opt, optlen; @@ -2620,7 +2632,7 @@ tcp_dooptions(to, cp, cnt, is_syn) case TCPOPT_MAXSEG: if (optlen != TCPOLEN_MAXSEG) continue; - if (!is_syn) + if (!(flags & TO_SYN)) continue; to->to_flags |= TOF_MSS; bcopy((char *)cp + 2, @@ -2630,7 +2642,7 @@ tcp_dooptions(to, cp, cnt, is_syn) case TCPOPT_WINDOW: if (optlen != TCPOLEN_WINDOW) continue; - if (! is_syn) + if (!(flags & TO_SYN)) continue; to->to_flags |= TOF_SCALE; to->to_requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT); @@ -2645,12 +2657,6 @@ tcp_dooptions(to, cp, cnt, is_syn) bcopy((char *)cp + 6, (char *)&to->to_tsecr, sizeof(to->to_tsecr)); to->to_tsecr = ntohl(to->to_tsecr); - /* - * If echoed timestamp is later than the current time, - * fall back to non RFC1323 RTT calculation. - */ - if ((to->to_tsecr != 0) && TSTMP_GT(to->to_tsecr, ticks)) - to->to_tsecr = 0; break; #ifdef TCP_SIGNATURE /* @@ -2666,13 +2672,13 @@ tcp_dooptions(to, cp, cnt, is_syn) break; #endif case TCPOPT_SACK_PERMITTED: - if (!tcp_do_sack || - optlen != TCPOLEN_SACK_PERMITTED) + if (optlen != TCPOLEN_SACK_PERMITTED) continue; - if (is_syn) { - /* MUST only be set on SYN */ - to->to_flags |= TOF_SACK; - } + if (!(flags & TO_SYN)) + continue; + if (!tcp_do_sack) + continue; + to->to_flags |= TOF_SACK; break; case TCPOPT_SACK: if (optlen <= 2 || (optlen - 2) % TCPOLEN_SACK != 0) diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 7c59d2a..149c7d0 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -769,7 +769,7 @@ findpcb: * present in a SYN segment. See tcp_timewait(). */ if (thflags & TH_SYN) - tcp_dooptions(&to, optp, optlen, 1); + tcp_dooptions(&to, optp, optlen, TO_SYN); if (tcp_timewait(inp, &to, th, m, tlen)) goto findpcb; /* @@ -972,7 +972,7 @@ findpcb: tcp_trace(TA_INPUT, ostate, tp, (void *)tcp_saveipgen, &tcp_savetcp, 0); #endif - tcp_dooptions(&to, optp, optlen, 1); + tcp_dooptions(&to, optp, optlen, TO_SYN); if (!syncache_add(&inc, &to, th, inp, &so, m)) goto drop; /* XXX: does not happen */ if (so == NULL) { @@ -1096,11 +1096,23 @@ after_listen: tiwin = th->th_win << tp->snd_scale; /* + * Parse options on any incoming segment. + */ + tcp_dooptions(&to, optp, optlen, (thflags & TH_SYN) ? TO_SYN : 0); + + /* + * If echoed timestamp is later than the current time, + * fall back to non RFC1323 RTT calculation. + */ + if ((to.to_flags & TOF_TS) && (to.to_tsecr != 0) && + TSTMP_GT(to.to_tsecr, ticks)) + to.to_tsecr = 0; + + /* * Process options only when we get SYN/ACK back. The SYN case * for incoming connections is handled in tcp_syncache. * XXX this is traditional behavior, may need to be cleaned up. */ - tcp_dooptions(&to, optp, optlen, thflags & TH_SYN); if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) { if ((to.to_flags & TOF_SCALE) && (tp->t_flags & TF_REQ_SCALE)) { @@ -2594,11 +2606,11 @@ drop: * Parse TCP options and place in tcpopt. */ static void -tcp_dooptions(to, cp, cnt, is_syn) +tcp_dooptions(to, cp, cnt, flags) struct tcpopt *to; u_char *cp; int cnt; - int is_syn; + int flags; { int opt, optlen; @@ -2620,7 +2632,7 @@ tcp_dooptions(to, cp, cnt, is_syn) case TCPOPT_MAXSEG: if (optlen != TCPOLEN_MAXSEG) continue; - if (!is_syn) + if (!(flags & TO_SYN)) continue; to->to_flags |= TOF_MSS; bcopy((char *)cp + 2, @@ -2630,7 +2642,7 @@ tcp_dooptions(to, cp, cnt, is_syn) case TCPOPT_WINDOW: if (optlen != TCPOLEN_WINDOW) continue; - if (! is_syn) + if (!(flags & TO_SYN)) continue; to->to_flags |= TOF_SCALE; to->to_requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT); @@ -2645,12 +2657,6 @@ tcp_dooptions(to, cp, cnt, is_syn) bcopy((char *)cp + 6, (char *)&to->to_tsecr, sizeof(to->to_tsecr)); to->to_tsecr = ntohl(to->to_tsecr); - /* - * If echoed timestamp is later than the current time, - * fall back to non RFC1323 RTT calculation. - */ - if ((to->to_tsecr != 0) && TSTMP_GT(to->to_tsecr, ticks)) - to->to_tsecr = 0; break; #ifdef TCP_SIGNATURE /* @@ -2666,13 +2672,13 @@ tcp_dooptions(to, cp, cnt, is_syn) break; #endif case TCPOPT_SACK_PERMITTED: - if (!tcp_do_sack || - optlen != TCPOLEN_SACK_PERMITTED) + if (optlen != TCPOLEN_SACK_PERMITTED) continue; - if (is_syn) { - /* MUST only be set on SYN */ - to->to_flags |= TOF_SACK; - } + if (!(flags & TO_SYN)) + continue; + if (!tcp_do_sack) + continue; + to->to_flags |= TOF_SACK; break; case TCPOPT_SACK: if (optlen <= 2 || (optlen - 2) % TCPOLEN_SACK != 0) diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 7d36c71..c58b44e 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -229,9 +229,9 @@ struct tcpcb { */ struct tcpopt { u_long to_flags; /* which options are present */ -#define TOF_TS 0x0001 /* timestamp */ -#define TOF_MSS 0x0010 -#define TOF_SCALE 0x0020 +#define TOF_TS 0x0001 /* timestamp */ +#define TOF_MSS 0x0010 /* maximum segment size */ +#define TOF_SCALE 0x0020 /* window scaling */ #define TOF_SIGNATURE 0x0040 /* signature option present */ #define TOF_SIGLEN 0x0080 /* signature length valid (RFC2385) */ #define TOF_SACK 0x0100 /* Peer sent SACK option */ @@ -243,6 +243,11 @@ struct tcpopt { u_char *to_sacks; /* pointer to the first SACK blocks */ }; +/* + * Flags for tcp_dooptions. + */ +#define TO_SYN 0x01 /* parse SYN-only options */ + struct hc_metrics_lite { /* must stay in sync with hc_metrics */ u_long rmx_mtu; /* MTU for this path */ u_long rmx_ssthresh; /* outbound gateway buffer limit */ |