diff options
Diffstat (limited to 'sys/netiso/tp_driver.c')
-rw-r--r-- | sys/netiso/tp_driver.c | 997 |
1 files changed, 0 insertions, 997 deletions
diff --git a/sys/netiso/tp_driver.c b/sys/netiso/tp_driver.c deleted file mode 100644 index 5c42447896a2e..0000000000000 --- a/sys/netiso/tp_driver.c +++ /dev/null @@ -1,997 +0,0 @@ -/* - * $Id: tp_driver.c,v 1.2 1994/08/02 07:50:59 davidg Exp $ - */ -#define _XEBEC_PG static - -#include "tp_states.h" - -static struct act_ent { - int a_newstate; - int a_action; -} statetable[] = { {0,0}, -#include "tp_states.init" -}; - -/* @(#)tp.trans 8.1 (Berkeley) 6/10/93 */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/protosw.h> -#include <sys/mbuf.h> -#include <sys/time.h> -#include <sys/errno.h> - -#include <netiso/tp_param.h> -#include <netiso/tp_stat.h> -#include <netiso/tp_pcb.h> -#include <netiso/tp_tpdu.h> -#include <netiso/argo_debug.h> -#include <netiso/tp_trace.h> -#include <netiso/iso_errno.h> -#include <netiso/tp_seq.h> -#include <netiso/cons.h> - -#define DRIVERTRACE TPPTdriver -#define sbwakeup(sb) sowakeup(p->tp_sock, sb); -#define MCPY(d, w) (d ? m_copym(d, 0, (int)M_COPYALL, w): 0) - -static trick_hc = 1; - -int tp_emit(), - tp_goodack(), tp_goodXack(), - tp_stash() -; -void tp_indicate(), tp_getoptions(), - tp_soisdisconnecting(), tp_soisdisconnected(), - tp_recycle_tsuffix(), -#ifdef TP_DEBUG_TIMERS - tp_etimeout(), tp_euntimeout(), - tp_ctimeout(), tp_cuntimeout(), - tp_ctimeout_MIN(), -#endif - tp_freeref(), tp_detach(), - tp0_stash(), tp0_send(), - tp_netcmd(), tp_send() -; - -typedef struct tp_pcb tpcb_struct; - - - -typedef tpcb_struct tp_PCB_; - -#include "tp_events.h" - -_XEBEC_PG int _Xebec_action(a,e,p) -int a; -struct tp_event *e; -tp_PCB_ *p; -{ -switch(a) { -case -1: return tp_protocol_error(e,p); -case 0x1: - { - (void) tp_emit(DC_TPDU_type, p, 0, 0, MNULL); - } - break; -case 0x2: - { -# ifdef TP_DEBUG - if( e->ev_number != AK_TPDU ) - printf("TPDU 0x%x in REFWAIT!!!!\n", e->ev_number); -# endif TP_DEBUG - } - break; -case 0x3: - { - /* oh, man is this grotesque or what? */ - (void) 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); - /* but it's necessary because this pseudo-ack may happen - * before the CC arrives, but we HAVE to adjust the - * snduna as a result of the ack, WHENEVER it arrives - */ - } - break; -case 0x4: - { - tp_detach(p); - } - break; -case 0x5: - { - p->tp_refstate = REF_OPEN; /* has timers ??? */ - } - break; -case 0x6: - { - IFTRACE(D_CONN) - tptrace(TPPTmisc, "CR datalen data", e->ev_union.EV_CR_TPDU.e_datalen, e->ev_union.EV_CR_TPDU.e_data,0,0); - ENDTRACE - IFDEBUG(D_CONN) - printf("CR datalen 0x%x data 0x%x", e->ev_union.EV_CR_TPDU.e_datalen, e->ev_union.EV_CR_TPDU.e_data); - ENDDEBUG - p->tp_refstate = REF_OPEN; /* has timers */ - p->tp_fcredit = e->ev_union.EV_CR_TPDU.e_cdt; - - if (e->ev_union.EV_CR_TPDU.e_datalen > 0) { - /* n/a for class 0 */ - ASSERT(p->tp_Xrcv.sb_cc == 0); - sbappendrecord(&p->tp_Xrcv, e->ev_union.EV_CR_TPDU.e_data); - e->ev_union.EV_CR_TPDU.e_data = MNULL; - } - } - break; -case 0x7: - { - IncStat(ts_tp0_conn); - IFTRACE(D_CONN) - tptrace(TPPTmisc, "Confiming", p, 0,0,0); - ENDTRACE - IFDEBUG(D_CONN) - printf("Confirming connection: p" ); - ENDDEBUG - soisconnected(p->tp_sock); - (void) tp_emit(CC_TPDU_type, p, 0,0, MNULL) ; - p->tp_fcredit = 1; - } - break; -case 0x8: - { - IncStat(ts_tp4_conn); /* even though not quite open */ - IFTRACE(D_CONN) - tptrace(TPPTmisc, "Confiming", p, 0,0,0); - ENDTRACE - IFDEBUG(D_CONN) - printf("Confirming connection: p" ); - ENDDEBUG - tp_getoptions(p); - soisconnecting(p->tp_sock); - if ((p->tp_rx_strat & TPRX_FASTSTART) && (p->tp_fcredit > 0)) - p->tp_cong_win = p->tp_fcredit * p->tp_l_tpdusize; - p->tp_retrans = p->tp_Nretrans; - tp_ctimeout(p, TM_retrans, (int)p->tp_cc_ticks); - } - break; -case 0x9: - { - IFDEBUG(D_CONN) - printf("event: CR_TPDU emit CC failed done " ); - ENDDEBUG - soisdisconnected(p->tp_sock); - tp_recycle_tsuffix(p); - tp_freeref(p->tp_lref); - tp_detach(p); - } - break; -case 0xa: - { - int error; - struct mbuf *data = MNULL; - - IFTRACE(D_CONN) - tptrace(TPPTmisc, "T_CONN_req flags ucddata", (int)p->tp_flags, - p->tp_ucddata, 0, 0); - ENDTRACE - data = MCPY(p->tp_ucddata, M_WAIT); - if (data) { - IFDEBUG(D_CONN) - printf("T_CONN_req.trans m_copy cc 0x%x\n", - p->tp_ucddata); - dump_mbuf(data, "sosnd @ T_CONN_req"); - ENDDEBUG - } - - if (error = tp_emit(CR_TPDU_type, p, 0, 0, data) ) - return error; /* driver WON'T change state; will return error */ - - p->tp_refstate = REF_OPEN; /* has timers */ - if(p->tp_class != TP_CLASS_0) { - p->tp_retrans = p->tp_Nretrans; - tp_ctimeout(p, TM_retrans, (int)p->tp_cr_ticks); - } - } - break; -case 0xb: - { - sbflush(&p->tp_Xrcv); /* purge non-delivered data data */ - if (e->ev_union.EV_DR_TPDU.e_datalen > 0) { - sbappendrecord(&p->tp_Xrcv, e->ev_union.EV_DR_TPDU.e_data); - e->ev_union.EV_DR_TPDU.e_data = MNULL; - } - if (p->tp_state == TP_OPEN) - tp_indicate(T_DISCONNECT, p, 0); - else { - int so_error = ECONNREFUSED; - if (e->ev_union.EV_DR_TPDU.e_reason != (E_TP_NO_SESSION ^ TP_ERROR_MASK) && - e->ev_union.EV_DR_TPDU.e_reason != (E_TP_NO_CR_ON_NC ^ TP_ERROR_MASK) && - e->ev_union.EV_DR_TPDU.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->ev_union.EV_DR_TPDU.e_sref != 0 ) - (void) tp_emit(DC_TPDU_type, p, 0, 0, MNULL); - } - } - break; -case 0xc: - { - if( e->ev_union.EV_DR_TPDU.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); - } - break; -case 0xd: - { - tp_cuntimeout(p, TM_retrans); - tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason); - tp_soisdisconnected(p); - } - break; -case 0xe: - { - tp_cuntimeout(p, TM_retrans); - tp_soisdisconnected(p); - } - break; -case 0xf: - { - tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason); - tp_cuntimeout(p, TM_retrans); - tp_soisdisconnected(p); - } - break; -case 0x10: - { - tp_cuntimeout(p, TM_retrans); - tp_soisdisconnected(p); - } - break; -case 0x11: - { /* 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 */ - } - break; -case 0x12: - { - tp_soisdisconnecting(p->tp_sock); - tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason); - tp_soisdisconnected(p); - tp_netcmd( p, CONN_CLOSE ); - } - break; -case 0x13: - { - 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->ev_union.EV_ER_TPDU.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); - } - break; -case 0x14: - { - tp_cuntimeout(p, TM_retrans); - IncStat(ts_tp0_conn); - p->tp_fcredit = 1; - soisconnected(p->tp_sock); - } - break; -case 0x15: - { - 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->ev_union.EV_CC_TPDU.e_sref; - p->tp_fcredit = e->ev_union.EV_CC_TPDU.e_cdt; - if ((p->tp_rx_strat & TPRX_FASTSTART) && (e->ev_union.EV_CC_TPDU.e_cdt > 0)) - p->tp_cong_win = e->ev_union.EV_CC_TPDU.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->ev_union.EV_CC_TPDU.e_datalen > 0) { - ASSERT(p->tp_Xrcv.sb_cc == 0); /* should be empty */ - sbappendrecord(&p->tp_Xrcv, e->ev_union.EV_CC_TPDU.e_data); - e->ev_union.EV_CC_TPDU.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); - } - break; -case 0x16: - { - 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); - } - break; -case 0x17: - { - IncStat(ts_conn_gaveup); - p->tp_sock->so_error = ETIMEDOUT; - tp_indicate(T_DISCONNECT, p, ETIMEDOUT); - tp_soisdisconnected(p); - } - break; -case 0x18: - { - 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); - } - break; -case 0x19: - { - 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 - } - break; -case 0x1a: - { - tp0_stash(p, e); - sbwakeup( &p->tp_sock->so_rcv ); - - IFDEBUG(D_DATA) - printf("after stash calling sbwakeup\n"); - ENDDEBUG - } - break; -case 0x1b: - { - 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 - } - break; -case 0x1c: - { - IFTRACE(D_DATA) - tptrace(TPPTmisc, "NIW seq rcvnxt lcredit ", - e->ev_union.EV_DT_TPDU.e_seq, p->tp_rcvnxt, p->tp_lcredit, 0); - ENDTRACE - IncStat(ts_dt_niw); - m_freem(e->ev_union.EV_DT_TPDU.e_data); - tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks); - (void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL ); - } - break; -case 0x1d: - { - if (p->tp_ucddata) { - m_freem(p->tp_ucddata); - p->tp_ucddata = 0; - } - (void) 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); - 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); - } - break; -case 0x1e: - { - 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->ev_union.EV_XPD_TPDU.e_seq, e->ev_union.EV_XPD_TPDU.e_datalen, e->ev_union.EV_XPD_TPDU.e_data->m_len); - ENDTRACE - - p->tp_sock->so_state |= SS_RCVATMARK; - e->ev_union.EV_XPD_TPDU.e_data->m_flags |= M_EOR; - sbinsertoob(&p->tp_Xrcv, e->ev_union.EV_XPD_TPDU.e_data); - IFDEBUG(D_XPD) - dump_mbuf(e->ev_union.EV_XPD_TPDU.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); - } - 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; -} |