get rid of useless tp_param global structure.
[unix-history] / usr / src / sys / netiso / tp_emit.c
index 730d1cd..8bee83e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)tp_emit.c   7.8 (Berkeley) %G%
+ *     @(#)tp_emit.c   7.12 (Berkeley) %G%
  */
 
 /***********************************************************
  */
 
 /***********************************************************
@@ -148,6 +148,8 @@ tp_emit(dutype,     tpcb, seq, eot, data)
        int csum_offset=0;
        int datalen = 0;
        int error = 0;
        int csum_offset=0;
        int datalen = 0;
        int error = 0;
+       SeqNum olduwe;
+       int acking_ooo;
 
        /* NOTE:
         * here we treat tpdu_li as if it DID include the li field, up until
 
        /* NOTE:
         * here we treat tpdu_li as if it DID include the li field, up until
@@ -167,12 +169,14 @@ tp_emit(dutype,   tpcb, seq, eot, data)
                        m->m_type = TPMT_TPHDR;
                        mbstat.m_mtypes[TPMT_TPHDR]++;
                        m->m_next = MNULL;
                        m->m_type = TPMT_TPHDR;
                        mbstat.m_mtypes[TPMT_TPHDR]++;
                        m->m_next = MNULL;
-                       m->m_data = m->m_dat;
-                       m->m_flags = 0;
+                       m->m_nextpkt = MNULL;
+                       m->m_data = m->m_pktdat;
+                       m->m_flags = M_PKTHDR;
                }
        } else {
                }
        } else {
-               MGET(m, M_DONTWAIT, TPMT_TPHDR); 
+               MGETHDR(m, M_DONTWAIT, TPMT_TPHDR); 
        }
        }
+       m->m_data += max_hdr;
        if (m == NULL) {
                if(data != (struct mbuf *)0)
                        m_freem(data);
        if (m == NULL) {
                if(data != (struct mbuf *)0)
                        m_freem(data);
@@ -216,9 +220,7 @@ tp_emit(dutype,     tpcb, seq, eot, data)
                                tpcb->tp_win_recv = tp_start_win << 8;
                                LOCAL_CREDIT(tpcb);
                                CONG_INIT_SAMPLE(tpcb);
                                tpcb->tp_win_recv = tp_start_win << 8;
                                LOCAL_CREDIT(tpcb);
                                CONG_INIT_SAMPLE(tpcb);
-                               tpcb->tp_ackrcvd = 0;
-                       }
-                       else
+                       } else
                                LOCAL_CREDIT(tpcb);
 
 
                                LOCAL_CREDIT(tpcb);
 
 
@@ -429,68 +431,71 @@ tp_emit(dutype,   tpcb, seq, eot, data)
                case AK_TPDU_type:/* ak not used in class 0 */
                        ASSERT( tpcb->tp_class != TP_CLASS_0); 
                        data = (struct mbuf *)0;
                case AK_TPDU_type:/* ak not used in class 0 */
                        ASSERT( tpcb->tp_class != TP_CLASS_0); 
                        data = (struct mbuf *)0;
-                       {       SeqNum olduwe = tpcb->tp_sent_uwe;
+                       olduwe = tpcb->tp_sent_uwe;
 
 
+                       if (seq != tpcb->tp_sent_rcvnxt || tpcb->tp_rsycnt == 0) {
+                               LOCAL_CREDIT( tpcb ); 
                                tpcb->tp_sent_uwe = 
                                        SEQ(tpcb,tpcb->tp_rcvnxt + tpcb->tp_lcredit -1);
                                tpcb->tp_sent_uwe = 
                                        SEQ(tpcb,tpcb->tp_rcvnxt + tpcb->tp_lcredit -1);
-                               LOCAL_CREDIT( tpcb ); 
                                tpcb->tp_sent_lcdt = tpcb->tp_lcredit;
                                tpcb->tp_sent_lcdt = tpcb->tp_lcredit;
+                               acking_ooo = 0;
+                       } else
+                               acking_ooo = 1;
 
 
-                               IFDEBUG(D_RENEG)
-                                       /* occasionally fake a reneging so 
-                                               you can test subsequencing */
-                                       if( olduwe & 0x1 ) {
-                                               tpcb->tp_reneged = 1;
-                                               IncStat(ts_ldebug);
-                                       }
-                               ENDDEBUG
-                               /* Are we about to reneg on credit? 
-                                * When might we do so?
-                                *      a) when using optimistic credit (which we no longer do).
-                                *  b) when drain() gets implemented (not in the plans).
-                                *  c) when D_RENEG is on.
-                                *  d) when DEC BIT response is implemented.
-                                *      (not- when we do this, we'll need to implement flow control
-                                *      confirmation)
-                                */
-                               if( SEQ_LT(tpcb, tpcb->tp_sent_uwe, olduwe) ) {
+                       IFDEBUG(D_RENEG)
+                               /* occasionally fake a reneging so 
+                                       you can test subsequencing */
+                               if( olduwe & 0x1 ) {
                                        tpcb->tp_reneged = 1;
                                        tpcb->tp_reneged = 1;
-                                       IncStat(ts_lcdt_reduced);
-                                       IFTRACE(D_CREDIT)
-                                               tptraceTPCB(TPPTmisc, 
-                                                       "RENEG: olduwe newuwe lcredit rcvnxt",
-                                                       olduwe,
-                                                       tpcb->tp_sent_uwe, tpcb->tp_lcredit,
-                                                       tpcb->tp_rcvnxt);
-                                       ENDTRACE
+                                       IncStat(ts_ldebug);
                                }
                                }
+                       ENDDEBUG
+                       /* Are we about to reneg on credit? 
+                        * When might we do so?
+                        *      a) when using optimistic credit (which we no longer do).
+                        *  b) when drain() gets implemented (not in the plans).
+                        *  c) when D_RENEG is on.
+                        *  d) when DEC BIT response is implemented.
+                        *      (not- when we do this, we'll need to implement flow control
+                        *      confirmation)
+                        */
+                       if( SEQ_LT(tpcb, tpcb->tp_sent_uwe, olduwe) ) {
+                               tpcb->tp_reneged = 1;
+                               IncStat(ts_lcdt_reduced);
+                               IFTRACE(D_CREDIT)
+                                       tptraceTPCB(TPPTmisc, 
+                                               "RENEG: olduwe newuwe lcredit rcvnxt",
+                                               olduwe,
+                                               tpcb->tp_sent_uwe, tpcb->tp_lcredit,
+                                               tpcb->tp_rcvnxt);
+                               ENDTRACE
+                       }
+                       IFPERF(tpcb)
+                               /* new lwe is less than old uwe means we're
+                                * acking before we received a whole window full
+                                */
+                               if( SEQ_LT( tpcb, tpcb->tp_rcvnxt, olduwe) ) {
+                                       /* tmp1 = number of pkts fewer than the full window */
+                                       register int tmp1 = 
+                                               (int) SEQ_SUB( tpcb, olduwe, tpcb->tp_rcvnxt);
 
 
-                               IFPERF(tpcb)
-                                       /* new lwe is less than old uwe means we're
-                                        * acking before we received a whole window full
-                                        */
-                                       if( SEQ_LT( tpcb, tpcb->tp_rcvnxt, olduwe) ) {
-                                               /* tmp1 = number of pkts fewer than the full window */
-                                               register int tmp1 = 
-                                                       (int) SEQ_SUB( tpcb, olduwe, tpcb->tp_rcvnxt);
+                                       if(tmp1 > TP_PM_MAX)
+                                               tmp1 = TP_PM_MAX;
+                                       IncPStat( tpcb,  tps_ack_early[tmp1] );
 
 
-                                               if(tmp1 > TP_PM_MAX)
-                                                       tmp1 = TP_PM_MAX;
-                                               IncPStat( tpcb,  tps_ack_early[tmp1] );
+                                       /* tmp1 = amt of new cdt we're advertising */
+                                       tmp1 = SEQ_SUB( tpcb, seq, tpcb->tp_sent_rcvnxt);
+                                       if(tmp1 > TP_PM_MAX )
+                                               tmp1 = TP_PM_MAX;
 
 
-                                               /* tmp1 = amt of new cdt we're advertising */
-                                               tmp1 = SEQ_SUB( tpcb, seq, tpcb->tp_sent_rcvnxt);
-                                               if(tmp1 > TP_PM_MAX )
-                                                       tmp1 = TP_PM_MAX;
+                                       IncPStat( tpcb, 
+                                                       tps_cdt_acked [ tmp1 ]
+                                                       [ ((tpcb->tp_lcredit > TP_PM_MAX)?
+                                                               TP_PM_MAX:tpcb->tp_lcredit) ] );
 
 
-                                               IncPStat( tpcb, 
-                                                               tps_cdt_acked [ tmp1 ]
-                                                               [ ((tpcb->tp_lcredit > TP_PM_MAX)?
-                                                                       TP_PM_MAX:tpcb->tp_lcredit) ] );
+                               }
+                       ENDPERF
 
 
-                                       }
-                               ENDPERF
-                       }
                        IFTRACE(D_ACKSEND)
                                tptraceTPCB(TPPTack, seq, tpcb->tp_lcredit, tpcb->tp_sent_uwe, 
                                        tpcb->tp_r_subseq, 0);
                        IFTRACE(D_ACKSEND)
                                tptraceTPCB(TPPTack, seq, tpcb->tp_lcredit, tpcb->tp_sent_uwe, 
                                        tpcb->tp_r_subseq, 0);
@@ -512,7 +517,8 @@ tp_emit(dutype,     tpcb, seq, eot, data)
                                hdr->tpdu_AKseq = seq;
                                hdr->tpdu_AKcdt = tpcb->tp_lcredit;
                        }
                                hdr->tpdu_AKseq = seq;
                                hdr->tpdu_AKcdt = tpcb->tp_lcredit;
                        }
