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

📄 tp_driver.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		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);	}		 break;case 0x1f: 		{		if( p->tp_Xrcv.sb_cc == 0 ) {			/* kludge for select(): */ 			/* p->tp_sock->so_state &= ~SS_OOBAVAIL; */		}	}		 break;case 0x20: 		{		IFTRACE(D_XPD)			tptrace(TPPTmisc, "XPD tpdu niw (Xrcvnxt, e_seq) or not cdt (cc)\n",				p->tp_Xrcvnxt, e->ev_union.EV_XPD_TPDU.e_seq,  p->tp_Xrcv.sb_cc , 0);		ENDTRACE		if( p->tp_Xrcvnxt != e->ev_union.EV_XPD_TPDU.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->ev_union.EV_XPD_TPDU.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)		 */	}		 break;case 0x21: 		{		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);	}		 break;case 0x22: 		{		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);		}	}		 break;case 0x23: 		{		tp_soisdisconnecting(p->tp_sock);		tp_netcmd( p, CONN_CLOSE);		tp_soisdisconnected(p);	}		 break;case 0x24: 		{		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->ev_union.EV_T_DISC_req.e_reason, data);	}		 break;case 0x25: 		{		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);	}		 break;case 0x26: 		{		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);	}		 break;case 0x27: 		{		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);	}		 break;case 0x28: 		{		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);		}	}		 break;case 0x29: 		{			p->tp_rxtshift++;		(void) tp_data_retrans(p);	}		 break;case 0x2a: 		{			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);	}		 break;case 0x2b: 		{			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);	}		 break;case 0x2c: 		{		tp_freeref(p->tp_lref);		tp_detach(p);	}		 break;case 0x2d: 		{			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 */	}		 break;case 0x2e: 		{		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);	}		 break;case 0x2f: 		{		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;	}		 break;case 0x30: 		{		struct sockbuf *sb = &p->tp_sock->so_snd;		IFDEBUG(D_ACKRECV)			printf("GOOD ACK seq 0x%x cdt 0x%x\n", e->ev_union.EV_AK_TPDU.e_seq, e->ev_union.EV_AK_TPDU.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	}		 break;case 0x31: 		{		IFTRACE(D_ACKRECV)			tptrace(TPPTmisc, "BOGUS ACK fcc_present, tp_r_subseq e_subseq", 				e->ev_union.EV_AK_TPDU.e_fcc_present, p->tp_r_subseq, e->ev_union.EV_AK_TPDU.e_subseq, 0);		ENDTRACE		if( p->tp_class != TP_CLASS_0 ) {			if ( !e->ev_union.EV_AK_TPDU.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);		} 	}		 break;case 0x32: 		{			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);	}		 break;case 0x33: 		{		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);		} 	}		 break;case 0x34: 		{			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);	}		 break;case 0x35: 		{		if (sbspace(&p->tp_sock->so_rcv) > 0)			tp0_openflow(p);	}		 break;case 0x36: 		{			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);			}		}	}		 break;case 0x37: 		{		if(trick_hc)		return ECONNABORTED;	}		 break;case 0x38: 		{		ASSERT( p->tp_state != TP_LISTENING );		tp_indicate(T_DISCONNECT, p, ECONNRESET);		tp_soisdisconnected(p);	}		 break;	}return 0;}_XEBEC_PG int_Xebec_index( e,p )	struct tp_event *e;	tp_PCB_ *p;{switch( (e->ev_number<<4)+(p->tp_state) ) {case 0x12:	if (	p->tp_retrans > 0 ) return 0x1e;	 else return 0x1f;case 0x13:	if ( p->tp_retrans > 0 ) return 0x2f;	 else return 0x30;case 0x14:	if ( p->tp_retrans > 0 ) return 0x32;	 else return 0x31;case 0x15:	if (	p->tp_retrans > 0 ) return 0x34;	 else return 0x35;case 0x54:	if (p->tp_rxtshift < TP_NRETRANS) return 0x33;	 else return 0x31;case 0x64:	if (p->tp_class == TP_CLASS_0) return 0x1a;	 else return 0x1b;case 0x77:	if ( p->tp_class == TP_CLASS_0) return 0xd;	 else return 0xe;case 0x86:	if ( e->ev_union.EV_DR_TPDU.e_sref !=  0 ) return 0x2;	 else return 0x3;case 0xa2:	if (p->tp_class == TP_CLASS_0) return 0x1c;	 else return 0x1d;case 0xb2:	if (p->tp_class == TP_CLASS_0) return 0x5;	 else return 0x0;case 0xb4:	if ( tp_goodack(p, e->ev_union.EV_AK_TPDU.e_cdt, e->ev_union.EV_AK_TPDU.e_seq, e->ev_union.EV_AK_TPDU.e_subseq)  ) return 0x3a;	 else return 0x3b;case 0xc3:	if ( IN_RWINDOW( p, e->ev_union.EV_DT_TPDU.e_seq,					p->tp_rcvnxt, SEQ(p, p->tp_rcvnxt + p->tp_lcredit)) ) return 0x21;	 else return 0x24;case 0xc4:	if ( p->tp_class == TP_CLASS_0 ) return 0x22;	 else if ( IN_RWINDOW( p, e->ev_union.EV_DT_TPDU.e_seq,					p->tp_rcvnxt, SEQ(p, p->tp_rcvnxt + p->tp_lcredit)) ) return 0x23;	 else return 0x25;case 0xd3:	if (p->tp_Xrcvnxt == e->ev_union.EV_XPD_TPDU.e_seq) return 0x27;	 else return 0x2a;case 0xd4:	if (p->tp_Xrcvnxt == e->ev_union.EV_XPD_TPDU.e_seq) return 0x27;	 else return 0x29;case 0xe4:	if ( tp_goodXack(p, e->ev_union.EV_XAK_TPDU.e_seq) ) return 0x3c;	 else return 0x3d;case 0x102:	if ( p->tp_class == TP_CLASS_0 ) return 0x2d;	 else return 0x2e;case 0x104:	if ( p->tp_class == TP_CLASS_0 ) return 0x2d;	 else return 0x2e;case 0x144:	if (p->tp_class == TP_CLASS_0) return 0x3f;	 else return 0x40;case 0x162:	if (p->tp_class == TP_CLASS_0) return 0x2b;	 else return 0x2c;case 0x172:	if ( p->tp_class != TP_CLASS_4 ) return 0x42;	 else return 0x46;case 0x174:	if ( p->tp_class != TP_CLASS_4 ) return 0x42;	 else return 0x47;case 0x177:	if ( p->tp_class != TP_CLASS_4 ) return 0x42;	 else return 0x43;case 0x188:	if ( p->tp_class == TP_CLASS_0 ) return 0xf;	 else if (tp_emit(CC_TPDU_type, p, 0,0, MCPY(p->tp_ucddata, M_NOWAIT)) == 0) return 0x10;	 else return 0x11;default: return 0;} /* end switch */} /* _Xebec_index() */static int inx[26][9] = { {0,0,0,0,0,0,0,0,0,}, {0x0,0x0,0x0,0x0,0x31,0x0,0x0,0x0,0x0, }, {0x0,0x0,-1,-1,-1,-1,0x0,0x0,0x0, }, {0x0,0x0,0x0,0x0,0x3e,0x0,0x0,0x0,0x0, }, {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, }, {0x0,0x0,0x0,0x0,0x0,0x0,0x36,0x0,0x0, }, {0x0,0x0,0x0,0x0,-1,0x0,0x0,0x0,0x0, }, {0x0,0x7,0x15,0x1b,-1,0x17,0x3,0xa,0x0, }, {0x0,0x19,0x6,0x20,0x37,0x8,0x3,-1,0x0, }, {0x0,0x14,0x13,0x13,0x13,0x16,-1,0xa,0x0, }, {0x0,0x7,0x6,0x1,0x9,0x18,0x3,0xa,0x0, }, {0x0,0x19,-1,0x1,0x37,0x8,0x3,0xa,0x0, }, {0x0,0x7,-1,0x26,-1,0x8,0x3,0xa,0x0, }, {0x0,0x7,0x6,-1,-1,0x8,0x3,0xa,0x0, }, {0x0,0x7,0x6,-1,-1,0x8,0x3,0xa,0x0, }, {0x0,0x7,0x6,0x1,-1,0x8,0x3,0xa,0x0, }, {0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x0,0x0, }, {0x0,0x0,-1,0x2e,-1,0x0,0x4,0x0,0x2e, }, {0x0,0xb,0x0,0x0,0x0,0x0,0x0,0x0,0x0, }, {0x0,0x0,0x0,0x0,0x38,0x0,0x0,0x0,0x0, }, {0x0,0x0,0x0,0x0,0x39,0x0,0x0,0x0,0x0, }, {0x0,0x0,0x0,0x0,-1,0x0,0x41,0x0,0x0, }, {0x0,0x0,0x0,0x0,0x28,0x0,0x41,0x0,0x0, }, {0x0,0xc,-1,0x2c,0x0,0x2c,0x4,0xc,0x2c, }, {0x0,0x49,-1,0x45,-1,0x44,0x48,-1,0x0, }, {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,-1, },};tp_driver(p, e)register tp_PCB_ *p;register struct tp_event *e;{	register int index, error=0;	struct act_ent *a;	static struct act_ent erroraction = {0,-1};	index = inx[1 + e->ev_number][p->tp_state];	if(index<0) index=_Xebec_index(e, p);	if (index==0) {		a = &erroraction;	} else		a = &statetable[index];	if(a->a_action)		error = _Xebec_action( a->a_action, e, p );	IFTRACE(D_DRIVER)	tptrace(DRIVERTRACE,		a->a_newstate, p->tp_state, e->ev_number, a->a_action, 0);	ENDTRACE	if(error==0)	p->tp_state = a->a_newstate;	return error;}

⌨️ 快捷键说明

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