⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tp.trans

📁 早期freebsd实现
💻 TRANS
📖 第 1 页 / 共 3 页
字号:
		if ($P.tp_state == TP_OPEN)			tp_indicate(T_DISCONNECT, $P, 0);		else {			int so_error = ECONNREFUSED;			if ($$.e_reason != (E_TP_NO_SESSION ^ TP_ERROR_MASK) &&			    $$.e_reason != (E_TP_NO_CR_ON_NC ^ TP_ERROR_MASK) &&			    $$.e_reason != (E_TP_REF_OVERFLOW ^ TP_ERROR_MASK))				so_error = ECONNABORTED;			tp_indicate(T_DISCONNECT, $P, so_error);		}		tp_soisdisconnected($P);		if ($P.tp_class != TP_CLASS_0) {			if ($P.tp_state == TP_OPEN ) {				tp_euntimeout($P, TM_data_retrans); /* all */				tp_cuntimeout($P, TM_retrans);				tp_cuntimeout($P, TM_inact);				tp_cuntimeout($P, TM_sendack);				$P.tp_flags &= ~TPF_DELACK;			}			tp_cuntimeout($P, TM_retrans);			if( $$.e_sref !=  0 ) 				(void) tp_emit(DC_TPDU_type, $P, 0, 0, MNULL);		}	};SAME 			<==		TP_CLOSED 									DR_TPDU 	DEFAULT	{		if( $$.e_sref != 0 )			(void) tp_emit(DC_TPDU_type, $P, 0, 0, MNULL); 		/* reference timer already set - reset it to be safe (???) */		tp_euntimeout($P, TM_reference); /* all */		tp_etimeout($P, TM_reference, (int)$P.tp_refer_ticks);	};/* NBS(34) */TP_REFWAIT 		<==  	TP_CRSENT  									ER_TPDU	DEFAULT	{			tp_cuntimeout($P, TM_retrans);		tp_indicate(ER_TPDU, $P, $$.e_reason);		tp_soisdisconnected($P);	};/* NBS(27) */TP_REFWAIT		<==		TP_CLOSING									DR_TPDU	DEFAULT	{	 		tp_cuntimeout($P, TM_retrans);		tp_soisdisconnected($P);	};/* these two transitions are the same but can't be combined because xebec * can't handle the use of $$.e_reason if they're combined *//* NBS(27) */TP_REFWAIT		<==		TP_CLOSING									ER_TPDU	DEFAULT	{	 		tp_indicate(ER_TPDU, $P, $$.e_reason);		tp_cuntimeout($P, TM_retrans);		tp_soisdisconnected($P);	};/* NBS(27) */TP_REFWAIT		<==		TP_CLOSING									DC_TPDU 	DEFAULT	{	 		tp_cuntimeout($P, TM_retrans);		tp_soisdisconnected($P);	};/* NBS(21) */SAME 			<== 	TP_CLOSED 						[ CC_TPDU, CR_TPDU ]	DEFAULT	{	/* don't ask me why we have to do this - spec says so */		(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_NO_SESSION, MNULL);		/* don't bother with retransmissions of the DR */	};/* NBS(34) */TP_REFWAIT 		<== 	TP_OPEN  				 					ER_TPDU	($P.tp_class == TP_CLASS_0)	{		tp_soisdisconnecting($P.tp_sock);		tp_indicate(ER_TPDU, $P, $$.e_reason);		tp_soisdisconnected($P);		tp_netcmd( $P, CONN_CLOSE );	};TP_CLOSING 		<== 	[ TP_AKWAIT, TP_OPEN ]  					ER_TPDU	DEFAULT	{		if ($P.tp_state == TP_OPEN) {			tp_euntimeout($P, TM_data_retrans); /* all */			tp_cuntimeout($P, TM_inact);			tp_cuntimeout($P, TM_sendack);		}		tp_soisdisconnecting($P.tp_sock);		tp_indicate(ER_TPDU, $P, $$.e_reason);		$P.tp_retrans = $P.tp_Nretrans;		tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);		(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_PROTO_ERR, MNULL);	};/* NBS(6) */TP_OPEN			<==		TP_CRSENT									CC_TPDU 	($P.tp_class == TP_CLASS_0) 	{			tp_cuntimeout($P, TM_retrans);		IncStat(ts_tp0_conn);		$P.tp_fcredit = 1;		soisconnected($P.tp_sock);	};TP_OPEN			<==		TP_CRSENT									CC_TPDU 	DEFAULT	{			IFDEBUG(D_CONN)			printf("trans: CC_TPDU in CRSENT state flags 0x%x\n", 				(int)$P.tp_flags);		ENDDEBUG		IncStat(ts_tp4_conn);		$P.tp_fref = $$.e_sref;		$P.tp_fcredit = $$.e_cdt;		if (($P.tp_rx_strat & TPRX_FASTSTART) && ($$.e_cdt > 0))			$P.tp_cong_win = $$.e_cdt * $P.tp_l_tpdusize;		tp_getoptions($P);		tp_cuntimeout($P, TM_retrans);		if ($P.tp_ucddata) {			IFDEBUG(D_CONN)				printf("dropping user connect data cc 0x%x\n",					$P.tp_ucddata->m_len);			ENDDEBUG			m_freem($P.tp_ucddata);			$P.tp_ucddata = 0;		}		soisconnected($P.tp_sock);		if ($$.e_datalen > 0) {			ASSERT($P.tp_Xrcv.sb_cc == 0); /* should be empty */			sbappendrecord(&$P.tp_Xrcv, $$.e_data);			$$.e_data = MNULL;		}		(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL);		tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);	};/* TP4 only */SAME			<==		TP_CRSENT									TM_retrans 	(	$P.tp_retrans > 0 )	{		struct mbuf *data = MNULL;		int error;		IncStat(ts_retrans_cr);		$P.tp_cong_win = 1 * $P.tp_l_tpdusize;		data = MCPY($P.tp_ucddata, M_NOWAIT);		if($P.tp_ucddata) {			IFDEBUG(D_CONN)				printf("TM_retrans.trans m_copy cc 0x%x\n", data);				dump_mbuf($P.tp_ucddata, "sosnd @ TM_retrans");			ENDDEBUG			if( data == MNULL )				return ENOBUFS;		}		$P.tp_retrans --;		if( error = tp_emit(CR_TPDU_type, $P, 0, 0, data) ) {			$P.tp_sock->so_error = error;		}		tp_ctimeout($P, TM_retrans, (int)$P.tp_cr_ticks);	};/* TP4 only  */TP_REFWAIT		<==		TP_CRSENT									TM_retrans 	DEFAULT /* no more CR retransmissions */	{ 			IncStat(ts_conn_gaveup);		$P.tp_sock->so_error = ETIMEDOUT;		tp_indicate(T_DISCONNECT, $P, ETIMEDOUT);		tp_soisdisconnected($P);	};/* TP4 only */SAME 			<==	 TP_AKWAIT											CR_TPDU 	DEFAULT	/* duplicate CR (which doesn't really exist in the context of	 * a connectionless network layer) 	 * Doesn't occur in class 0.	 */	{			int error;		struct mbuf *data = MCPY($P.tp_ucddata, M_WAIT);		if( error = tp_emit(CC_TPDU_type, $P, 0, 0, data) ) {			$P.tp_sock->so_error = error;		}		$P.tp_retrans = $P.tp_Nretrans;		tp_ctimeout($P, TM_retrans, (int)$P.tp_cc_ticks);	};/* TP4 only */TP_OPEN			<==		TP_AKWAIT 										DT_TPDU 	( IN_RWINDOW( $P, $$.e_seq,					$P.tp_rcvnxt, SEQ($P, $P.tp_rcvnxt + $P.tp_lcredit)) )	{		int doack;		/*		 * Get rid of any confirm or connect data, so that if we		 * crash or close, it isn't thought of as disconnect data.		 */		if ($P.tp_ucddata) {			m_freem($P.tp_ucddata);			$P.tp_ucddata = 0;		}		tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);		tp_cuntimeout($P, TM_retrans);		soisconnected($P.tp_sock);		tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);		/* see also next 2 transitions, if you make any changes */		doack = tp_stash($P, $E);		IFDEBUG(D_DATA)			printf("tp_stash returns %d\n",doack);		ENDDEBUG		if (doack) {			(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL ); 			tp_ctimeout($P, TM_sendack, (int)$P.tp_keepalive_ticks);		} else			tp_ctimeout( $P, TM_sendack, (int)$P.tp_sendack_ticks);				IFDEBUG(D_DATA)			printf("after stash calling sbwakeup\n");		ENDDEBUG	};SAME			<==		TP_OPEN 									DT_TPDU 	( $P.tp_class == TP_CLASS_0 )	{		tp0_stash($P, $E);		sbwakeup( &$P.tp_sock->so_rcv );		IFDEBUG(D_DATA)			printf("after stash calling sbwakeup\n");		ENDDEBUG	};/* TP4 only */SAME			<==		TP_OPEN 									DT_TPDU 	( IN_RWINDOW( $P, $$.e_seq,					$P.tp_rcvnxt, SEQ($P, $P.tp_rcvnxt + $P.tp_lcredit)) )	{		int doack; /* tells if we must ack immediately */		tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);		sbwakeup( &$P.tp_sock->so_rcv );		doack = tp_stash($P, $E);		IFDEBUG(D_DATA)			printf("tp_stash returns %d\n",doack);		ENDDEBUG		if(doack)			(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL ); 		else			tp_ctimeout_MIN( $P, TM_sendack, (int)$P.tp_sendack_ticks);				IFDEBUG(D_DATA)			printf("after stash calling sbwakeup\n");		ENDDEBUG	};/* Not in window  - we must ack under certain circumstances, namely * a) if the seq number is below lwe but > lwe - (max credit ever given) * (to handle lost acks) Can use max-possible-credit for this ^^^. * and  * b) seq number is > uwe but < uwe + previously sent & withdrawn credit * * (see 12.2.3.8.1 of ISO spec, p. 73) * We just always ack. *//* TP4 only */SAME 			<== 	[ TP_OPEN, TP_AKWAIT ]							DT_TPDU	DEFAULT /* Not in window */	{ 			IFTRACE(D_DATA)			tptrace(TPPTmisc, "NIW seq rcvnxt lcredit ",				$$.e_seq, $P.tp_rcvnxt, $P.tp_lcredit, 0);		ENDTRACE		IncStat(ts_dt_niw);		m_freem($$.e_data);		tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);		(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL ); 	};/* TP4 only */TP_OPEN			<==		TP_AKWAIT										AK_TPDU	DEFAULT	{		if ($P.tp_ucddata) {			m_freem($P.tp_ucddata);			$P.tp_ucddata = 0;		}		(void) tp_goodack($P, $$.e_cdt, $$.e_seq, $$.e_subseq);		tp_cuntimeout($P, TM_retrans);		soisconnected($P.tp_sock);		IFTRACE(D_CONN)			struct socket *so = $P.tp_sock;			tptrace(TPPTmisc, 			"called sosiconn: so so_state rcv.sb_sel rcv.sb_flags",				so, so->so_state, so->so_rcv.sb_sel, so->so_rcv.sb_flags);			tptrace(TPPTmisc, 			"called sosiconn 2: so_qlen so_error so_rcv.sb_cc so_head",				so->so_qlen, so->so_error, so->so_rcv.sb_cc, so->so_head);		ENDTRACE		tp_ctimeout($P, TM_sendack, (int)$P.tp_keepalive_ticks);		tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);	};/* TP4 only */TP_OPEN 		<== 	[ TP_OPEN, TP_AKWAIT ]						XPD_TPDU	($P.tp_Xrcvnxt == $$.e_seq)	{		if( $P.tp_state == TP_AKWAIT ) {			if ($P.tp_ucddata) {				m_freem($P.tp_ucddata);				$P.tp_ucddata = 0;			}			tp_cuntimeout($P, TM_retrans);			soisconnected($P.tp_sock);			tp_ctimeout($P, TM_sendack, (int)$P.tp_keepalive_ticks);			tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);		} 		IFTRACE(D_XPD)		tptrace(TPPTmisc, "XPD tpdu accepted Xrcvnxt, e_seq datalen m_len\n",				$P.tp_Xrcvnxt,$$.e_seq,  $$.e_datalen, $$.e_data->m_len);		ENDTRACE		$P.tp_sock->so_state |= SS_RCVATMARK;		$$.e_data->m_flags |= M_EOR;		sbinsertoob(&$P.tp_Xrcv, $$.e_data);		IFDEBUG(D_XPD)			dump_mbuf($$.e_data, "XPD TPDU: tp_Xrcv");		ENDDEBUG		tp_indicate(T_XDATA, $P, 0);		sbwakeup( &$P.tp_Xrcv );		(void) tp_emit(XAK_TPDU_type, $P, $P.tp_Xrcvnxt, 0, MNULL);		SEQ_INC($P, $P.tp_Xrcvnxt);	};/* TP4 only */SAME			<==		TP_OPEN 									T_USR_Xrcvd	DEFAULT	{		if( $P.tp_Xrcv.sb_cc == 0 ) {			/* kludge for select(): */ 			/* $P.tp_sock->so_state &= ~SS_OOBAVAIL; */		}	}	/* OLD WAY:	 * Ack only after the user receives the XPD.  This is better for 	 * users that use one XPD right after another.	 * Acking right away (the NEW WAY, see the prev. transition) is 	 * better for occasional * XPD, when the receiving user doesn't 	 * want to read the XPD immediately (which is session's behavior).	 *		int error = tp_emit(XAK_TPDU_type, $P, $P.tp_Xrcvnxt, 0, MNULL);		SEQ_INC($P, $P.tp_Xrcvnxt);		return error;	*/;/* NOTE: presently if the user doesn't read the connection data * before and expedited data PDU comes in, the connection data will * be dropped. This is a bug.  To avoid it, we need somewhere else * to put the connection data. * On the other hand, we need not to have it sitting around forever. * This is a problem with the idea of trying to accommodate * data on connect w/ a passive-open user interface.  *//* TP4 only */SAME	 		<== 	[ TP_AKWAIT, TP_OPEN ] 							XPD_TPDU	DEFAULT /* not in window or cdt==0 */	{		IFTRACE(D_XPD)			tptrace(TPPTmisc, "XPD tpdu niw (Xrcvnxt, e_seq) or not cdt (cc)\n",				$P.tp_Xrcvnxt, $$.e_seq,  $P.tp_Xrcv.sb_cc , 0);		ENDTRACE		if( $P.tp_Xrcvnxt != $$.e_seq )			IncStat(ts_xpd_niw);		if( $P.tp_Xrcv.sb_cc ) {			/* might as well kick 'em again */			tp_indicate(T_XDATA, $P, 0);			IncStat(ts_xpd_dup);		}		m_freem($$.e_data);		tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);		/* don't send an xack because the xak gives "last one received", not		 * "next one i expect" (dumb)		 */	};/* Occurs (AKWAIT, OPEN) when parent (listening) socket gets aborted, and tries * to detach all its "children" * Also (CRSENT) when user kills a job that's doing a connect() */TP_REFWAIT		<== 	TP_CRSENT 										T_DETACH	($P.tp_class == TP_CLASS_0)	{		struct socket *so = $P.tp_sock;		/* detach from parent socket so it can finish closing */		if (so->so_head) {			if (!soqremque(so, 0) && !soqremque(so, 1))				panic("tp: T_DETACH");			so->so_head = 0;		}		tp_soisdisconnecting($P.tp_sock);		tp_netcmd( $P, CONN_CLOSE);		tp_soisdisconnected($P);	};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -