3571e53040
patches for easier mirroring, to eliminate a special copy, to make www.freebsd.org/security a full copy of security.freebsd.org and be eventually be the same. For now files are just sitting there. The symlinks are missing. Discussed on: www (repository location) Discussed with: simon (so)
291 lines
7.8 KiB
Diff
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);
|