mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-10-18 16:39:34 +08:00
Update to FreeBSD head 2017-04-04
Git mirror commit 642b174daddbd0efd9bb5f242c43f4ab4db6869f.
This commit is contained in:
@@ -98,13 +98,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/toecore.h>
|
||||
#endif
|
||||
|
||||
#ifdef IPSEC
|
||||
#include <netipsec/ipsec.h>
|
||||
#ifdef INET6
|
||||
#include <netipsec/ipsec6.h>
|
||||
#endif
|
||||
#include <netipsec/key.h>
|
||||
#endif /*IPSEC*/
|
||||
#include <netipsec/ipsec_support.h>
|
||||
|
||||
#include <machine/in_cksum.h>
|
||||
|
||||
@@ -122,6 +116,14 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, syncookies_only, CTLFLAG_VNET | CTLFLAG_RW,
|
||||
&VNET_NAME(tcp_syncookiesonly), 0,
|
||||
"Use only TCP SYN cookies");
|
||||
|
||||
static VNET_DEFINE(int, functions_inherit_listen_socket_stack) = 1;
|
||||
#define V_functions_inherit_listen_socket_stack \
|
||||
VNET(functions_inherit_listen_socket_stack)
|
||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, functions_inherit_listen_socket_stack,
|
||||
CTLFLAG_VNET | CTLFLAG_RW,
|
||||
&VNET_NAME(functions_inherit_listen_socket_stack), 0,
|
||||
"Inherit listen socket's stack");
|
||||
|
||||
#ifdef TCP_OFFLOAD
|
||||
#define ADDED_BY_TOE(sc) ((sc)->sc_tod != NULL)
|
||||
#endif
|
||||
@@ -738,11 +740,6 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
|
||||
INP_HASH_WUNLOCK(&V_tcbinfo);
|
||||
goto abort;
|
||||
}
|
||||
#ifdef IPSEC
|
||||
/* Copy old policy into new socket's. */
|
||||
if (ipsec_copy_policy(sotoinpcb(lso)->inp_sp, inp->inp_sp))
|
||||
printf("syncache_socket: could not copy policy\n");
|
||||
#endif
|
||||
#ifdef INET6
|
||||
if (sc->sc_inc.inc_flags & INC_ISIPV6) {
|
||||
struct inpcb *oinp = sotoinpcb(lso);
|
||||
@@ -832,6 +829,11 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
|
||||
}
|
||||
}
|
||||
#endif /* INET */
|
||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
|
||||
/* Copy old policy into new socket's. */
|
||||
if (ipsec_copy_pcbpolicy(sotoinpcb(lso), inp) != 0)
|
||||
printf("syncache_socket: could not copy policy\n");
|
||||
#endif
|
||||
INP_HASH_WUNLOCK(&V_tcbinfo);
|
||||
tp = intotcpcb(inp);
|
||||
tcp_state_change(tp, TCPS_SYN_RECEIVED);
|
||||
@@ -840,7 +842,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
|
||||
tcp_rcvseqinit(tp);
|
||||
tcp_sendseqinit(tp);
|
||||
blk = sototcpcb(lso)->t_fb;
|
||||
if (blk != tp->t_fb) {
|
||||
if (V_functions_inherit_listen_socket_stack && blk != tp->t_fb) {
|
||||
/*
|
||||
* Our parents t_fb was not the default,
|
||||
* we need to release our ref on tp->t_fb and
|
||||
@@ -882,7 +884,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
|
||||
tp->ts_recent_age = tcp_ts_getticks();
|
||||
tp->ts_offset = sc->sc_tsoff;
|
||||
}
|
||||
#ifdef TCP_SIGNATURE
|
||||
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
|
||||
if (sc->sc_flags & SCF_SIGNATURE)
|
||||
tp->t_flags |= TF_SIGNATURE;
|
||||
#endif
|
||||
@@ -1006,7 +1008,57 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
|
||||
"(probably spoofed)\n", s, __func__);
|
||||
goto failed;
|
||||
}
|
||||
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
|
||||
/* If received ACK has MD5 signature, check it. */
|
||||
if ((to->to_flags & TOF_SIGNATURE) != 0 &&
|
||||
(!TCPMD5_ENABLED() ||
|
||||
TCPMD5_INPUT(m, th, to->to_signature) != 0)) {
|
||||
/* Drop the ACK. */
|
||||
if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
|
||||
log(LOG_DEBUG, "%s; %s: Segment rejected, "
|
||||
"MD5 signature doesn't match.\n",
|
||||
s, __func__);
|
||||
free(s, M_TCPLOG);
|
||||
}
|
||||
TCPSTAT_INC(tcps_sig_err_sigopt);
|
||||
return (-1); /* Do not send RST */
|
||||
}
|
||||
#endif /* TCP_SIGNATURE */
|
||||
} else {
|
||||
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
|
||||
/*
|
||||
* If listening socket requested TCP digests, check that
|
||||
* received ACK has signature and it is correct.
|
||||
* If not, drop the ACK and leave sc entry in th cache,
|
||||
* because SYN was received with correct signature.
|
||||
*/
|
||||
if (sc->sc_flags & SCF_SIGNATURE) {
|
||||
if ((to->to_flags & TOF_SIGNATURE) == 0) {
|
||||
/* No signature */
|
||||
TCPSTAT_INC(tcps_sig_err_nosigopt);
|
||||
SCH_UNLOCK(sch);
|
||||
if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
|
||||
log(LOG_DEBUG, "%s; %s: Segment "
|
||||
"rejected, MD5 signature wasn't "
|
||||
"provided.\n", s, __func__);
|
||||
free(s, M_TCPLOG);
|
||||
}
|
||||
return (-1); /* Do not send RST */
|
||||
}
|
||||
if (!TCPMD5_ENABLED() ||
|
||||
TCPMD5_INPUT(m, th, to->to_signature) != 0) {
|
||||
/* Doesn't match or no SA */
|
||||
SCH_UNLOCK(sch);
|
||||
if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
|
||||
log(LOG_DEBUG, "%s; %s: Segment "
|
||||
"rejected, MD5 signature doesn't "
|
||||
"match.\n", s, __func__);
|
||||
free(s, M_TCPLOG);
|
||||
}
|
||||
return (-1); /* Do not send RST */
|
||||
}
|
||||
}
|
||||
#endif /* TCP_SIGNATURE */
|
||||
/*
|
||||
* Pull out the entry to unlock the bucket row.
|
||||
*
|
||||
@@ -1276,6 +1328,22 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
|
||||
ipopts = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
|
||||
/*
|
||||
* If listening socket requested TCP digests, check that received
|
||||
* SYN has signature and it is correct. If signature doesn't match
|
||||
* or TCP_SIGNATURE support isn't enabled, drop the packet.
|
||||
*/
|
||||
if (ltflags & TF_SIGNATURE) {
|
||||
if ((to->to_flags & TOF_SIGNATURE) == 0) {
|
||||
TCPSTAT_INC(tcps_sig_err_nosigopt);
|
||||
goto done;
|
||||
}
|
||||
if (!TCPMD5_ENABLED() ||
|
||||
TCPMD5_INPUT(m, th, to->to_signature) != 0)
|
||||
goto done;
|
||||
}
|
||||
#endif /* TCP_SIGNATURE */
|
||||
/*
|
||||
* See if we already have an entry for this connection.
|
||||
* If we do, resend the SYN,ACK, and reset the retransmit timer.
|
||||
@@ -1451,15 +1519,15 @@ skip_alloc:
|
||||
sc->sc_flags |= SCF_WINSCALE;
|
||||
}
|
||||
}
|
||||
#ifdef TCP_SIGNATURE
|
||||
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
|
||||
/*
|
||||
* If listening socket requested TCP digests, OR received SYN
|
||||
* contains the option, flag this in the syncache so that
|
||||
* syncache_respond() will do the right thing with the SYN+ACK.
|
||||
* If listening socket requested TCP digests, flag this in the
|
||||
* syncache so that syncache_respond() will do the right thing
|
||||
* with the SYN+ACK.
|
||||
*/
|
||||
if (to->to_flags & TOF_SIGNATURE || ltflags & TF_SIGNATURE)
|
||||
if (ltflags & TF_SIGNATURE)
|
||||
sc->sc_flags |= SCF_SIGNATURE;
|
||||
#endif
|
||||
#endif /* TCP_SIGNATURE */
|
||||
if (to->to_flags & TOF_SACKPERM)
|
||||
sc->sc_flags |= SCF_SACK;
|
||||
if (to->to_flags & TOF_MSS)
|
||||
@@ -1550,10 +1618,6 @@ syncache_respond(struct syncache *sc, struct syncache_head *sch, int locked,
|
||||
#ifdef INET6
|
||||
struct ip6_hdr *ip6 = NULL;
|
||||
#endif
|
||||
#ifdef TCP_SIGNATURE
|
||||
struct secasvar *sav;
|
||||
#endif
|
||||
|
||||
hlen =
|
||||
#ifdef INET6
|
||||
(sc->sc_inc.inc_flags & INC_ISIPV6) ? sizeof(struct ip6_hdr) :
|
||||
@@ -1662,32 +1726,10 @@ syncache_respond(struct syncache *sc, struct syncache_head *sch, int locked,
|
||||
}
|
||||
if (sc->sc_flags & SCF_SACK)
|
||||
to.to_flags |= TOF_SACKPERM;
|
||||
#ifdef TCP_SIGNATURE
|
||||
sav = NULL;
|
||||
if (sc->sc_flags & SCF_SIGNATURE) {
|
||||
sav = tcp_get_sav(m, IPSEC_DIR_OUTBOUND);
|
||||
if (sav != NULL)
|
||||
to.to_flags |= TOF_SIGNATURE;
|
||||
else {
|
||||
|
||||
/*
|
||||
* We've got SCF_SIGNATURE flag
|
||||
* inherited from listening socket,
|
||||
* but no SADB key for given source
|
||||
* address. Assume signature is not
|
||||
* required and remove signature flag
|
||||
* instead of silently dropping
|
||||
* connection.
|
||||
*/
|
||||
if (locked == 0)
|
||||
SCH_LOCK(sch);
|
||||
sc->sc_flags &= ~SCF_SIGNATURE;
|
||||
if (locked == 0)
|
||||
SCH_UNLOCK(sch);
|
||||
}
|
||||
}
|
||||
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
|
||||
if (sc->sc_flags & SCF_SIGNATURE)
|
||||
to.to_flags |= TOF_SIGNATURE;
|
||||
#endif
|
||||
|
||||
#ifdef TCP_RFC7413
|
||||
if (sc->sc_tfo_cookie) {
|
||||
to.to_flags |= TOF_FASTOPEN;
|
||||
@@ -1703,18 +1745,25 @@ syncache_respond(struct syncache *sc, struct syncache_head *sch, int locked,
|
||||
th->th_off = (sizeof(struct tcphdr) + optlen) >> 2;
|
||||
m->m_len += optlen;
|
||||
m->m_pkthdr.len += optlen;
|
||||
|
||||
#ifdef TCP_SIGNATURE
|
||||
if (sc->sc_flags & SCF_SIGNATURE)
|
||||
tcp_signature_do_compute(m, 0, optlen,
|
||||
to.to_signature, sav);
|
||||
#endif
|
||||
#ifdef INET6
|
||||
if (sc->sc_inc.inc_flags & INC_ISIPV6)
|
||||
ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) + optlen);
|
||||
else
|
||||
#endif
|
||||
ip->ip_len = htons(ntohs(ip->ip_len) + optlen);
|
||||
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
|
||||
if (sc->sc_flags & SCF_SIGNATURE) {
|
||||
KASSERT(to.to_flags & TOF_SIGNATURE,
|
||||
("tcp_addoptions() didn't set tcp_signature"));
|
||||
|
||||
/* NOTE: to.to_signature is inside of mbuf */
|
||||
if (!TCPMD5_ENABLED() ||
|
||||
TCPMD5_OUTPUT(m, th, to.to_signature) != 0) {
|
||||
m_freem(m);
|
||||
return (EACCES);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
optlen = 0;
|
||||
|
||||
@@ -2178,13 +2227,13 @@ syncache_pcblist(struct sysctl_req *req, int max_pcbs, int *pcbs_exported)
|
||||
xt.xt_inp.inp_vflag = INP_IPV6;
|
||||
else
|
||||
xt.xt_inp.inp_vflag = INP_IPV4;
|
||||
bcopy(&sc->sc_inc, &xt.xt_inp.inp_inc, sizeof (struct in_conninfo));
|
||||
xt.xt_tp.t_inpcb = &xt.xt_inp;
|
||||
xt.xt_tp.t_state = TCPS_SYN_RECEIVED;
|
||||
xt.xt_socket.xso_protocol = IPPROTO_TCP;
|
||||
xt.xt_socket.xso_len = sizeof (struct xsocket);
|
||||
xt.xt_socket.so_type = SOCK_STREAM;
|
||||
xt.xt_socket.so_state = SS_ISCONNECTING;
|
||||
bcopy(&sc->sc_inc, &xt.xt_inp.inp_inc,
|
||||
sizeof (struct in_conninfo));
|
||||
xt.t_state = TCPS_SYN_RECEIVED;
|
||||
xt.xt_inp.xi_socket.xso_protocol = IPPROTO_TCP;
|
||||
xt.xt_inp.xi_socket.xso_len = sizeof (struct xsocket);
|
||||
xt.xt_inp.xi_socket.so_type = SOCK_STREAM;
|
||||
xt.xt_inp.xi_socket.so_state = SS_ISCONNECTING;
|
||||
error = SYSCTL_OUT(req, &xt, sizeof xt);
|
||||
if (error) {
|
||||
SCH_UNLOCK(sch);
|
||||
|
Reference in New Issue
Block a user