Пример #1
0
/*
 * Tcp protocol timeout routine called every 500 ms.
 * Updates timestamps used for TCP
 * causes finite state machine actions if timers expire.
 */
void
tcp_slowtimo(void)
{
	VNET_ITERATOR_DECL(vnet_iter);

	VNET_LIST_RLOCK_NOSLEEP();
	VNET_FOREACH(vnet_iter) {
		CURVNET_SET(vnet_iter);
		(void) tcp_tw_2msl_scan(0);
		CURVNET_RESTORE();
	}
	VNET_LIST_RUNLOCK_NOSLEEP();
}
Пример #2
0
/*
 * Tcp protocol timeout routine called every 500 ms.
 * Updates timestamps used for TCP
 * causes finite state machine actions if timers expire.
 */
void
tcp_slowtimo(void)
{
	VNET_ITERATOR_DECL(vnet_iter);

	VNET_LIST_RLOCK_NOSLEEP();
	VNET_FOREACH(vnet_iter) {
		CURVNET_SET(vnet_iter);
		tcp_maxidle = tcp_keepcnt * tcp_keepintvl;
		INP_INFO_WLOCK(&V_tcbinfo);
		(void) tcp_tw_2msl_scan(0);
		INP_INFO_WUNLOCK(&V_tcbinfo);
		CURVNET_RESTORE();
	}
	VNET_LIST_RUNLOCK_NOSLEEP();
}
Пример #3
0
/*
 * Move a TCP connection into TIME_WAIT state.
 *    tcbinfo is locked.
 *    inp is locked, and is unlocked before returning.
 */
void
tcp_twstart(struct tcpcb *tp)
{
    struct tcptw *tw;
    struct inpcb *inp = tp->t_inpcb;
    int acknow;
    struct socket *so;
#ifdef INET6
//ScenSim-Port//    int isipv6 = inp->inp_inc.inc_flags & INC_ISIPV6;
#endif

//ScenSim-Port//    INP_INFO_WLOCK_ASSERT(&V_tcbinfo);  /* tcp_tw_2msl_reset(). */
//ScenSim-Port//    INP_WLOCK_ASSERT(inp);

//ScenSim-Port//    if (V_nolocaltimewait) {
//ScenSim-Port//        int error = 0;
//ScenSim-Port//#ifdef INET6
//ScenSim-Port//        if (isipv6)
//ScenSim-Port//            error = in6_localaddr(&inp->in6p_faddr);
//ScenSim-Port//#endif
//ScenSim-Port//#if defined(INET6) && defined(INET)
//ScenSim-Port//        else
//ScenSim-Port//#endif
//ScenSim-Port//#ifdef INET
//ScenSim-Port//            error = in_localip(inp->inp_faddr);
//ScenSim-Port//#endif
//ScenSim-Port//        if (error) {
//ScenSim-Port//            tp = tcp_close(tp);
//ScenSim-Port//            if (tp != NULL)
//ScenSim-Port//                INP_WUNLOCK(inp);
//ScenSim-Port//            return;
//ScenSim-Port//        }
//ScenSim-Port//    }

//ScenSim-Port//    tw = uma_zalloc(V_tcptw_zone, M_NOWAIT);
    tw = (struct tcptw *)uma_zalloc(V_tcptw_zone, M_NOWAIT);    //ScenSim-Port//
    if (tw == NULL) {
        tw = tcp_tw_2msl_scan(1);
        if (tw == NULL) {
            tp = tcp_close(tp);
//ScenSim-Port//            if (tp != NULL)
//ScenSim-Port//                INP_WUNLOCK(inp);
            return;
        }
    }
    tw->tw_inpcb = inp;

    /*
     * Recover last window size sent.
     */
//ScenSim-Port//    KASSERT(SEQ_GEQ(tp->rcv_adv, tp->rcv_nxt),
//ScenSim-Port//        ("tcp_twstart negative window: tp %p rcv_nxt %u rcv_adv %u", tp,
//ScenSim-Port//        tp->rcv_nxt, tp->rcv_adv));
    tw->last_win = (tp->rcv_adv - tp->rcv_nxt) >> tp->rcv_scale;

    /*
     * Set t_recent if timestamps are used on the connection.
     */
    if ((tp->t_flags & (TF_REQ_TSTMP|TF_RCVD_TSTMP|TF_NOOPT)) ==
        (TF_REQ_TSTMP|TF_RCVD_TSTMP)) {
        tw->t_recent = tp->ts_recent;
        tw->ts_offset = tp->ts_offset;
    } else {
        tw->t_recent = 0;
        tw->ts_offset = 0;
    }

    tw->snd_nxt = tp->snd_nxt;
    tw->rcv_nxt = tp->rcv_nxt;
    tw->iss     = tp->iss;
    tw->irs     = tp->irs;
    tw->t_starttime = tp->t_starttime;
    tw->tw_time = 0;

/* XXX
 * If this code will
 * be used for fin-wait-2 state also, then we may need
 * a ts_recent from the last segment.
 */
    acknow = tp->t_flags & TF_ACKNOW;

    /*
     * First, discard tcpcb state, which includes stopping its timers and
     * freeing it.  tcp_discardcb() used to also release the inpcb, but
     * that work is now done in the caller.
     *
     * Note: soisdisconnected() call used to be made in tcp_discardcb(),
     * and might not be needed here any longer.
     */
    tcp_discardcb(tp);
    so = inp->inp_socket;
    soisdisconnected(so);
//ScenSim-Port//    tw->tw_cred = crhold(so->so_cred);
//ScenSim-Port//    SOCK_LOCK(so);
    tw->tw_so_options = so->so_options;
//ScenSim-Port//    SOCK_UNLOCK(so);
    if (acknow)
        tcp_twrespond(tw, TH_ACK);
    inp->inp_ppcb = tw;
    inp->inp_flags |= INP_TIMEWAIT;
    tcp_tw_2msl_reset(tw, 0);

    /*
     * If the inpcb owns the sole reference to the socket, then we can
     * detach and free the socket as it is not needed in time wait.
     */
    if (inp->inp_flags & INP_SOCKREF) {
//ScenSim-Port//        KASSERT(so->so_state & SS_PROTOREF,
//ScenSim-Port//            ("tcp_twstart: !SS_PROTOREF"));
        inp->inp_flags &= ~INP_SOCKREF;
//ScenSim-Port//        INP_WUNLOCK(inp);
//ScenSim-Port//        ACCEPT_LOCK();
//ScenSim-Port//        SOCK_LOCK(so);
        so->so_state &= ~SS_PROTOREF;
        sofree(so);
    } else
//ScenSim-Port//        INP_WUNLOCK(inp);
    ;                                                           //ScenSim-Port//
}