doc/website/static/security/patches/SA-04:04/tcp51.patch
Sergio Carlavilla Delgado 989d921f5d Migrate doc to Hugo/AsciiDoctor
I'm very pleased to announce the release of
our new website and documentation using
the new toolchain with Hugo and AsciiDoctor.

To get more information about the new toolchain
please read the FreeBSD Documentation Project Primer[1],
Hugo docs[2] and AsciiDoctor docs[3].

Acknowledgment:
Benedict Reuschling <bcr@>
Glen Barber <gjb@>
Hiroki Sato <hrs@>
Li-Wen Hsu <lwhsu@>
Sean Chittenden <seanc@>
The FreeBSD Foundation

[1] https://docs.FreeBSD.org/en/books/fdp-primer/
[2] https://gohugo.io/documentation/
[3] https://docs.asciidoctor.org/home/

Approved by:    doceng, core
2021-01-26 00:31:29 +01:00

291 lines
7.8 KiB
Diff

Index: sys/netinet/tcp_input.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.205
retrieving revision 1.205.2.1
diff -c -r1.205 -r1.205.2.1
*** sys/netinet/tcp_input.c 7 May 2003 05:26:27 -0000 1.205
--- sys/netinet/tcp_input.c 15 Mar 2004 20:02:07 -0000 1.205.2.1
***************
*** 57,62 ****
--- 57,64 ----
#include <machine/cpu.h> /* before tcp_seq.h, for tcp_random18() */
+ #include <vm/uma.h>
+
#include <net/if.h>
#include <net/route.h>
***************
*** 97,104 ****
#include <machine/in_cksum.h>
- MALLOC_DEFINE(M_TSEGQ, "tseg_qent", "TCP segment queue entry");
-
static const int tcprexmtthresh = 3;
tcp_cc tcp_ccgen;
--- 99,104 ----
***************
*** 134,139 ****
--- 134,157 ----
&tcp_do_rfc3390, 0,
"Enable RFC 3390 (Increasing TCP's Initial Congestion Window)");
+ SYSCTL_NODE(_net_inet_tcp, OID_AUTO, reass, CTLFLAG_RW, 0,
+ "TCP Segment Reassembly Queue");
+
+ static int tcp_reass_maxseg = 0;
+ SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RD,
+ &tcp_reass_maxseg, 0,
+ "Global maximum number of TCP Segments in Reassembly Queue");
+
+ int tcp_reass_qsize = 0;
+ SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, cursegments, CTLFLAG_RD,
+ &tcp_reass_qsize, 0,
+ "Global number of TCP Segments currently in Reassembly Queue");
+
+ static int tcp_reass_overflows = 0;
+ SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, overflows, CTLFLAG_RD,
+ &tcp_reass_overflows, 0,
+ "Global number of TCP Segment Reassembly Queue Overflows");
+
struct inpcbhead tcb;
#define tcb6 tcb /* for KAME src sync over BSD*'s */
struct inpcbinfo tcbinfo;
***************
*** 175,180 ****
--- 193,211 ----
(tp->t_flags & TF_RXWIN0SENT) == 0) && \
(tcp_delack_enabled || (tp->t_flags & TF_NEEDSYN)))
+ /* Initialize TCP reassembly queue */
+ uma_zone_t tcp_reass_zone;
+ void
+ tcp_reass_init()
+ {
+ tcp_reass_maxseg = nmbclusters / 16;
+ TUNABLE_INT_FETCH("net.inet.tcp.reass.maxsegments",
+ &tcp_reass_maxseg);
+ tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent),
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
+ uma_zone_set_max(tcp_reass_zone, tcp_reass_maxseg);
+ }
+
static int
tcp_reass(tp, th, tlenp, m)
register struct tcpcb *tp;
***************
*** 185,191 ****
struct tseg_qent *q;
struct tseg_qent *p = NULL;
struct tseg_qent *nq;
! struct tseg_qent *te;
struct socket *so = tp->t_inpcb->inp_socket;
int flags;
--- 216,222 ----
struct tseg_qent *q;
struct tseg_qent *p = NULL;
struct tseg_qent *nq;
! struct tseg_qent *te = NULL;
struct socket *so = tp->t_inpcb->inp_socket;
int flags;
***************
*** 196,209 ****
if (th == 0)
goto present;
! /* Allocate a new queue entry. If we can't, just drop the pkt. XXX */
! MALLOC(te, struct tseg_qent *, sizeof (struct tseg_qent), M_TSEGQ,
! M_NOWAIT);
if (te == NULL) {
tcpstat.tcps_rcvmemdrop++;
m_freem(m);
return (0);
}
/*
* Find a segment which begins after this one does.
--- 227,258 ----
if (th == 0)
goto present;
! /*
! * Limit the number of segments in the reassembly queue to prevent
! * holding on to too many segments (and thus running out of mbufs).
! * Make sure to let the missing segment through which caused this
! * queue. Always keep one global queue entry spare to be able to
! * process the missing segment.
! */
! if (th->th_seq != tp->rcv_nxt &&
! tcp_reass_qsize + 1 >= tcp_reass_maxseg) {
! tcp_reass_overflows++;
! tcpstat.tcps_rcvmemdrop++;
! m_freem(m);
! return (0);
! }
!
! /*
! * Allocate a new queue entry. If we can't, or hit the zone limit
! * just drop the pkt.
! */
! te = uma_zalloc(tcp_reass_zone, M_NOWAIT);
if (te == NULL) {
tcpstat.tcps_rcvmemdrop++;
m_freem(m);
return (0);
}
+ tcp_reass_qsize++;
/*
* Find a segment which begins after this one does.
***************
*** 228,234 ****
tcpstat.tcps_rcvduppack++;
tcpstat.tcps_rcvdupbyte += *tlenp;
m_freem(m);
! FREE(te, M_TSEGQ);
/*
* Try to present any queued data
* at the left window edge to the user.
--- 277,284 ----
tcpstat.tcps_rcvduppack++;
tcpstat.tcps_rcvdupbyte += *tlenp;
m_freem(m);
! uma_zfree(tcp_reass_zone, te);
! tcp_reass_qsize--;
/*
* Try to present any queued data
* at the left window edge to the user.
***************
*** 263,269 ****
nq = LIST_NEXT(q, tqe_q);
LIST_REMOVE(q, tqe_q);
m_freem(q->tqe_m);
! FREE(q, M_TSEGQ);
q = nq;
}
--- 313,320 ----
nq = LIST_NEXT(q, tqe_q);
LIST_REMOVE(q, tqe_q);
m_freem(q->tqe_m);
! uma_zfree(tcp_reass_zone, q);
! tcp_reass_qsize--;
q = nq;
}
***************
*** 297,303 ****
m_freem(q->tqe_m);
else
sbappend(&so->so_rcv, q->tqe_m);
! FREE(q, M_TSEGQ);
q = nq;
} while (q && q->tqe_th->th_seq == tp->rcv_nxt);
ND6_HINT(tp);
--- 348,355 ----
m_freem(q->tqe_m);
else
sbappend(&so->so_rcv, q->tqe_m);
! uma_zfree(tcp_reass_zone, q);
! tcp_reass_qsize--;
q = nq;
} while (q && q->tqe_th->th_seq == tp->rcv_nxt);
ND6_HINT(tp);
Index: sys/netinet/tcp_subr.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.160
retrieving revision 1.160.2.1
diff -c -r1.160 -r1.160.2.1
*** sys/netinet/tcp_subr.c 7 May 2003 05:26:27 -0000 1.160
--- sys/netinet/tcp_subr.c 15 Mar 2004 20:02:07 -0000 1.160.2.1
***************
*** 262,267 ****
--- 262,268 ----
uma_zone_set_max(tcptw_zone, maxsockets);
tcp_timer_init();
syncache_init();
+ tcp_reass_init();
}
/*
***************
*** 763,769 ****
while ((q = LIST_FIRST(&tp->t_segq)) != NULL) {
LIST_REMOVE(q, tqe_q);
m_freem(q->tqe_m);
! FREE(q, M_TSEGQ);
}
inp->inp_ppcb = NULL;
tp->t_inpcb = NULL;
--- 764,771 ----
while ((q = LIST_FIRST(&tp->t_segq)) != NULL) {
LIST_REMOVE(q, tqe_q);
m_freem(q->tqe_m);
! uma_zfree(tcp_reass_zone, q);
! tcp_reass_qsize--;
}
inp->inp_ppcb = NULL;
tp->t_inpcb = NULL;
***************
*** 824,830 ****
!= NULL) {
LIST_REMOVE(te, tqe_q);
m_freem(te->tqe_m);
! FREE(te, M_TSEGQ);
}
}
INP_UNLOCK(inpb);
--- 826,833 ----
!= NULL) {
LIST_REMOVE(te, tqe_q);
m_freem(te->tqe_m);
! uma_zfree(tcp_reass_zone, te);
! tcp_reass_qsize--;
}
}
INP_UNLOCK(inpb);
Index: sys/netinet/tcp_var.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_var.h,v
retrieving revision 1.89
retrieving revision 1.89.2.1
diff -c -r1.89 -r1.89.2.1
*** sys/netinet/tcp_var.h 7 May 2003 05:26:27 -0000 1.89
--- sys/netinet/tcp_var.h 15 Mar 2004 20:02:07 -0000 1.89.2.1
***************
*** 54,62 ****
struct mbuf *tqe_m; /* mbuf contains packet */
};
LIST_HEAD(tsegqe_head, tseg_qent);
! #ifdef MALLOC_DECLARE
! MALLOC_DECLARE(M_TSEGQ);
! #endif
struct tcptemp {
u_char tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
--- 54,61 ----
struct mbuf *tqe_m; /* mbuf contains packet */
};
LIST_HEAD(tsegqe_head, tseg_qent);
! extern int tcp_reass_qsize;
! extern struct uma_zone *tcp_reass_zone;
struct tcptemp {
u_char tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
***************
*** 489,494 ****
--- 488,494 ----
int tcp_output(struct tcpcb *);
struct inpcb *
tcp_quench(struct inpcb *, int);
+ void tcp_reass_init(void);
void tcp_respond(struct tcpcb *, void *,
struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int);
int tcp_twrespond(struct tcptw *, struct socket *, struct mbuf *, int);