+ if (tp->t_state < TCPS_ESTABLISHED)
+ goto dropit;
+ if (tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE) {
+ if (tp->t_idle >= TCPTV_MAXIDLE)
+ goto dropit;
+ /*
+ * Saying tp->rcv_nxt-1 lies about what
+ * we have received, and by the protocol spec
+ * requires the correspondent TCP to respond.
+ * Saying tp->snd_una-1 causes the transmitted
+ * byte to lie outside the receive window; this
+ * is important because we don't necessarily
+ * have a byte in the window to send (consider
+ * a one-way stream!)
+ */
+ tcp_respond(tp,
+ tp->t_template, tp->rcv_nxt-1, tp->snd_una-1, 0);
+ } else
+ tp->t_idle = 0;
+ tp->t_timer[TCPT_KEEP] = TCPTV_KEEP;
+ break;
+ dropit:
+ tp = tcp_drop(tp, ETIMEDOUT);
+ break;