Annotation of kernel/bsd/netiso/tp_usrreq.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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