diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-04-04 09:36:57 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-04-04 14:46:23 +0200 |
commit | de8a76da2f374792594ce03a203b3f30e4889f6f (patch) | |
tree | 12b5e1e59358005c3c522955c08aee4795e4829c /freebsd/sys/netinet/tcp_input.c | |
parent | Enable bridging by default (diff) | |
download | rtems-libbsd-de8a76da2f374792594ce03a203b3f30e4889f6f.tar.bz2 |
Update to FreeBSD head 2017-04-04
Git mirror commit 642b174daddbd0efd9bb5f242c43f4ab4db6869f.
Diffstat (limited to 'freebsd/sys/netinet/tcp_input.c')
-rw-r--r-- | freebsd/sys/netinet/tcp_input.c | 120 |
1 files changed, 47 insertions, 73 deletions
diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c index bc77edbc..d23e1d31 100644 --- a/freebsd/sys/netinet/tcp_input.c +++ b/freebsd/sys/netinet/tcp_input.c @@ -30,7 +30,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -122,10 +122,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/tcp_offload.h> #endif -#ifdef IPSEC -#include <netipsec/ipsec.h> -#include <netipsec/ipsec6.h> -#endif /*IPSEC*/ +#include <netipsec/ipsec_support.h> #include <machine/in_cksum.h> @@ -489,20 +486,6 @@ cc_post_recovery(struct tcpcb *tp, struct tcphdr *th) tp->t_bytes_acked = 0; } -#ifdef TCP_SIGNATURE -static inline int -tcp_signature_verify_input(struct mbuf *m, int off0, int tlen, int optlen, - struct tcpopt *to, struct tcphdr *th, u_int tcpbflag) -{ - int ret; - - tcp_fields_to_net(th); - ret = tcp_signature_verify(m, off0, tlen, optlen, to, th, tcpbflag); - tcp_fields_to_host(th); - return (ret); -} -#endif - /* * Indicate whether this ack should be delayed. We can delay the ack if * following conditions are met: @@ -613,9 +596,6 @@ tcp_input(struct mbuf **mp, int *offp, int proto) int drop_hdrlen; int thflags; int rstreason = 0; /* For badport_bandlim accounting purposes */ -#ifdef TCP_SIGNATURE - uint8_t sig_checked = 0; -#endif uint8_t iptos; struct m_tag *fwd_tag = NULL; #ifdef INET6 @@ -946,15 +926,22 @@ findpcb: inp->inp_flowid = m->m_pkthdr.flowid; inp->inp_flowtype = M_HASHTYPE_GET(m); } -#ifdef IPSEC +#if defined(IPSEC) || defined(IPSEC_SUPPORT) #ifdef INET6 - if (isipv6 && ipsec6_in_reject(m, inp)) { + if (isipv6 && IPSEC_ENABLED(ipv6) && + IPSEC_CHECK_POLICY(ipv6, m, inp) != 0) { goto dropunlock; - } else + } +#ifdef INET + else +#endif #endif /* INET6 */ - if (ipsec4_in_reject(m, inp) != 0) { +#ifdef INET + if (IPSEC_ENABLED(ipv4) && + IPSEC_CHECK_POLICY(ipv4, m, inp) != 0) { goto dropunlock; } +#endif /* INET */ #endif /* IPSEC */ /* @@ -1137,7 +1124,16 @@ relocked: * NB: syncache_expand() doesn't unlock * inp and tcpinfo locks. */ - if (!syncache_expand(&inc, &to, th, &so, m)) { + rstreason = syncache_expand(&inc, &to, th, &so, m); + if (rstreason < 0) { + /* + * A failing TCP MD5 signature comparison + * must result in the segment being dropped + * and must not produce any response back + * to the sender. + */ + goto dropunlock; + } else if (rstreason == 0) { /* * No syncache entry or ACK was not * for our SYN/ACK. Send a RST. @@ -1189,26 +1185,6 @@ tfo_socket_result: tp = intotcpcb(inp); KASSERT(tp->t_state == TCPS_SYN_RECEIVED, ("%s: ", __func__)); -#ifdef TCP_SIGNATURE - if (sig_checked == 0) { - tcp_dooptions(&to, optp, optlen, - (thflags & TH_SYN) ? TO_SYN : 0); - if (!tcp_signature_verify_input(m, off0, tlen, - optlen, &to, th, tp->t_flags)) { - - /* - * In SYN_SENT state if it receives an - * RST, it is allowed for further - * processing. - */ - if ((thflags & TH_RST) == 0 || - (tp->t_state == TCPS_SYN_SENT) == 0) - goto dropunlock; - } - sig_checked = 1; - } -#endif - /* * Process the segment and the data it * contains. tcp_do_segment() consumes @@ -1438,26 +1414,18 @@ tfo_socket_result: */ goto dropunlock; } - -#ifdef TCP_SIGNATURE - if (sig_checked == 0) { - tcp_dooptions(&to, optp, optlen, - (thflags & TH_SYN) ? TO_SYN : 0); - if (!tcp_signature_verify_input(m, off0, tlen, optlen, &to, - th, tp->t_flags)) { - - /* - * In SYN_SENT state if it receives an RST, it is - * allowed for further processing. - */ - if ((thflags & TH_RST) == 0 || - (tp->t_state == TCPS_SYN_SENT) == 0) - goto dropunlock; +#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) + if (tp->t_flags & TF_SIGNATURE) { + tcp_dooptions(&to, optp, optlen, thflags); + if ((to.to_flags & TOF_SIGNATURE) == 0) { + TCPSTAT_INC(tcps_sig_err_nosigopt); + goto dropunlock; } - sig_checked = 1; + if (!TCPMD5_ENABLED() || + TCPMD5_INPUT(m, th, to.to_signature) != 0) + goto dropunlock; } #endif - TCP_PROBE5(receive, NULL, tp, m, tp, th); /* @@ -1634,6 +1602,13 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, (th->th_off << 2) - sizeof(struct tcphdr), (thflags & TH_SYN) ? TO_SYN : 0); +#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) + if ((tp->t_flags & TF_SIGNATURE) != 0 && + (to.to_flags & TOF_SIGNATURE) == 0) { + TCPSTAT_INC(tcps_sig_err_sigopt); + /* XXX: should drop? */ + } +#endif /* * If echoed timestamp is later than the current time, * fall back to non RFC1323 RTT calculation. Normalize @@ -3420,20 +3395,19 @@ tcp_dooptions(struct tcpopt *to, u_char *cp, int cnt, int flags) (char *)&to->to_tsecr, sizeof(to->to_tsecr)); to->to_tsecr = ntohl(to->to_tsecr); break; -#ifdef TCP_SIGNATURE - /* - * XXX In order to reply to a host which has set the - * TCP_SIGNATURE option in its initial SYN, we have to - * record the fact that the option was observed here - * for the syncache code to perform the correct response. - */ case TCPOPT_SIGNATURE: + /* + * In order to reply to a host which has set the + * TCP_SIGNATURE option in its initial SYN, we have + * to record the fact that the option was observed + * here for the syncache code to perform the correct + * response. + */ if (optlen != TCPOLEN_SIGNATURE) continue; to->to_flags |= TOF_SIGNATURE; to->to_signature = cp + 2; break; -#endif case TCPOPT_SACK_PERMITTED: if (optlen != TCPOLEN_SACK_PERMITTED) continue; @@ -3522,7 +3496,7 @@ tcp_xmit_timer(struct tcpcb *tp, int rtt) TCPSTAT_INC(tcps_rttupdated); tp->t_rttupdated++; - if (tp->t_srtt != 0) { + if ((tp->t_srtt != 0) && (tp->t_rxtshift <= TCP_RTT_INVALIDATE)) { /* * srtt is stored as fixed point with 5 bits after the * binary point (i.e., scaled by 8). The following magic |