-                       if ((tpcb->tp_class == TP_CLASS_4) && tpcb->tp_reneged ) {
+                       if ((tpcb->tp_class == TP_CLASS_4) &&
+                               (tpcb->tp_reneged || acking_ooo)) {
                                /* 
                                 * Ack subsequence parameter req'd if WE reneged on 
                                 * credit offered.  (ISO 8073, 12.2.3.8.2, p. 74)
                                /* 
                                 * Ack subsequence parameter req'd if WE reneged on 
                                 * credit offered.  (ISO 8073, 12.2.3.8.2, p. 74)
@@ -592,8 +598,14 @@ tp_emit(dutype,    tpcb, seq, eot, data)
                        }
                        tpcb->tp_reneged = 0;
                        tpcb->tp_sent_rcvnxt = seq;
                        }
                        tpcb->tp_reneged = 0;
                        tpcb->tp_sent_rcvnxt = seq;
-                       tp_ctimeout(tpcb->tp_refp, TM_sendack, 
-                               (int)tpcb->tp_keepalive_ticks);
+                       if (tpcb->tp_fcredit == 0) {
+                               int timo = tpcb->tp_keepalive_ticks;
+                               if (tpcb->tp_rxtshift < TP_MAXRXTSHIFT)
+                                       tpcb->tp_rxtshift++;
+                               timo = min(timo, ((int)tpcb->tp_dt_ticks) << tpcb->tp_rxtshift);
+                               tp_ctimeout(tpcb, TM_sendack, timo);
+                       } else
+                               tp_ctimeout(tpcb, TM_sendack, tpcb->tp_keepalive_ticks);
                        IncStat(ts_AK_sent);
                        IncPStat(tpcb, tps_AK_sent);
                        IFDEBUG(D_ACKSEND)
                        IncStat(ts_AK_sent);
                        IncPStat(tpcb, tps_AK_sent);
                        IFDEBUG(D_ACKSEND)
@@ -689,9 +701,13 @@ tp_emit(dutype,    tpcb, seq, eot, data)
                        tpcb->tp_nlproto->nlp_output, tpcb->tp_netservice, error, datalen); 
        ENDTRACE
 done:
                        tpcb->tp_nlproto->nlp_output, tpcb->tp_netservice, error, datalen); 
        ENDTRACE
 done:
-       if( error == E_CO_QFULL ) {
-               tp_quench(tpcb, PRC_QUENCH);
-               return 0;
+       if (error) {
+               if (dutype == AK_TPDU_type)
+                       tp_ctimeout(tpcb, TM_sendack, 1);
+               if (error == E_CO_QFULL) {
+                       tp_quench(tpcb, PRC_QUENCH);
+                       return 0;
+               }
        }
        return error;
 }
        }
        return error;
 }
@@ -729,7 +745,7 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
        struct mbuf     *erdata;
        int                     erlen;
        struct tp_pcb   *tpcb;
        struct mbuf     *erdata;
        int                     erlen;
        struct tp_pcb   *tpcb;
-       int                     cons_channel;
+       caddr_t                 cons_channel;
        int                             (*dgout_routine)();
 {
        int                                             dutype;
        int                             (*dgout_routine)();
 {
        int                                             dutype;
@@ -806,6 +822,7 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
                IncStat(ts_ER_sent);
                hdr->tpdu_li = 5; 
                hdr->tpdu_ERreason = (char)error;
                IncStat(ts_ER_sent);
                hdr->tpdu_li = 5; 
                hdr->tpdu_ERreason = (char)error;
+               hdr->tpdu_ERdref = htons(sref);
                break;
 
        default:
                break;
 
        default:
@@ -871,8 +888,7 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
        ENDTRACE
 
        datalen = m_datalen( m);
        ENDTRACE
 
        datalen = m_datalen( m);
-
-       if(tpcb) {
+       if (tpcb) {
                if( tpcb->tp_use_checksum ) {
                        IFTRACE(D_ERROR_EMIT)
                                tptrace(TPPTmisc, "before gen csum datalen", datalen,0,0,0);
                if( tpcb->tp_use_checksum ) {
                        IFTRACE(D_ERROR_EMIT)
                                tptrace(TPPTmisc, "before gen csum datalen", datalen,0,0,0);
@@ -889,11 +905,27 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
                        printf("OUTPUT: tpcb 0x%x, isop 0x%x, so 0x%x\n",
                                tpcb,  tpcb->tp_npcb,  tpcb->tp_sock);
                ENDDEBUG
                        printf("OUTPUT: tpcb 0x%x, isop 0x%x, so 0x%x\n",
                                tpcb,  tpcb->tp_npcb,  tpcb->tp_sock);
                ENDDEBUG
-               /* Problem: if packet comes in on ISO but sock is listening
-                * in INET, this assertion will fail.
-                * Have to believe the argument, not the nlp_proto.
-               ASSERT( tpcb->tp_nlproto->nlp_dgoutput == dgout_routine );
-                */
+       }
+       if (cons_channel) {
+#ifdef TPCONS
+               struct pklcd *lcp = (struct pklcd *)cons_channel;
+               struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext;
+
+               tpcons_dg_output(cons_channel, m, datalen);
+               /* was if (tpcb == 0) iso_pcbdetach(isop); */
+               /* but other side may want to try again over same VC,
+                  so, we'll depend on him closing it, but in case it gets forgotten
+                  we'll mark it for garbage collection */
+               lcp->lcd_flags |= X25_DG_CIRCUIT;
+               IFDEBUG(D_ERROR_EMIT)
+                       printf("OUTPUT: dutype 0x%x channel 0x%x\n",
+                               dutype, cons_channel);
+               ENDDEBUG
+#else
+               printf("TP panic! cons channel 0x%x but not cons configured\n",
+                       cons_channel);
+#endif
+       } else if (tpcb) {
 
                IFDEBUG(D_ERROR_EMIT)
                        printf("tp_error_emit 1 sending DG: Laddr\n");
 
                IFDEBUG(D_ERROR_EMIT)
                        printf("tp_error_emit 1 sending DG: Laddr\n");
@@ -906,38 +938,22 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
                        &faddr->siso_addr, 
                        m, datalen, 
                                        /* no route */  (caddr_t)0, !tpcb->tp_use_checksum); 
                        &faddr->siso_addr, 
                        m, datalen, 
                                        /* no route */  (caddr_t)0, !tpcb->tp_use_checksum); 
