summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_syncache.c
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2003-08-13 10:20:57 +0000
committerharti <harti@FreeBSD.org>2003-08-13 10:20:57 +0000
commit45f9ef9ca4a4369cc93d9a6b72d979f8ff519da4 (patch)
treea80ece702ce9bbbb90ac565c4ba9ce08ff2c731a /sys/netinet/tcp_syncache.c
parentdc2bd4173974d71ff3bcaf1c9886a74d7d12f860 (diff)
downloadFreeBSD-src-45f9ef9ca4a4369cc93d9a6b72d979f8ff519da4.zip
FreeBSD-src-45f9ef9ca4a4369cc93d9a6b72d979f8ff519da4.tar.gz
The syncache has made use of TCPDEBUG problematic, because the SYN
segments are lost for the application. This broke, for example, ports/benchmarks/dbs which needs the SYN segment to filter the contents of the trace buffer for the connection it is interested in. This patch makes the SYN segments available again. Unfortunately they are now associated with the listening socket instead of the new one, so a change to applications is required, but without this patch it wouldn't work altogether. PR: kern/45966
Diffstat (limited to 'sys/netinet/tcp_syncache.c')
-rw-r--r--sys/netinet/tcp_syncache.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 239592e..1f00101 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -37,6 +37,7 @@
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_mac.h"
+#include "opt_tcpdebug.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -68,10 +69,16 @@
#include <netinet6/in6_pcb.h>
#endif
#include <netinet/tcp.h>
+#ifdef TCPDEBUG
+#include <netinet/tcpip.h>
+#endif
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
+#ifdef TCPDEBUG
+#include <netinet/tcp_debug.h>
+#endif
#ifdef INET6
#include <netinet6/tcp6_var.h>
#endif
@@ -104,7 +111,11 @@ static void syncache_drop(struct syncache *, struct syncache_head *);
static void syncache_free(struct syncache *);
static void syncache_insert(struct syncache *, struct syncache_head *);
struct syncache *syncache_lookup(struct in_conninfo *, struct syncache_head **);
+#ifdef TCPDEBUG
+static int syncache_respond(struct syncache *, struct mbuf *, struct socket *);
+#else
static int syncache_respond(struct syncache *, struct mbuf *);
+#endif
static struct socket *syncache_socket(struct syncache *, struct socket *,
struct mbuf *m);
static void syncache_timer(void *);
@@ -397,7 +408,11 @@ syncache_timer(xslot)
* to modify another entry, so do not obtain the next
* entry on the timer chain until it has completed.
*/
+#ifdef TCPDEBUG
+ (void) syncache_respond(sc, NULL, NULL);
+#else
(void) syncache_respond(sc, NULL);
+#endif
nsc = TAILQ_NEXT(sc, sc_timerq);
tcpstat.tcps_sc_retransmitted++;
TAILQ_REMOVE(&tcp_syncache.timerq[slot], sc, sc_timerq);
@@ -870,7 +885,11 @@ syncache_add(inc, to, th, sop, m)
*/
sc->sc_tp = tp;
sc->sc_inp_gencnt = tp->t_inpcb->inp_gencnt;
+#ifdef TCPDEBUG
+ if (syncache_respond(sc, m, so) == 0) {
+#else
if (syncache_respond(sc, m) == 0) {
+#endif
s = splnet();
TAILQ_REMOVE(&tcp_syncache.timerq[sc->sc_rxtslot],
sc, sc_timerq);
@@ -1027,7 +1046,11 @@ syncache_add(inc, to, th, sop, m)
* TAO test failed or there was no CC option,
* do a standard 3-way handshake.
*/
+#ifdef TCPDEBUG
+ if (syncache_respond(sc, m, so) == 0) {
+#else
if (syncache_respond(sc, m) == 0) {
+#endif
syncache_insert(sc, sch);
tcpstat.tcps_sndacks++;
tcpstat.tcps_sndtotal++;
@@ -1039,10 +1062,18 @@ syncache_add(inc, to, th, sop, m)
return (1);
}
+#ifdef TCPDEBUG
+static int
+syncache_respond(sc, m, so)
+ struct syncache *sc;
+ struct mbuf *m;
+ struct socket *so;
+#else
static int
syncache_respond(sc, m)
struct syncache *sc;
struct mbuf *m;
+#endif
{
u_int8_t *optp;
int optlen, error;
@@ -1217,6 +1248,16 @@ syncache_respond(sc, m)
htons(tlen - hlen + IPPROTO_TCP));
m->m_pkthdr.csum_flags = CSUM_TCP;
m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
+#ifdef TCPDEBUG
+ /*
+ * Trace.
+ */
+ if (so != NULL && so->so_options & SO_DEBUG) {
+ struct tcpcb *tp = sototcpcb(so);
+ tcp_trace(TA_OUTPUT, tp->t_state, tp,
+ mtod(m, void *), th, 0);
+ }
+#endif
error = ip_output(m, sc->sc_ipopts, &sc->sc_route, 0, NULL,
sc->sc_tp->t_inpcb);
}
OpenPOWER on IntegriCloud