move packetizing routine to tp_subr.c
[unix-history] / usr / src / sys / netiso / tp_usrreq.c
index d461deb..242865b 100644 (file)
@@ -1,3 +1,12 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ *
+ *     @(#)tp_usrreq.c 7.22 (Berkeley) %G%
+ */
+
 /***********************************************************
                                Copyright IBM Corporation 1987
 
 /***********************************************************
                                Copyright IBM Corporation 1987
 
@@ -29,7 +38,6 @@ SOFTWARE.
  *
  * $Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_usrreq.c,v $
  *
  * $Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_usrreq.c,v $
- *     @(#)tp_usrreq.c 7.15 (Berkeley) %G%
  *
  * tp_usrreq(), the fellow that gets called from most of the socket code.
  * Pretty straighforward.
  *
  * tp_usrreq(), the fellow that gets called from most of the socket code.
  * Pretty straighforward.
@@ -38,19 +46,15 @@ SOFTWARE.
  * tp_rcvoob() and tp_sendoob() are contained here and called by tp_usrreq().
  */
 
  * tp_rcvoob() and tp_sendoob() are contained here and called by tp_usrreq().
  */
 
-#ifndef lint
-static char *rcsid = "$Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $";
-#endif lint
-
 #include "param.h"
 #include "systm.h"
 #include "param.h"
 #include "systm.h"
-#include "user.h"
 #include "mbuf.h"
 #include "socket.h"
 #include "socketvar.h"
 #include "domain.h"
 #include "protosw.h"
 #include "errno.h"
 #include "mbuf.h"
 #include "socket.h"
 #include "socketvar.h"
 #include "domain.h"
 #include "protosw.h"
 #include "errno.h"
+#include "time.h"
 
 #include "tp_param.h"
 #include "tp_timer.h"
 
 #include "tp_param.h"
 #include "tp_timer.h"
@@ -64,7 +68,7 @@ static char *rcsid = "$Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $";
 #include "iso.h"
 #include "iso_errno.h"
 
 #include "iso.h"
 #include "iso_errno.h"
 
-int tp_attach(), tp_driver();
+int tp_attach(), tp_driver(), tp_pcbbind();
 int TNew;
 int TPNagle1, TPNagle2;
 struct tp_pcb *tp_listeners, *tp_intercepts;
 int TNew;
 int TPNagle1, TPNagle2;
 struct tp_pcb *tp_listeners, *tp_intercepts;
@@ -378,18 +382,15 @@ tp_usrreq(so, req, m, nam, controlp)
        case PRU_ATTACH:
                if (tpcb) {
                        error = EISCONN;
        case PRU_ATTACH:
                if (tpcb) {
                        error = EISCONN;
-                       break;
-               }
-               if (error = tp_attach(so, so->so_proto->pr_domain->dom_family))
-                       break;
-               tpcb = sototpcb(so);
+               } else if ((error = tp_attach(so, (int)nam)) == 0)
+                       tpcb = sototpcb(so);
                break;
 
        case PRU_ABORT:         /* called from close() */
                /* called for each incoming connect queued on the 
                 *      parent (accepting) socket 
                 */
                break;
 
        case PRU_ABORT:         /* called from close() */
                /* called for each incoming connect queued on the 
                 *      parent (accepting) socket 
                 */
-               if (tpcb->tp_state == TP_OPEN) {
+               if (tpcb->tp_state == TP_OPEN || tpcb->tp_state == TP_CONFIRMING) {
                        E.ATTR(T_DISC_req).e_reason = E_TP_NO_SESSION;
                        error = DoEvent(T_DISC_req); /* pretend it was a close() */
                        break;
                        E.ATTR(T_DISC_req).e_reason = E_TP_NO_SESSION;
                        error = DoEvent(T_DISC_req); /* pretend it was a close() */
                        break;
@@ -404,18 +405,13 @@ tp_usrreq(so, req, m, nam, controlp)
                                        break;
                        if (*tt)
                                *tt = tpcb->tp_nextlisten;
                                        break;
                        if (*tt)
                                *tt = tpcb->tp_nextlisten;
-                       else {
-                               for (tt = &tp_intercepts; *tt; tt = &((*tt)->tp_nextlisten))
-                                       if (*tt == tpcb)
-                                               break;
-                               if (*tt)
-                                       *tt = tpcb->tp_nextlisten;
-                               else
-                                       printf("tp_usrreq - detach: should panic\n");
-                       }
+                       else
+                               printf("tp_usrreq - detach: should panic\n");
                }
                }
-               if (tpcb->tp_next)
+               if (tpcb->tp_next) {
                        remque(tpcb);
                        remque(tpcb);
+                       tpcb->tp_next = tpcb->tp_prev = 0;
+               }
                error = DoEvent(T_DETACH);
                if (tpcb->tp_state == TP_CLOSED) {
                        free((caddr_t)tpcb, M_PCB);
                error = DoEvent(T_DETACH);
                if (tpcb->tp_state == TP_CLOSED) {
                        free((caddr_t)tpcb, M_PCB);
@@ -431,30 +427,24 @@ tp_usrreq(so, req, m, nam, controlp)
                break;
 
        case PRU_BIND:
                break;
 
        case PRU_BIND:
-               error =  (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, nam);
-               if (error == 0) {
-                       (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
-                               tpcb->tp_lsuffix, TP_LOCAL);
-               }
+               error =  tp_pcbbind(tpcb, nam);
                break;
 
        case PRU_LISTEN:
                break;
 
        case PRU_LISTEN:
-               if (tpcb->tp_lsuffixlen == 0) {
-                       if (error = (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, MNULL))
-                               break;
-                       (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
-                               tpcb->tp_lsuffix, TP_LOCAL);
-               }
-               if (tpcb->tp_next == 0) {
+               if (tpcb->tp_state != TP_CLOSED || tpcb->tp_lsuffixlen == 0 ||
+                               tpcb->tp_next == 0)
+                       error = EINVAL;
+               else {
+                       register struct tp_pcb **tt;
+                       remque(tpcb);
                        tpcb->tp_next = tpcb->tp_prev = tpcb;
                        tpcb->tp_next = tpcb->tp_prev = tpcb;
-                       tpcb->tp_nextlisten = tp_listeners;
-                       tp_listeners = tpcb;
+                       for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))
+                               if ((*tt)->tp_lsuffixlen)
+                                       break;
+                       tpcb->tp_nextlisten = *tt;
+                       *tt = tpcb;
+                       error = DoEvent(T_LISTEN_req);
                }
                }
-               IFDEBUG(D_TPISO)
-                       if (tpcb->tp_state != TP_CLOSED)
-                               printf("LISTEN ERROR: state 0x%x\n", tpcb->tp_state);
-               ENDDEBUG
-               error = DoEvent(T_LISTEN_req);
                break;
 
        case PRU_CONNECT2:
                break;
 
        case PRU_CONNECT2:
@@ -474,16 +464,13 @@ tp_usrreq(so, req, m, nam, controlp)
                                tpcb->tp_class);
                ENDDEBUG
                if (tpcb->tp_lsuffixlen == 0) {
                                tpcb->tp_class);
                ENDDEBUG
                if (tpcb->tp_lsuffixlen == 0) {
-                       if (error = (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, MNULL)) {
+                       if (error = tp_pcbbind(tpcb, MNULL)) {
                                IFDEBUG(D_CONN)
                                        printf("pcbbind returns error 0x%x\n", error);
                                ENDDEBUG
                                break;
                        }
                                IFDEBUG(D_CONN)
                                        printf("pcbbind returns error 0x%x\n", error);
                                ENDDEBUG
                                break;
                        }
-                       (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
-                               tpcb->tp_lsuffix, TP_LOCAL);
                }
                }
-
                IFDEBUG(D_CONN)
                        printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
                        dump_buf(tpcb->tp_npcb, 16);
                IFDEBUG(D_CONN)
                        printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
                        dump_buf(tpcb->tp_npcb, 16);
@@ -499,16 +486,16 @@ tp_usrreq(so, req, m, nam, controlp)
                ENDDEBUG
                if (tpcb->tp_fsuffixlen ==  0) {
                        /* didn't set peer extended suffix */
                ENDDEBUG
                if (tpcb->tp_fsuffixlen ==  0) {
                        /* didn't set peer extended suffix */
-                       (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_fsuffixlen,
+                       (tpcb->tp_nlproto->nlp_getsufx)(tpcb->tp_npcb, &tpcb->tp_fsuffixlen,
                                tpcb->tp_fsuffix, TP_FOREIGN);
                }
                                tpcb->tp_fsuffix, TP_FOREIGN);
                }
-               (void) (tpcb->tp_nlproto->nlp_mtu)(so, so->so_pcb,
+               (void) (tpcb->tp_nlproto->nlp_mtu)(so, tpcb->tp_npcb,
                                        &tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0);
                if (tpcb->tp_state == TP_CLOSED) {
                        soisconnecting(so);  
                        error = DoEvent(T_CONN_req);
                } else {
                                        &tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0);
                if (tpcb->tp_state == TP_CLOSED) {
                        soisconnecting(so);  
                        error = DoEvent(T_CONN_req);
                } else {
-                       (tpcb->tp_nlproto->nlp_pcbdisc)(so->so_pcb);
+                       (tpcb->tp_nlproto->nlp_pcbdisc)(tpcb->tp_npcb);
                        error = EISCONN;
                }
                IFPERF(tpcb)
                        error = EISCONN;
                }
                IFPERF(tpcb)
@@ -523,7 +510,7 @@ tp_usrreq(so, req, m, nam, controlp)
                break;
 
        case PRU_ACCEPT: 
                break;
 
        case PRU_ACCEPT: 
-               (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_FOREIGN);
+               (tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_FOREIGN);
                IFDEBUG(D_REQUEST)
                        printf("ACCEPT PEERADDDR:");
                        dump_buf(mtod(nam, char *), nam->m_len);
                IFDEBUG(D_REQUEST)
                        printf("ACCEPT PEERADDDR:");
                        dump_buf(mtod(nam, char *), nam->m_len);
