Annotation of 43BSDReno/sys/netiso/tp_usrreq.c, revision 1.1.1.1

1.1       root        1: /***********************************************************
                      2:                                Copyright IBM Corporation 1987
                      3: 
                      4:                       All Rights Reserved
                      5: 
                      6: Permission to use, copy, modify, and distribute this software and its 
                      7: documentation for any purpose and without fee is hereby granted, 
                      8: provided that the above copyright notice appear in all copies and that
                      9: both that copyright notice and this permission notice appear in 
                     10: supporting documentation, and that the name of IBM not be
                     11: used in advertising or publicity pertaining to distribution of the
                     12: software without specific, written prior permission.  
                     13: 
                     14: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     15: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     16: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     17: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     18: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     19: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     20: SOFTWARE.
                     21: 
                     22: ******************************************************************/
                     23: 
                     24: /*
                     25:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
                     26:  */
                     27: /* 
                     28:  * ARGO TP
                     29:  *
                     30:  * $Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $
                     31:  * $Source: /usr/argo/sys/netiso/RCS/tp_usrreq.c,v $
                     32:  *     @(#)tp_usrreq.c 7.13 (Berkeley) 6/29/90
                     33:  *
                     34:  * tp_usrreq(), the fellow that gets called from most of the socket code.
                     35:  * Pretty straighforward.
                     36:  * THe only really awful stuff here is the OOB processing, which is done
                     37:  * wholly here.
                     38:  * tp_rcvoob() and tp_sendoob() are contained here and called by tp_usrreq().
                     39:  */
                     40: 
                     41: #ifndef lint
                     42: static char *rcsid = "$Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $";
                     43: #endif lint
                     44: 
                     45: #include "param.h"
                     46: #include "systm.h"
                     47: #include "user.h"
                     48: #include "mbuf.h"
                     49: #include "socket.h"
                     50: #include "socketvar.h"
                     51: #include "domain.h"
                     52: #include "protosw.h"
                     53: #include "errno.h"
                     54: 
                     55: #include "tp_param.h"
                     56: #include "tp_timer.h"
                     57: #include "tp_stat.h"
                     58: #include "tp_seq.h"
                     59: #include "tp_ip.h"
                     60: #include "tp_pcb.h"
                     61: #include "argo_debug.h"
                     62: #include "tp_trace.h"
                     63: #include "tp_meas.h"
                     64: #include "iso.h"
                     65: #include "iso_errno.h"
                     66: 
                     67: int tp_attach(), tp_driver();
                     68: int TNew;
                     69: int TPNagle1, TPNagle2;
                     70: struct tp_pcb *tp_listeners, *tp_intercepts;
                     71: 
                     72: #ifdef ARGO_DEBUG
                     73: /*
                     74:  * CALLED FROM:
                     75:  *  anywhere you want to debug...
                     76:  * FUNCTION and ARGUMENTS:
                     77:  *  print (str) followed by the control info in the mbufs of an mbuf chain (n)
                     78:  */
                     79: void
                     80: dump_mbuf(n, str)
                     81:        struct mbuf *n;
                     82:        char *str;
                     83: {
                     84:        struct mbuf *nextrecord;
                     85: 
                     86:        printf("dump %s\n", str);
                     87: 
                     88:        if (n == MNULL)  {
                     89:                printf("EMPTY:\n");
                     90:                return;
                     91:        }
                     92:                
                     93:        while (n) {
                     94:                nextrecord = n->m_act;
                     95:                printf("RECORD:\n");
                     96:                while (n) {
                     97:                        printf("%x : Len %x Data %x A %x Nx %x Tp %x\n",
                     98:                                n, n->m_len, n->m_data, n->m_act, n->m_next, n->m_type);
                     99: #ifdef notdef
                    100:                        {
                    101:                                register char *p = mtod(n, char *);
                    102:                                register int i;
                    103: 
                    104:                                printf("data: ");
                    105:                                for (i = 0; i < n->m_len; i++) {
                    106:                                        if (i%8 == 0)
                    107:                                                printf("\n");
                    108:                                        printf("0x%x ", *(p+i));
                    109:                                }
                    110:                                printf("\n");
                    111:                        }
                    112: #endif notdef
                    113:                        if (n->m_next == n) {
                    114:                                printf("LOOP!\n");
                    115:                                return;
                    116:                        }
                    117:                        n = n->m_next;
                    118:                }
                    119:                n = nextrecord;
                    120:        }
                    121:        printf("\n");
                    122: }
                    123: 
                    124: #endif ARGO_DEBUG
                    125: 
                    126: /*
                    127:  * CALLED FROM:
                    128:  *  tp_usrreq(), PRU_RCVOOB
                    129:  * FUNCTION and ARGUMENTS:
                    130:  *     Copy data from the expedited data socket buffer into
                    131:  *     the pre-allocated mbuf m.
                    132:  *     There is an isomorphism between XPD TPDUs and expedited data TSDUs.
                    133:  *     XPD tpdus are limited to 16 bytes of data so they fit in one mbuf.
                    134:  * RETURN VALUE:
                    135:  *  EINVAL if debugging is on and a disaster has occurred
                    136:  *  ENOTCONN if the socket isn't connected
                    137:  *  EWOULDBLOCK if the socket is in non-blocking mode and there's no
                    138:  *             xpd data in the buffer
                    139:  *  E* whatever is returned from the fsm.
                    140:  */
                    141: tp_rcvoob(tpcb, so, m, outflags, inflags)
                    142:        struct tp_pcb   *tpcb;
                    143:        register struct socket  *so;
                    144:        register struct mbuf    *m;
                    145:        int                     *outflags;
                    146:        int                     inflags;
                    147: {
                    148:        register struct mbuf *n;
                    149:        register struct sockbuf *sb = &so->so_rcv;
                    150:        struct tp_event E;
                    151:        int error = 0;
                    152:        register struct mbuf **nn;
                    153: 
                    154:        IFDEBUG(D_XPD)
                    155:                printf("PRU_RCVOOB, sostate 0x%x\n", so->so_state);
                    156:        ENDDEBUG
                    157: 
                    158:        /* if you use soreceive */
                    159:        if (m == MNULL)
                    160:                return ENOBUFS;
                    161: 
                    162: restart:
                    163:        if ((((so->so_state & SS_ISCONNECTED) == 0)
                    164:                 || (so->so_state & SS_ISDISCONNECTING) != 0) &&
                    165:                (so->so_proto->pr_flags & PR_CONNREQUIRED)) {
                    166:                        return ENOTCONN;
                    167:        }
                    168: 
                    169:        /* Take the first mbuf off the chain.
                    170:         * Each XPD TPDU gives you a complete TSDU so the chains don't get 
                    171:         * coalesced, but one TSDU may span several mbufs.
                    172:         * Nevertheless, since n should have a most 16 bytes, it
                    173:         * will fit into m.  (size was checked in tp_input() )
                    174:         */
                    175: 
                    176:        /*
                    177:         * Code for excision of OOB data should be added to
                    178:         * uipc_socket2.c (like sbappend).
                    179:         */
                    180:        
                    181:        sblock(sb);
                    182:        for (nn = &sb->sb_mb; n = *nn; nn = &n->m_act)
                    183:                if (n->m_type == MT_OOBDATA)
                    184:                        break;
                    185: 
                    186:        if (n == 0) {
                    187:                ASSERT((tpcb->tp_flags & TPF_DISC_DATA_IN) == 0);
                    188:                IFDEBUG(D_XPD)
                    189:                        printf("RCVOOB: empty queue!\n");
                    190:                ENDDEBUG
                    191:                sbunlock(sb);
                    192:                if (so->so_state & SS_NBIO) {
                    193:                        return  EWOULDBLOCK;
                    194:                }
                    195:                sbwait(sb);
                    196:                goto restart;
                    197:        }
                    198:        m->m_len = 0;
                    199: 
                    200:        /* Assuming at most one xpd tpdu is in the buffer at once */
                    201:        while (n != MNULL) {
                    202:                m->m_len += n->m_len;
                    203:                bcopy(mtod(n, caddr_t), mtod(m, caddr_t), (unsigned)n->m_len);
                    204:                m->m_data += n->m_len; /* so mtod() in bcopy() above gives right addr */
                    205:                n = n->m_next;
                    206:        }
                    207:        m->m_data = m->m_dat;
                    208:        m->m_flags |= M_EOR;
                    209: 
                    210:        IFDEBUG(D_XPD)
                    211:                printf("tp_rcvoob: xpdlen 0x%x\n", m->m_len);
                    212:                dump_mbuf(so->so_rcv.sb_mb, "RCVOOB: Rcv socketbuf");
                    213:                dump_mbuf(sb->sb_mb, "RCVOOB: Xrcv socketbuf");
                    214:        ENDDEBUG
                    215: 
                    216:        if ((inflags & MSG_PEEK) == 0) {
                    217:                n = *nn;
                    218:                *nn = n->m_act;
                    219:                sb->sb_cc -= m->m_len;
                    220:        }
                    221: 
                    222: release:
                    223:        sbunlock(sb);
                    224: 
                    225:        IFTRACE(D_XPD)
                    226:                tptraceTPCB(TPPTmisc, "PRU_RCVOOB @ release sb_cc m_len",
                    227:                        tpcb->tp_Xrcv.sb_cc, m->m_len, 0, 0);
                    228:        ENDTRACE
                    229:        if (error == 0)
                    230:                error = DoEvent(T_USR_Xrcvd); 
                    231:        return error;
                    232: }
                    233: 
                    234: /*
                    235:  * CALLED FROM:
                    236:  *  tp_usrreq(), PRU_SENDOOB
                    237:  * FUNCTION and ARGUMENTS:
                    238:  *     Send what's in the mbuf chain (m) as an XPD TPDU.
                    239:  *     The mbuf may not contain more then 16 bytes of data.
                    240:  *     XPD TSDUs aren't segmented, so they translate into
                    241:  *     exactly one XPD TPDU, with EOT bit set.
                    242:  * RETURN VALUE:
                    243:  *  EWOULDBLOCK if socket is in non-blocking mode and the previous
                    244:  *   xpd data haven't been acked yet.
                    245:  *  EMSGSIZE if trying to send > max-xpd bytes (16)
                    246:  *  ENOBUFS if ran out of mbufs
                    247:  */
                    248: tp_sendoob(tpcb, so, xdata, outflags)
                    249:        struct tp_pcb   *tpcb;
                    250:        register struct socket  *so;
                    251:        register struct mbuf    *xdata;
                    252:        int                     *outflags; /* not used */
                    253: {
                    254:        /*
                    255:         * Each mbuf chain represents a sequence # in the XPD seq space.
                    256:         * The first one in the queue has sequence # tp_Xuna.
                    257:         * When we add to the XPD queue, we stuff a zero-length
                    258:         * mbuf (mark) into the DATA queue, with its sequence number in m_next
                    259:         * to be assigned to this XPD tpdu, so data xfer can stop
                    260:         * when it reaches the zero-length mbuf if this XPD TPDU hasn't
                    261:         * yet been acknowledged.  
                    262:         */
                    263:        register struct sockbuf *sb = &(tpcb->tp_Xsnd);
                    264:        register struct mbuf    *xmark;
                    265:        register int                    len=0;
                    266:        struct tp_event E;
                    267: 
                    268:        IFDEBUG(D_XPD)
                    269:                printf("tp_sendoob:");
                    270:                if (xdata)
                    271:                        printf("xdata len 0x%x\n", xdata->m_len);
                    272:        ENDDEBUG
                    273:        /* DO NOT LOCK the Xsnd buffer!!!! You can have at MOST one 
                    274:         * socket buf locked at any time!!! (otherwise you might
                    275:         * sleep() in sblock() w/ a signal pending and cause the
                    276:         * system call to be aborted w/ a locked socketbuf, which
                    277:         * is a problem.  So the so_snd buffer lock
                    278:         * (done in sosend()) serves as the lock for Xpd.
                    279:         */
                    280:        if (sb->sb_mb) { /* Anything already in eXpedited data sockbuf? */
                    281:                if (so->so_state & SS_NBIO) {
                    282:                        return EWOULDBLOCK;
                    283:                }
                    284:                while (sb->sb_mb) {
                    285:                        sbunlock(&so->so_snd); /* already locked by sosend */
                    286:                        sbwait(&so->so_snd);
                    287:                        sblock(&so->so_snd);  /* sosend will unlock on return */
                    288:                }
                    289:        }
                    290: 
                    291:        if (xdata == (struct mbuf *)0) {
                    292:                /* empty xpd packet */
                    293:                MGETHDR(xdata, M_WAIT, MT_OOBDATA);
                    294:                if (xdata == NULL) {
                    295:                        return ENOBUFS;
                    296:                }
                    297:                xdata->m_len = 0;
                    298:                xdata->m_pkthdr.len = 0;
                    299:        }
                    300:        IFDEBUG(D_XPD)
                    301:                printf("tp_sendoob 1:");
                    302:                if (xdata)
                    303:                        printf("xdata len 0x%x\n", xdata->m_len);
                    304:        ENDDEBUG
                    305:        xmark = xdata; /* temporary use of variable xmark */
                    306:        while (xmark) {
                    307:                len += xmark->m_len;
                    308:                xmark = xmark->m_next;
                    309:        }
                    310:        if (len > TP_MAX_XPD_DATA) {
                    311:                return EMSGSIZE;
                    312:        }
                    313:        IFDEBUG(D_XPD)
                    314:                printf("tp_sendoob 2:");
                    315:                if (xdata)
                    316:                        printf("xdata len 0x%x\n", len);
                    317:        ENDDEBUG
                    318: 
                    319: 
                    320:        IFTRACE(D_XPD)
                    321:                tptraceTPCB(TPPTmisc, "XPD mark m_next ", xdata->m_next, 0, 0, 0);
                    322:        ENDTRACE
                    323: 
                    324:        sbappendrecord(sb, xdata);      
                    325: 
                    326:        IFDEBUG(D_XPD)
                    327:                printf("tp_sendoob len 0x%x\n", len);
                    328:                dump_mbuf(so->so_snd.sb_mb, "XPD request Regular sndbuf:");
                    329:                dump_mbuf(tpcb->tp_Xsnd.sb_mb, "XPD request Xsndbuf:");
                    330:        ENDDEBUG
                    331:        return DoEvent(T_XPD_req); 
                    332: }
                    333: 
                    334: /*
                    335:  * CALLED FROM:
                    336:  *  the socket routines
                    337:  * FUNCTION and ARGUMENTS:
                    338:  *     Handles all "user requests" except the [gs]ockopts() requests.
                    339:  *     The argument (req) is the request type (PRU*), 
                    340:  *     (m) is an mbuf chain, generally used for send and
                    341:  *     receive type requests only.
                    342:  *     (nam) is used for addresses usually, in particular for the bind request.
                    343:  * 
                    344:  */
                    345: /*ARGSUSED*/
                    346: ProtoHook
                    347: tp_usrreq(so, req, m, nam, controlp)
                    348:        struct socket *so;
                    349:        u_int req;
                    350:        struct mbuf *m, *nam, *controlp;
                    351: {      
                    352:        register struct tp_pcb *tpcb =  sototpcb(so);
                    353:        int s = splnet();
                    354:        int error = 0;
                    355:        int flags, *outflags = &flags; 
                    356:        u_long eotsdu = 0;
                    357:        struct tp_event E;
                    358: 
                    359:        IFDEBUG(D_REQUEST)
                    360:                printf("usrreq(0x%x,%d,0x%x,0x%x,0x%x)\n",so,req,m,nam,outflags);
                    361:                if (so->so_error)
                    362:                        printf("WARNING!!! so->so_error is 0x%x\n", so->so_error);
                    363:        ENDDEBUG
                    364:        IFTRACE(D_REQUEST)
                    365:                tptraceTPCB(TPPTusrreq, "req so m state [", req, so, m, 
                    366:                        tpcb?tpcb->tp_state:0);
                    367:        ENDTRACE
                    368: 
                    369:        if ((u_int)tpcb == 0 && req != PRU_ATTACH) {
                    370:                IFTRACE(D_REQUEST)
                    371:                        tptraceTPCB(TPPTusrreq, "req failed NO TPCB[", 0, 0, 0, 0);
                    372:                ENDTRACE
                    373:                splx(s);
                    374:                return ENOTCONN;
                    375:        }
                    376: 
                    377:        switch (req) {
                    378: 
                    379:        case PRU_ATTACH:
                    380:                if (tpcb) {
                    381:                        error = EISCONN;
                    382:                        break;
                    383:                }
                    384:                if (error = tp_attach(so, so->so_proto->pr_domain->dom_family))
                    385:                        break;
                    386:                tpcb = sototpcb(so);
                    387:                break;
                    388: 
                    389:        case PRU_ABORT:         /* called from close() */
                    390:                /* called for each incoming connect queued on the 
                    391:                 *      parent (accepting) socket 
                    392:                 */
                    393:                if (tpcb->tp_state == TP_OPEN) {
                    394:                        E.ATTR(T_DISC_req).e_reason = E_TP_NO_SESSION;
                    395:                        error = DoEvent(T_DISC_req); /* pretend it was a close() */
                    396:                        break;
                    397:                } /* else DROP THROUGH */
                    398: 
                    399:        case PRU_DETACH:        /* called from close() */
                    400:                /* called only after disconnect was called */
                    401:                if (tpcb->tp_state == TP_LISTENING) {
                    402:                        register struct tp_pcb **tt;
                    403:                        for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))
                    404:                                if (*tt == tpcb)
                    405:                                        break;
                    406:                        if (*tt)
                    407:                                *tt = tpcb->tp_nextlisten;
                    408:                        else {
                    409:                                for (tt = &tp_intercepts; *tt; tt = &((*tt)->tp_nextlisten))
                    410:                                        if (*tt == tpcb)
                    411:                                                break;
                    412:                                if (*tt)
                    413:                                        *tt = tpcb->tp_nextlisten;
                    414:                                else
                    415:                                        printf("tp_usrreq - detach: should panic\n");
                    416:                        }
                    417:                }
                    418:                if (tpcb->tp_next)
                    419:                        remque(tpcb);
                    420:                error = DoEvent(T_DETACH);
                    421:                if (tpcb->tp_state == TP_CLOSED) {
                    422:                        free((caddr_t)tpcb, M_PCB);
                    423:                        tpcb = 0;
                    424:                }
                    425:                break;
                    426: 
                    427:        case PRU_SHUTDOWN:
                    428:                /* recv end may have been released; local credit might be zero  */
                    429:        case PRU_DISCONNECT:
                    430:                E.ATTR(T_DISC_req).e_reason = E_TP_NORMAL_DISC;
                    431:                error = DoEvent(T_DISC_req);
                    432:                break;
                    433: 
                    434:        case PRU_BIND:
                    435:                error =  (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, nam);
                    436:                if (error == 0) {
                    437:                        (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
                    438:                                tpcb->tp_lsuffix, TP_LOCAL);
                    439:                }
                    440:                break;
                    441: 
                    442:        case PRU_LISTEN:
                    443:                if (tpcb->tp_lsuffixlen == 0) {
                    444:                        if (error = (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, MNULL))
                    445:                                break;
                    446:                        (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
                    447:                                tpcb->tp_lsuffix, TP_LOCAL);
                    448:                }
                    449:                if (tpcb->tp_next == 0) {
                    450:                        tpcb->tp_next = tpcb->tp_prev = tpcb;
                    451:                        tpcb->tp_nextlisten = tp_listeners;
                    452:                        tp_listeners = tpcb;
                    453:                }
                    454:                IFDEBUG(D_TPISO)
                    455:                        if (tpcb->tp_state != TP_CLOSED)
                    456:                                printf("LISTEN ERROR: state 0x%x\n", tpcb->tp_state);
                    457:                ENDDEBUG
                    458:                error = DoEvent(T_LISTEN_req);
                    459:                break;
                    460: 
                    461:        case PRU_CONNECT2:
                    462:                error = EOPNOTSUPP; /* for unix domain sockets */
                    463:                break;
                    464: 
                    465:        case PRU_CONNECT:
                    466:                IFTRACE(D_CONN)
                    467:                        tptraceTPCB(TPPTmisc, 
                    468:                        "PRU_CONNECT: so 0x%x *SHORT_LSUFXP(tpcb) 0x%x lsuflen 0x%x, class 0x%x",
                    469:                        tpcb->tp_sock, *SHORT_LSUFXP(tpcb), tpcb->tp_lsuffixlen,
                    470:                                tpcb->tp_class);
                    471:                ENDTRACE
                    472:                IFDEBUG(D_CONN)
                    473:                        printf("PRU_CONNECT: so *SHORT_LSUFXP(tpcb) 0x%x lsuflen 0x%x, class 0x%x",
                    474:                        tpcb->tp_sock, *SHORT_LSUFXP(tpcb), tpcb->tp_lsuffixlen,
                    475:                                tpcb->tp_class);
                    476:                ENDDEBUG
                    477:                if (tpcb->tp_lsuffixlen == 0) {
                    478:                        if (error = (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, MNULL)) {
                    479:                                IFDEBUG(D_CONN)
                    480:                                        printf("pcbbind returns error 0x%x\n", error);
                    481:                                ENDDEBUG
                    482:                                break;
                    483:                        }
                    484:                        (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
                    485:                                tpcb->tp_lsuffix, TP_LOCAL);
                    486:                }
                    487: 
                    488:                IFDEBUG(D_CONN)
                    489:                        printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
                    490:                        dump_buf(tpcb->tp_npcb, 16);
                    491:                ENDDEBUG
                    492:                if (error = tp_route_to(nam, tpcb, /* channel */0))
                    493:                        break;
                    494:                IFDEBUG(D_CONN)
                    495:                        printf(
                    496:                                "PRU_CONNECT after tpcb 0x%x so 0x%x npcb 0x%x flags 0x%x\n", 
                    497:                                tpcb, so, tpcb->tp_npcb, tpcb->tp_flags);
                    498:                        printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
                    499:                        dump_buf(tpcb->tp_npcb, 16);
                    500:                ENDDEBUG
                    501:                if (tpcb->tp_fsuffixlen ==  0) {
                    502:                        /* didn't set peer extended suffix */
                    503:                        (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_fsuffixlen,
                    504:                                tpcb->tp_fsuffix, TP_FOREIGN);
                    505:                }
                    506:                (void) (tpcb->tp_nlproto->nlp_mtu)(so, so->so_pcb,
                    507:                                        &tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0);
                    508:                if (tpcb->tp_state == TP_CLOSED) {
                    509:                        soisconnecting(so);  
                    510:                        error = DoEvent(T_CONN_req);
                    511:                } else {
                    512:                        (tpcb->tp_nlproto->nlp_pcbdisc)(so->so_pcb);
                    513:                        error = EISCONN;
                    514:                }
                    515:                IFPERF(tpcb)
                    516:                        u_int lsufx, fsufx;
                    517:                        lsufx = *(u_short *)(tpcb->tp_lsuffix);
                    518:                        fsufx = *(u_short *)(tpcb->tp_fsuffix);
                    519: 
                    520:                        tpmeas(tpcb->tp_lref, 
                    521:                                TPtime_open | (tpcb->tp_xtd_format << 4), 
                    522:                                &time, lsufx, fsufx, tpcb->tp_fref);
                    523:                ENDPERF
                    524:                break;
                    525: 
                    526:        case PRU_ACCEPT: 
                    527:                (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_FOREIGN);
                    528:                IFDEBUG(D_REQUEST)
                    529:                        printf("ACCEPT PEERADDDR:");
                    530:                        dump_buf(mtod(nam, char *), nam->m_len);
                    531:                ENDDEBUG
                    532:                IFPERF(tpcb)
                    533:                        u_int lsufx, fsufx;
                    534:                        lsufx = *(u_short *)(tpcb->tp_lsuffix);
                    535:                        fsufx = *(u_short *)(tpcb->tp_fsuffix);
                    536: 
                    537:                        tpmeas(tpcb->tp_lref, TPtime_open, 
                    538:                                &time, lsufx, fsufx, tpcb->tp_fref);
                    539:                ENDPERF
                    540:                break;
                    541: 
                    542:        case PRU_RCVD:
                    543:                if (so->so_state & SS_ISCONFIRMING) {
                    544:                        if (tpcb->tp_state == TP_CONFIRMING)
                    545:                                error = tp_confirm(tpcb);
                    546:                        break;
                    547:                }
                    548:                IFTRACE(D_DATA)
                    549:                        tptraceTPCB(TPPTmisc,
                    550:                        "RCVD BF: lcredit sent_lcdt cc hiwat \n",
                    551:                                tpcb->tp_lcredit, tpcb->tp_sent_lcdt,
                    552:                                so->so_rcv.sb_cc, so->so_rcv.sb_hiwat);
                    553:                        LOCAL_CREDIT(tpcb);
                    554:                        tptraceTPCB(TPPTmisc, 
                    555:                                "PRU_RCVD AF sbspace lcredit hiwat cc",
                    556:                                sbspace(&so->so_rcv), tpcb->tp_lcredit,
                    557:                                so->so_rcv.sb_cc, so->so_rcv.sb_hiwat);
                    558:                ENDTRACE
                    559:                IFDEBUG(D_REQUEST)
                    560:                        printf("RCVD: cc %d space %d hiwat %d\n",
                    561:                                so->so_rcv.sb_cc, sbspace(&so->so_rcv),
                    562:                                so->so_rcv.sb_hiwat);
                    563:                ENDDEBUG
                    564:                if (((int)nam) & MSG_OOB)
                    565:                        error = DoEvent(T_USR_Xrcvd); 
                    566:                else 
                    567:                        error = DoEvent(T_USR_rcvd); 
                    568:                break;
                    569: 
                    570:        case PRU_RCVOOB:
                    571:                if ((so->so_state & SS_ISCONNECTED) == 0) {
                    572:                        error = ENOTCONN;
                    573:                        break;
                    574:                }
                    575:                if (! tpcb->tp_xpd_service) {
                    576:                        error = EOPNOTSUPP;
                    577:                        break;
                    578:                }
                    579:                /* kludge - nam is really flags here */
                    580:                error = tp_rcvoob(tpcb, so, m, outflags, (int)nam);
                    581:                break;
                    582: 
                    583:        case PRU_SEND:
                    584:        case PRU_SENDOOB:
                    585:                if (controlp) {
                    586:                        error = tp_snd_control(controlp, so, &m);
                    587:                        controlp = NULL;
                    588:                        if (error)
                    589:                                break;
                    590:                }
                    591:                if (so->so_state & SS_ISCONFIRMING) {
                    592:                        if (tpcb->tp_state == TP_CONFIRMING)
                    593:                                error = tp_confirm(tpcb);
                    594:                        if (m) {
                    595:                                if (error == 0 && m->m_len != 0)
                    596:                                        error =  ENOTCONN;
                    597:                                m_freem(m);
                    598:                                m = 0;
                    599:                        }
                    600:                        break;
                    601:                }
                    602:                if (m == 0)
                    603:                        break;
                    604: 
                    605:                if (req == PRU_SENDOOB) {
                    606:                        if (tpcb->tp_xpd_service == 0) {
                    607:                                error = EOPNOTSUPP;
                    608:                                break;
                    609:                        }
                    610:                        error = tp_sendoob(tpcb, so, m, outflags);
                    611:                        break;
                    612:                }
                    613:                /*
                    614:                 * The protocol machine copies mbuf chains,
                    615:                 * prepends headers, assigns seq numbers, and
                    616:                 * puts the packets on the device.
                    617:                 * When they are acked they are removed from the socket buf.
                    618:                 *
                    619:                 * sosend calls this up until sbspace goes negative.
                    620:                 * Sbspace may be made negative by appending this mbuf chain,
                    621:                 * possibly by a whole cluster.
                    622:                 */
                    623:                {
                    624:                        register struct mbuf *n = m;
                    625:                        register struct sockbuf *sb = &so->so_snd;
                    626:                        int     maxsize = tpcb->tp_l_tpdusize 
                    627:                                    - tp_headersize(DT_TPDU_type, tpcb)
                    628:                                    - (tpcb->tp_use_checksum?4:0) ;
                    629:                        int totlen = n->m_pkthdr.len;
                    630:                        int     mbufcnt = 0;
                    631:                        struct mbuf *nn;
                    632: 
                    633:                        /*
                    634:                         * Could have eotsdu and no data.(presently MUST have
                    635:                         * an mbuf though, even if its length == 0) 
                    636:                         */
                    637:                        if (n->m_flags & M_EOR) {
                    638:                                eotsdu = 1;
                    639:                                n->m_flags &= ~M_EOR;
                    640:                        }
                    641:                        IFPERF(tpcb)
                    642:                           PStat(tpcb, Nb_from_sess) += totlen;
                    643:                           tpmeas(tpcb->tp_lref, TPtime_from_session, 0, 0, 
                    644:                                        PStat(tpcb, Nb_from_sess), totlen);
                    645:                        ENDPERF
                    646:                        IFDEBUG(D_SYSCALL)
                    647:                                printf(
                    648:                                "PRU_SEND: eot %d before sbappend 0x%x len 0x%x to sb @ 0x%x\n",
                    649:                                        eotsdu, m, totlen, sb);
                    650:                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
                    651:                                dump_mbuf(m, "m : to be added");
                    652:                        ENDDEBUG
                    653:                        /*
                    654:                         * Pre-packetize the data in the sockbuf
                    655:                         * according to negotiated mtu.  Do it here
                    656:                         * where we can safely wait for mbufs.
                    657:                         *
                    658:                         * This presumes knowledge of sockbuf conventions.
                    659:                         */
                    660:                        if (n = sb->sb_mb)
                    661:                                while (n->m_act)
                    662:                                        n = n->m_act;
                    663:                        if ((nn = n) && n->m_pkthdr.len < maxsize) {
                    664:                                u_int space = maxsize - n->m_pkthdr.len;
                    665: 
                    666:                                do {
                    667:                                        if (n->m_flags & M_EOR)
                    668:                                                goto on1;
                    669:                                } while (n->m_next && (n = n->m_next));
                    670:                                if (totlen <= space) {
                    671:                                        TPNagle1++;
                    672:                                        n->m_next = m; 
                    673:                                        nn->m_pkthdr.len += totlen;
                    674:                                        while (n = n->m_next)
                    675:                                                sballoc(sb, n);
                    676:                                        if (eotsdu)
                    677:                                                nn->m_flags |= M_EOR; 
                    678:                                        goto on2; 
                    679:                                } else {
                    680:                                        /*
                    681:                                         * Can't sleep here, because when you wake up
                    682:                                         * packet you want to attach to may be gone!
                    683:                                         */
                    684:                                        if (TNew && (n->m_next = m_copym(m, 0, space, M_NOWAIT))) {
                    685:                                                nn->m_pkthdr.len += space;
                    686:                                                TPNagle2++;
                    687:                                                while (n = n->m_next)
                    688:                                                        sballoc(sb, n);
                    689:                                                m_adj(m, space);
                    690:                                        }
                    691:                                }
                    692:                        }       
                    693:        on1:    mbufcnt++;
                    694:                        for (n = m; n->m_pkthdr.len > maxsize;) {
                    695:                                nn = m_copym(n, 0, maxsize, M_WAIT);
                    696:                                sbappendrecord(sb, nn);
                    697:                                m_adj(n, maxsize);
                    698:                                mbufcnt++;
                    699:                        }
                    700:                        if (eotsdu)
                    701:                                n->m_flags |= M_EOR;
                    702:                        sbappendrecord(sb, n);
                    703:        on2:    
                    704:                        IFTRACE(D_DATA)
                    705:                                tptraceTPCB(TPPTmisc,
                    706:                                "SEND BF: maxsize totlen mbufcnt eotsdu",
                    707:                                        maxsize, totlen, mbufcnt, eotsdu);
                    708:                        ENDTRACE
                    709:                        IFDEBUG(D_SYSCALL)
                    710:                                printf("PRU_SEND: eot %d after sbappend 0x%x mbufcnt 0x%x\n",
                    711:                                        eotsdu, n, mbufcnt);
                    712:                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
                    713:                        ENDDEBUG
                    714:                        error = DoEvent(T_DATA_req); 
                    715:                        IFDEBUG(D_SYSCALL)
                    716:                                printf("PRU_SEND: after driver error 0x%x \n",error);
                    717:                                printf("so_snd 0x%x cc 0t%d mbcnt 0t%d\n",
                    718:                                                sb, sb->sb_cc, sb->sb_mbcnt);
                    719:                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb after driver");
                    720:                        ENDDEBUG
                    721:                }
                    722:                break;
                    723: 
                    724:        case PRU_SOCKADDR:
                    725:                (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_LOCAL);
                    726:                break;
                    727: 
                    728:        case PRU_PEERADDR:
                    729:                (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_FOREIGN);
                    730:                break;
                    731: 
                    732:        case PRU_CONTROL:
                    733:                error = EOPNOTSUPP;
                    734:                break;
                    735: 
                    736:        case PRU_PROTOSEND:
                    737:        case PRU_PROTORCV:
                    738:        case PRU_SENSE:
                    739:        case PRU_SLOWTIMO:
                    740:        case PRU_FASTTIMO:
                    741:                error = EOPNOTSUPP;
                    742:                break;
                    743: 
                    744:        default:
                    745: #ifdef ARGO_DEBUG
                    746:                printf("tp_usrreq UNKNOWN PRU %d\n", req);
                    747: #endif ARGO_DEBUG
                    748:                error = EOPNOTSUPP;
                    749:        }
                    750: 
                    751:        IFDEBUG(D_REQUEST)
                    752:                printf("%s, so 0x%x, tpcb 0x%x, error %d, state %d\n",
                    753:                        "returning from tp_usrreq", so, tpcb, error,
                    754:                        tpcb ? 0 : tpcb->tp_state);
                    755:        ENDDEBUG
                    756:        IFTRACE(D_REQUEST)
                    757:                tptraceTPCB(TPPTusrreq, "END req so m state [", req, so, m, 
                    758:                        tpcb?0:tpcb->tp_state);
                    759:        ENDTRACE
                    760:        if (controlp) {
                    761:                m_freem(controlp);
                    762:                printf("control data unexpectedly retained in tp_usrreq()");
                    763:        }
                    764:        splx(s);
                    765:        return error;
                    766: }
                    767: tp_ltrace(so, uio)
                    768: struct socket *so;
                    769: struct uio *uio;
                    770: {
                    771:        IFTRACE(D_DATA)
                    772:                register struct tp_pcb *tpcb =  sototpcb(so);
                    773:                if (tpcb) {
                    774:                        tptraceTPCB(TPPTmisc, "sosend so resid iovcnt", so,
                    775:                                uio->uio_resid, uio->uio_iovcnt, 0);
                    776:                }
                    777:        ENDTRACE
                    778: }
                    779: 
                    780: tp_confirm(tpcb)
                    781: register struct tp_pcb *tpcb;
                    782: {
                    783:        struct tp_event E;
                    784:        if (tpcb->tp_state == TP_CONFIRMING)
                    785:            return DoEvent(T_ACPT_req);
                    786:        printf("Tp confirm called when not confirming; tpcb 0x%x, state 0x%x\n",
                    787:                tpcb, tpcb->tp_state);
                    788:        return 0;
                    789: }
                    790: 
                    791: /*
                    792:  * Process control data sent with sendmsg()
                    793:  */
                    794: tp_snd_control(m, so, data)
                    795:        struct mbuf *m;
                    796:        struct socket *so;
                    797:        register struct mbuf **data;
                    798: {
                    799:        register struct cmsghdr *ch;
                    800:        int error = 0;
                    801: 
                    802:        if (m && m->m_len) {
                    803:                ch = mtod(m, struct cmsghdr *);
                    804:                m->m_len -= sizeof (*ch);
                    805:                m->m_data += sizeof (*ch);
                    806:                error = tp_ctloutput(PRCO_SETOPT,
                    807:                                                         so, ch->cmsg_level, ch->cmsg_type, &m);
                    808:                if (ch->cmsg_type == TPOPT_DISC_DATA) {
                    809:                        if (data && *data) {
                    810:                                m_freem(*data);
                    811:                                *data = 0;
                    812:                        }
                    813:                        error = tp_usrreq(so, PRU_DISCONNECT, (struct mbuf *)0,
                    814:                                                                (caddr_t)0, (struct mbuf *)0);
                    815:                }
                    816:        }
                    817:        if (m)
                    818:                m_freem(m);
                    819:        return error;
                    820: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.