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

📄 tp.trans

📁 早期freebsd实现
💻 TRANS
📖 第 1 页 / 共 3 页
字号:
/* TP4 only */TP_CLOSING		<== [ TP_CLOSING, TP_AKWAIT, TP_CRSENT, TP_CONFIRMING ]	T_DETACH	DEFAULT	{		struct socket *so = $P.tp_sock;		struct mbuf *data = MNULL;		/* 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;		}		if ($P.tp_state != TP_CLOSING) {			tp_soisdisconnecting($P.tp_sock);			data = MCPY($P.tp_ucddata, M_NOWAIT);			(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_NORMAL_DISC, data);			$P.tp_retrans = $P.tp_Nretrans;			tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);		}	};TP_REFWAIT		<==		[ TP_OPEN, TP_CRSENT ]		 	  			T_DISC_req	( $P.tp_class == TP_CLASS_0 )	{		tp_soisdisconnecting($P.tp_sock);		tp_netcmd( $P, CONN_CLOSE);		tp_soisdisconnected($P);	};/* TP4 only */TP_CLOSING		<==	[ TP_AKWAIT, TP_OPEN, TP_CRSENT, TP_CONFIRMING ]  T_DISC_req	DEFAULT	{		struct mbuf *data = MCPY($P.tp_ucddata, M_WAIT);		if($P.tp_state == TP_OPEN) {			tp_euntimeout($P, TM_data_retrans); /* all */			tp_cuntimeout($P, TM_inact);			tp_cuntimeout($P, TM_sendack);			$P.tp_flags &= ~TPF_DELACK;		}		if (data) {			IFDEBUG(D_CONN)				printf("T_DISC_req.trans tp_ucddata 0x%x\n", 					$P.tp_ucddata);				dump_mbuf(data, "ucddata @ T_DISC_req");			ENDDEBUG		}		tp_soisdisconnecting($P.tp_sock);		$P.tp_retrans = $P.tp_Nretrans;		tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);		if( trick_hc )			return tp_emit(DR_TPDU_type, $P, 0, $$.e_reason, data);	};/* TP4 only */SAME			<==		TP_AKWAIT									TM_retrans	( $P.tp_retrans > 0 )	{		int error;		struct mbuf *data = MCPY($P.tp_ucddata, M_WAIT);		IncStat(ts_retrans_cc);		$P.tp_retrans --;		$P.tp_cong_win = 1 * $P.tp_l_tpdusize;		if( error = tp_emit(CC_TPDU_type, $P, 0, 0, data) ) 			$P.tp_sock->so_error = error;		tp_ctimeout($P, TM_retrans, (int)$P.tp_cc_ticks);	};/* TP4 only */TP_CLOSING		<==		TP_AKWAIT									TM_retrans	DEFAULT  /* out of time */	{		IncStat(ts_conn_gaveup);		tp_soisdisconnecting($P.tp_sock);		$P.tp_sock->so_error = ETIMEDOUT;		tp_indicate(T_DISCONNECT, $P, ETIMEDOUT);		(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_CONGEST, MNULL);		$P.tp_retrans = $P.tp_Nretrans;		tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);	};/* the retrans timers had better go off BEFORE the inactivity timer does, * if transmissions are going on. * (i.e., TM_inact should be greater than timer for all retrans plus ack * turnaround) *//* TP4 only */TP_CLOSING 		<==		TP_OPEN		   [ TM_inact, TM_retrans, TM_data_retrans ]	DEFAULT	{		tp_euntimeout($P, TM_data_retrans); /* all */		tp_cuntimeout($P, TM_inact); 		tp_cuntimeout($P, TM_sendack);		IncStat(ts_conn_gaveup);		tp_soisdisconnecting($P.tp_sock);		$P.tp_sock->so_error = ETIMEDOUT;		tp_indicate(T_DISCONNECT, $P, ETIMEDOUT);		(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_CONGEST_2, MNULL);		$P.tp_retrans = $P.tp_Nretrans;		tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);	};/* TP4 only */SAME			<==		TP_OPEN										TM_retrans	( $P.tp_retrans > 0 )	{		$P.tp_cong_win = 1 * $P.tp_l_tpdusize;		/* resume XPD */		if	( $P.tp_Xsnd.sb_mb )  {			struct mbuf *m = m_copy($P.tp_Xsnd.sb_mb, 0, (int)$P.tp_Xsnd.sb_cc);			int shift;			IFTRACE(D_XPD)				tptrace(TPPTmisc, "XPD retrans: Xuna Xsndnxt sndnxt snduna",					$P.tp_Xuna, $P.tp_Xsndnxt, $P.tp_sndnxt, 					$P.tp_snduna); 			ENDTRACE			IFDEBUG(D_XPD)				dump_mbuf(m, "XPD retrans emitting M");			ENDDEBUG			IncStat(ts_retrans_xpd);			$P.tp_retrans --;			shift = max($P.tp_Nretrans - $P.tp_retrans, 6);			(void) tp_emit(XPD_TPDU_type, $P, $P.tp_Xuna, 1, m);			tp_ctimeout($P, TM_retrans, ((int)$P.tp_dt_ticks) << shift);		}	};/* TP4 only */SAME 			<==		TP_OPEN									TM_data_retrans	($P.tp_rxtshift < TP_NRETRANS)	{			$P.tp_rxtshift++;		(void) tp_data_retrans($P);	};/* TP4 only */SAME	 		<==		TP_CLOSING									TM_retrans	(	$P.tp_retrans > 0 )	{			$P.tp_retrans --;		(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_DR_NO_REAS, MNULL);		IncStat(ts_retrans_dr);		tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);	};/* TP4 only */TP_REFWAIT 		<==		TP_CLOSING									TM_retrans	DEFAULT	/* no more retrans - gave up */	{			$P.tp_sock->so_error = ETIMEDOUT;		$P.tp_refstate = REF_FROZEN;		tp_recycle_tsuffix( $P );		tp_etimeout($P, TM_reference, (int)$P.tp_refer_ticks);	};/* * The resources are kept around until the ref timer goes off. * The suffices are wiped out sooner so they can be reused right away. *//* applicable in TP4, TP0 */TP_CLOSED 		<==		TP_REFWAIT 									TM_reference	DEFAULT	{		tp_freeref($P.tp_lref);		tp_detach($P);	};/* applicable in TP4, TP0 *//* A duplicate CR from connectionless network layer can't happen */SAME 			<== 	TP_OPEN 							[ CR_TPDU, CC_TPDU ]	DEFAULT	{			if( $P.tp_class != TP_CLASS_0) {			tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);			if ( $E.ev_number == CC_TPDU )				(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL); 		}		/* ignore it if class 0 - state tables are blank for this */	};/* applicable in TP4, TP0 */SAME			<== 	TP_OPEN									T_DATA_req	DEFAULT	{		IFTRACE(D_DATA)			tptrace(TPPTmisc, "T_DATA_req sndnxt snduna fcredit, tpcb",				$P.tp_sndnxt, $P.tp_snduna, $P.tp_fcredit, $P);		ENDTRACE		tp_send($P);	};/* TP4 only */SAME			<==		TP_OPEN										T_XPD_req	DEFAULT		/* T_XPD_req was issued by sosend iff xpd socket buf was empty		 * at time of sosend(), 		 * AND (which means) there were no unacknowledged XPD tpdus outstanding!		 */	{		int error = 0;		/* resume XPD */		if	( $P.tp_Xsnd.sb_mb )  {			struct mbuf *m = m_copy($P.tp_Xsnd.sb_mb, 0, (int)$P.tp_Xsnd.sb_cc);			/* m_copy doesn't preserve the m_xlink field, but at this pt.			 * that doesn't matter			 */			IFTRACE(D_XPD)				tptrace(TPPTmisc, "XPD req: Xuna Xsndnxt sndnxt snduna",					$P.tp_Xuna, $P.tp_Xsndnxt, $P.tp_sndnxt, 					$P.tp_snduna); 			ENDTRACE			IFDEBUG(D_XPD)				printf("T_XPD_req: sb_cc 0x%x\n", $P.tp_Xsnd.sb_cc);				dump_mbuf(m, "XPD req emitting M");			ENDDEBUG			error = 				tp_emit(XPD_TPDU_type, $P, $P.tp_Xuna, 1, m);			$P.tp_retrans = $P.tp_Nretrans;			tp_ctimeout($P, TM_retrans, (int)$P.tp_rxtcur);			SEQ_INC($P, $P.tp_Xsndnxt);		} 		if(trick_hc)			return error;	};/* TP4, faked ack in TP0 when cons send completes */SAME 			<==		TP_OPEN 									AK_TPDU	( tp_goodack($P, $$.e_cdt, $$.e_seq, $$.e_subseq)  )	/* tp_goodack == true means 	 * EITHER it actually acked something heretofore unacknowledged	 * OR no news but the credit should be processed.	 */	{		struct sockbuf *sb = &$P.tp_sock->so_snd;		IFDEBUG(D_ACKRECV)			printf("GOOD ACK seq 0x%x cdt 0x%x\n", $$.e_seq, $$.e_cdt);		ENDDEBUG		if( $P.tp_class != TP_CLASS_0) {			tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);		}		sbwakeup(sb);		IFDEBUG(D_ACKRECV)			printf("GOOD ACK new sndnxt 0x%x\n", $P.tp_sndnxt);		ENDDEBUG	};/* TP4, and TP0 after sending a CC or possibly a CR */SAME			<==		TP_OPEN 			 						 AK_TPDU	DEFAULT	{		IFTRACE(D_ACKRECV)			tptrace(TPPTmisc, "BOGUS ACK fcc_present, tp_r_subseq e_subseq", 				$$.e_fcc_present, $P.tp_r_subseq, $$.e_subseq, 0);		ENDTRACE		if( $P.tp_class != TP_CLASS_0 ) {			if ( !$$.e_fcc_present ) {				/* send ACK with FCC */				IncStat( ts_ackreason[_ACK_FCC_] );				(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 1, MNULL);			}			tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);		} 	};/* NBS(47) */	/* goes in at *** */		/* just so happens that this is never true now, because we allow		 * only 1 packet in the queue at once (this could be changed)		if	( $P.tp_Xsnd.sb_mb )  {			struct mbuf *m = m_copy($P.tp_Xsnd.sb_mb, 0, ??);			(void) tp_emit(XPD_TPDU_type, $P, $P.tp_Xuna, 1, m);			$P.tp_retrans = $P.tp_Nretrans;			tp_ctimeout($P, TM_retrans, (int)$P.tp_xpd_ticks);			SEQ_INC($P, $P.tp_Xsndnxt);		}		 */	/* end of the above hack *//* TP4 only */SAME			<== 	TP_OPEN										XAK_TPDU	( tp_goodXack($P, $$.e_seq) )	/* tp_goodXack checks for good ack, removes the correct 	 * tpdu from the queue and  returns 1 if ack was legit, 0 if not.	 * also updates tp_Xuna	 */	{			tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);		tp_cuntimeout($P, TM_retrans);		sbwakeup( &$P.tp_sock->so_snd );		/* resume normal data */		tp_send($P);	};/* TP4, and TP0 after sending a CC or possibly a CR */SAME			<==		TP_OPEN 			 						XAK_TPDU	DEFAULT	{		IFTRACE(D_ACKRECV)			tptrace(TPPTmisc, "BOGUS XACK eventtype ", $E.ev_number, 0, 0,0);		ENDTRACE		if( $P.tp_class != TP_CLASS_0 ) {			tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);		} 	};/* TP4 only */SAME			<==		TP_OPEN 								TM_sendack 	DEFAULT	{			int timo;		IFTRACE(D_TIMER)			tptrace(TPPTsendack, -1, $P.tp_lcredit, $P.tp_sent_uwe, 			$P.tp_sent_lcdt, 0);		ENDTRACE		IncPStat($P, tps_n_TMsendack);		(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL);		if ($P.tp_fcredit == 0) {			if ($P.tp_rxtshift < TP_MAXRXTSHIFT)				$P.tp_rxtshift++;			timo = ($P.tp_dt_ticks) << $P.tp_rxtshift;		} else			timo = $P.tp_sendack_ticks;		tp_ctimeout($P, TM_sendack, timo);	};/* TP0 only */SAME			<==		TP_OPEN 									T_USR_rcvd	($P.tp_class == TP_CLASS_0)	{		if (sbspace(&$P.tp_sock->so_rcv) > 0)			tp0_openflow($P);	};/* TP4 only */		/* If old credit was zero, 		 * we'd better inform other side that we now have space		 * But this is not enough.  Sender might not yet have		 * seen an ack with cdt 0 but it might still think the		 * window is closed, so it's going to wait.		 * Best to send an ack each time.		 * Strictly speaking, this ought to be a function of the		 * general ack strategy.		 */SAME			<==		TP_OPEN 									T_USR_rcvd	DEFAULT	{			if( trick_hc ) {			SeqNum ack_thresh;			/*			 * If the upper window edge has advanced a reasonable			 * amount beyond what was known, send an ACK.			 * A reasonable amount is 2 packets, unless the max window			 * is only 1 or 2 packets, in which case we			 * should send an ack for any advance in the upper window edge.			 */			LOCAL_CREDIT($P);			ack_thresh = SEQ_SUB($P, $P.tp_lcredit + $P.tp_rcvnxt,									 ($P.tp_maxlcredit > 2 ? 2 : 1));			if (SEQ_GT($P, ack_thresh, $P.tp_sent_uwe)) {				IncStat(ts_ackreason[_ACK_USRRCV_]);				$P.tp_flags &= ~TPF_DELACK;				return tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL);			}		}	};/* applicable in TP4, TP0 */SAME			<==		TP_REFWAIT 				[ T_USR_rcvd, T_USR_Xrcvd ]	DEFAULT	/* This happens if other end sent a DR when  the user was waiting 	 * on a receive.  	 * Processing the DR includes putting us in REFWAIT state.	 */	{		if(trick_hc)		return ECONNABORTED;	};/* TP0 only */TP_REFWAIT		<==		[ TP_OPEN, TP_CRSENT, TP_LISTENING ] 	T_NETRESET	( $P.tp_class != TP_CLASS_4 ) 		/* 0 or (4 and 0) */		/* in OPEN class will be 0 or 4 but not both */		/* in CRSENT or LISTENING it could be in negotiation, hence both */		/* Actually, this shouldn't ever happen in LISTENING */	{		ASSERT( $P.tp_state != TP_LISTENING );		tp_indicate(T_DISCONNECT, $P, ECONNRESET);		tp_soisdisconnected($P);	};/* TP4: ignore resets */SAME		<==		[ TP_OPEN, TP_CRSENT, TP_AKWAIT,						TP_CLOSING, TP_LISTENING ] 				T_NETRESET	DEFAULT	NULLACTION; /* applicable in TP4, TP0 */SAME			<==		[ TP_CLOSED, TP_REFWAIT ]				T_NETRESET	DEFAULT	NULLACTION;/* C'EST TOUT */

⌨️ 快捷键说明

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