@@ -619,19 +606,12 @@ tp_usrreq(so, req, m, nam, controlp)
                 * possibly by a whole cluster.
                 */
                {
                 * possibly by a whole cluster.
                 */
                {
-                       register struct mbuf *n = m;
-                       register struct sockbuf *sb = &so->so_snd;
-                       int     maxsize = tpcb->tp_l_tpdusize 
-                                   - tp_headersize(DT_TPDU_type, tpcb)
-                                   - (tpcb->tp_use_checksum?4:0) ;
-                       int totlen = n->m_pkthdr.len;
-                       int     mbufcnt = 0;
-                       struct mbuf *nn;
-
                        /*
                         * Could have eotsdu and no data.(presently MUST have
                         * an mbuf though, even if its length == 0) 
                         */
                        /*
                         * Could have eotsdu and no data.(presently MUST have
                         * an mbuf though, even if its length == 0) 
                         */
+                       int totlen = m->m_pkthdr.len;
+                       struct sockbuf *sb = &so->so_snd;
                        IFPERF(tpcb)
                           PStat(tpcb, Nb_from_sess) += totlen;
                           tpmeas(tpcb->tp_lref, TPtime_from_session, 0, 0, 
                        IFPERF(tpcb)
                           PStat(tpcb, Nb_from_sess) += totlen;
                           tpmeas(tpcb->tp_lref, TPtime_from_session, 0, 0, 
@@ -644,65 +624,9 @@ tp_usrreq(so, req, m, nam, controlp)
                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
                                dump_mbuf(m, "m : to be added");
                        ENDDEBUG
                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
                                dump_mbuf(m, "m : to be added");
                        ENDDEBUG
-                       /*
-                        * Pre-packetize the data in the sockbuf
-                        * according to negotiated mtu.  Do it here
-                        * where we can safely wait for mbufs.
-                        *
-                        * This presumes knowledge of sockbuf conventions.
-                        */
-                       if (n = sb->sb_mb)
-                               while (n->m_act)
-                                       n = n->m_act;
-                       if ((nn = n) && n->m_pkthdr.len < maxsize) {
-                               u_int space = maxsize - n->m_pkthdr.len;
-
-                               do {
-                                       if (n->m_flags & M_EOR)
-                                               goto on1;
-                               } while (n->m_next && (n = n->m_next));
-                               if (totlen <= space) {
-                                       TPNagle1++;
-                                       n->m_next = m; 
-                                       nn->m_pkthdr.len += totlen;
-                                       while (n = n->m_next)
-                                               sballoc(sb, n);
-                                       if (eotsdu)
-                                               nn->m_flags |= M_EOR; 
-                                       goto on2; 
-                               } else {
-                                       /*
-                                        * Can't sleep here, because when you wake up
-                                        * packet you want to attach to may be gone!
-                                        */
-                                       if (TNew && (n->m_next = m_copym(m, 0, space, M_NOWAIT))) {
-                                               nn->m_pkthdr.len += space;
-                                               TPNagle2++;
-                                               while (n = n->m_next)
-                                                       sballoc(sb, n);
-                                               m_adj(m, space);
-                                       }
-                               }
-                       }       
-       on1:    mbufcnt++;
-                       for (n = m; n->m_pkthdr.len > maxsize;) {
-                               nn = m_copym(n, 0, maxsize, M_WAIT);
-                               sbappendrecord(sb, nn);
-                               m_adj(n, maxsize);
-                               mbufcnt++;
-                       }
-                       if (eotsdu)
-                               n->m_flags |= M_EOR;
-                       sbappendrecord(sb, n);
-       on2:    
-                       IFTRACE(D_DATA)
-                               tptraceTPCB(TPPTmisc,
-                               "SEND BF: maxsize totlen mbufcnt eotsdu",
-                                       maxsize, totlen, mbufcnt, eotsdu);
-                       ENDTRACE
+                       tp_packetize(tpcb, m, eotsdu);
                        IFDEBUG(D_SYSCALL)
                        IFDEBUG(D_SYSCALL)
-                               printf("PRU_SEND: eot %d after sbappend 0x%x mbufcnt 0x%x\n",
-                                       eotsdu, n, mbufcnt);
+                               printf("PRU_SEND: eot %d after sbappend 0x%x\n", eotsdu, m);
                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
                        ENDDEBUG
                        if (tpcb->tp_state == TP_OPEN)
                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
                        ENDDEBUG
                        if (tpcb->tp_state == TP_OPEN)
@@ -717,11 +641,11 @@ tp_usrreq(so, req, m, nam, controlp)
                break;
 
        case PRU_SOCKADDR:
                break;
 
        case PRU_SOCKADDR:
-               (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_LOCAL);
+               (tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_LOCAL);
                break;
 
        case PRU_PEERADDR:
                break;
 
        case PRU_PEERADDR:
-               (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_FOREIGN);
+               (tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_FOREIGN);
                break;
 
        case PRU_CONTROL:
                break;
 
        case PRU_CONTROL: