Hi, The output from tcp debug sockets was incomplete. After detach tp was NULL and nothing was traced. So save the old tcpcb and use that to retreive some information. Note that otb may be freed and must not be dereferenced. Use a heuristic for cases where the address family is in the IP header but not provided in the PCB.
ok? bluhm Index: netinet/tcp_debug.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_debug.c,v retrieving revision 1.26 diff -u -p -r1.26 tcp_debug.c --- netinet/tcp_debug.c 10 May 2018 13:30:25 -0000 1.26 +++ netinet/tcp_debug.c 6 Jun 2018 22:12:59 -0000 @@ -110,18 +110,19 @@ int tcp_debx; * Tcp debug routines */ void -tcp_trace(short act, short ostate, struct tcpcb *tp, caddr_t headers, - int req, int len) +tcp_trace(short act, short ostate, struct tcpcb *tp, struct tcpcb *otp, + caddr_t headers, int req, int len) { #ifdef TCPDEBUG tcp_seq seq, ack; int flags; #endif + int pf = PF_UNSPEC; struct tcp_debug *td = &tcp_debug[tcp_debx++]; struct tcpiphdr *ti = (struct tcpiphdr *)headers; struct tcphdr *th; #ifdef INET6 - struct tcpipv6hdr *ti6 = (struct tcpipv6hdr *)ti; + struct tcpipv6hdr *ti6 = (struct tcpipv6hdr *)headers; #endif if (tcp_debx == TCP_NDEBUG) @@ -129,40 +130,54 @@ tcp_trace(short act, short ostate, struc td->td_time = iptime(); td->td_act = act; td->td_ostate = ostate; - td->td_tcb = (caddr_t)tp; - if (tp) + td->td_tcb = (caddr_t)otp; + if (tp) { + pf = tp->pf; td->td_cb = *tp; - else + } else bzero((caddr_t)&td->td_cb, sizeof (*tp)); - switch (tp->pf) { + + bzero(&td->td_ti6, sizeof(struct tcpipv6hdr)); + bzero(&td->td_ti, sizeof(struct tcpiphdr)); + if (headers) { + /* The address family may be in tcpcb or ip header. */ + if (pf == PF_UNSPEC) { + switch (ti6->ti6_i.ip6_vfc & IPV6_VERSION_MASK) { #ifdef INET6 - case PF_INET6: - if (ti6) { + case IPV6_VERSION: + pf = PF_INET6; + break; +#endif /* INET6 */ + case IPVERSION: + pf = PF_INET; + break; + } + } + switch (pf) { +#ifdef INET6 + case PF_INET6: th = &ti6->ti6_t; td->td_ti6 = *ti6; td->td_ti6.ti6_plen = len; - } else - bzero(&td->td_ti6, sizeof(struct tcpipv6hdr)); - break; + break; #endif /* INET6 */ - case PF_INET: - if (ti) { + case PF_INET: th = &ti->ti_t; td->td_ti = *ti; td->td_ti.ti_len = len; - } else - bzero(&td->td_ti, sizeof(struct tcpiphdr)); - break; - default: - return; + break; + default: + headers = NULL; + break; + } } td->td_req = req; #ifdef TCPDEBUG if (tcpconsdebug == 0) return; - if (tp) - printf("%p %s:", tp, tcpstates[ostate]); + if (otp) + printf("%p %s:", otp, tcpstates[ostate]); else printf("???????? "); printf("%s ", tanames[act]); @@ -171,7 +186,7 @@ tcp_trace(short act, short ostate, struc case TA_INPUT: case TA_OUTPUT: case TA_DROP: - if (ti == 0) + if (headers == NULL) break; seq = th->th_seq; ack = th->th_ack; @@ -205,7 +220,7 @@ tcp_trace(short act, short ostate, struc printf(" -> %s", tcpstates[tp->t_state]); /* print out internal state of tp !?! */ printf("\n"); - if (tp == 0) + if (tp == NULL) return; printf("\trcv_(nxt,wnd,up) (%x,%lx,%x) snd_(una,nxt,max) (%x,%x,%x)\n", tp->rcv_nxt, tp->rcv_wnd, tp->rcv_up, tp->snd_una, tp->snd_nxt, Index: netinet/tcp_input.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v retrieving revision 1.355 diff -u -p -r1.355 tcp_input.c --- netinet/tcp_input.c 8 May 2018 15:10:33 -0000 1.355 +++ netinet/tcp_input.c 6 Jun 2018 20:57:26 -0000 @@ -366,12 +366,13 @@ tcp_input(struct mbuf **mp, int *offp, i u_int8_t *optp = NULL; int optlen = 0; int tlen, off; - struct tcpcb *tp = NULL; + struct tcpcb *otp = NULL, *tp = NULL; int tiflags; struct socket *so = NULL; int todrop, acked, ourfinisacked; int hdroptlen = 0; - short ostate = 0; + short ostate; + caddr_t saveti; tcp_seq iss, *reuse = NULL; u_long tiwin; struct tcp_opt_info opti; @@ -635,20 +636,21 @@ findpcb: dst.sin6.sin6_port = th->th_dport; break; #endif /* INET6 */ - default: - goto badsyn; /*sanity*/ } if (so->so_options & SO_DEBUG) { + otp = tp; ostate = tp->t_state; switch (af) { #ifdef INET6 case AF_INET6: + saveti = (caddr_t) &tcp_saveti6; memcpy(&tcp_saveti6.ti6_i, ip6, sizeof(*ip6)); memcpy(&tcp_saveti6.ti6_t, th, sizeof(*th)); break; #endif case AF_INET: + saveti = (caddr_t) &tcp_saveti; memcpy(&tcp_saveti.ti_i, ip, sizeof(*ip)); memcpy(&tcp_saveti.ti_t, th, sizeof(*th)); break; @@ -2001,20 +2003,8 @@ dodata: /* XXX */ break; } } - if (so->so_options & SO_DEBUG) { - switch (tp->pf) { -#ifdef INET6 - case PF_INET6: - tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti6, - 0, tlen); - break; -#endif /* INET6 */ - case PF_INET: - tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti, - 0, tlen); - break; - } - } + if (otp) + tcp_trace(TA_INPUT, ostate, tp, otp, saveti, 0, tlen); /* * Return any desired output. @@ -2089,20 +2079,8 @@ drop: /* * Drop space held by incoming segment and return. */ - if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) { - switch (tp->pf) { -#ifdef INET6 - case PF_INET6: - tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti6, - 0, tlen); - break; -#endif /* INET6 */ - case PF_INET: - tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti, - 0, tlen); - break; - } - } + if (otp) + tcp_trace(TA_DROP, ostate, tp, otp, saveti, 0, tlen); m_freem(m); return IPPROTO_DONE; Index: netinet/tcp_output.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_output.c,v retrieving revision 1.124 diff -u -p -r1.124 tcp_output.c --- netinet/tcp_output.c 8 May 2018 15:10:33 -0000 1.124 +++ netinet/tcp_output.c 6 Jun 2018 20:59:19 -0000 @@ -983,7 +983,7 @@ send: * Trace. */ if (so->so_options & SO_DEBUG) - tcp_trace(TA_OUTPUT, tp->t_state, tp, mtod(m, caddr_t), 0, + tcp_trace(TA_OUTPUT, tp->t_state, tp, tp, mtod(m, caddr_t), 0, len); /* Index: netinet/tcp_timer.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_timer.c,v retrieving revision 1.66 diff -u -p -r1.66 tcp_timer.c --- netinet/tcp_timer.c 10 May 2018 13:30:25 -0000 1.66 +++ netinet/tcp_timer.c 6 Jun 2018 21:09:49 -0000 @@ -109,7 +109,7 @@ tcp_timer_init(void) void tcp_timer_delack(void *arg) { - struct tcpcb *tp = arg; + struct tcpcb *otp = NULL, *tp = arg; short ostate; /* @@ -124,11 +124,14 @@ tcp_timer_delack(void *arg) goto out; CLR((tp)->t_flags, TF_TMR_DELACK); - ostate = tp->t_state; + if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) { + otp = tp; + ostate = tp->t_state; + } tp->t_flags |= TF_ACKNOW; (void) tcp_output(tp); - if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) - tcp_trace(TA_TIMER, ostate, tp, (caddr_t)0, TCPT_DELACK, 0); + if (otp) + tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_DELACK, 0); out: NET_UNLOCK(); } @@ -192,7 +195,7 @@ tcp_timer_freesack(struct tcpcb *tp) void tcp_timer_rexmt(void *arg) { - struct tcpcb *tp = arg; + struct tcpcb *otp = NULL, *tp = arg; uint32_t rto; short ostate; @@ -239,7 +242,10 @@ tcp_timer_rexmt(void *arg) tp->t_softerror : ETIMEDOUT); goto out; } - ostate = tp->t_state; + if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) { + otp = tp; + ostate = tp->t_state; + } tcpstat_inc(tcps_rexmttimeo); rto = TCP_REXMTVAL(tp); if (rto < tp->t_rttmin) @@ -374,8 +380,8 @@ tcp_timer_rexmt(void *arg) #endif } (void) tcp_output(tp); - if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) - tcp_trace(TA_TIMER, ostate, tp, (caddr_t)0, TCPT_REXMT, 0); + if (otp) + tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_REXMT, 0); out: NET_UNLOCK(); } @@ -383,7 +389,7 @@ tcp_timer_rexmt(void *arg) void tcp_timer_persist(void *arg) { - struct tcpcb *tp = arg; + struct tcpcb *otp = NULL, *tp = arg; uint32_t rto; short ostate; @@ -397,7 +403,10 @@ tcp_timer_persist(void *arg) if (TCP_TIMER_ISARMED(tp, TCPT_REXMT)) goto out; - ostate = tp->t_state; + if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) { + otp = tp; + ostate = tp->t_state; + } tcpstat_inc(tcps_persisttimeo); /* * Hack: if the peer is dead/unreachable, we do not @@ -420,8 +429,8 @@ tcp_timer_persist(void *arg) tp->t_force = 1; (void) tcp_output(tp); tp->t_force = 0; - if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) - tcp_trace(TA_TIMER, ostate, tp, (caddr_t)0, TCPT_PERSIST, 0); + if (otp) + tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_PERSIST, 0); out: NET_UNLOCK(); } @@ -429,7 +438,7 @@ tcp_timer_persist(void *arg) void tcp_timer_keep(void *arg) { - struct tcpcb *tp = arg; + struct tcpcb *otp = NULL, *tp = arg; short ostate; NET_LOCK(); @@ -439,7 +448,10 @@ tcp_timer_keep(void *arg) goto out; CLR((tp)->t_flags, TF_TMR_KEEP); - ostate = tp->t_state; + if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) { + otp = tp; + ostate = tp->t_state; + } tcpstat_inc(tcps_keeptimeo); if (TCPS_HAVEESTABLISHED(tp->t_state) == 0) goto dropit; @@ -467,8 +479,8 @@ tcp_timer_keep(void *arg) TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepintvl); } else TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepidle); - if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) - tcp_trace(TA_TIMER, ostate, tp, (caddr_t)0, TCPT_KEEP, 0); + if (otp) + tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_KEEP, 0); out: NET_UNLOCK(); return; @@ -482,7 +494,7 @@ tcp_timer_keep(void *arg) void tcp_timer_2msl(void *arg) { - struct tcpcb *tp = arg; + struct tcpcb *otp = NULL, *tp = arg; short ostate; NET_LOCK(); @@ -492,7 +504,10 @@ tcp_timer_2msl(void *arg) goto out; CLR((tp)->t_flags, TF_TMR_2MSL); - ostate = tp->t_state; + if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) { + otp = tp; + ostate = tp->t_state; + } tcp_timer_freesack(tp); if (tp->t_state != TCPS_TIME_WAIT && @@ -500,8 +515,8 @@ tcp_timer_2msl(void *arg) TCP_TIMER_ARM(tp, TCPT_2MSL, tcp_keepintvl); else tp = tcp_close(tp); - if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) - tcp_trace(TA_TIMER, ostate, tp, (caddr_t)0, TCPT_2MSL, 0); + if (otp) + tcp_trace(TA_TIMER, ostate, tp, otp, NULL, TCPT_2MSL, 0); out: NET_UNLOCK(); } Index: netinet/tcp_usrreq.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.168 diff -u -p -r1.168 tcp_usrreq.c --- netinet/tcp_usrreq.c 24 Apr 2018 15:40:55 -0000 1.168 +++ netinet/tcp_usrreq.c 6 Jun 2018 20:44:20 -0000 @@ -127,7 +127,7 @@ tcp_usrreq(struct socket *so, int req, s struct mbuf *control, struct proc *p) { struct inpcb *inp; - struct tcpcb *tp = NULL; + struct tcpcb *otp = NULL, *tp = NULL; int error = 0; short ostate; @@ -172,7 +172,10 @@ tcp_usrreq(struct socket *so, int req, s /* tp might get 0 when using socket splicing */ if (tp == NULL) return (0); - ostate = tp->t_state; + if (so->so_options & SO_DEBUG) { + otp = tp; + ostate = tp->t_state; + } switch (req) { @@ -399,8 +402,8 @@ tcp_usrreq(struct socket *so, int req, s default: panic("tcp_usrreq"); } - if (tp && (so->so_options & SO_DEBUG)) - tcp_trace(TA_USER, ostate, tp, (caddr_t)0, req, 0); + if (otp) + tcp_trace(TA_USER, ostate, tp, otp, NULL, req, 0); return (error); } @@ -599,7 +602,7 @@ tcp_attach(struct socket *so, int proto) so->so_linger = TCP_LINGERTIME; if (so->so_options & SO_DEBUG) - tcp_trace(TA_USER, TCPS_CLOSED, tp, (caddr_t)0, PRU_ATTACH, 0); + tcp_trace(TA_USER, TCPS_CLOSED, tp, tp, NULL, PRU_ATTACH, 0); return (0); } @@ -607,7 +610,7 @@ int tcp_detach(struct socket *so) { struct inpcb *inp; - struct tcpcb *tp = NULL; + struct tcpcb *otp = NULL, *tp = NULL; int error = 0; short ostate; @@ -629,7 +632,10 @@ tcp_detach(struct socket *so) /* tp might get 0 when using socket splicing */ if (tp == NULL) return (0); - ostate = tp->t_state; + if (so->so_options & SO_DEBUG) { + otp = tp; + ostate = tp->t_state; + } /* * Detach the TCP protocol from the socket. @@ -640,8 +646,8 @@ tcp_detach(struct socket *so) */ tp = tcp_disconnect(tp); - if (tp && (so->so_options & SO_DEBUG)) - tcp_trace(TA_USER, ostate, tp, (caddr_t)0, PRU_DETACH, 0); + if (otp) + tcp_trace(TA_USER, ostate, tp, otp, NULL, PRU_DETACH, 0); return (error); } Index: netinet/tcp_var.h =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_var.h,v retrieving revision 1.132 diff -u -p -r1.132 tcp_var.h --- netinet/tcp_var.h 8 May 2018 15:10:33 -0000 1.132 +++ netinet/tcp_var.h 6 Jun 2018 20:39:16 -0000 @@ -721,7 +721,8 @@ void tcp_update_rcvspace(struct tcpcb * void tcp_slowtimo(void); struct mbuf * tcp_template(struct tcpcb *); -void tcp_trace(short, short, struct tcpcb *, caddr_t, int, int); +void tcp_trace(short, short, struct tcpcb *, struct tcpcb *, caddr_t, + int, int); struct tcpcb * tcp_usrclosed(struct tcpcb *); int tcp_sysctl(int *, u_int, void *, size_t *, void *, size_t);