-       } else  {
-               if( cons_channel ) {
-#ifdef TPCONS
-                       tpcons_dg_output(cons_channel, m, datalen);
-                       pk_disconnect((struct pklcd *)cons_channel);
-                       IFDEBUG(D_ERROR_EMIT)
-                               printf("OUTPUT: dutype 0x%x channel 0x%x\n",
-                                       dutype, cons_channel);
-                       ENDDEBUG
-#else
-                       printf("TP panic! cons channel 0x%x but not cons configured\n",
-                               cons_channel);
-#endif
-               } else {
-#ifndef notdef
+       } else if (dgout_routine) {
                        IFDEBUG(D_ERROR_EMIT)
                                printf("tp_error_emit sending DG: Laddr\n");
                                dump_addr((struct sockaddr *)laddr);
                                printf("Faddr\n");
                                dump_addr((struct sockaddr *)faddr);
                        ENDDEBUG
                        IFDEBUG(D_ERROR_EMIT)
                                printf("tp_error_emit sending DG: Laddr\n");
                                dump_addr((struct sockaddr *)laddr);
                                printf("Faddr\n");
                                dump_addr((struct sockaddr *)faddr);
                        ENDDEBUG
-                       return (*dgout_routine)( &laddr->siso_addr, &faddr->siso_addr, 
-                               m, datalen, /* no route */ 
-                               (caddr_t)0, /* nochecksum==false */0);
-#else notdef
+                               return (*dgout_routine)( &laddr->siso_addr, &faddr->siso_addr, 
+                                       m, datalen, /* no route */ 
+                                       (caddr_t)0, /* nochecksum==false */0);
+       } else {
                        IFDEBUG(D_ERROR_EMIT)
                                printf("tp_error_emit DROPPING \n", m);
                        ENDDEBUG
                        IncStat(ts_send_drop);
                        m_freem(m);
                        return 0;
                        IFDEBUG(D_ERROR_EMIT)
                                printf("tp_error_emit DROPPING \n", m);
                        ENDDEBUG
                        IncStat(ts_send_drop);
                        m_freem(m);
                        return 0;
-#endif notdef
-               }
        }
 }
        }
 }